aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2010-03-20 23:25:11 -0400
committerKevin O'Connor <kevin@koconnor.net>2010-03-20 23:25:11 -0400
commit87ab2fb96e2d19b157fab0443854b4eafa7d67cf (patch)
tree9247768f3b48e0cd2db5c7f6de9f5f24de152737
parentd705e5accd1de84c46c60d1f872e12a5374e8082 (diff)
downloadseabios-87ab2fb96e2d19b157fab0443854b4eafa7d67cf.zip
seabios-87ab2fb96e2d19b157fab0443854b4eafa7d67cf.tar.gz
seabios-87ab2fb96e2d19b157fab0443854b4eafa7d67cf.tar.bz2
Improve USB EHCI timing.
Add a small delay even in non-power-switching mode to ensure device detect completes. Start companion controllers as soon as all port detects are complete - don't wait for ehci device config to complete. This ensure critical high/low speed devices (eg, usb keyboards) are initialized quickly. Also, be sure to disable port on a failed reset.
-rw-r--r--src/usb-ehci.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/src/usb-ehci.c b/src/usb-ehci.c
index 5306705..8e3219f 100644
--- a/src/usb-ehci.c
+++ b/src/usb-ehci.c
@@ -74,18 +74,20 @@ init_ehci_port(void *data)
portsc |= PORT_POWER;
writel(portreg, portsc);
msleep(EHCI_TIME_POSTPOWER);
- portsc = readl(portreg);
+ } else {
+ msleep(1); // XXX - time for connect to be detected.
}
+ portsc = readl(portreg);
if (!(portsc & PORT_CONNECT))
// No device present
- goto done;
+ goto doneearly;
if ((portsc & PORT_LINESTATUS_MASK) == PORT_LINESTATUS_KSTATE) {
// low speed device
cntl->legacycount++;
writel(portreg, portsc | PORT_OWNER);
- goto done;
+ goto doneearly;
}
// XXX - if just powered up, need to wait for USB_TIME_ATTDB?
@@ -109,9 +111,16 @@ init_ehci_port(void *data)
writel(portreg, portsc | PORT_OWNER);
goto resetfail;
}
+
+ if (! --cntl->checkports)
+ ehci_startcompanion(cntl);
+
struct usb_pipe *pipe = usb_set_address(hub, port, USB_HIGHSPEED);
- if (!pipe)
- goto resetfail;
+ if (!pipe) {
+ writel(portreg, portsc & ~PORT_PE);
+ mutex_unlock(&cntl->usb.resetlock);
+ goto done;
+ }
mutex_unlock(&cntl->usb.resetlock);
// Configure port
@@ -122,13 +131,14 @@ init_ehci_port(void *data)
writel(portreg, portsc & ~PORT_PE);
hub->devcount += count;
done:
- if (! --cntl->checkports)
- ehci_startcompanion(cntl);
hub->threads--;
return;
resetfail:
mutex_unlock(&cntl->usb.resetlock);
+doneearly:
+ if (! --cntl->checkports)
+ ehci_startcompanion(cntl);
goto done;
}