Hi,

On 14-03-16 18:31, Stephen Warren wrote:
On 03/14/2016 04:18 AM, Stefan Roese wrote:

<snip>

@@ -120,7 +121,21 @@ static void usb_hub_power_on(struct usb_hub_device *hub)
          pgood_delay = max(pgood_delay,
                        (unsigned)simple_strtol(env, NULL, 0));
      debug("pgood_delay=%dms\n", pgood_delay);
-    mdelay(pgood_delay + 1000);
+
+    /*
+     * Do a minimum delay of the larger value of 100ms or pgood_delay
+     * so that the power can stablize before the devices are queried
+     */
+    dev->query_delay = get_timer(0) + max(100, (int)pgood_delay);
+
+    /*
+     * Record the power-on timeout here. The max. delay (timeout)
+     * will be done based on this value in the USB port loop in
+     * usb_hub_configure() later.
+     */
+    dev->connect_timeout = get_timer(0) + pgood_delay + 1000;

I'd be tempted to make that:

dev->connect_timeout = dev->query_delay + 1000;

That way, if the max() used in the calculation of dev->query_delay was 
dominated by the 100 not the pgood_delay, then we still get a 1000ms time for the 
device to connect after the power is stable.

Ack, good catch.

Currently, if pgood_delay<=100 (is that legal?) then the delta might be as 
little as 900ms (for pgood_delay==0).

AFAIK it is not legal, but guess what the firmware authors of cheap hubs put in 
the
descriptor when 0 seems to work just fine ?

Rule of thumb: Never trust usb descriptors.

Regards,

Hans




static LIST_HEAD(usb_scan_list);

You could put that onto the stack in usb_hub_configure() and pass it as a 
parameter to usb_device_list_scan(). That would avoid some globals, which might 
make it easier to apply this technique across multiple controllers/hubs/... in 
the future?

+static int usb_scan_port(struct usb_device_scan *usb_scan)

+    ret = usb_get_port_status(dev, i + 1, portsts);
+    if (ret < 0) {
+        debug("get_port_status failed\n");
+        return 0;

Shouldn't this cause a timeout eventually if it repeats forever?

+    /* Test if the connection came up, and if so, exit. */
+    if (portstatus & USB_PORT_STAT_CONNECTION) {

If you invert that test, you can return early and remove and indentation level 
from the rest of the function.

+        debug("devnum=%d port=%d: USB dev found\n", dev->devnum, i + 1);
+        /* Remove this device from scanning list */
+        list_del(&usb_scan->list);
+
+        /* A new USB device is ready at this point */
+
+        debug("Port %d Status %X Change %X\n",
+              i + 1, portstatus, portchange);

It might be nice to print this a little earlier (outside the USB_PORT_STAT_CONNECTION 
if block) so that any USB_PORT_STAT_C_CONNECTION triggers the print, not just if 
C_CONNECTION && CONNECTION. That might help debug, and match the existing code.

+        if (portchange & USB_PORT_STAT_C_CONNECTION) {
 > +            debug("port %d connection change\n", i + 1);
 > +            usb_hub_port_connect_change(dev, i);
 > +        }

That test is always true, or the function would have returned earlier.

+static int usb_device_list_scan(void)
...
+    static int running;
+    int ret = 0;
+
+    /* Only run this loop once for each controller */
+    if (running)
+        return 0;
+
+    running = 1;
...
+out:
+    /*
+     * This USB controller has has finished scanning all its connected
+     * USB devices. Set "running" back to 0, so that other USB controllers
+     * will scan their devices too.
+     */
+    running = 0;

Doesn't this function only get called a single time from usb_hub_configure()? If so, I 
don't think the "running" variable is required.

  static int usb_hub_configure(struct usb_device *dev)

+    for (i = 0; i < dev->maxchild; i++) {
+        struct usb_device_scan *usb_scan;

+        usb_scan = calloc(1, sizeof(*usb_scan));
+        if (!usb_scan) {
+            printf("Can't allocate memory for USB device!\n");
+            return -ENOMEM;

I think there should be some resource cleanup for the previously allocated list 
entries here. Perhaps that's what you meant in your other email where you 
talked about some missing free()s?
_______________________________________________
U-Boot mailing list
[email protected]
http://lists.denx.de/mailman/listinfo/u-boot
_______________________________________________
U-Boot mailing list
[email protected]
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to