aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/hub.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-07-07 02:07:35 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-07 02:07:35 -0400
commitd763d5edf945eec47bd443b699f174976f0afc13 (patch)
tree3e5cd46b9a783999716bf92176854f4f1215d930 /drivers/usb/core/hub.c
parent790e2a290b499b0400254e6870ec27969065d122 (diff)
parent1b40a895df6c7d5a80e71f65674060b03d84bbef (diff)
Merge branch 'linus' into tracing/mmiotrace
Diffstat (limited to 'drivers/usb/core/hub.c')
-rw-r--r--drivers/usb/core/hub.c85
1 files changed, 71 insertions, 14 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index eb57fcc701d7..4cfe32a16c37 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -644,6 +644,48 @@ static void hub_stop(struct usb_hub *hub)
644 644
645#ifdef CONFIG_PM 645#ifdef CONFIG_PM
646 646
647/* Try to identify which devices need USB-PERSIST handling */
648static int persistent_device(struct usb_device *udev)
649{
650 int i;
651 int retval;
652 struct usb_host_config *actconfig;
653
654 /* Explicitly not marked persistent? */
655 if (!udev->persist_enabled)
656 return 0;
657
658 /* No active config? */
659 actconfig = udev->actconfig;
660 if (!actconfig)
661 return 0;
662
663 /* FIXME! We should check whether it's open here or not! */
664
665 /*
666 * Check that all the interface drivers have a
667 * 'reset_resume' entrypoint
668 */
669 retval = 0;
670 for (i = 0; i < actconfig->desc.bNumInterfaces; i++) {
671 struct usb_interface *intf;
672 struct usb_driver *driver;
673
674 intf = actconfig->interface[i];
675 if (!intf->dev.driver)
676 continue;
677 driver = to_usb_driver(intf->dev.driver);
678 if (!driver->reset_resume)
679 return 0;
680 /*
681 * We have at least one driver, and that one
682 * has a reset_resume method.
683 */
684 retval = 1;
685 }
686 return retval;
687}
688
647static void hub_restart(struct usb_hub *hub, int type) 689static void hub_restart(struct usb_hub *hub, int type)
648{ 690{
649 struct usb_device *hdev = hub->hdev; 691 struct usb_device *hdev = hub->hdev;
@@ -671,26 +713,19 @@ static void hub_restart(struct usb_hub *hub, int type)
671 } 713 }
672 714
673 /* Was the power session lost while we were suspended? */ 715 /* Was the power session lost while we were suspended? */
674 switch (type) { 716 status = hub_port_status(hub, port1, &portstatus, &portchange);
675 case HUB_RESET_RESUME:
676 portstatus = 0;
677 portchange = USB_PORT_STAT_C_CONNECTION;
678 break;
679 717
680 case HUB_RESET: 718 /* If the device is gone, khubd will handle it later */
681 case HUB_RESUME: 719 if (status == 0 && !(portstatus & USB_PORT_STAT_CONNECTION))
682 status = hub_port_status(hub, port1, 720 continue;
683 &portstatus, &portchange);
684 break;
685 }
686 721
687 /* For "USB_PERSIST"-enabled children we must 722 /* For "USB_PERSIST"-enabled children we must
688 * mark the child device for reset-resume and 723 * mark the child device for reset-resume and
689 * turn off the various status changes to prevent 724 * turn off the various status changes to prevent
690 * khubd from disconnecting it later. 725 * khubd from disconnecting it later.
691 */ 726 */
692 if (udev->persist_enabled && status == 0 && 727 if (status == 0 && !(portstatus & USB_PORT_STAT_ENABLE) &&
693 !(portstatus & USB_PORT_STAT_ENABLE)) { 728 persistent_device(udev)) {
694 if (portchange & USB_PORT_STAT_C_ENABLE) 729 if (portchange & USB_PORT_STAT_C_ENABLE)
695 clear_port_feature(hub->hdev, port1, 730 clear_port_feature(hub->hdev, port1,
696 USB_PORT_FEAT_C_ENABLE); 731 USB_PORT_FEAT_C_ENABLE);
@@ -1326,6 +1361,12 @@ void usb_disconnect(struct usb_device **pdev)
1326 1361
1327 usb_unlock_device(udev); 1362 usb_unlock_device(udev);
1328 1363
1364 /* Remove the device-specific files from sysfs. This must be
1365 * done with udev unlocked, because some of the attribute
1366 * routines try to acquire the device lock.
1367 */
1368 usb_remove_sysfs_dev_files(udev);
1369
1329 /* Unregister the device. The device driver is responsible 1370 /* Unregister the device. The device driver is responsible
1330 * for removing the device files from usbfs and sysfs and for 1371 * for removing the device files from usbfs and sysfs and for
1331 * de-configuring the device. 1372 * de-configuring the device.
@@ -1541,6 +1582,9 @@ int usb_new_device(struct usb_device *udev)
1541 goto fail; 1582 goto fail;
1542 } 1583 }
1543 1584
1585 /* put device-specific files into sysfs */
1586 usb_create_sysfs_dev_files(udev);
1587
1544 /* Tell the world! */ 1588 /* Tell the world! */
1545 announce_device(udev); 1589 announce_device(udev);
1546 return err; 1590 return err;
@@ -2029,6 +2073,8 @@ int usb_port_resume(struct usb_device *udev)
2029 } 2073 }
2030 2074
2031 clear_bit(port1, hub->busy_bits); 2075 clear_bit(port1, hub->busy_bits);
2076 if (!hub->hdev->parent && !hub->busy_bits[0])
2077 usb_enable_root_hub_irq(hub->hdev->bus);
2032 2078
2033 if (status == 0) 2079 if (status == 0)
2034 status = finish_port_resume(udev); 2080 status = finish_port_resume(udev);
@@ -2744,7 +2790,11 @@ loop:
2744 if ((status == -ENOTCONN) || (status == -ENOTSUPP)) 2790 if ((status == -ENOTCONN) || (status == -ENOTSUPP))
2745 break; 2791 break;
2746 } 2792 }
2747 dev_err(hub_dev, "unable to enumerate USB device on port %d\n", port1); 2793 if (hub->hdev->parent ||
2794 !hcd->driver->port_handed_over ||
2795 !(hcd->driver->port_handed_over)(hcd, port1))
2796 dev_err(hub_dev, "unable to enumerate USB device on port %d\n",
2797 port1);
2748 2798
2749done: 2799done:
2750 hub_port_disable(hub, port1, 1); 2800 hub_port_disable(hub, port1, 1);
@@ -2954,6 +3004,11 @@ static void hub_events(void)
2954 3004
2955 hub->activating = 0; 3005 hub->activating = 0;
2956 3006
3007 /* If this is a root hub, tell the HCD it's okay to
3008 * re-enable port-change interrupts now. */
3009 if (!hdev->parent && !hub->busy_bits[0])
3010 usb_enable_root_hub_irq(hdev->bus);
3011
2957loop_autopm: 3012loop_autopm:
2958 /* Allow autosuspend if we're not going to run again */ 3013 /* Allow autosuspend if we're not going to run again */
2959 if (list_empty(&hub->event_list)) 3014 if (list_empty(&hub->event_list))
@@ -3179,6 +3234,8 @@ int usb_reset_device(struct usb_device *udev)
3179 break; 3234 break;
3180 } 3235 }
3181 clear_bit(port1, parent_hub->busy_bits); 3236 clear_bit(port1, parent_hub->busy_bits);
3237 if (!parent_hdev->parent && !parent_hub->busy_bits[0])
3238 usb_enable_root_hub_irq(parent_hdev->bus);
3182 3239
3183 if (ret < 0) 3240 if (ret < 0)
3184 goto re_enumerate; 3241 goto re_enumerate;