commit 583ceada075597a5b6acab1140d61ac81586a2a6
tree 27ea85087cc6d09333f0121534e866f5e65c1c83
parent 51b5bce8c253b82d4789161cc3b0c74bee313bb1
author Alan Stern <[EMAIL PROTECTED]> 1161705862 -0400
committer Greg Kroah-Hartman <[EMAIL PROTECTED]> 1163715971 -0800

USB: OHCI: fix root-hub resume bug

When a suspended OHCI controller sees a port's status change, it sets
both the Root-Hub-Status-Change and the Resume-Detect bits in the
Interrupt Status register.  Processing both these bits, the driver
tries to resume the root hub twice!

This patch (as807) fixes the bug by ignoring RD if RHSC is set.  It
also prints a slightly more informative log message when a
remote-wakeup event occurs.

Signed-off-by: Alan Stern <[EMAIL PROTECTED]>
Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]>


 drivers/usb/host/ohci-hcd.c |   25 +++++++++++++++----------
 drivers/usb/host/ohci-hub.c |    3 ++-
 2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 9be6b30..ea4714e 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -715,13 +715,6 @@ static irqreturn_t ohci_irq (struct usb_
                return IRQ_NOTMINE;
        }
 
-       if (ints & OHCI_INTR_RHSC) {
-               ohci_vdbg (ohci, "rhsc\n");
-               ohci->next_statechange = jiffies + STATECHANGE_DELAY;
-               ohci_writel (ohci, OHCI_INTR_RHSC, &regs->intrstatus);
-               usb_hcd_poll_rh_status(hcd);
-       }
-
        if (ints & OHCI_INTR_UE) {
                disable (ohci);
                ohci_err (ohci, "OHCI Unrecoverable Error, disabled\n");
@@ -731,9 +724,21 @@ static irqreturn_t ohci_irq (struct usb_
                ohci_usb_reset (ohci);
        }
 
-       if (ints & OHCI_INTR_RD) {
-               ohci_vdbg (ohci, "resume detect\n");
-               ohci_writel (ohci, OHCI_INTR_RD, &regs->intrstatus);
+       if (ints & OHCI_INTR_RHSC) {
+               ohci_vdbg(ohci, "rhsc\n");
+               ohci->next_statechange = jiffies + STATECHANGE_DELAY;
+               ohci_writel(ohci, OHCI_INTR_RD | OHCI_INTR_RHSC,
+                               &regs->intrstatus);
+               usb_hcd_poll_rh_status(hcd);
+       }
+
+       /* For connect and disconnect events, we expect the controller
+        * to turn on RHSC along with RD.  But for remote wakeup events
+        * this might not happen.
+        */
+       else if (ints & OHCI_INTR_RD) {
+               ohci_vdbg(ohci, "resume detect\n");
+               ohci_writel(ohci, OHCI_INTR_RD, &regs->intrstatus);
                hcd->poll_rh = 1;
                if (ohci->autostop) {
                        spin_lock (&ohci->lock);
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index da09e79..6995ea3 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -169,7 +169,8 @@ __acquires(ohci->lock)
                break;
        case OHCI_USB_RESUME:
                /* HCFS changes sometime after INTR_RD */
-               ohci_info (ohci, "wakeup\n");
+               ohci_info(ohci, "%swakeup\n",
+                               autostopped ? "auto-" : "");
                break;
        case OHCI_USB_OPER:
                /* this can happen after resuming a swsusp snapshot */
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to