summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNico Huber <nico.huber@secunet.com>2012-11-22 15:45:48 +0100
committerPatrick Georgi <patrick@georgi-clan.de>2012-11-24 08:46:34 +0100
commitb9917c20683258b5736a05fd384f7b52e53e02f9 (patch)
tree37e8b9dfa90ec11bf55b7fa8e17af116edc22c78
parentbe58fee28e9f0c4d8f196added0105a101512acc (diff)
libpayload: Rework connection state detection for OHCI
The connection state detection in the OHCI root hub driver was broken if you used more than one device per root hub. Change-Id: Ica5c735426beac45ef6f591ce68a72d8283a00f5 Signed-off-by: Nico Huber <nico.huber@secunet.com> Reviewed-on: http://review.coreboot.org/1904 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
-rw-r--r--payloads/libpayload/drivers/usb/ohci_rh.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/payloads/libpayload/drivers/usb/ohci_rh.c b/payloads/libpayload/drivers/usb/ohci_rh.c
index 9de2b981f8..aa44f338ec 100644
--- a/payloads/libpayload/drivers/usb/ohci_rh.c
+++ b/payloads/libpayload/drivers/usb/ohci_rh.c
@@ -128,15 +128,14 @@ ohci_rh_scanport (usbdev_t *dev, int port)
static int
ohci_rh_report_port_changes (usbdev_t *dev)
{
- int i;
+ ohci_t *const ohcic = OHCI_INST (dev->controller);
- if (!(OHCI_INST (dev->controller)->opreg->HcInterruptStatus & RootHubStatusChange)) return -1;
- OHCI_INST (dev->controller)->opreg->HcInterruptStatus = RootHubStatusChange;
- usb_debug("port change\n");
+ int i;
for (i = 0; i < RH_INST(dev)->numports; i++) {
// maybe detach+attach happened between two scans?
- if (OHCI_INST (dev->controller)->opreg->HcRhPortStatus[i] & ConnectStatusChange) {
+ if (ohcic->opreg->HcRhPortStatus[i] & ConnectStatusChange) {
+ ohcic->opreg->HcRhPortStatus[i] = ConnectStatusChange;
usb_debug("attachment change on port %d\n", i);
return i;
}
@@ -158,7 +157,17 @@ ohci_rh_destroy (usbdev_t *dev)
static void
ohci_rh_poll (usbdev_t *dev)
{
+ ohci_t *const ohcic = OHCI_INST (dev->controller);
+
int port;
+
+ /* Check if anything changed. */
+ if (!(ohcic->opreg->HcInterruptStatus & RootHubStatusChange))
+ return;
+ ohcic->opreg->HcInterruptStatus = RootHubStatusChange;
+ usb_debug("root hub status change\n");
+
+ /* Scan ports with changed connection status. */
while ((port = ohci_rh_report_port_changes (dev)) != -1)
ohci_rh_scanport (dev, port);
}