From 93c2582feaf88a899c2537698e91fbb58d488a5b Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Wed, 26 Sep 2012 00:14:36 +0200 Subject: [PATCH] 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 Reviewed-by: Marek Vasut --- common/cmd_usb.c | 16 ++++-- common/usb.c | 106 +++++++++++++++++++----------------- common/usb_storage.c | 2 +- drivers/usb/eth/usb_ether.c | 2 +- 4 files changed, 70 insertions(+), 56 deletions(-) diff --git a/common/cmd_usb.c b/common/cmd_usb.c index 181e727f00..c128455d74 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); @@ -390,6 +389,9 @@ int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) #ifdef CONFIG_USB_HOST_ETHER /* 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 e58b6f498f..1c9763cb6c 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 4aeed827c1..950451e11f 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 */ diff --git a/drivers/usb/eth/usb_ether.c b/drivers/usb/eth/usb_ether.c index 6cad6c87ca..f361e8b168 100644 --- a/drivers/usb/eth/usb_ether.c +++ b/drivers/usb/eth/usb_ether.c @@ -123,7 +123,7 @@ int usb_host_eth_scan(int mode) if (mode == 1) - printf(" scanning bus for ethernet devices... "); + printf(" scanning usb for ethernet devices... "); old_async = usb_disable_asynch(1); /* asynch transfer not allowed */ -- 2.39.5