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@xxxxxxxxxxxxxxx> Acked-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> --- 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, -- 1.7.9 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html