summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2010-01-08 11:18:38 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-04-01 15:55:36 -0700
commit09524c55c1748d21ab45b4e9e4419b42d669685b (patch)
treefc00d6715fafdefa4b6848d2cd7c19e5111767ad /drivers
parent4bbb96c37a538469960a95333a4f1bf74efedc94 (diff)
downloadlwn-09524c55c1748d21ab45b4e9e4419b42d669685b.tar.gz
lwn-09524c55c1748d21ab45b4e9e4419b42d669685b.zip
USB: add missing delay during remote wakeup
commit 49d0f078f494b9d81e820a13dd8093a9bfb0b6b1 upstream. This patch (as1330) fixes a bug in khbud's handling of remote wakeups. When a device sends a remote-wakeup request, the parent hub (or the host controller driver, for directly attached devices) begins the resume sequence and notifies khubd when the sequence finishes. At this point the port's SUSPEND feature is automatically turned off. However the device needs an additional 10-ms resume-recovery time (TRSMRCY in the USB spec). Khubd does not wait for this delay if the SUSPEND feature is off, and as a result some devices fail to behave properly following a remote wakeup. This patch adds the missing delay to the remote-wakeup path. It also extends the resume-signalling delay used by ehci-hcd and uhci-hcd from 20 ms (the value in the spec) to 25 ms (the value we use for non-remote-wakeup resumes). The extra time appears to help some devices. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Cc: Rickard Bellini <rickard.bellini@ericsson.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/core/hub.c3
-rw-r--r--drivers/usb/host/ehci-hcd.c5
-rw-r--r--drivers/usb/host/uhci-hub.c2
3 files changed, 7 insertions, 3 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index b41989e0c6c1..e9e170519597 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3188,6 +3188,9 @@ static void hub_events(void)
USB_PORT_FEAT_C_SUSPEND);
udev = hdev->children[i-1];
if (udev) {
+ /* TRSMRCY = 10 msec */
+ msleep(10);
+
usb_lock_device(udev);
ret = remote_wakeup(hdev->
children[i-1]);
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 7e4b381716a7..73502b1d87b3 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -764,9 +764,10 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
/* start 20 msec resume signaling from this port,
* and make khubd collect PORT_STAT_C_SUSPEND to
- * stop that signaling.
+ * stop that signaling. Use 5 ms extra for safety,
+ * like usb_port_resume() does.
*/
- ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
+ ehci->reset_done[i] = jiffies + msecs_to_jiffies(25);
ehci_dbg (ehci, "port %d remote wakeup\n", i + 1);
mod_timer(&hcd->rh_timer, ehci->reset_done[i]);
}
diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c
index 885b585360b9..8270055848ca 100644
--- a/drivers/usb/host/uhci-hub.c
+++ b/drivers/usb/host/uhci-hub.c
@@ -167,7 +167,7 @@ static void uhci_check_ports(struct uhci_hcd *uhci)
/* Port received a wakeup request */
set_bit(port, &uhci->resuming_ports);
uhci->ports_timeout = jiffies +
- msecs_to_jiffies(20);
+ msecs_to_jiffies(25);
/* Make sure we see the port again
* after the resuming period is over. */