aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2014-09-10 11:04:26 -0400
committerKevin O'Connor <kevin@koconnor.net>2014-09-16 11:16:40 -0400
commite2d6fddcd956b3bbcb9852d8f87ff41eab239a2e (patch)
treebc13e5b406b9eee8e6e010bae4e02d62a1198484
parent57e34016a6e5d0c4ec7766b3f6194ddf51f8bf46 (diff)
downloadseabios-e2d6fddcd956b3bbcb9852d8f87ff41eab239a2e.zip
seabios-e2d6fddcd956b3bbcb9852d8f87ff41eab239a2e.tar.gz
seabios-e2d6fddcd956b3bbcb9852d8f87ff41eab239a2e.tar.bz2
ehci: Stall uhci/ohci init only until default port routing is done.
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@koconnor.net>
-rw-r--r--src/hw/usb-ehci.c31
1 files 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();
}