|
@@ -2535,42 +2535,9 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1,
|
|
|
return ret;
|
|
|
|
|
|
/* The port state is unknown until the reset completes. */
|
|
|
- if ((portstatus & USB_PORT_STAT_RESET))
|
|
|
- goto delay;
|
|
|
-
|
|
|
- if (hub_port_warm_reset_required(hub, portstatus))
|
|
|
- return -ENOTCONN;
|
|
|
-
|
|
|
- /* Device went away? */
|
|
|
- if (!(portstatus & USB_PORT_STAT_CONNECTION))
|
|
|
- return -ENOTCONN;
|
|
|
-
|
|
|
- /* bomb out completely if the connection bounced. A USB 3.0
|
|
|
- * connection may bounce if multiple warm resets were issued,
|
|
|
- * but the device may have successfully re-connected. Ignore it.
|
|
|
- */
|
|
|
- if (!hub_is_superspeed(hub->hdev) &&
|
|
|
- (portchange & USB_PORT_STAT_C_CONNECTION))
|
|
|
- return -ENOTCONN;
|
|
|
-
|
|
|
- if ((portstatus & USB_PORT_STAT_ENABLE)) {
|
|
|
- if (!udev)
|
|
|
- return 0;
|
|
|
-
|
|
|
- if (hub_is_wusb(hub))
|
|
|
- udev->speed = USB_SPEED_WIRELESS;
|
|
|
- else if (hub_is_superspeed(hub->hdev))
|
|
|
- udev->speed = USB_SPEED_SUPER;
|
|
|
- else if (portstatus & USB_PORT_STAT_HIGH_SPEED)
|
|
|
- udev->speed = USB_SPEED_HIGH;
|
|
|
- else if (portstatus & USB_PORT_STAT_LOW_SPEED)
|
|
|
- udev->speed = USB_SPEED_LOW;
|
|
|
- else
|
|
|
- udev->speed = USB_SPEED_FULL;
|
|
|
- return 0;
|
|
|
- }
|
|
|
+ if (!(portstatus & USB_PORT_STAT_RESET))
|
|
|
+ break;
|
|
|
|
|
|
-delay:
|
|
|
/* switch to the long delay after two short delay failures */
|
|
|
if (delay_time >= 2 * HUB_SHORT_RESET_TIME)
|
|
|
delay = HUB_LONG_RESET_TIME;
|
|
@@ -2580,7 +2547,41 @@ delay:
|
|
|
port1, warm ? "warm " : "", delay);
|
|
|
}
|
|
|
|
|
|
- return -EBUSY;
|
|
|
+ if ((portstatus & USB_PORT_STAT_RESET))
|
|
|
+ return -EBUSY;
|
|
|
+
|
|
|
+ if (hub_port_warm_reset_required(hub, portstatus))
|
|
|
+ return -ENOTCONN;
|
|
|
+
|
|
|
+ /* Device went away? */
|
|
|
+ if (!(portstatus & USB_PORT_STAT_CONNECTION))
|
|
|
+ return -ENOTCONN;
|
|
|
+
|
|
|
+ /* bomb out completely if the connection bounced. A USB 3.0
|
|
|
+ * connection may bounce if multiple warm resets were issued,
|
|
|
+ * but the device may have successfully re-connected. Ignore it.
|
|
|
+ */
|
|
|
+ if (!hub_is_superspeed(hub->hdev) &&
|
|
|
+ (portchange & USB_PORT_STAT_C_CONNECTION))
|
|
|
+ return -ENOTCONN;
|
|
|
+
|
|
|
+ if (!(portstatus & USB_PORT_STAT_ENABLE))
|
|
|
+ return -EBUSY;
|
|
|
+
|
|
|
+ if (!udev)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ if (hub_is_wusb(hub))
|
|
|
+ udev->speed = USB_SPEED_WIRELESS;
|
|
|
+ else if (hub_is_superspeed(hub->hdev))
|
|
|
+ udev->speed = USB_SPEED_SUPER;
|
|
|
+ else if (portstatus & USB_PORT_STAT_HIGH_SPEED)
|
|
|
+ udev->speed = USB_SPEED_HIGH;
|
|
|
+ else if (portstatus & USB_PORT_STAT_LOW_SPEED)
|
|
|
+ udev->speed = USB_SPEED_LOW;
|
|
|
+ else
|
|
|
+ udev->speed = USB_SPEED_FULL;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
static void hub_port_finish_reset(struct usb_hub *hub, int port1,
|