Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 104630
b: refs/heads/master
c: 86c57ed
h: refs/heads/master
v: v3
  • Loading branch information
Alan Stern authored and Greg Kroah-Hartman committed Jul 21, 2008
1 parent 930e6c7 commit a4be9e8
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 6 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ac90e36592ea5171c4e70f58b39a782d871a7d9f
refs/heads/master: 86c57edf60f5c98adb496880f56cd0e5a3423153
7 changes: 5 additions & 2 deletions trunk/Documentation/usb/persist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,11 @@ re-enumeration shows that the device now attached to that port has the
same descriptors as before, including the Vendor and Product IDs, then
the kernel continues to use the same device structure. In effect, the
kernel treats the device as though it had merely been reset instead of
unplugged. The same thing happens if the host controller is in the
expected state but a USB device was unplugged and then replugged.
unplugged.

The same thing happens if the host controller is in the expected state
but a USB device was unplugged and then replugged, or if a USB device
fails to carry out a normal resume.

If no device is now attached to the port, or if the descriptors are
different from what the kernel remembers, then the treatment is what
Expand Down
20 changes: 17 additions & 3 deletions trunk/drivers/usb/core/hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -1822,9 +1822,15 @@ static int check_port_resume_type(struct usb_device *udev,
status = -ENODEV;
}

/* Can't do a normal resume if the port isn't enabled */
else if (!(portstatus & USB_PORT_STAT_ENABLE) && !udev->reset_resume)
status = -ENODEV;
/* Can't do a normal resume if the port isn't enabled,
* so try a reset-resume instead.
*/
else if (!(portstatus & USB_PORT_STAT_ENABLE) && !udev->reset_resume) {
if (udev->persist_enabled)
udev->reset_resume = 1;
else
status = -ENODEV;
}

if (status) {
dev_dbg(hub->intfdev,
Expand Down Expand Up @@ -1973,6 +1979,7 @@ static int finish_port_resume(struct usb_device *udev)
* resumed.
*/
if (udev->reset_resume)
retry_reset_resume:
status = usb_reset_and_verify_device(udev);

/* 10.5.4.5 says be sure devices in the tree are still there.
Expand All @@ -1984,6 +1991,13 @@ static int finish_port_resume(struct usb_device *udev)
status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus);
if (status >= 0)
status = (status > 0 ? 0 : -ENODEV);

/* If a normal resume failed, try doing a reset-resume */
if (status && !udev->reset_resume && udev->persist_enabled) {
dev_dbg(&udev->dev, "retry with reset-resume\n");
udev->reset_resume = 1;
goto retry_reset_resume;
}
}

if (status) {
Expand Down

0 comments on commit a4be9e8

Please sign in to comment.