diff options
author | Nico Huber <nico.huber@secunet.com> | 2012-11-22 15:45:48 +0100 |
---|---|---|
committer | Patrick Georgi <patrick@georgi-clan.de> | 2012-11-24 08:46:34 +0100 |
commit | b9917c20683258b5736a05fd384f7b52e53e02f9 (patch) | |
tree | 37e8b9dfa90ec11bf55b7fa8e17af116edc22c78 | |
parent | be58fee28e9f0c4d8f196added0105a101512acc (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.c | 19 |
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); } |