path: root/drivers
diff options
authorAlan Stern <stern@rowland.harvard.edu>2009-07-22 14:42:54 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-09-23 06:46:30 -0700
commit527101ce6a96c037a2555aa43222faa6fdd21e97 (patch)
treebfe5f573b7e30dad062aa5b7aa2de8b8413c75ae /drivers
parent25118084ef03f4fc314ab33ef6a9d9271d0e616a (diff)
USB: don't lose mode switch events on suspended devices
This patch (as1268) changes the way usbcore handles child devices that undergo a disconnection and reconnection while the parent hub is suspended. Currently, if the child isn't enabled for remote wakeup we leave it alone, figuring that it will go through a reset-resume when somebody tries to use it. However this isn't a good approach if the reason for the disconnection is that the child decided to switch modes or in some other way alter its descriptors. In that case we want to re-enumerate it as soon as possible, not wait until somebody forces a reset-resume. To resolve the issue, this patch treats reconnected suspended child devices as though they had requested a remote wakeup, even if they weren't enabled for it. The mode switch or descriptor change will be detected during the reset part of the reset-resume, and the device will be re-enumerated immediately. The disadvantage of this change is that it will cause autosuspended devices to be resumed when the computer wakes up from a system sleep during which the root hub was reset or lost power. This shouldn't matter much; some people would even argue that autosuspended devices should _always_ be resumed when the system wakes up! Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Tested-by: "Yang Fei-AFY095" <fei.yang@motorola.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
1 files changed, 1 insertions, 8 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 645686a1421..a880516020f 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2932,14 +2932,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
/* For a suspended device, treat this as a
* remote wakeup event.
- if (udev->do_remote_wakeup)
- status = remote_wakeup(udev);
- /* Otherwise leave it be; devices can't tell the
- * difference between suspended and disabled.
- */
- else
- status = 0;
+ status = remote_wakeup(udev);
} else {