summaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2008-07-21 09:56:26 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2008-08-13 17:32:49 -0700
commit38b375d9610e2467cb793a84d17c6f65e44cdb39 (patch)
treebaade98427207a0086b018b153947ae2da7a5802 /drivers/usb/host
parentfa41019c7aa172fde075849834409d23eb49f582 (diff)
downloadop-kernel-dev-38b375d9610e2467cb793a84d17c6f65e44cdb39.zip
op-kernel-dev-38b375d9610e2467cb793a84d17c6f65e44cdb39.tar.gz
USB: OHCI: fix system hang caused by earlier patch
This patch (as1114) fixes a problem that was revealed by an earlier patch (as1069b). Some broken controllers seem never to turn off their RHCS interrupt status bit, even when told to do so. As a result they generate an interrupt storm and hang the system. The patch avoids enabling RHSC interrupt requests when the RHCS status bit is already set. This should have no adverse affects on normal controllers, since they won't set the status bit until a root-hub status change actually occurs, in which case we wouldn't enable RHSC interrupt requests anyway -- we would wait until the status change had been processed and cleared. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Tested by: Andrey Borzenkov <arvidjaar@mail.ru> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/ohci-hub.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index b567392..d54183f 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -483,6 +483,13 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
length++;
}
+ /* Some broken controllers never turn off RHCS in the interrupt
+ * status register. For their sake we won't re-enable RHSC
+ * interrupts if the flag is already set.
+ */
+ if (ohci_readl(ohci, &ohci->regs->intrstatus) & OHCI_INTR_RHSC)
+ changed = 1;
+
/* look at each port */
for (i = 0; i < ohci->num_ports; i++) {
u32 status = roothub_portstatus (ohci, i);
OpenPOWER on IntegriCloud