summaryrefslogtreecommitdiffstats
path: root/src/drivers/usb
diff options
context:
space:
mode:
authorMichael Brown2015-05-08 17:51:12 +0200
committerMichael Brown2015-05-09 21:09:08 +0200
commit9ea8a2daa7ffd489898318c038fcfd7edc810adc (patch)
tree200d5ebc4de94ef5665c81ca7948b0c7230be5ef /src/drivers/usb
parent[usb] Add find_usb_bus_by_location() helper function (diff)
downloadipxe-9ea8a2daa7ffd489898318c038fcfd7edc810adc.tar.gz
ipxe-9ea8a2daa7ffd489898318c038fcfd7edc810adc.tar.xz
ipxe-9ea8a2daa7ffd489898318c038fcfd7edc810adc.zip
[ehci] Allow UHCI/OHCI controllers to locate the EHCI companion controller
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers/usb')
-rw-r--r--src/drivers/usb/ehci.c26
-rw-r--r--src/drivers/usb/ehci.h2
2 files changed, 28 insertions, 0 deletions
diff --git a/src/drivers/usb/ehci.c b/src/drivers/usb/ehci.c
index e847c6b7..516ffd8c 100644
--- a/src/drivers/usb/ehci.c
+++ b/src/drivers/usb/ehci.c
@@ -337,6 +337,32 @@ static void ehci_poll_companions ( struct ehci_device *ehci ) {
}
}
+/**
+ * Locate EHCI companion controller
+ *
+ * @v pci PCI device
+ * @ret busdevfn EHCI companion controller bus:dev.fn (if any)
+ */
+unsigned int ehci_companion ( struct pci_device *pci ) {
+ struct pci_device tmp;
+ unsigned int busdevfn;
+ int rc;
+
+ /* Look for an EHCI function on the same PCI device */
+ busdevfn = pci->busdevfn;
+ while ( ++busdevfn <= PCI_LAST_FUNC ( pci->busdevfn ) ) {
+ pci_init ( &tmp, busdevfn );
+ if ( ( rc = pci_read_config ( &tmp ) ) != 0 )
+ continue;
+ if ( tmp.class == PCI_CLASS ( PCI_CLASS_SERIAL,
+ PCI_CLASS_SERIAL_USB,
+ PCI_CLASS_SERIAL_USB_EHCI ) )
+ return busdevfn;
+ }
+
+ return 0;
+}
+
/******************************************************************************
*
* Run / stop / reset
diff --git a/src/drivers/usb/ehci.h b/src/drivers/usb/ehci.h
index d8814ec7..f35a07ce 100644
--- a/src/drivers/usb/ehci.h
+++ b/src/drivers/usb/ehci.h
@@ -537,4 +537,6 @@ struct ehci_endpoint {
struct ehci_ring ring;
};
+extern unsigned int ehci_companion ( struct pci_device *pci );
+
#endif /* _IPXE_EHCI_H */