summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/usb.c11
-rw-r--r--common/usb_hub.c19
2 files changed, 25 insertions, 5 deletions
diff --git a/common/usb.c b/common/usb.c
index 60daa10..bd0f8d5 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -34,7 +34,7 @@
#include <asm/byteorder.h>
#include <asm/unaligned.h>
#include <compiler.h>
-
+#include <errno.h>
#include <usb.h>
#ifdef CONFIG_4xx
#include <asm/4xx_pci.h>
@@ -60,6 +60,7 @@ int usb_init(void)
void *ctrl;
struct usb_device *dev;
int i, start_index = 0;
+ int ret;
dev_index = 0;
asynch_allowed = 1;
@@ -75,7 +76,13 @@ int usb_init(void)
for (i = 0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++) {
/* init low_level USB */
printf("USB%d: ", i);
- if (usb_lowlevel_init(i, USB_INIT_HOST, &ctrl)) {
+ ret = usb_lowlevel_init(i, USB_INIT_HOST, &ctrl);
+ if (ret == -ENODEV) { /* No such device. */
+ puts("Port not available.\n");
+ continue;
+ }
+
+ if (ret) { /* Other error. */
puts("lowlevel init failed\n");
continue;
}
diff --git a/common/usb_hub.c b/common/usb_hub.c
index 2add4b9..c416e5e 100644
--- a/common/usb_hub.c
+++ b/common/usb_hub.c
@@ -209,9 +209,22 @@ int hub_port_reset(struct usb_device *dev, int port,
(portstatus & USB_PORT_STAT_CONNECTION) ? 1 : 0,
(portstatus & USB_PORT_STAT_ENABLE) ? 1 : 0);
- if ((portchange & USB_PORT_STAT_C_CONNECTION) ||
- !(portstatus & USB_PORT_STAT_CONNECTION))
- return -1;
+ /*
+ * Perhaps we should check for the following here:
+ * - C_CONNECTION hasn't been set.
+ * - CONNECTION is still set.
+ *
+ * Doing so would ensure that the device is still connected
+ * to the bus, and hasn't been unplugged or replaced while the
+ * USB bus reset was going on.
+ *
+ * However, if we do that, then (at least) a San Disk Ultra
+ * USB 3.0 16GB device fails to reset on (at least) an NVIDIA
+ * Tegra Jetson TK1 board. For some reason, the device appears
+ * to briefly drop off the bus when this second bus reset is
+ * executed, yet if we retry this loop, it'll eventually come
+ * back after another reset or two.
+ */
if (portstatus & USB_PORT_STAT_ENABLE)
break;