
Dear Jim Lin,
Add support for command line "usb reset" or "usb start" to initialize , "usb stop" to stop multiple USB controllers at once. Other command like "usb tree" also supports multiple controllers.
New added definitions in header file are: CONFIG_USB_MULTI CONFIG_USB_MAX_CONTROLLER_COUNT
Signed-off-by: Jim Lin jilin@nvidia.com
Changes in v2:
- Renaming from CONFIG_USB_INIT_MULTI to CONFIG_USB_MULTI
- Define CONFIG_USB_MAX_CONTROLLER_COUNT as 1 if not defined
- Remove volatile from structure ehci_ctrl of ehci-hcd.c for a
checkpatch.pl warning
common/cmd_usb.c | 10 +++ common/usb.c | 98 +++++++++++++++++++++++++- common/usb_hub.c | 4 + drivers/usb/host/ehci-hcd.c | 167 +++++++++++++++++++++++++++++++----------- drivers/usb/host/ehci.h | 5 ++ include/usb.h | 12 +++ 6 files changed, 251 insertions(+), 45 deletions(-)
diff --git a/common/cmd_usb.c b/common/cmd_usb.c index a8e3ae5..8d3093b 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -554,7 +554,17 @@ int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char
- const argv[]) } if (strncmp(argv[1], "tree", 4) == 0) { printf("\nDevice Tree:\n");
+#ifdef CONFIG_USB_MULTI
How's this supposed to work? Shouldn't this call usb_show_tree on roots of all the trees?
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);
}
+#else usb_show_tree(usb_get_dev_index(0)); +#endif return 0; } if (strncmp(argv[1], "inf", 3) == 0) { diff --git a/common/usb.c b/common/usb.c index 1b40228..065c70c 100644 --- a/common/usb.c +++ b/common/usb.c @@ -77,6 +77,89 @@ static int asynch_allowed;
char usb_started; /* flag for the started/stopped USB status */
+#ifdef CONFIG_USB_MULTI +/************************************************************************* ** + * Init USB Device
- */
+#ifndef CONFIG_USB_MAX_CONTROLLER_COUNT +#define CONFIG_USB_MAX_CONTROLLER_COUNT 1 +#endif
+int usb_init(void) +{
void *ctrl;
int i;
struct usb_device *dev;
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: ");
for (i = 0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++) {
/* init low_level USB */
ctrl = usb_lowlevel_init(i);
/*
* if lowlevel init is OK, scan the bus for devices
* i.e. search HUBs and configure them
*/
if (ctrl) {
running = 1;
printf("scanning bus for devices... ");
dev = usb_alloc_new_device(ctrl);
/*
* device 0 is always present
* (root hub, so let it analyze)
*/
if (dev)
usb_new_device(dev);
}
}
if (running) {
if (!dev_index)
printf("No USB Device found\n");
else
printf("%d USB Device(s) found\n", dev_index);
+#ifdef CONFIG_USB_KEYBOARD
drv_usb_kbd_init();
Will the keyboard driver survive this?
+#endif
USB_PRINTF("scan end\n");
usb_started = 1;
return 0;
} else {
printf("Error, couldn't init Lowlevel part\n");
usb_started = 0;
return -1;
}
+}
+/************************************************************************* ***** + * Stop USB this stops the LowLevel Part and deregisters USB devices. + */ +int usb_stop(void) +{
int i;
if (usb_started) {
asynch_allowed = 1;
usb_started = 0;
usb_hub_reset();
for (i = 0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++)
usb_lowlevel_stop(i);
}
return 0;
+} +#else /**********************************************************************
- some forward declerations...
*/ @@ -127,6 +210,7 @@ int usb_stop(void) } return res; } +#endif
/*
- disables the asynch behaviour of the control message. This is used for
data @@ -750,11 +834,18 @@ struct usb_device *usb_get_dev_index(int index) return &usb_dev[index]; }
+#ifdef CONFIG_USB_MULTI
I still believe it's possible to get rid of this MULTI crap, simply set the "multiness" to 1 for non-multi setups. How big overhead will that generate? [...] btw you might want to rebase on top of latest u-boot-usb.