summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2010-02-08 09:43:22 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-04-01 15:52:18 -0700
commit88b60df09c5ce701e308e27932fcf1c8a6bc6375 (patch)
treeeb8a0b0dbf3bffbc12296fa25066e904ceaf0462
parente2db86fdddfbf179ebc8e717b50770cf7acf78b6 (diff)
EHCI: fix bug in keeping track of resuming ports
This patch fixes a bug caused by backporting commit cec3a53c7fe794237b582e8e77fc0e48465e65ee (USB: EHCI & UHCI: fix race between root-hub suspend and port resume) to 2.6.27.stable without also backporting commit eafe5b99f2135488b21cf17a262c54997c44f784 (USB: EHCI: fix remote-wakeup support for ARC/TDI core). This extracts the necessary changes from the earlier patch and backports them. The symptom of the bug is that the system will fail to suspend more than once. The problem is caused by setting ehci->reset_done[i] but never clearing it. When ehci_bus_suspend() sees a nonzero value there, it assumes this means the port is in the middle of resuming so it aborts the bus suspend. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Cc: Corey Wright <undefined@pobox.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/host/ehci-hub.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index ef9b0383fed3..f1a29e210af9 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -254,10 +254,8 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
if (test_bit(i, &ehci->bus_suspended) &&
- (temp & PORT_SUSPEND)) {
- ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
+ (temp & PORT_SUSPEND))
temp |= PORT_RESUME;
- }
ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
}
i = HCS_N_PORTS (ehci->hcs_params);
@@ -752,6 +750,9 @@ static int ehci_hub_control (
ehci_readl(ehci, status_reg));
}
+ if (!(temp & (PORT_RESUME|PORT_RESET)))
+ ehci->reset_done[wIndex] = 0;
+
/* transfer dedicated ports to the companion hc */
if ((temp & PORT_CONNECT) &&
test_bit(wIndex, &ehci->companion_ports)) {