aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/core/hub.c34
1 files changed, 15 insertions, 19 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 37c67d7e8b84..e1731ff8af4d 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -525,15 +525,16 @@ static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
525 525
526 526
527/* caller has locked the hub device */ 527/* caller has locked the hub device */
528static void hub_pre_reset(struct usb_hub *hub, int disable_ports) 528static void hub_pre_reset(struct usb_interface *intf)
529{ 529{
530 struct usb_hub *hub = usb_get_intfdata(intf);
530 struct usb_device *hdev = hub->hdev; 531 struct usb_device *hdev = hub->hdev;
531 int port1; 532 int port1;
532 533
533 for (port1 = 1; port1 <= hdev->maxchild; ++port1) { 534 for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
534 if (hdev->children[port1 - 1]) { 535 if (hdev->children[port1 - 1]) {
535 usb_disconnect(&hdev->children[port1 - 1]); 536 usb_disconnect(&hdev->children[port1 - 1]);
536 if (disable_ports) 537 if (hub->error == 0)
537 hub_port_disable(hub, port1, 0); 538 hub_port_disable(hub, port1, 0);
538 } 539 }
539 } 540 }
@@ -541,8 +542,10 @@ static void hub_pre_reset(struct usb_hub *hub, int disable_ports)
541} 542}
542 543
543/* caller has locked the hub device */ 544/* caller has locked the hub device */
544static void hub_post_reset(struct usb_hub *hub) 545static void hub_post_reset(struct usb_interface *intf)
545{ 546{
547 struct usb_hub *hub = usb_get_intfdata(intf);
548
546 hub_activate(hub); 549 hub_activate(hub);
547 hub_power_on(hub); 550 hub_power_on(hub);
548} 551}
@@ -802,15 +805,16 @@ static void hub_disconnect(struct usb_interface *intf)
802 struct usb_hub *hub = usb_get_intfdata (intf); 805 struct usb_hub *hub = usb_get_intfdata (intf);
803 struct usb_device *hdev; 806 struct usb_device *hdev;
804 807
808 /* Disconnect all children and quiesce the hub */
809 hub->error = 0;
810 hub_pre_reset(intf);
811
805 usb_set_intfdata (intf, NULL); 812 usb_set_intfdata (intf, NULL);
806 hdev = hub->hdev; 813 hdev = hub->hdev;
807 814
808 if (hdev->speed == USB_SPEED_HIGH) 815 if (hdev->speed == USB_SPEED_HIGH)
809 highspeed_hubs--; 816 highspeed_hubs--;
810 817
811 /* Disconnect all children and quiesce the hub */
812 hub_pre_reset(hub, 1);
813
814 usb_free_urb(hub->urb); 818 usb_free_urb(hub->urb);
815 hub->urb = NULL; 819 hub->urb = NULL;
816 820
@@ -2747,7 +2751,8 @@ static void hub_events(void)
2747 2751
2748 /* If the hub has died, clean up after it */ 2752 /* If the hub has died, clean up after it */
2749 if (hdev->state == USB_STATE_NOTATTACHED) { 2753 if (hdev->state == USB_STATE_NOTATTACHED) {
2750 hub_pre_reset(hub, 0); 2754 hub->error = -ENODEV;
2755 hub_pre_reset(intf);
2751 goto loop; 2756 goto loop;
2752 } 2757 }
2753 2758
@@ -2759,7 +2764,7 @@ static void hub_events(void)
2759 dev_dbg (hub_dev, "resetting for error %d\n", 2764 dev_dbg (hub_dev, "resetting for error %d\n",
2760 hub->error); 2765 hub->error);
2761 2766
2762 ret = usb_reset_device(hdev); 2767 ret = usb_reset_composite_device(hdev, intf);
2763 if (ret) { 2768 if (ret) {
2764 dev_dbg (hub_dev, 2769 dev_dbg (hub_dev,
2765 "error resetting hub: %d\n", ret); 2770 "error resetting hub: %d\n", ret);
@@ -2928,6 +2933,8 @@ static struct usb_driver hub_driver = {
2928 .disconnect = hub_disconnect, 2933 .disconnect = hub_disconnect,
2929 .suspend = hub_suspend, 2934 .suspend = hub_suspend,
2930 .resume = hub_resume, 2935 .resume = hub_resume,
2936 .pre_reset = hub_pre_reset,
2937 .post_reset = hub_post_reset,
2931 .ioctl = hub_ioctl, 2938 .ioctl = hub_ioctl,
2932 .id_table = hub_id_table, 2939 .id_table = hub_id_table,
2933}; 2940};
@@ -3033,7 +3040,6 @@ int usb_reset_device(struct usb_device *udev)
3033 struct usb_device *parent_hdev = udev->parent; 3040 struct usb_device *parent_hdev = udev->parent;
3034 struct usb_hub *parent_hub; 3041 struct usb_hub *parent_hub;
3035 struct usb_device_descriptor descriptor = udev->descriptor; 3042 struct usb_device_descriptor descriptor = udev->descriptor;
3036 struct usb_hub *hub = NULL;
3037 int i, ret = 0; 3043 int i, ret = 0;
3038 int port1 = udev->portnum; 3044 int port1 = udev->portnum;
3039 3045
@@ -3051,14 +3057,6 @@ int usb_reset_device(struct usb_device *udev)
3051 } 3057 }
3052 parent_hub = hdev_to_hub(parent_hdev); 3058 parent_hub = hdev_to_hub(parent_hdev);
3053 3059
3054 /* If we're resetting an active hub, take some special actions */
3055 if (udev->actconfig && udev->actconfig->desc.bNumInterfaces > 0 &&
3056 udev->actconfig->interface[0]->dev.driver ==
3057 &hub_driver.driver &&
3058 (hub = hdev_to_hub(udev)) != NULL) {
3059 hub_pre_reset(hub, 0);
3060 }
3061
3062 set_bit(port1, parent_hub->busy_bits); 3060 set_bit(port1, parent_hub->busy_bits);
3063 for (i = 0; i < SET_CONFIG_TRIES; ++i) { 3061 for (i = 0; i < SET_CONFIG_TRIES; ++i) {
3064 3062
@@ -3117,8 +3115,6 @@ int usb_reset_device(struct usb_device *udev)
3117 } 3115 }
3118 3116
3119done: 3117done:
3120 if (hub)
3121 hub_post_reset(hub);
3122 return 0; 3118 return 0;
3123 3119
3124re_enumerate: 3120re_enumerate: