diff options
Diffstat (limited to 'drivers/usb/core/hub.c')
-rw-r--r-- | drivers/usb/core/hub.c | 212 |
1 files changed, 162 insertions, 50 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 265c2f675d04..28664eb7f555 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -62,6 +62,8 @@ struct usb_hub { | |||
62 | resumed */ | 62 | resumed */ |
63 | unsigned long removed_bits[1]; /* ports with a "removed" | 63 | unsigned long removed_bits[1]; /* ports with a "removed" |
64 | device present */ | 64 | device present */ |
65 | unsigned long wakeup_bits[1]; /* ports that have signaled | ||
66 | remote wakeup */ | ||
65 | #if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */ | 67 | #if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */ |
66 | #error event_bits[] is too short! | 68 | #error event_bits[] is too short! |
67 | #endif | 69 | #endif |
@@ -411,6 +413,29 @@ void usb_kick_khubd(struct usb_device *hdev) | |||
411 | kick_khubd(hub); | 413 | kick_khubd(hub); |
412 | } | 414 | } |
413 | 415 | ||
416 | /* | ||
417 | * Let the USB core know that a USB 3.0 device has sent a Function Wake Device | ||
418 | * Notification, which indicates it had initiated remote wakeup. | ||
419 | * | ||
420 | * USB 3.0 hubs do not report the port link state change from U3 to U0 when the | ||
421 | * device initiates resume, so the USB core will not receive notice of the | ||
422 | * resume through the normal hub interrupt URB. | ||
423 | */ | ||
424 | void usb_wakeup_notification(struct usb_device *hdev, | ||
425 | unsigned int portnum) | ||
426 | { | ||
427 | struct usb_hub *hub; | ||
428 | |||
429 | if (!hdev) | ||
430 | return; | ||
431 | |||
432 | hub = hdev_to_hub(hdev); | ||
433 | if (hub) { | ||
434 | set_bit(portnum, hub->wakeup_bits); | ||
435 | kick_khubd(hub); | ||
436 | } | ||
437 | } | ||
438 | EXPORT_SYMBOL_GPL(usb_wakeup_notification); | ||
414 | 439 | ||
415 | /* completion function, fires on port status changes and various faults */ | 440 | /* completion function, fires on port status changes and various faults */ |
416 | static void hub_irq(struct urb *urb) | 441 | static void hub_irq(struct urb *urb) |
@@ -823,12 +848,6 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) | |||
823 | clear_port_feature(hub->hdev, port1, | 848 | clear_port_feature(hub->hdev, port1, |
824 | USB_PORT_FEAT_C_ENABLE); | 849 | USB_PORT_FEAT_C_ENABLE); |
825 | } | 850 | } |
826 | if (portchange & USB_PORT_STAT_C_LINK_STATE) { | ||
827 | need_debounce_delay = true; | ||
828 | clear_port_feature(hub->hdev, port1, | ||
829 | USB_PORT_FEAT_C_PORT_LINK_STATE); | ||
830 | } | ||
831 | |||
832 | if ((portchange & USB_PORT_STAT_C_BH_RESET) && | 851 | if ((portchange & USB_PORT_STAT_C_BH_RESET) && |
833 | hub_is_superspeed(hub->hdev)) { | 852 | hub_is_superspeed(hub->hdev)) { |
834 | need_debounce_delay = true; | 853 | need_debounce_delay = true; |
@@ -850,12 +869,19 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) | |||
850 | set_bit(port1, hub->change_bits); | 869 | set_bit(port1, hub->change_bits); |
851 | 870 | ||
852 | } else if (portstatus & USB_PORT_STAT_ENABLE) { | 871 | } else if (portstatus & USB_PORT_STAT_ENABLE) { |
872 | bool port_resumed = (portstatus & | ||
873 | USB_PORT_STAT_LINK_STATE) == | ||
874 | USB_SS_PORT_LS_U0; | ||
853 | /* The power session apparently survived the resume. | 875 | /* The power session apparently survived the resume. |
854 | * If there was an overcurrent or suspend change | 876 | * If there was an overcurrent or suspend change |
855 | * (i.e., remote wakeup request), have khubd | 877 | * (i.e., remote wakeup request), have khubd |
856 | * take care of it. | 878 | * take care of it. Look at the port link state |
879 | * for USB 3.0 hubs, since they don't have a suspend | ||
880 | * change bit, and they don't set the port link change | ||
881 | * bit on device-initiated resume. | ||
857 | */ | 882 | */ |
858 | if (portchange) | 883 | if (portchange || (hub_is_superspeed(hub->hdev) && |
884 | port_resumed)) | ||
859 | set_bit(port1, hub->change_bits); | 885 | set_bit(port1, hub->change_bits); |
860 | 886 | ||
861 | } else if (udev->persist_enabled) { | 887 | } else if (udev->persist_enabled) { |
@@ -1021,8 +1047,10 @@ static int hub_configure(struct usb_hub *hub, | |||
1021 | dev_info (hub_dev, "%d port%s detected\n", hdev->maxchild, | 1047 | dev_info (hub_dev, "%d port%s detected\n", hdev->maxchild, |
1022 | (hdev->maxchild == 1) ? "" : "s"); | 1048 | (hdev->maxchild == 1) ? "" : "s"); |
1023 | 1049 | ||
1050 | hdev->children = kzalloc(hdev->maxchild * | ||
1051 | sizeof(struct usb_device *), GFP_KERNEL); | ||
1024 | hub->port_owners = kzalloc(hdev->maxchild * sizeof(void *), GFP_KERNEL); | 1052 | hub->port_owners = kzalloc(hdev->maxchild * sizeof(void *), GFP_KERNEL); |
1025 | if (!hub->port_owners) { | 1053 | if (!hdev->children || !hub->port_owners) { |
1026 | ret = -ENOMEM; | 1054 | ret = -ENOMEM; |
1027 | goto fail; | 1055 | goto fail; |
1028 | } | 1056 | } |
@@ -1253,7 +1281,8 @@ static unsigned highspeed_hubs; | |||
1253 | 1281 | ||
1254 | static void hub_disconnect(struct usb_interface *intf) | 1282 | static void hub_disconnect(struct usb_interface *intf) |
1255 | { | 1283 | { |
1256 | struct usb_hub *hub = usb_get_intfdata (intf); | 1284 | struct usb_hub *hub = usb_get_intfdata(intf); |
1285 | struct usb_device *hdev = interface_to_usbdev(intf); | ||
1257 | 1286 | ||
1258 | /* Take the hub off the event list and don't let it be added again */ | 1287 | /* Take the hub off the event list and don't let it be added again */ |
1259 | spin_lock_irq(&hub_event_lock); | 1288 | spin_lock_irq(&hub_event_lock); |
@@ -1275,6 +1304,7 @@ static void hub_disconnect(struct usb_interface *intf) | |||
1275 | highspeed_hubs--; | 1304 | highspeed_hubs--; |
1276 | 1305 | ||
1277 | usb_free_urb(hub->urb); | 1306 | usb_free_urb(hub->urb); |
1307 | kfree(hdev->children); | ||
1278 | kfree(hub->port_owners); | 1308 | kfree(hub->port_owners); |
1279 | kfree(hub->descriptor); | 1309 | kfree(hub->descriptor); |
1280 | kfree(hub->status); | 1310 | kfree(hub->status); |
@@ -1293,14 +1323,8 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1293 | desc = intf->cur_altsetting; | 1323 | desc = intf->cur_altsetting; |
1294 | hdev = interface_to_usbdev(intf); | 1324 | hdev = interface_to_usbdev(intf); |
1295 | 1325 | ||
1296 | /* Hubs have proper suspend/resume support. USB 3.0 device suspend is | 1326 | /* Hubs have proper suspend/resume support. */ |
1297 | * different from USB 2.0/1.1 device suspend, and unfortunately we | 1327 | usb_enable_autosuspend(hdev); |
1298 | * don't support it yet. So leave autosuspend disabled for USB 3.0 | ||
1299 | * external hubs for now. Enable autosuspend for USB 3.0 roothubs, | ||
1300 | * since that isn't a "real" hub. | ||
1301 | */ | ||
1302 | if (!hub_is_superspeed(hdev) || !hdev->parent) | ||
1303 | usb_enable_autosuspend(hdev); | ||
1304 | 1328 | ||
1305 | if (hdev->level == MAX_TOPO_LEVEL) { | 1329 | if (hdev->level == MAX_TOPO_LEVEL) { |
1306 | dev_err(&intf->dev, | 1330 | dev_err(&intf->dev, |
@@ -1656,7 +1680,7 @@ void usb_disconnect(struct usb_device **pdev) | |||
1656 | usb_lock_device(udev); | 1680 | usb_lock_device(udev); |
1657 | 1681 | ||
1658 | /* Free up all the children before we remove this device */ | 1682 | /* Free up all the children before we remove this device */ |
1659 | for (i = 0; i < USB_MAXCHILDREN; i++) { | 1683 | for (i = 0; i < udev->maxchild; i++) { |
1660 | if (udev->children[i]) | 1684 | if (udev->children[i]) |
1661 | usb_disconnect(&udev->children[i]); | 1685 | usb_disconnect(&udev->children[i]); |
1662 | } | 1686 | } |
@@ -1842,6 +1866,37 @@ fail: | |||
1842 | return err; | 1866 | return err; |
1843 | } | 1867 | } |
1844 | 1868 | ||
1869 | static void set_usb_port_removable(struct usb_device *udev) | ||
1870 | { | ||
1871 | struct usb_device *hdev = udev->parent; | ||
1872 | struct usb_hub *hub; | ||
1873 | u8 port = udev->portnum; | ||
1874 | u16 wHubCharacteristics; | ||
1875 | bool removable = true; | ||
1876 | |||
1877 | if (!hdev) | ||
1878 | return; | ||
1879 | |||
1880 | hub = hdev_to_hub(udev->parent); | ||
1881 | |||
1882 | wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); | ||
1883 | |||
1884 | if (!(wHubCharacteristics & HUB_CHAR_COMPOUND)) | ||
1885 | return; | ||
1886 | |||
1887 | if (hub_is_superspeed(hdev)) { | ||
1888 | if (hub->descriptor->u.ss.DeviceRemovable & (1 << port)) | ||
1889 | removable = false; | ||
1890 | } else { | ||
1891 | if (hub->descriptor->u.hs.DeviceRemovable[port / 8] & (1 << (port % 8))) | ||
1892 | removable = false; | ||
1893 | } | ||
1894 | |||
1895 | if (removable) | ||
1896 | udev->removable = USB_DEVICE_REMOVABLE; | ||
1897 | else | ||
1898 | udev->removable = USB_DEVICE_FIXED; | ||
1899 | } | ||
1845 | 1900 | ||
1846 | /** | 1901 | /** |
1847 | * usb_new_device - perform initial device setup (usbcore-internal) | 1902 | * usb_new_device - perform initial device setup (usbcore-internal) |
@@ -1900,6 +1955,15 @@ int usb_new_device(struct usb_device *udev) | |||
1900 | announce_device(udev); | 1955 | announce_device(udev); |
1901 | 1956 | ||
1902 | device_enable_async_suspend(&udev->dev); | 1957 | device_enable_async_suspend(&udev->dev); |
1958 | |||
1959 | /* | ||
1960 | * check whether the hub marks this port as non-removable. Do it | ||
1961 | * now so that platform-specific data can override it in | ||
1962 | * device_add() | ||
1963 | */ | ||
1964 | if (udev->parent) | ||
1965 | set_usb_port_removable(udev); | ||
1966 | |||
1903 | /* Register the device. The device driver is responsible | 1967 | /* Register the device. The device driver is responsible |
1904 | * for configuring the device and invoking the add-device | 1968 | * for configuring the device and invoking the add-device |
1905 | * notifier chain (used by usbfs and possibly others). | 1969 | * notifier chain (used by usbfs and possibly others). |
@@ -2385,11 +2449,27 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) | |||
2385 | * we don't explicitly enable it here. | 2449 | * we don't explicitly enable it here. |
2386 | */ | 2450 | */ |
2387 | if (udev->do_remote_wakeup) { | 2451 | if (udev->do_remote_wakeup) { |
2388 | status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | 2452 | if (!hub_is_superspeed(hub->hdev)) { |
2389 | USB_REQ_SET_FEATURE, USB_RECIP_DEVICE, | 2453 | status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), |
2390 | USB_DEVICE_REMOTE_WAKEUP, 0, | 2454 | USB_REQ_SET_FEATURE, USB_RECIP_DEVICE, |
2391 | NULL, 0, | 2455 | USB_DEVICE_REMOTE_WAKEUP, 0, |
2392 | USB_CTRL_SET_TIMEOUT); | 2456 | NULL, 0, |
2457 | USB_CTRL_SET_TIMEOUT); | ||
2458 | } else { | ||
2459 | /* Assume there's only one function on the USB 3.0 | ||
2460 | * device and enable remote wake for the first | ||
2461 | * interface. FIXME if the interface association | ||
2462 | * descriptor shows there's more than one function. | ||
2463 | */ | ||
2464 | status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
2465 | USB_REQ_SET_FEATURE, | ||
2466 | USB_RECIP_INTERFACE, | ||
2467 | USB_INTRF_FUNC_SUSPEND, | ||
2468 | USB_INTRF_FUNC_SUSPEND_RW | | ||
2469 | USB_INTRF_FUNC_SUSPEND_LP, | ||
2470 | NULL, 0, | ||
2471 | USB_CTRL_SET_TIMEOUT); | ||
2472 | } | ||
2393 | if (status) { | 2473 | if (status) { |
2394 | dev_dbg(&udev->dev, "won't remote wakeup, status %d\n", | 2474 | dev_dbg(&udev->dev, "won't remote wakeup, status %d\n", |
2395 | status); | 2475 | status); |
@@ -2679,6 +2759,7 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg) | |||
2679 | struct usb_hub *hub = usb_get_intfdata (intf); | 2759 | struct usb_hub *hub = usb_get_intfdata (intf); |
2680 | struct usb_device *hdev = hub->hdev; | 2760 | struct usb_device *hdev = hub->hdev; |
2681 | unsigned port1; | 2761 | unsigned port1; |
2762 | int status; | ||
2682 | 2763 | ||
2683 | /* Warn if children aren't already suspended */ | 2764 | /* Warn if children aren't already suspended */ |
2684 | for (port1 = 1; port1 <= hdev->maxchild; port1++) { | 2765 | for (port1 = 1; port1 <= hdev->maxchild; port1++) { |
@@ -2691,6 +2772,17 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg) | |||
2691 | return -EBUSY; | 2772 | return -EBUSY; |
2692 | } | 2773 | } |
2693 | } | 2774 | } |
2775 | if (hub_is_superspeed(hdev) && hdev->do_remote_wakeup) { | ||
2776 | /* Enable hub to send remote wakeup for all ports. */ | ||
2777 | for (port1 = 1; port1 <= hdev->maxchild; port1++) { | ||
2778 | status = set_port_feature(hdev, | ||
2779 | port1 | | ||
2780 | USB_PORT_FEAT_REMOTE_WAKE_CONNECT | | ||
2781 | USB_PORT_FEAT_REMOTE_WAKE_DISCONNECT | | ||
2782 | USB_PORT_FEAT_REMOTE_WAKE_OVER_CURRENT, | ||
2783 | USB_PORT_FEAT_REMOTE_WAKE_MASK); | ||
2784 | } | ||
2785 | } | ||
2694 | 2786 | ||
2695 | dev_dbg(&intf->dev, "%s\n", __func__); | 2787 | dev_dbg(&intf->dev, "%s\n", __func__); |
2696 | 2788 | ||
@@ -3424,6 +3516,46 @@ done: | |||
3424 | hcd->driver->relinquish_port(hcd, port1); | 3516 | hcd->driver->relinquish_port(hcd, port1); |
3425 | } | 3517 | } |
3426 | 3518 | ||
3519 | /* Returns 1 if there was a remote wakeup and a connect status change. */ | ||
3520 | static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port, | ||
3521 | u16 portstatus, u16 portchange) | ||
3522 | { | ||
3523 | struct usb_device *hdev; | ||
3524 | struct usb_device *udev; | ||
3525 | int connect_change = 0; | ||
3526 | int ret; | ||
3527 | |||
3528 | hdev = hub->hdev; | ||
3529 | udev = hdev->children[port-1]; | ||
3530 | if (!hub_is_superspeed(hdev)) { | ||
3531 | if (!(portchange & USB_PORT_STAT_C_SUSPEND)) | ||
3532 | return 0; | ||
3533 | clear_port_feature(hdev, port, USB_PORT_FEAT_C_SUSPEND); | ||
3534 | } else { | ||
3535 | if (!udev || udev->state != USB_STATE_SUSPENDED || | ||
3536 | (portstatus & USB_PORT_STAT_LINK_STATE) != | ||
3537 | USB_SS_PORT_LS_U0) | ||
3538 | return 0; | ||
3539 | } | ||
3540 | |||
3541 | if (udev) { | ||
3542 | /* TRSMRCY = 10 msec */ | ||
3543 | msleep(10); | ||
3544 | |||
3545 | usb_lock_device(udev); | ||
3546 | ret = usb_remote_wakeup(udev); | ||
3547 | usb_unlock_device(udev); | ||
3548 | if (ret < 0) | ||
3549 | connect_change = 1; | ||
3550 | } else { | ||
3551 | ret = -ENODEV; | ||
3552 | hub_port_disable(hub, port, 1); | ||
3553 | } | ||
3554 | dev_dbg(hub->intfdev, "resume on port %d, status %d\n", | ||
3555 | port, ret); | ||
3556 | return connect_change; | ||
3557 | } | ||
3558 | |||
3427 | static void hub_events(void) | 3559 | static void hub_events(void) |
3428 | { | 3560 | { |
3429 | struct list_head *tmp; | 3561 | struct list_head *tmp; |
@@ -3436,7 +3568,7 @@ static void hub_events(void) | |||
3436 | u16 portstatus; | 3568 | u16 portstatus; |
3437 | u16 portchange; | 3569 | u16 portchange; |
3438 | int i, ret; | 3570 | int i, ret; |
3439 | int connect_change; | 3571 | int connect_change, wakeup_change; |
3440 | 3572 | ||
3441 | /* | 3573 | /* |
3442 | * We restart the list every time to avoid a deadlock with | 3574 | * We restart the list every time to avoid a deadlock with |
@@ -3515,8 +3647,9 @@ static void hub_events(void) | |||
3515 | if (test_bit(i, hub->busy_bits)) | 3647 | if (test_bit(i, hub->busy_bits)) |
3516 | continue; | 3648 | continue; |
3517 | connect_change = test_bit(i, hub->change_bits); | 3649 | connect_change = test_bit(i, hub->change_bits); |
3650 | wakeup_change = test_and_clear_bit(i, hub->wakeup_bits); | ||
3518 | if (!test_and_clear_bit(i, hub->event_bits) && | 3651 | if (!test_and_clear_bit(i, hub->event_bits) && |
3519 | !connect_change) | 3652 | !connect_change && !wakeup_change) |
3520 | continue; | 3653 | continue; |
3521 | 3654 | ||
3522 | ret = hub_port_status(hub, i, | 3655 | ret = hub_port_status(hub, i, |
@@ -3557,31 +3690,10 @@ static void hub_events(void) | |||
3557 | } | 3690 | } |
3558 | } | 3691 | } |
3559 | 3692 | ||
3560 | if (portchange & USB_PORT_STAT_C_SUSPEND) { | 3693 | if (hub_handle_remote_wakeup(hub, i, |
3561 | struct usb_device *udev; | 3694 | portstatus, portchange)) |
3695 | connect_change = 1; | ||
3562 | 3696 | ||
3563 | clear_port_feature(hdev, i, | ||
3564 | USB_PORT_FEAT_C_SUSPEND); | ||
3565 | udev = hdev->children[i-1]; | ||
3566 | if (udev) { | ||
3567 | /* TRSMRCY = 10 msec */ | ||
3568 | msleep(10); | ||
3569 | |||
3570 | usb_lock_device(udev); | ||
3571 | ret = usb_remote_wakeup(hdev-> | ||
3572 | children[i-1]); | ||
3573 | usb_unlock_device(udev); | ||
3574 | if (ret < 0) | ||
3575 | connect_change = 1; | ||
3576 | } else { | ||
3577 | ret = -ENODEV; | ||
3578 | hub_port_disable(hub, i, 1); | ||
3579 | } | ||
3580 | dev_dbg (hub_dev, | ||
3581 | "resume on port %d, status %d\n", | ||
3582 | i, ret); | ||
3583 | } | ||
3584 | |||
3585 | if (portchange & USB_PORT_STAT_C_OVERCURRENT) { | 3697 | if (portchange & USB_PORT_STAT_C_OVERCURRENT) { |
3586 | u16 status = 0; | 3698 | u16 status = 0; |
3587 | u16 unused; | 3699 | u16 unused; |