Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 104542
b: refs/heads/master
c: 8808f00
h: refs/heads/master
v: v3
  • Loading branch information
Alan Stern authored and Greg Kroah-Hartman committed Jul 21, 2008
1 parent 1f39290 commit b6f8788
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 23 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: 6ee0b270c733027b2b716b1c80b9aced41e08d20
refs/heads/master: 8808f00c7adfc8dc0b797c34ec03490b237fce4e
13 changes: 5 additions & 8 deletions trunk/drivers/usb/core/driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -1537,14 +1537,11 @@ static int usb_resume(struct device *dev)
udev = to_usb_device(dev);

/* If udev->skip_sys_resume is set then udev was already suspended
* when the system suspend started, so we don't want to resume
* udev during this system wakeup. However a reset-resume counts
* as a wakeup event, so allow a reset-resume to occur if remote
* wakeup is enabled. */
if (udev->skip_sys_resume) {
if (!(udev->reset_resume && udev->do_remote_wakeup))
return -EHOSTUNREACH;
}
* when the system sleep started, so we don't want to resume it
* during this system wakeup.
*/
if (udev->skip_sys_resume)
return 0;
return usb_external_resume_device(udev);
}

Expand Down
62 changes: 48 additions & 14 deletions trunk/drivers/usb/core/hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -690,18 +690,11 @@ static void hub_restart(struct usb_hub *hub, enum hub_activation_type type)
set_bit(port1, hub->change_bits);

} else if (udev->persist_enabled) {
/* Turn off the status changes to prevent khubd
* from disconnecting the device.
*/
if (portchange & USB_PORT_STAT_C_ENABLE)
clear_port_feature(hub->hdev, port1,
USB_PORT_FEAT_C_ENABLE);
if (portchange & USB_PORT_STAT_C_CONNECTION)
clear_port_feature(hub->hdev, port1,
USB_PORT_FEAT_C_CONNECTION);
#ifdef CONFIG_PM
udev->reset_resume = 1;
#endif
set_bit(port1, hub->change_bits);

} else {
/* The power session is gone; tell khubd */
usb_set_device_state(udev, USB_STATE_NOTATTACHED);
Expand Down Expand Up @@ -2075,17 +2068,16 @@ int usb_port_resume(struct usb_device *udev)
return status;
}

/* caller has locked udev */
static int remote_wakeup(struct usb_device *udev)
{
int status = 0;

usb_lock_device(udev);
if (udev->state == USB_STATE_SUSPENDED) {
dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-");
usb_mark_last_busy(udev);
status = usb_external_resume_device(udev);
}
usb_unlock_device(udev);
return status;
}

Expand Down Expand Up @@ -2632,6 +2624,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
unsigned wHubCharacteristics =
le16_to_cpu(hub->descriptor->wHubCharacteristics);
struct usb_device *udev;
int status, i;

dev_dbg (hub_dev,
Expand Down Expand Up @@ -2666,8 +2659,45 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
}
}

/* Try to resuscitate an existing device */
udev = hdev->children[port1-1];
if ((portstatus & USB_PORT_STAT_CONNECTION) && udev &&
udev->state != USB_STATE_NOTATTACHED) {

usb_lock_device(udev);
if (portstatus & USB_PORT_STAT_ENABLE) {
status = 0; /* Nothing to do */
} else if (!udev->persist_enabled) {
status = -ENODEV; /* Mustn't resuscitate */

#ifdef CONFIG_USB_SUSPEND
} else if (udev->state == USB_STATE_SUSPENDED) {
/* 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;
#endif

} else {
status = usb_reset_composite_device(udev, NULL);
}
usb_unlock_device(udev);

if (status == 0) {
clear_bit(port1, hub->change_bits);
return;
}
}

/* Disconnect any existing devices under this port */
if (hdev->children[port1-1])
if (udev)
usb_disconnect(&hdev->children[port1-1]);
clear_bit(port1, hub->change_bits);

Expand All @@ -2685,7 +2715,6 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
}

for (i = 0; i < SET_CONFIG_TRIES; i++) {
struct usb_device *udev;

/* reallocate for each attempt, since references
* to the previous one can escape in various ways
Expand Down Expand Up @@ -2944,11 +2973,16 @@ static void hub_events(void)
}

if (portchange & USB_PORT_STAT_C_SUSPEND) {
struct usb_device *udev;

clear_port_feature(hdev, i,
USB_PORT_FEAT_C_SUSPEND);
if (hdev->children[i-1]) {
udev = hdev->children[i-1];
if (udev) {
usb_lock_device(udev);
ret = remote_wakeup(hdev->
children[i-1]);
usb_unlock_device(udev);
if (ret < 0)
connect_change = 1;
} else {
Expand Down

0 comments on commit b6f8788

Please sign in to comment.