aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/hub.c
diff options
context:
space:
mode:
authorDavid Brownell <david-b@pacbell.net>2005-09-23 01:32:24 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-10-28 19:47:40 -0400
commit979d5199fee9e80290ddeb532e5993bd15506712 (patch)
tree6987772d41ec540b7e32beaa50c1493a95e3e2c8 /drivers/usb/core/hub.c
parent9293677af3dace2645dec0d0808efa02d36bf47b (diff)
[PATCH] root hub changes (lesser half)
This patch collects various small updates related to root hubs, to shrink later patches which build on them. - For root hub suspend/resume support: * Make the existing usb_hcd_resume_root_hub() routine respect pmcore locking, exporting and using the dpm_runtime_resume() method. * Add a new usb_hcd_suspend_root_hub() to pair with that routine. (Essential to make OHCI autosuspend behave again...) * HC_SUSPENDED by itself only refers to the root hub's downstream ports. So let HCDs see root hub URBs unless the parent device is suspended. - Remove an assertion we no longer need (and now, also don't want). - Generic suspend/resume updates to work better with swsusp. * Ignore the FREEZE vs SUSPEND distinction for hardware; trying to use it breaks the swsusp snapshots it's supposed to help (sigh). * On resume, mark devices as resumed right away, but then do nothing else if the device is marked NOTATTACHED. These changes shouldn't be very noticable by themselves. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> drivers/base/power/runtime.c | 1 drivers/usb/core/hcd.c | 64 ++++++++++++++++++++++++++++++++++++++----- drivers/usb/core/hcd.h | 1 drivers/usb/core/hub.c | 45 ++++++++++++++++++++++++------ drivers/usb/core/usb.c | 20 +++++++++---- drivers/usb/core/usb.h | 1 6 files changed, 111 insertions(+), 21 deletions(-)
Diffstat (limited to 'drivers/usb/core/hub.c')
-rw-r--r--drivers/usb/core/hub.c45
1 files changed, 37 insertions, 8 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 660064466791..3c8d8d1f993c 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -449,11 +449,18 @@ static void hub_power_on(struct usb_hub *hub)
449 msleep(max(pgood_delay, (unsigned) 100)); 449 msleep(max(pgood_delay, (unsigned) 100));
450} 450}
451 451
452static void hub_quiesce(struct usb_hub *hub) 452static inline void __hub_quiesce(struct usb_hub *hub)
453{ 453{
454 /* stop khubd and related activity */ 454 /* (nonblocking) khubd and related activity won't re-trigger */
455 hub->quiescing = 1; 455 hub->quiescing = 1;
456 hub->activating = 0; 456 hub->activating = 0;
457 hub->resume_root_hub = 0;
458}
459
460static void hub_quiesce(struct usb_hub *hub)
461{
462 /* (blocking) stop khubd and related activity */
463 __hub_quiesce(hub);
457 usb_kill_urb(hub->urb); 464 usb_kill_urb(hub->urb);
458 if (hub->has_indicators) 465 if (hub->has_indicators)
459 cancel_delayed_work(&hub->leds); 466 cancel_delayed_work(&hub->leds);
@@ -467,6 +474,7 @@ static void hub_activate(struct usb_hub *hub)
467 474
468 hub->quiescing = 0; 475 hub->quiescing = 0;
469 hub->activating = 1; 476 hub->activating = 1;
477 hub->resume_root_hub = 0;
470 status = usb_submit_urb(hub->urb, GFP_NOIO); 478 status = usb_submit_urb(hub->urb, GFP_NOIO);
471 if (status < 0) 479 if (status < 0)
472 dev_err(hub->intfdev, "activate --> %d\n", status); 480 dev_err(hub->intfdev, "activate --> %d\n", status);
@@ -1959,6 +1967,18 @@ static int hub_resume(struct usb_interface *intf)
1959 return 0; 1967 return 0;
1960} 1968}
1961 1969
1970void usb_suspend_root_hub(struct usb_device *hdev)
1971{
1972 struct usb_hub *hub = hdev_to_hub(hdev);
1973
1974 /* This also makes any led blinker stop retriggering. We're called
1975 * from irq, so the blinker might still be scheduled. Caller promises
1976 * that the root hub status URB will be canceled.
1977 */
1978 __hub_quiesce(hub);
1979 mark_quiesced(to_usb_interface(hub->intfdev));
1980}
1981
1962void usb_resume_root_hub(struct usb_device *hdev) 1982void usb_resume_root_hub(struct usb_device *hdev)
1963{ 1983{
1964 struct usb_hub *hub = hdev_to_hub(hdev); 1984 struct usb_hub *hub = hdev_to_hub(hdev);
@@ -2616,21 +2636,30 @@ static void hub_events(void)
2616 intf = to_usb_interface(hub->intfdev); 2636 intf = to_usb_interface(hub->intfdev);
2617 hub_dev = &intf->dev; 2637 hub_dev = &intf->dev;
2618 2638
2619 dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n", 2639 i = hub->resume_root_hub;
2640
2641 dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x%s\n",
2620 hdev->state, hub->descriptor 2642 hdev->state, hub->descriptor
2621 ? hub->descriptor->bNbrPorts 2643 ? hub->descriptor->bNbrPorts
2622 : 0, 2644 : 0,
2623 /* NOTE: expects max 15 ports... */ 2645 /* NOTE: expects max 15 ports... */
2624 (u16) hub->change_bits[0], 2646 (u16) hub->change_bits[0],
2625 (u16) hub->event_bits[0]); 2647 (u16) hub->event_bits[0],
2648 i ? ", resume root" : "");
2626 2649
2627 usb_get_intf(intf); 2650 usb_get_intf(intf);
2628 i = hub->resume_root_hub;
2629 spin_unlock_irq(&hub_event_lock); 2651 spin_unlock_irq(&hub_event_lock);
2630 2652
2631 /* Is this is a root hub wanting to be resumed? */ 2653 /* Is this is a root hub wanting to reactivate the downstream
2632 if (i) 2654 * ports? If so, be sure the interface resumes even if its
2633 usb_resume_device(hdev); 2655 * stub "device" node was never suspended.
2656 */
2657 if (i) {
2658 extern void dpm_runtime_resume(struct device *);
2659
2660 dpm_runtime_resume(&hdev->dev);
2661 dpm_runtime_resume(&intf->dev);
2662 }
2634 2663
2635 /* Lock the device, then check to see if we were 2664 /* Lock the device, then check to see if we were
2636 * disconnected while waiting for the lock to succeed. */ 2665 * disconnected while waiting for the lock to succeed. */