|
@@ -705,10 +705,26 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
|
|
|
if (type == HUB_INIT3)
|
|
|
goto init3;
|
|
|
|
|
|
- /* After a resume, port power should still be on.
|
|
|
+ /* The superspeed hub except for root hub has to use Hub Depth
|
|
|
+ * value as an offset into the route string to locate the bits
|
|
|
+ * it uses to determine the downstream port number. So hub driver
|
|
|
+ * should send a set hub depth request to superspeed hub after
|
|
|
+ * the superspeed hub is set configuration in initialization or
|
|
|
+ * reset procedure.
|
|
|
+ *
|
|
|
+ * After a resume, port power should still be on.
|
|
|
* For any other type of activation, turn it on.
|
|
|
*/
|
|
|
if (type != HUB_RESUME) {
|
|
|
+ if (hdev->parent && hub_is_superspeed(hdev)) {
|
|
|
+ ret = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
|
|
|
+ HUB_SET_DEPTH, USB_RT_HUB,
|
|
|
+ hdev->level - 1, 0, NULL, 0,
|
|
|
+ USB_CTRL_SET_TIMEOUT);
|
|
|
+ if (ret < 0)
|
|
|
+ dev_err(hub->intfdev,
|
|
|
+ "set hub depth failed\n");
|
|
|
+ }
|
|
|
|
|
|
/* Speed up system boot by using a delayed_work for the
|
|
|
* hub's initial power-up delays. This is pretty awkward
|
|
@@ -987,18 +1003,6 @@ static int hub_configure(struct usb_hub *hub,
|
|
|
goto fail;
|
|
|
}
|
|
|
|
|
|
- if (hub_is_superspeed(hdev) && (hdev->parent != NULL)) {
|
|
|
- ret = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
|
|
|
- HUB_SET_DEPTH, USB_RT_HUB,
|
|
|
- hdev->level - 1, 0, NULL, 0,
|
|
|
- USB_CTRL_SET_TIMEOUT);
|
|
|
-
|
|
|
- if (ret < 0) {
|
|
|
- message = "can't set hub depth";
|
|
|
- goto fail;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
/* Request the entire hub descriptor.
|
|
|
* hub->descriptor can handle USB_MAXCHILDREN ports,
|
|
|
* but the hub can/will return fewer bytes here.
|