diff options
author | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2012-12-11 18:14:03 (GMT) |
---|---|---|
committer | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2013-01-03 22:10:38 (GMT) |
commit | 470f0be8aa78034030d3e05580e85ba7d0e26da7 (patch) | |
tree | 54fdaad6b458cfb1e3b9e3f85d0f4360894aa3f4 /drivers/usb/core/hub.c | |
parent | c2f60db740f2935a5e8a348298b590f2462e952f (diff) | |
download | linux-470f0be8aa78034030d3e05580e85ba7d0e26da7.tar.xz |
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/hub.c')
-rw-r--r-- | drivers/usb/core/hub.c | 73 |
1 files changed, 37 insertions, 36 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index be976ee..ae10862 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, 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, |