summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorLucas Stach <dev@lynxeye.de>2012-09-26 00:14:36 +0200
committerTom Rini <trini@ti.com>2012-10-15 11:54:00 -0700
commit93c2582feaf88a899c2537698e91fbb58d488a5b (patch)
tree217525cc0ef1739fd98bfc918a611bd3dc10b9d6 /common
parent676ae068d9af8c4848dc8f3a66d65e2bff066239 (diff)
downloadu-boot-imx-93c2582feaf88a899c2537698e91fbb58d488a5b.zip
u-boot-imx-93c2582feaf88a899c2537698e91fbb58d488a5b.tar.gz
u-boot-imx-93c2582feaf88a899c2537698e91fbb58d488a5b.tar.bz2
usb: add support for multiple usb controllers
Allows to initialize more than one USB controller at once. v2: print message when controller stop fails Signed-off-by: Lucas Stach <dev@lynxeye.de> Reviewed-by: Marek Vasut <marex@denx.de>
Diffstat (limited to 'common')
-rw-r--r--common/cmd_usb.c16
-rw-r--r--common/usb.c106
-rw-r--r--common/usb_storage.c2
3 files changed, 69 insertions, 55 deletions
diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index 181e727..c128455 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -381,8 +381,7 @@ int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
bootstage_mark_name(BOOTSTAGE_ID_USB_START, "usb_start");
usb_stop();
printf("(Re)start USB...\n");
- i = usb_init();
- if (i >= 0) {
+ if (usb_init() >= 0) {
#ifdef CONFIG_USB_STORAGE
/* try to recognize storage devices immediately */
usb_stor_curr_dev = usb_stor_scan(1);
@@ -391,6 +390,9 @@ int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
/* try to recognize ethernet devices immediately */
usb_ether_curr_dev = usb_host_eth_scan(1);
#endif
+#ifdef CONFIG_USB_KEYBOARD
+ drv_usb_kbd_init();
+#endif
}
return 0;
}
@@ -417,8 +419,14 @@ int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
return 1;
}
if (strncmp(argv[1], "tree", 4) == 0) {
- printf("\nDevice Tree:\n");
- usb_show_tree(usb_get_dev_index(0));
+ puts("USB device tree:\n");
+ for (i = 0; i < USB_MAX_DEVICE; i++) {
+ dev = usb_get_dev_index(i);
+ if (dev == NULL)
+ break;
+ if (dev->parent == NULL)
+ usb_show_tree(dev);
+ }
return 0;
}
if (strncmp(argv[1], "inf", 3) == 0) {
diff --git a/common/usb.c b/common/usb.c
index e58b6f4..1c9763c 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -72,45 +72,72 @@
static struct usb_device usb_dev[USB_MAX_DEVICE];
static int dev_index;
-static int running;
static int asynch_allowed;
char usb_started; /* flag for the started/stopped USB status */
-void *ctrl; /* goes away in a following commit, but don't break bisect */
-/**********************************************************************
- * some forward declerations...
- */
-static void usb_scan_devices(void);
+#ifndef CONFIG_USB_MAX_CONTROLLER_COUNT
+#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
+#endif
/***************************************************************************
* Init USB Device
*/
-
int usb_init(void)
{
- int result;
+ void *ctrl;
+ struct usb_device *dev;
+ int i, start_index = 0;
- running = 0;
dev_index = 0;
asynch_allowed = 1;
usb_hub_reset();
+
+ /* first make all devices unknown */
+ for (i = 0; i < USB_MAX_DEVICE; i++) {
+ memset(&usb_dev[i], 0, sizeof(struct usb_device));
+ usb_dev[i].devnum = -1;
+ }
+
/* init low_level USB */
- printf("USB: ");
- result = usb_lowlevel_init(0, &ctrl);
- /* if lowlevel init is OK, scan the bus for devices
- * i.e. search HUBs and configure them */
- if (result == 0) {
- printf("scanning bus for devices... ");
- running = 1;
- usb_scan_devices();
+ for (i = 0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++) {
+ /* init low_level USB */
+ printf("USB%d: ", i);
+ if (usb_lowlevel_init(i, &ctrl)) {
+ puts("lowlevel init failed\n");
+ continue;
+ }
+ /*
+ * lowlevel init is OK, now scan the bus for devices
+ * i.e. search HUBs and configure them
+ */
+ start_index = dev_index;
+ printf("scanning bus %d for devices... ", i);
+ dev = usb_alloc_new_device(ctrl);
+ /*
+ * device 0 is always present
+ * (root hub, so let it analyze)
+ */
+ if (dev)
+ usb_new_device(dev);
+
+ if (start_index == dev_index)
+ puts("No USB Device found\n");
+ else
+ printf("%d USB Device(s) found\n",
+ dev_index - start_index);
+
usb_started = 1;
- return 0;
- } else {
- printf("Error, couldn't init Lowlevel part\n");
- usb_started = 0;
+ }
+
+ USB_PRINTF("scan end\n");
+ /* if we were not able to find at least one working bus, bail out */
+ if (!usb_started) {
+ puts("USB error: all controllers failed lowlevel init\n");
return -1;
}
+
+ return 0;
}
/******************************************************************************
@@ -118,15 +145,20 @@ int usb_init(void)
*/
int usb_stop(void)
{
- int res = 0;
+ int i;
if (usb_started) {
asynch_allowed = 1;
usb_started = 0;
usb_hub_reset();
- res = usb_lowlevel_stop(0);
+
+ for (i = 0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++) {
+ if (usb_lowlevel_stop(i))
+ printf("failed to stop USB controller %d\n", i);
+ }
}
- return res;
+
+ return 0;
}
/*
@@ -751,7 +783,6 @@ struct usb_device *usb_get_dev_index(int index)
return &usb_dev[index];
}
-
/* returns a pointer of a new device structure or NULL, if
* no device struct is available
*/
@@ -947,29 +978,4 @@ int usb_new_device(struct usb_device *dev)
return 0;
}
-/* build device Tree */
-static void usb_scan_devices(void)
-{
- int i;
- struct usb_device *dev;
-
- /* first make all devices unknown */
- for (i = 0; i < USB_MAX_DEVICE; i++) {
- memset(&usb_dev[i], 0, sizeof(struct usb_device));
- usb_dev[i].devnum = -1;
- }
- dev_index = 0;
- /* device 0 is always present (root hub, so let it analyze) */
- dev = usb_alloc_new_device(ctrl);
- if (usb_new_device(dev))
- printf("No USB Device found\n");
- else
- printf("%d USB Device(s) found\n", dev_index);
- /* insert "driver" if possible */
-#ifdef CONFIG_USB_KEYBOARD
- drv_usb_kbd_init();
-#endif
- USB_PRINTF("scan end\n");
-}
-
/* EOF */
diff --git a/common/usb_storage.c b/common/usb_storage.c
index 4aeed82..950451e 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -244,7 +244,7 @@ int usb_stor_scan(int mode)
struct usb_device *dev;
if (mode == 1)
- printf(" scanning bus for storage devices... ");
+ printf(" scanning usb for storage devices... ");
usb_disable_asynch(1); /* asynch transfer not allowed */