Skip to content

Commit

Permalink
USB: retain USB device power/wakeup setting across reconfiguration
Browse files Browse the repository at this point in the history
Currently a non-root-hub USB device's wakeup settings are initialized when the
device is set to a configured state using device_init_wakeup(), but this is not
correct as wakeup is split into "capable" (can_wakeup) and "enabled"
(should_wakeup).  The settings should be initialized instead in the device
initialization (usb_new_device) with the "capable" setting disabled and the
"enabled" setting enabled.  The "capable" setting should be set based on the
device being configured or unconfigured, and "enabled" setting set based on
the sysfs power/wakeup control.

This patch retains the sysfs power/wakeup setting of a non-root-hub USB device
over a USB device re-configuration, which can happen (for example) after a
suspend/resume cycle.

Signed-off-by: Dan Streetman <ddstreet@ieee.org>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Cc: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Dan Streetman authored and Greg Kroah-Hartman committed Mar 2, 2010
1 parent ce12664 commit 1698540
Showing 1 changed file with 12 additions and 4 deletions.
16 changes: 12 additions & 4 deletions drivers/usb/core/hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -1448,11 +1448,11 @@ void usb_set_device_state(struct usb_device *udev,
|| new_state == USB_STATE_SUSPENDED)
; /* No change to wakeup settings */
else if (new_state == USB_STATE_CONFIGURED)
device_init_wakeup(&udev->dev,
device_set_wakeup_capable(&udev->dev,
(udev->actconfig->desc.bmAttributes
& USB_CONFIG_ATT_WAKEUP));
else
device_init_wakeup(&udev->dev, 0);
device_set_wakeup_capable(&udev->dev, 0);
}
if (udev->state == USB_STATE_SUSPENDED &&
new_state != USB_STATE_SUSPENDED)
Expand Down Expand Up @@ -1799,10 +1799,18 @@ int usb_new_device(struct usb_device *udev)
{
int err;

/* Increment the parent's count of unsuspended children */
if (udev->parent)
if (udev->parent) {
/* Increment the parent's count of unsuspended children */
usb_autoresume_device(udev->parent);

/* Initialize non-root-hub device wakeup to disabled;
* device (un)configuration controls wakeup capable
* sysfs power/wakeup controls wakeup enabled/disabled
*/
device_init_wakeup(&udev->dev, 0);
device_set_wakeup_enable(&udev->dev, 1);
}

usb_detect_quirks(udev);
err = usb_enumerate_device(udev); /* Read descriptors */
if (err < 0)
Expand Down

0 comments on commit 1698540

Please sign in to comment.