diff --git a/common/usb_hub.c b/common/usb_hub.c index e1d93b8333580008ad1f1f4c9d05cf406ea6eb06..4b1e899a2946234b0b4325e058be90d9f3debb87 100644 --- a/common/usb_hub.c +++ b/common/usb_hub.c @@ -196,7 +196,7 @@ static void usb_hub_power_on(struct usb_hub_device *hub) * Do a minimum delay of the larger value of 100ms or pgood_delay * so that the power can stablize before the devices are queried */ - hub->query_delay = get_timer(0) + max(100, (int)pgood_delay); + hub->query_delay = max(100, (int)pgood_delay); /* * Record the power-on timeout here. The max. delay (timeout) @@ -427,7 +427,7 @@ int usb_hub_port_connect_change(struct usb_device *dev, int port) return ret; } -static int usb_scan_port(struct usb_device_scan *usb_scan) +static int usb_scan_port(struct usb_device_scan *usb_scan, unsigned long start) { ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1); unsigned short portstatus; @@ -445,21 +445,13 @@ static int usb_scan_port(struct usb_device_scan *usb_scan) * Don't talk to the device before the query delay is expired. * This is needed for voltages to stabalize. */ - if (get_timer(0) < hub->query_delay) + if (get_timer(start) < hub->query_delay) return 0; ret = usb_get_port_status(dev, i + 1, portsts); if (ret < 0) { debug("get_port_status failed\n"); - if (get_timer(0) >= hub->connect_timeout) { - debug("devnum=%d port=%d: timeout\n", - dev->devnum, i + 1); - /* Remove this device from scanning list */ - list_del(&usb_scan->list); - free(usb_scan); - return 0; - } - return 0; + goto check_timeout; } portstatus = le16_to_cpu(portsts->wPortStatus); @@ -474,17 +466,8 @@ static int usb_scan_port(struct usb_device_scan *usb_scan) * in the PORTSC register of a root hub), ignore such case. */ if (!(portchange & USB_PORT_STAT_C_CONNECTION) && - !(portstatus & USB_PORT_STAT_CONNECTION)) { - if (get_timer(0) >= hub->connect_timeout) { - debug("devnum=%d port=%d: timeout\n", - dev->devnum, i + 1); - /* Remove this device from scanning list */ - list_del(&usb_scan->list); - free(usb_scan); - return 0; - } - return 0; - } + !(portstatus & USB_PORT_STAT_CONNECTION)) + goto check_timeout; if (portchange & USB_PORT_STAT_C_RESET) { debug("port %d reset change\n", i + 1); @@ -558,6 +541,16 @@ static int usb_scan_port(struct usb_device_scan *usb_scan) list_del(&usb_scan->list); free(usb_scan); + return 0; +check_timeout: + if (get_timer(start) >= hub->connect_timeout) { + debug("devnum=%d port=%d: timeout\n", + dev->devnum, i + 1); + /* Remove this device from scanning list */ + list_del(&usb_scan->list); + free(usb_scan); + return 0; + } return 0; } @@ -567,6 +560,7 @@ static int usb_device_list_scan(void) struct usb_device_scan *tmp; static int running; int ret = 0; + unsigned long start; /* Only run this loop once for each controller */ if (running) @@ -574,16 +568,18 @@ static int usb_device_list_scan(void) running = 1; + start = get_timer(0); while (1) { /* We're done, once the list is empty again */ if (list_empty(&usb_scan_list)) goto out; + mdelay(1); list_for_each_entry_safe(usb_scan, tmp, &usb_scan_list, list) { int ret; /* Scan this port */ - ret = usb_scan_port(usb_scan); + ret = usb_scan_port(usb_scan, start); if (ret) goto out; }