Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 41336
b: refs/heads/master
c: ee49fb5
h: refs/heads/master
v: v3
  • Loading branch information
Alan Stern authored and Greg Kroah-Hartman committed Dec 1, 2006
1 parent d2b8253 commit 520fd38
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 12 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: d25450c68767481f7c9cc4823a6da8235db40be6
refs/heads/master: ee49fb5dc89d34f1794ac9362fa97c1a640f7ddd
34 changes: 23 additions & 11 deletions trunk/drivers/usb/core/driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -1048,7 +1048,7 @@ int usb_suspend_both(struct usb_device *udev, pm_message_t msg)

/* If the suspend succeeded, propagate it up the tree */
} else if (parent)
usb_autosuspend_device(parent, 0);
usb_autosuspend_device(parent, 1);

// dev_dbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status);
return status;
Expand Down Expand Up @@ -1096,9 +1096,25 @@ int usb_resume_both(struct usb_device *udev)
/* Propagate the resume up the tree, if necessary */
if (udev->state == USB_STATE_SUSPENDED) {
if (parent) {
usb_pm_lock(parent);
parent->auto_pm = 1;
status = usb_resume_both(parent);
status = usb_autoresume_device(parent, 1);
if (status == 0) {
status = usb_resume_device(udev);
if (status) {
usb_autosuspend_device(parent, 1);

/* It's possible usb_resume_device()
* failed after the port was
* unsuspended, causing udev to be
* logically disconnected. We don't
* want usb_disconnect() to autosuspend
* the parent again, so tell it that
* udev disconnected while still
* suspended. */
if (udev->state ==
USB_STATE_NOTATTACHED)
udev->discon_suspended = 1;
}
}
} else {

/* We can't progagate beyond the USB subsystem,
Expand All @@ -1107,20 +1123,16 @@ int usb_resume_both(struct usb_device *udev)
if (udev->dev.parent->power.power_state.event !=
PM_EVENT_ON)
status = -EHOSTUNREACH;
}
if (status == 0)
status = usb_resume_device(udev);
if (parent)
usb_pm_unlock(parent);
else
status = usb_resume_device(udev);
}
} else {

/* Needed only for setting udev->dev.power.power_state.event
* and for possible debugging message. */
status = usb_resume_device(udev);
}

/* Now the parent won't suspend until we are finished */

if (status == 0 && udev->actconfig) {
for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
intf = udev->actconfig->interface[i];
Expand Down
14 changes: 14 additions & 0 deletions trunk/drivers/usb/core/hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -1039,6 +1039,8 @@ static void recursively_mark_NOTATTACHED(struct usb_device *udev)
if (udev->children[i])
recursively_mark_NOTATTACHED(udev->children[i]);
}
if (udev->state == USB_STATE_SUSPENDED)
udev->discon_suspended = 1;
udev->state = USB_STATE_NOTATTACHED;
}

Expand Down Expand Up @@ -1228,6 +1230,14 @@ void usb_disconnect(struct usb_device **pdev)
*pdev = NULL;
spin_unlock_irq(&device_state_lock);

/* Decrement the parent's count of unsuspended children */
if (udev->parent) {
usb_pm_lock(udev);
if (!udev->discon_suspended)
usb_autosuspend_device(udev->parent, 1);
usb_pm_unlock(udev);
}

put_device(&udev->dev);
}

Expand Down Expand Up @@ -1356,6 +1366,10 @@ static int __usb_new_device(void *void_data)
goto fail;
}

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

exit:
module_put(THIS_MODULE);
return err;
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ struct usb_device {
u8 portnum; /* Parent port number (origin 1) */
u8 level; /* Number of USB hub ancestors */

unsigned discon_suspended:1; /* Disconnected while suspended */
unsigned have_langid:1; /* whether string_langid is valid */
int string_langid; /* language ID for strings */

Expand Down

0 comments on commit 520fd38

Please sign in to comment.