aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2015-05-08 16:51:12 +0100
committerMichael Brown <mcb30@ipxe.org>2015-05-09 20:09:08 +0100
commit9ea8a2daa7ffd489898318c038fcfd7edc810adc (patch)
tree200d5ebc4de94ef5665c81ca7948b0c7230be5ef /src
parenta66fd8920df1e0a534d0a8ed68adb6143a304a66 (diff)
downloadipxe-9ea8a2daa7ffd489898318c038fcfd7edc810adc.zip
ipxe-9ea8a2daa7ffd489898318c038fcfd7edc810adc.tar.gz
ipxe-9ea8a2daa7ffd489898318c038fcfd7edc810adc.tar.bz2
[ehci] Allow UHCI/OHCI controllers to locate the EHCI companion controller
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src')
-rw-r--r--src/drivers/usb/ehci.c26
-rw-r--r--src/drivers/usb/ehci.h2
-rw-r--r--src/include/ipxe/pci.h1
3 files changed, 29 insertions, 0 deletions
diff --git a/src/drivers/usb/ehci.c b/src/drivers/usb/ehci.c
index e847c6b..516ffd8 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 d8814ec..f35a07c 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 */
diff --git a/src/include/ipxe/pci.h b/src/include/ipxe/pci.h
index ccc42fe..a841e00 100644
--- a/src/include/ipxe/pci.h
+++ b/src/include/ipxe/pci.h
@@ -239,6 +239,7 @@ struct pci_driver {
#define PCI_BUSDEVFN( bus, slot, func ) \
( ( (bus) << 8 ) | ( (slot) << 3 ) | ( (func) << 0 ) )
#define PCI_FIRST_FUNC( busdevfn ) ( (busdevfn) & ~0x07 )
+#define PCI_LAST_FUNC( busdevfn ) ( (busdevfn) | 0x07 )
#define PCI_BASE_CLASS( class ) ( (class) >> 16 )
#define PCI_SUB_CLASS( class ) ( ( (class) >> 8 ) & 0xff )