diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2008-04-28 11:06:55 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-07-21 18:15:51 -0400 |
commit | 8808f00c7adfc8dc0b797c34ec03490b237fce4e (patch) | |
tree | 0062a4de8f9957faa51b96bb17351c3ca48c41a1 /drivers/usb/core/driver.c | |
parent | 6ee0b270c733027b2b716b1c80b9aced41e08d20 (diff) |
USB: try to salvage lost power sessions
This patch (as1073) adds to khubd a way to recover from power-session
interruption caused by transient connect-change or enable-change
events. After the debouncing period, khubd attempts to do a
USB-Persist-style reset or reset-resume. If it works, the connection
will remain unscathed.
The upshot is that we will be more immune to noise caused by EMI. The
grace period is on the order of 100 ms, so this won't permit recovery
from the "accidentally knocked the USB cable out of its socket" type
of event, but it's a start.
As an added bonus, if a device was suspended when the system goes to
sleep then we no longer need to check for power-session interruptions
when the system wakes up. Khubd will naturally see the status change
while processing the device's parent hub and will do the right thing.
The remote_wakeup() routine is changed; now it expects the caller to
acquire the device lock rather than acquiring the lock itself.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/core/driver.c')
-rw-r--r-- | drivers/usb/core/driver.c | 13 |
1 files changed, 5 insertions, 8 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index bf1585b203c..0a0e8cea0af 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -1537,14 +1537,11 @@ static int usb_resume(struct device *dev) | |||
1537 | udev = to_usb_device(dev); | 1537 | udev = to_usb_device(dev); |
1538 | 1538 | ||
1539 | /* If udev->skip_sys_resume is set then udev was already suspended | 1539 | /* If udev->skip_sys_resume is set then udev was already suspended |
1540 | * when the system suspend started, so we don't want to resume | 1540 | * when the system sleep started, so we don't want to resume it |
1541 | * udev during this system wakeup. However a reset-resume counts | 1541 | * during this system wakeup. |
1542 | * as a wakeup event, so allow a reset-resume to occur if remote | 1542 | */ |
1543 | * wakeup is enabled. */ | 1543 | if (udev->skip_sys_resume) |
1544 | if (udev->skip_sys_resume) { | 1544 | return 0; |
1545 | if (!(udev->reset_resume && udev->do_remote_wakeup)) | ||
1546 | return -EHOSTUNREACH; | ||
1547 | } | ||
1548 | return usb_external_resume_device(udev); | 1545 | return usb_external_resume_device(udev); |
1549 | } | 1546 | } |
1550 | 1547 | ||