USB: Set hub depth after USB3 hub reset
[profile/ivi/kernel-adaptation-intel-automotive.git] / drivers / usb / core / hub.c
index a0613d8..265c2f6 100644 (file)
@@ -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.