diff options
Diffstat (limited to 'drivers/usb/core/hub.c')
-rw-r--r-- | drivers/usb/core/hub.c | 97 |
1 files changed, 74 insertions, 23 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 610735823d93..090469ebfcff 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -141,19 +141,27 @@ static int usb_device_supports_lpm(struct usb_device *udev) | |||
141 | return 0; | 141 | return 0; |
142 | } | 142 | } |
143 | 143 | ||
144 | /* All USB 3.0 must support LPM, but we need their max exit latency | 144 | /* |
145 | * information from the SuperSpeed Extended Capabilities BOS descriptor. | 145 | * According to the USB 3.0 spec, all USB 3.0 devices must support LPM. |
146 | * However, there are some that don't, and they set the U1/U2 exit | ||
147 | * latencies to zero. | ||
146 | */ | 148 | */ |
147 | if (!udev->bos->ss_cap) { | 149 | if (!udev->bos->ss_cap) { |
148 | dev_warn(&udev->dev, "No LPM exit latency info found. " | 150 | dev_info(&udev->dev, "No LPM exit latency info found, disabling LPM.\n"); |
149 | "Power management will be impacted.\n"); | 151 | return 0; |
152 | } | ||
153 | |||
154 | if (udev->bos->ss_cap->bU1devExitLat == 0 && | ||
155 | udev->bos->ss_cap->bU2DevExitLat == 0) { | ||
156 | if (udev->parent) | ||
157 | dev_info(&udev->dev, "LPM exit latency is zeroed, disabling LPM.\n"); | ||
158 | else | ||
159 | dev_info(&udev->dev, "We don't know the algorithms for LPM for this host, disabling LPM.\n"); | ||
150 | return 0; | 160 | return 0; |
151 | } | 161 | } |
152 | if (udev->parent->lpm_capable) | ||
153 | return 1; | ||
154 | 162 | ||
155 | dev_warn(&udev->dev, "Parent hub missing LPM exit latency info. " | 163 | if (!udev->parent || udev->parent->lpm_capable) |
156 | "Power management will be impacted.\n"); | 164 | return 1; |
157 | return 0; | 165 | return 0; |
158 | } | 166 | } |
159 | 167 | ||
@@ -499,7 +507,8 @@ static void led_work (struct work_struct *work) | |||
499 | changed++; | 507 | changed++; |
500 | } | 508 | } |
501 | if (changed) | 509 | if (changed) |
502 | schedule_delayed_work(&hub->leds, LED_CYCLE_PERIOD); | 510 | queue_delayed_work(system_power_efficient_wq, |
511 | &hub->leds, LED_CYCLE_PERIOD); | ||
503 | } | 512 | } |
504 | 513 | ||
505 | /* use a short timeout for hub/port status fetches */ | 514 | /* use a short timeout for hub/port status fetches */ |
@@ -1041,7 +1050,8 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) | |||
1041 | if (type == HUB_INIT) { | 1050 | if (type == HUB_INIT) { |
1042 | delay = hub_power_on(hub, false); | 1051 | delay = hub_power_on(hub, false); |
1043 | INIT_DELAYED_WORK(&hub->init_work, hub_init_func2); | 1052 | INIT_DELAYED_WORK(&hub->init_work, hub_init_func2); |
1044 | schedule_delayed_work(&hub->init_work, | 1053 | queue_delayed_work(system_power_efficient_wq, |
1054 | &hub->init_work, | ||
1045 | msecs_to_jiffies(delay)); | 1055 | msecs_to_jiffies(delay)); |
1046 | 1056 | ||
1047 | /* Suppress autosuspend until init is done */ | 1057 | /* Suppress autosuspend until init is done */ |
@@ -1195,7 +1205,8 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) | |||
1195 | /* Don't do a long sleep inside a workqueue routine */ | 1205 | /* Don't do a long sleep inside a workqueue routine */ |
1196 | if (type == HUB_INIT2) { | 1206 | if (type == HUB_INIT2) { |
1197 | INIT_DELAYED_WORK(&hub->init_work, hub_init_func3); | 1207 | INIT_DELAYED_WORK(&hub->init_work, hub_init_func3); |
1198 | schedule_delayed_work(&hub->init_work, | 1208 | queue_delayed_work(system_power_efficient_wq, |
1209 | &hub->init_work, | ||
1199 | msecs_to_jiffies(delay)); | 1210 | msecs_to_jiffies(delay)); |
1200 | return; /* Continues at init3: below */ | 1211 | return; /* Continues at init3: below */ |
1201 | } else { | 1212 | } else { |
@@ -1209,7 +1220,8 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) | |||
1209 | if (status < 0) | 1220 | if (status < 0) |
1210 | dev_err(hub->intfdev, "activate --> %d\n", status); | 1221 | dev_err(hub->intfdev, "activate --> %d\n", status); |
1211 | if (hub->has_indicators && blinkenlights) | 1222 | if (hub->has_indicators && blinkenlights) |
1212 | schedule_delayed_work(&hub->leds, LED_CYCLE_PERIOD); | 1223 | queue_delayed_work(system_power_efficient_wq, |
1224 | &hub->leds, LED_CYCLE_PERIOD); | ||
1213 | 1225 | ||
1214 | /* Scan all ports that need attention */ | 1226 | /* Scan all ports that need attention */ |
1215 | kick_khubd(hub); | 1227 | kick_khubd(hub); |
@@ -3095,9 +3107,19 @@ static int finish_port_resume(struct usb_device *udev) | |||
3095 | * operation is carried out here, after the port has been | 3107 | * operation is carried out here, after the port has been |
3096 | * resumed. | 3108 | * resumed. |
3097 | */ | 3109 | */ |
3098 | if (udev->reset_resume) | 3110 | if (udev->reset_resume) { |
3111 | /* | ||
3112 | * If the device morphs or switches modes when it is reset, | ||
3113 | * we don't want to perform a reset-resume. We'll fail the | ||
3114 | * resume, which will cause a logical disconnect, and then | ||
3115 | * the device will be rediscovered. | ||
3116 | */ | ||
3099 | retry_reset_resume: | 3117 | retry_reset_resume: |
3100 | status = usb_reset_and_verify_device(udev); | 3118 | if (udev->quirks & USB_QUIRK_RESET) |
3119 | status = -ENODEV; | ||
3120 | else | ||
3121 | status = usb_reset_and_verify_device(udev); | ||
3122 | } | ||
3101 | 3123 | ||
3102 | /* 10.5.4.5 says be sure devices in the tree are still there. | 3124 | /* 10.5.4.5 says be sure devices in the tree are still there. |
3103 | * For now let's assume the device didn't go crazy on resume, | 3125 | * For now let's assume the device didn't go crazy on resume, |
@@ -3960,7 +3982,7 @@ static void hub_set_initial_usb2_lpm_policy(struct usb_device *udev) | |||
3960 | connect_type = usb_get_hub_port_connect_type(udev->parent, | 3982 | connect_type = usb_get_hub_port_connect_type(udev->parent, |
3961 | udev->portnum); | 3983 | udev->portnum); |
3962 | 3984 | ||
3963 | if ((udev->bos->ext_cap->bmAttributes & USB_BESL_SUPPORT) || | 3985 | if ((udev->bos->ext_cap->bmAttributes & cpu_to_le32(USB_BESL_SUPPORT)) || |
3964 | connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) { | 3986 | connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) { |
3965 | udev->usb2_hw_lpm_allowed = 1; | 3987 | udev->usb2_hw_lpm_allowed = 1; |
3966 | usb_set_usb2_hardware_lpm(udev, 1); | 3988 | usb_set_usb2_hardware_lpm(udev, 1); |
@@ -4109,8 +4131,12 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
4109 | 4131 | ||
4110 | did_new_scheme = true; | 4132 | did_new_scheme = true; |
4111 | retval = hub_enable_device(udev); | 4133 | retval = hub_enable_device(udev); |
4112 | if (retval < 0) | 4134 | if (retval < 0) { |
4135 | dev_err(&udev->dev, | ||
4136 | "hub failed to enable device, error %d\n", | ||
4137 | retval); | ||
4113 | goto fail; | 4138 | goto fail; |
4139 | } | ||
4114 | 4140 | ||
4115 | #define GET_DESCRIPTOR_BUFSIZE 64 | 4141 | #define GET_DESCRIPTOR_BUFSIZE 64 |
4116 | buf = kmalloc(GET_DESCRIPTOR_BUFSIZE, GFP_NOIO); | 4142 | buf = kmalloc(GET_DESCRIPTOR_BUFSIZE, GFP_NOIO); |
@@ -4313,7 +4339,8 @@ check_highspeed (struct usb_hub *hub, struct usb_device *udev, int port1) | |||
4313 | /* hub LEDs are probably harder to miss than syslog */ | 4339 | /* hub LEDs are probably harder to miss than syslog */ |
4314 | if (hub->has_indicators) { | 4340 | if (hub->has_indicators) { |
4315 | hub->indicator[port1-1] = INDICATOR_GREEN_BLINK; | 4341 | hub->indicator[port1-1] = INDICATOR_GREEN_BLINK; |
4316 | schedule_delayed_work (&hub->leds, 0); | 4342 | queue_delayed_work(system_power_efficient_wq, |
4343 | &hub->leds, 0); | ||
4317 | } | 4344 | } |
4318 | } | 4345 | } |
4319 | kfree(qual); | 4346 | kfree(qual); |
@@ -4542,7 +4569,9 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
4542 | if (hub->has_indicators) { | 4569 | if (hub->has_indicators) { |
4543 | hub->indicator[port1-1] = | 4570 | hub->indicator[port1-1] = |
4544 | INDICATOR_AMBER_BLINK; | 4571 | INDICATOR_AMBER_BLINK; |
4545 | schedule_delayed_work (&hub->leds, 0); | 4572 | queue_delayed_work( |
4573 | system_power_efficient_wq, | ||
4574 | &hub->leds, 0); | ||
4546 | } | 4575 | } |
4547 | status = -ENOTCONN; /* Don't retry */ | 4576 | status = -ENOTCONN; /* Don't retry */ |
4548 | goto loop_disable; | 4577 | goto loop_disable; |
@@ -4741,6 +4770,8 @@ static void hub_events(void) | |||
4741 | 4770 | ||
4742 | /* deal with port status changes */ | 4771 | /* deal with port status changes */ |
4743 | for (i = 1; i <= hdev->maxchild; i++) { | 4772 | for (i = 1; i <= hdev->maxchild; i++) { |
4773 | struct usb_device *udev = hub->ports[i - 1]->child; | ||
4774 | |||
4744 | if (test_bit(i, hub->busy_bits)) | 4775 | if (test_bit(i, hub->busy_bits)) |
4745 | continue; | 4776 | continue; |
4746 | connect_change = test_bit(i, hub->change_bits); | 4777 | connect_change = test_bit(i, hub->change_bits); |
@@ -4839,8 +4870,6 @@ static void hub_events(void) | |||
4839 | */ | 4870 | */ |
4840 | if (hub_port_warm_reset_required(hub, portstatus)) { | 4871 | if (hub_port_warm_reset_required(hub, portstatus)) { |
4841 | int status; | 4872 | int status; |
4842 | struct usb_device *udev = | ||
4843 | hub->ports[i - 1]->child; | ||
4844 | 4873 | ||
4845 | dev_dbg(hub_dev, "warm reset port %d\n", i); | 4874 | dev_dbg(hub_dev, "warm reset port %d\n", i); |
4846 | if (!udev || | 4875 | if (!udev || |
@@ -4857,6 +4886,24 @@ static void hub_events(void) | |||
4857 | usb_unlock_device(udev); | 4886 | usb_unlock_device(udev); |
4858 | connect_change = 0; | 4887 | connect_change = 0; |
4859 | } | 4888 | } |
4889 | /* | ||
4890 | * On disconnect USB3 protocol ports transit from U0 to | ||
4891 | * SS.Inactive to Rx.Detect. If this happens a warm- | ||
4892 | * reset is not needed, but a (re)connect may happen | ||
4893 | * before khubd runs and sees the disconnect, and the | ||
4894 | * device may be an unknown state. | ||
4895 | * | ||
4896 | * If the port went through SS.Inactive without khubd | ||
4897 | * seeing it the C_LINK_STATE change flag will be set, | ||
4898 | * and we reset the dev to put it in a known state. | ||
4899 | */ | ||
4900 | } else if (udev && hub_is_superspeed(hub->hdev) && | ||
4901 | (portchange & USB_PORT_STAT_C_LINK_STATE) && | ||
4902 | (portstatus & USB_PORT_STAT_CONNECTION)) { | ||
4903 | usb_lock_device(udev); | ||
4904 | usb_reset_device(udev); | ||
4905 | usb_unlock_device(udev); | ||
4906 | connect_change = 0; | ||
4860 | } | 4907 | } |
4861 | 4908 | ||
4862 | if (connect_change) | 4909 | if (connect_change) |
@@ -5114,7 +5161,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev) | |||
5114 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | 5161 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); |
5115 | struct usb_device_descriptor descriptor = udev->descriptor; | 5162 | struct usb_device_descriptor descriptor = udev->descriptor; |
5116 | struct usb_host_bos *bos; | 5163 | struct usb_host_bos *bos; |
5117 | int i, ret = 0; | 5164 | int i, j, ret = 0; |
5118 | int port1 = udev->portnum; | 5165 | int port1 = udev->portnum; |
5119 | 5166 | ||
5120 | if (udev->state == USB_STATE_NOTATTACHED || | 5167 | if (udev->state == USB_STATE_NOTATTACHED || |
@@ -5240,6 +5287,9 @@ static int usb_reset_and_verify_device(struct usb_device *udev) | |||
5240 | ret); | 5287 | ret); |
5241 | goto re_enumerate; | 5288 | goto re_enumerate; |
5242 | } | 5289 | } |
5290 | /* Resetting also frees any allocated streams */ | ||
5291 | for (j = 0; j < intf->cur_altsetting->desc.bNumEndpoints; j++) | ||
5292 | intf->cur_altsetting->endpoint[j].streams = 0; | ||
5243 | } | 5293 | } |
5244 | 5294 | ||
5245 | done: | 5295 | done: |
@@ -5342,10 +5392,11 @@ int usb_reset_device(struct usb_device *udev) | |||
5342 | else if (cintf->condition == | 5392 | else if (cintf->condition == |
5343 | USB_INTERFACE_BOUND) | 5393 | USB_INTERFACE_BOUND) |
5344 | rebind = 1; | 5394 | rebind = 1; |
5395 | if (rebind) | ||
5396 | cintf->needs_binding = 1; | ||
5345 | } | 5397 | } |
5346 | if (ret == 0 && rebind) | ||
5347 | usb_rebind_intf(cintf); | ||
5348 | } | 5398 | } |
5399 | usb_unbind_and_rebind_marked_interfaces(udev); | ||
5349 | } | 5400 | } |
5350 | 5401 | ||
5351 | usb_autosuspend_device(udev); | 5402 | usb_autosuspend_device(udev); |