X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=common%2Fusb_hub.c;h=2add4b97920fefedbad4d2cd04b888d294992841;hb=24289208354c143967968755cff5c825a12e3f90;hp=a11b401e624b8d1e3edf33c2f89ce5d35487d65d;hpb=0adc331b37b71093a047607faf1ed1b60e572017;p=u-boot diff --git a/common/usb_hub.c b/common/usb_hub.c index a11b401e62..2add4b9792 100644 --- a/common/usb_hub.c +++ b/common/usb_hub.c @@ -35,15 +35,15 @@ #include #endif -#ifndef CONFIG_USB_HUB_MIN_POWER_ON_DELAY -#define CONFIG_USB_HUB_MIN_POWER_ON_DELAY 100 -#endif - #define USB_BUFSIZ 512 static struct usb_hub_device hub_dev[USB_MAX_HUB]; static int usb_hub_index; +__weak void usb_hub_reset_devices(int port) +{ + return; +} static int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size) { @@ -134,8 +134,11 @@ static void usb_hub_power_on(struct usb_hub_device *hub) debug("port %d returns %lX\n", i + 1, dev->status); } - /* Wait for power to become stable */ - mdelay(max(pgood_delay, CONFIG_USB_HUB_MIN_POWER_ON_DELAY)); + /* + * Wait for power to become stable, + * plus spec-defined max time for device to connect + */ + mdelay(pgood_delay + 1000); } void usb_hub_reset(void) @@ -302,7 +305,7 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port) static int usb_hub_configure(struct usb_device *dev) { - int i; + int i, length; ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, USB_BUFSIZ); unsigned char *bitmap; short hubCharacteristics; @@ -323,20 +326,14 @@ static int usb_hub_configure(struct usb_device *dev) } descriptor = (struct usb_hub_descriptor *)buffer; - /* silence compiler warning if USB_BUFSIZ is > 256 [= sizeof(char)] */ - i = descriptor->bLength; - if (i > USB_BUFSIZ) { - debug("usb_hub_configure: failed to get hub " \ - "descriptor - too long: %d\n", descriptor->bLength); - return -1; - } + length = min(descriptor->bLength, sizeof(struct usb_hub_descriptor)); - if (usb_get_hub_descriptor(dev, buffer, descriptor->bLength) < 0) { + if (usb_get_hub_descriptor(dev, buffer, length) < 0) { debug("usb_hub_configure: failed to get hub " \ "descriptor 2nd giving up %lX\n", dev->status); return -1; } - memcpy((unsigned char *)&hub->desc, buffer, descriptor->bLength); + memcpy((unsigned char *)&hub->desc, buffer, length); /* adjust 16bit values */ put_unaligned(le16_to_cpu(get_unaligned( &descriptor->wHubCharacteristics)), @@ -426,6 +423,14 @@ static int usb_hub_configure(struct usb_device *dev) "" : "no "); usb_hub_power_on(hub); + /* + * Reset any devices that may be in a bad state when applying + * the power. This is a __weak function. Resetting of the devices + * should occur in the board file of the device. + */ + for (i = 0; i < dev->maxchild; i++) + usb_hub_reset_devices(i + 1); + for (i = 0; i < dev->maxchild; i++) { ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1); unsigned short portstatus, portchange;