]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
USB: add missing delay during remote wakeup
authorAlan Stern <stern@rowland.harvard.edu>
Fri, 8 Jan 2010 16:18:38 +0000 (11:18 -0500)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 28 Jan 2010 23:20:32 +0000 (15:20 -0800)
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>
drivers/usb/core/hub.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/uhci-hub.c

index 769f80f6e8024204e96200b4d572ec69f01e1478..3240519ad6c4a406640ecf5747f97a78578752e2 100644 (file)
@@ -3015,6 +3015,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]);
index df7b60575f77583f153c700b3588d828a0415f02..6ef2a89281866e3b61d00e538f3b72f28ce10ee2 100644 (file)
@@ -723,9 +723,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]);
                }
index 885b585360b967f23661c015dd8945371f5fa058..8270055848cacd2a8e32379d873b1f624006db71 100644 (file)
@@ -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. */