[SeaBIOS] [PATCH 6/7] ehci: Stall uhci/ohci init only until default port routing is done.

Kevin O'Connor kevin at koconnor.net
Wed Sep 10 20:46:05 CEST 2014


Now that uhci and ohci will continually poll for a device connect, the
ehci controller only needs to ensure that the default routing is setup
properly before allowing uhci and ohci to be initialized.

This also fixes two error paths in configure_ehci() that were not
properly updating PendingEHCIPorts.

Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
 src/hw/usb-ehci.c | 31 +++++++++++++------------------
 1 file changed, 13 insertions(+), 18 deletions(-)

diff --git a/src/hw/usb-ehci.c b/src/hw/usb-ehci.c
index 4e4cc72..86496ce 100644
--- a/src/hw/usb-ehci.c
+++ b/src/hw/usb-ehci.c
@@ -32,7 +32,7 @@ struct ehci_pipe {
     struct usb_pipe pipe;
 };
 
-static int PendingEHCIPorts;
+static int PendingEHCI;
 
 
 /****************************************************************
@@ -52,12 +52,12 @@ ehci_hub_detect(struct usbhub_s *hub, u32 port)
 
     if (!(portsc & PORT_CONNECT))
         // No device present
-        goto doneearly;
+        return -1;
 
     if ((portsc & PORT_LINESTATUS_MASK) == PORT_LINESTATUS_KSTATE) {
         // low speed device
         writel(portreg, portsc | PORT_OWNER);
-        goto doneearly;
+        return -1;
     }
 
     // XXX - if just powered up, need to wait for USB_TIME_ATTDB?
@@ -67,10 +67,6 @@ ehci_hub_detect(struct usbhub_s *hub, u32 port)
     writel(portreg, portsc);
     msleep(USB_TIME_DRSTR);
     return 0;
-
-doneearly:
-    PendingEHCIPorts--;
-    return -1;
 }
 
 // Reset device on port
@@ -86,21 +82,17 @@ ehci_hub_reset(struct usbhub_s *hub, u32 port)
     writel(portreg, portsc);
     msleep(EHCI_TIME_POSTRESET);
 
-    int rv = -1;
     portsc = readl(portreg);
     if (!(portsc & PORT_CONNECT))
         // No longer connected
-        goto resetfail;
+        return -1;
     if (!(portsc & PORT_PE)) {
         // full speed device
         writel(portreg, portsc | PORT_OWNER);
-        goto resetfail;
+        return -1;
     }
 
-    rv = USB_HIGHSPEED;
-resetfail:
-    PendingEHCIPorts--;
-    return rv;
+    return USB_HIGHSPEED;
 }
 
 // Disable port
@@ -230,6 +222,7 @@ configure_ehci(void *data)
     struct ehci_qh *async_qh = memalign_high(EHCI_QH_ALIGN, sizeof(*async_qh));
     if (!fl || !intr_qh || !async_qh) {
         warn_noalloc();
+        PendingEHCI--;
         goto fail;
     }
 
@@ -245,6 +238,7 @@ configure_ehci(void *data)
             break;
         if (timer_check(end)) {
             warn_timeout();
+            PendingEHCI--;
             goto fail;
         }
         yield();
@@ -278,6 +272,7 @@ configure_ehci(void *data)
 
     // Set default of high speed for root hub.
     writel(&cntl->regs->configflag, 1);
+    PendingEHCI--;
 
     // Find devices
     int count = check_ehci_ports(cntl);
@@ -318,7 +313,7 @@ ehci_controller_setup(struct pci_device *pci)
     cntl->regs = (void*)caps + readb(&caps->caplength);
     if (hcc_params & HCC_64BIT_ADDR)
         cntl->regs->ctrldssegment = 0;
-    PendingEHCIPorts += cntl->checkports;
+    PendingEHCI++;
 
     dprintf(1, "EHCI init on dev %02x:%02x.%x (regs=%p)\n"
             , pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf)
@@ -342,9 +337,9 @@ ehci_setup(void)
             ehci_controller_setup(pci);
     }
 
-    // Wait for all EHCI ports to initialize.  This forces OHCI/UHCI
-    // setup to always be after any EHCI ports are set to low speed.
-    while (PendingEHCIPorts)
+    // Wait for all EHCI controllers to initialize.  This forces OHCI/UHCI
+    // setup to always be after any EHCI ports are routed to EHCI.
+    while (PendingEHCI)
         yield();
 }
 
-- 
1.9.3




More information about the SeaBIOS mailing list