diff options
Diffstat (limited to 'drivers/usb/core/hub.c')
| -rw-r--r-- | drivers/usb/core/hub.c | 53 |
1 files changed, 43 insertions, 10 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 4191db32f12c..558313de4911 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
| @@ -668,6 +668,15 @@ resubmit: | |||
| 668 | static inline int | 668 | static inline int |
| 669 | hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt) | 669 | hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt) |
| 670 | { | 670 | { |
| 671 | /* Need to clear both directions for control ep */ | ||
| 672 | if (((devinfo >> 11) & USB_ENDPOINT_XFERTYPE_MASK) == | ||
| 673 | USB_ENDPOINT_XFER_CONTROL) { | ||
| 674 | int status = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), | ||
| 675 | HUB_CLEAR_TT_BUFFER, USB_RT_PORT, | ||
| 676 | devinfo ^ 0x8000, tt, NULL, 0, 1000); | ||
| 677 | if (status) | ||
| 678 | return status; | ||
| 679 | } | ||
| 671 | return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), | 680 | return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), |
| 672 | HUB_CLEAR_TT_BUFFER, USB_RT_PORT, devinfo, | 681 | HUB_CLEAR_TT_BUFFER, USB_RT_PORT, devinfo, |
| 673 | tt, NULL, 0, 1000); | 682 | tt, NULL, 0, 1000); |
| @@ -2848,6 +2857,15 @@ static int usb_disable_function_remotewakeup(struct usb_device *udev) | |||
| 2848 | USB_CTRL_SET_TIMEOUT); | 2857 | USB_CTRL_SET_TIMEOUT); |
| 2849 | } | 2858 | } |
| 2850 | 2859 | ||
| 2860 | /* Count of wakeup-enabled devices at or below udev */ | ||
| 2861 | static unsigned wakeup_enabled_descendants(struct usb_device *udev) | ||
| 2862 | { | ||
| 2863 | struct usb_hub *hub = usb_hub_to_struct_hub(udev); | ||
| 2864 | |||
| 2865 | return udev->do_remote_wakeup + | ||
| 2866 | (hub ? hub->wakeup_enabled_descendants : 0); | ||
| 2867 | } | ||
| 2868 | |||
| 2851 | /* | 2869 | /* |
| 2852 | * usb_port_suspend - suspend a usb device's upstream port | 2870 | * usb_port_suspend - suspend a usb device's upstream port |
| 2853 | * @udev: device that's no longer in active use, not a root hub | 2871 | * @udev: device that's no longer in active use, not a root hub |
| @@ -2888,8 +2906,8 @@ static int usb_disable_function_remotewakeup(struct usb_device *udev) | |||
| 2888 | * Linux (2.6) currently has NO mechanisms to initiate that: no khubd | 2906 | * Linux (2.6) currently has NO mechanisms to initiate that: no khubd |
| 2889 | * timer, no SRP, no requests through sysfs. | 2907 | * timer, no SRP, no requests through sysfs. |
| 2890 | * | 2908 | * |
| 2891 | * If Runtime PM isn't enabled or used, non-SuperSpeed devices really get | 2909 | * If Runtime PM isn't enabled or used, non-SuperSpeed devices may not get |
| 2892 | * suspended only when their bus goes into global suspend (i.e., the root | 2910 | * suspended until their bus goes into global suspend (i.e., the root |
| 2893 | * hub is suspended). Nevertheless, we change @udev->state to | 2911 | * hub is suspended). Nevertheless, we change @udev->state to |
| 2894 | * USB_STATE_SUSPENDED as this is the device's "logical" state. The actual | 2912 | * USB_STATE_SUSPENDED as this is the device's "logical" state. The actual |
| 2895 | * upstream port setting is stored in @udev->port_is_suspended. | 2913 | * upstream port setting is stored in @udev->port_is_suspended. |
| @@ -2960,15 +2978,21 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) | |||
| 2960 | /* see 7.1.7.6 */ | 2978 | /* see 7.1.7.6 */ |
| 2961 | if (hub_is_superspeed(hub->hdev)) | 2979 | if (hub_is_superspeed(hub->hdev)) |
| 2962 | status = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_U3); | 2980 | status = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_U3); |
| 2963 | else if (PMSG_IS_AUTO(msg)) | 2981 | |
| 2964 | status = set_port_feature(hub->hdev, port1, | ||
| 2965 | USB_PORT_FEAT_SUSPEND); | ||
| 2966 | /* | 2982 | /* |
| 2967 | * For system suspend, we do not need to enable the suspend feature | 2983 | * For system suspend, we do not need to enable the suspend feature |
| 2968 | * on individual USB-2 ports. The devices will automatically go | 2984 | * on individual USB-2 ports. The devices will automatically go |
| 2969 | * into suspend a few ms after the root hub stops sending packets. | 2985 | * into suspend a few ms after the root hub stops sending packets. |
| 2970 | * The USB 2.0 spec calls this "global suspend". | 2986 | * The USB 2.0 spec calls this "global suspend". |
| 2987 | * | ||
| 2988 | * However, many USB hubs have a bug: They don't relay wakeup requests | ||
| 2989 | * from a downstream port if the port's suspend feature isn't on. | ||
| 2990 | * Therefore we will turn on the suspend feature if udev or any of its | ||
| 2991 | * descendants is enabled for remote wakeup. | ||
| 2971 | */ | 2992 | */ |
| 2993 | else if (PMSG_IS_AUTO(msg) || wakeup_enabled_descendants(udev) > 0) | ||
| 2994 | status = set_port_feature(hub->hdev, port1, | ||
| 2995 | USB_PORT_FEAT_SUSPEND); | ||
| 2972 | else { | 2996 | else { |
| 2973 | really_suspend = false; | 2997 | really_suspend = false; |
| 2974 | status = 0; | 2998 | status = 0; |
| @@ -3003,15 +3027,16 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) | |||
| 3003 | if (!PMSG_IS_AUTO(msg)) | 3027 | if (!PMSG_IS_AUTO(msg)) |
| 3004 | status = 0; | 3028 | status = 0; |
| 3005 | } else { | 3029 | } else { |
| 3006 | /* device has up to 10 msec to fully suspend */ | ||
| 3007 | dev_dbg(&udev->dev, "usb %ssuspend, wakeup %d\n", | 3030 | dev_dbg(&udev->dev, "usb %ssuspend, wakeup %d\n", |
| 3008 | (PMSG_IS_AUTO(msg) ? "auto-" : ""), | 3031 | (PMSG_IS_AUTO(msg) ? "auto-" : ""), |
| 3009 | udev->do_remote_wakeup); | 3032 | udev->do_remote_wakeup); |
| 3010 | usb_set_device_state(udev, USB_STATE_SUSPENDED); | ||
| 3011 | if (really_suspend) { | 3033 | if (really_suspend) { |
| 3012 | udev->port_is_suspended = 1; | 3034 | udev->port_is_suspended = 1; |
| 3035 | |||
| 3036 | /* device has up to 10 msec to fully suspend */ | ||
| 3013 | msleep(10); | 3037 | msleep(10); |
| 3014 | } | 3038 | } |
| 3039 | usb_set_device_state(udev, USB_STATE_SUSPENDED); | ||
| 3015 | } | 3040 | } |
| 3016 | 3041 | ||
| 3017 | /* | 3042 | /* |
| @@ -3293,7 +3318,11 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg) | |||
| 3293 | unsigned port1; | 3318 | unsigned port1; |
| 3294 | int status; | 3319 | int status; |
| 3295 | 3320 | ||
| 3296 | /* Warn if children aren't already suspended */ | 3321 | /* |
| 3322 | * Warn if children aren't already suspended. | ||
| 3323 | * Also, add up the number of wakeup-enabled descendants. | ||
| 3324 | */ | ||
| 3325 | hub->wakeup_enabled_descendants = 0; | ||
| 3297 | for (port1 = 1; port1 <= hdev->maxchild; port1++) { | 3326 | for (port1 = 1; port1 <= hdev->maxchild; port1++) { |
| 3298 | struct usb_device *udev; | 3327 | struct usb_device *udev; |
| 3299 | 3328 | ||
| @@ -3303,6 +3332,9 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg) | |||
| 3303 | if (PMSG_IS_AUTO(msg)) | 3332 | if (PMSG_IS_AUTO(msg)) |
| 3304 | return -EBUSY; | 3333 | return -EBUSY; |
| 3305 | } | 3334 | } |
| 3335 | if (udev) | ||
| 3336 | hub->wakeup_enabled_descendants += | ||
| 3337 | wakeup_enabled_descendants(udev); | ||
| 3306 | } | 3338 | } |
| 3307 | 3339 | ||
| 3308 | if (hdev->do_remote_wakeup && hub->quirk_check_port_auto_suspend) { | 3340 | if (hdev->do_remote_wakeup && hub->quirk_check_port_auto_suspend) { |
| @@ -4766,7 +4798,8 @@ static void hub_events(void) | |||
| 4766 | hub->ports[i - 1]->child; | 4798 | hub->ports[i - 1]->child; |
| 4767 | 4799 | ||
| 4768 | dev_dbg(hub_dev, "warm reset port %d\n", i); | 4800 | dev_dbg(hub_dev, "warm reset port %d\n", i); |
| 4769 | if (!udev) { | 4801 | if (!udev || !(portstatus & |
| 4802 | USB_PORT_STAT_CONNECTION)) { | ||
| 4770 | status = hub_port_reset(hub, i, | 4803 | status = hub_port_reset(hub, i, |
| 4771 | NULL, HUB_BH_RESET_TIME, | 4804 | NULL, HUB_BH_RESET_TIME, |
| 4772 | true); | 4805 | true); |
| @@ -4776,8 +4809,8 @@ static void hub_events(void) | |||
| 4776 | usb_lock_device(udev); | 4809 | usb_lock_device(udev); |
| 4777 | status = usb_reset_device(udev); | 4810 | status = usb_reset_device(udev); |
| 4778 | usb_unlock_device(udev); | 4811 | usb_unlock_device(udev); |
| 4812 | connect_change = 0; | ||
| 4779 | } | 4813 | } |
| 4780 | connect_change = 0; | ||
| 4781 | } | 4814 | } |
| 4782 | 4815 | ||
| 4783 | if (connect_change) | 4816 | if (connect_change) |
