EHCI controller setup needs to occur prior to checking any UHCI or OHCI ports to ensure a high speed device is not mistakenly configured on a full speed "companion" controller. However, only the UHCI/OHCI port scan needs to be delayed, not the full UHCI/OHCI controller init.
This change moves back the ehci controller setup check until port scan in UHCI/OHCI.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/hw/usb-ehci.c | 8 ++++++-- src/hw/usb-ehci.h | 1 + src/hw/usb-ohci.c | 3 +++ src/hw/usb-uhci.c | 4 ++++ 4 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/src/hw/usb-ehci.c b/src/hw/usb-ehci.c index 41f8579..010746c 100644 --- a/src/hw/usb-ehci.c +++ b/src/hw/usb-ehci.c @@ -337,9 +337,13 @@ ehci_setup(void) if (pci_classprog(pci) == PCI_CLASS_SERIAL_USB_EHCI) ehci_controller_setup(pci); } +}
- // Wait for all EHCI controllers to initialize. This forces OHCI/UHCI - // setup to always be after any EHCI ports are routed to EHCI. +// Wait for all EHCI controllers to initialize. This forces OHCI/UHCI +// setup to always be after any EHCI ports are routed to EHCI. +void +ehci_wait_controllers(void) +{ while (PendingEHCI) yield(); } diff --git a/src/hw/usb-ehci.h b/src/hw/usb-ehci.h index 88f7b6a..0442188 100644 --- a/src/hw/usb-ehci.h +++ b/src/hw/usb-ehci.h @@ -3,6 +3,7 @@
// usb-ehci.c void ehci_setup(void); +void ehci_wait_controllers(void); struct usbdevice_s; struct usb_endpoint_descriptor; struct usb_pipe; diff --git a/src/hw/usb-ohci.c b/src/hw/usb-ohci.c index 42f8a06..7ed964f 100644 --- a/src/hw/usb-ohci.c +++ b/src/hw/usb-ohci.c @@ -14,6 +14,7 @@ #include "pci_regs.h" // PCI_BASE_ADDRESS_0 #include "string.h" // memset #include "usb.h" // struct usb_s +#include "usb-ehci.h" // ehci_wait_controllers #include "usb-ohci.h" // struct ohci_hcca #include "util.h" // msleep #include "x86.h" // readl @@ -96,6 +97,8 @@ static int check_ohci_ports(struct usb_ohci_s *cntl) { ASSERT32FLAT(); + // Wait for ehci init - in case this is a "companion controller" + ehci_wait_controllers(); // Turn on power for all devices on roothub. u32 rha = readl(&cntl->regs->roothub_a); rha &= ~(RH_A_PSM | RH_A_OCPM); diff --git a/src/hw/usb-uhci.c b/src/hw/usb-uhci.c index 69c33ee..6d8aa47 100644 --- a/src/hw/usb-uhci.c +++ b/src/hw/usb-uhci.c @@ -13,6 +13,7 @@ #include "pci_regs.h" // PCI_BASE_ADDRESS_4 #include "string.h" // memset #include "usb.h" // struct usb_s +#include "usb-ehci.h" // ehci_wait_controllers #include "usb-uhci.h" // USBLEGSUP #include "util.h" // msleep #include "x86.h" // outw @@ -94,6 +95,9 @@ static int check_uhci_ports(struct usb_uhci_s *cntl) { ASSERT32FLAT(); + // Wait for ehci init - in case this is a "companion controller" + ehci_wait_controllers(); + struct usbhub_s hub; memset(&hub, 0, sizeof(hub)); hub.cntl = &cntl->usb;