aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2012-12-11 13:14:03 -0500
committerSarah Sharp <sarah.a.sharp@linux.intel.com>2013-01-03 17:10:38 -0500
commit470f0be8aa78034030d3e05580e85ba7d0e26da7 (patch)
tree54fdaad6b458cfb1e3b9e3f85d0f4360894aa3f4 /drivers/usb/core
parentc2f60db740f2935a5e8a348298b590f2462e952f (diff)
USB: Refactor hub_port_wait_reset.
Refactor hub_port_wait_reset into a small loop to wait for the port reset to be complete, and then a larger block to deal with the final port status. This patch should not change any current behavior. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Acked-by: Alan Stern <stern@rowland.harvard.edu>
Diffstat (limited to 'drivers/usb/core')
-rw-r--r--drivers/usb/core/hub.c73
1 files changed, 37 insertions, 36 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index be976ee84b8e..ae10862fb041 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2535,42 +2535,9 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1,
2535 return ret; 2535 return ret;
2536 2536
2537 /* The port state is unknown until the reset completes. */ 2537 /* The port state is unknown until the reset completes. */
2538 if ((portstatus & USB_PORT_STAT_RESET)) 2538 if (!(portstatus & USB_PORT_STAT_RESET))
2539 goto delay; 2539 break;
2540
2541 if (hub_port_warm_reset_required(hub, portstatus))
2542 return -ENOTCONN;
2543
2544 /* Device went away? */
2545 if (!(portstatus & USB_PORT_STAT_CONNECTION))
2546 return -ENOTCONN;
2547
2548 /* bomb out completely if the connection bounced. A USB 3.0
2549 * connection may bounce if multiple warm resets were issued,
2550 * but the device may have successfully re-connected. Ignore it.
2551 */
2552 if (!hub_is_superspeed(hub->hdev) &&
2553 (portchange & USB_PORT_STAT_C_CONNECTION))
2554 return -ENOTCONN;
2555
2556 if ((portstatus & USB_PORT_STAT_ENABLE)) {
2557 if (!udev)
2558 return 0;
2559
2560 if (hub_is_wusb(hub))
2561 udev->speed = USB_SPEED_WIRELESS;
2562 else if (hub_is_superspeed(hub->hdev))
2563 udev->speed = USB_SPEED_SUPER;
2564 else if (portstatus & USB_PORT_STAT_HIGH_SPEED)
2565 udev->speed = USB_SPEED_HIGH;
2566 else if (portstatus & USB_PORT_STAT_LOW_SPEED)
2567 udev->speed = USB_SPEED_LOW;
2568 else
2569 udev->speed = USB_SPEED_FULL;
2570 return 0;
2571 }
2572 2540
2573delay:
2574 /* switch to the long delay after two short delay failures */ 2541 /* switch to the long delay after two short delay failures */
2575 if (delay_time >= 2 * HUB_SHORT_RESET_TIME) 2542 if (delay_time >= 2 * HUB_SHORT_RESET_TIME)
2576 delay = HUB_LONG_RESET_TIME; 2543 delay = HUB_LONG_RESET_TIME;
@@ -2580,7 +2547,41 @@ delay:
2580 port1, warm ? "warm " : "", delay); 2547 port1, warm ? "warm " : "", delay);
2581 } 2548 }
2582 2549
2583 return -EBUSY; 2550 if ((portstatus & USB_PORT_STAT_RESET))
2551 return -EBUSY;
2552
2553 if (hub_port_warm_reset_required(hub, portstatus))
2554 return -ENOTCONN;
2555
2556 /* Device went away? */
2557 if (!(portstatus & USB_PORT_STAT_CONNECTION))
2558 return -ENOTCONN;
2559
2560 /* bomb out completely if the connection bounced. A USB 3.0
2561 * connection may bounce if multiple warm resets were issued,
2562 * but the device may have successfully re-connected. Ignore it.
2563 */
2564 if (!hub_is_superspeed(hub->hdev) &&
2565 (portchange & USB_PORT_STAT_C_CONNECTION))
2566 return -ENOTCONN;
2567
2568 if (!(portstatus & USB_PORT_STAT_ENABLE))
2569 return -EBUSY;
2570
2571 if (!udev)
2572 return 0;
2573
2574 if (hub_is_wusb(hub))
2575 udev->speed = USB_SPEED_WIRELESS;
2576 else if (hub_is_superspeed(hub->hdev))
2577 udev->speed = USB_SPEED_SUPER;
2578 else if (portstatus & USB_PORT_STAT_HIGH_SPEED)
2579 udev->speed = USB_SPEED_HIGH;
2580 else if (portstatus & USB_PORT_STAT_LOW_SPEED)
2581 udev->speed = USB_SPEED_LOW;
2582 else
2583 udev->speed = USB_SPEED_FULL;
2584 return 0;
2584} 2585}
2585 2586
2586static void hub_port_finish_reset(struct usb_hub *hub, int port1, 2587static void hub_port_finish_reset(struct usb_hub *hub, int port1,