Commit 93c2582feaf88a899c2537698e91fbb58d488a5b
Committed by
Tom Rini
1 parent
676ae068d9
Exists in
master
and in
54 other branches
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>
Showing 4 changed files with 70 additions and 56 deletions Side-by-side Diff
common/cmd_usb.c
... | ... | @@ -381,8 +381,7 @@ |
381 | 381 | bootstage_mark_name(BOOTSTAGE_ID_USB_START, "usb_start"); |
382 | 382 | usb_stop(); |
383 | 383 | printf("(Re)start USB...\n"); |
384 | - i = usb_init(); | |
385 | - if (i >= 0) { | |
384 | + if (usb_init() >= 0) { | |
386 | 385 | #ifdef CONFIG_USB_STORAGE |
387 | 386 | /* try to recognize storage devices immediately */ |
388 | 387 | usb_stor_curr_dev = usb_stor_scan(1); |
... | ... | @@ -391,6 +390,9 @@ |
391 | 390 | /* try to recognize ethernet devices immediately */ |
392 | 391 | usb_ether_curr_dev = usb_host_eth_scan(1); |
393 | 392 | #endif |
393 | +#ifdef CONFIG_USB_KEYBOARD | |
394 | + drv_usb_kbd_init(); | |
395 | +#endif | |
394 | 396 | } |
395 | 397 | return 0; |
396 | 398 | } |
... | ... | @@ -417,8 +419,14 @@ |
417 | 419 | return 1; |
418 | 420 | } |
419 | 421 | if (strncmp(argv[1], "tree", 4) == 0) { |
420 | - printf("\nDevice Tree:\n"); | |
421 | - usb_show_tree(usb_get_dev_index(0)); | |
422 | + puts("USB device tree:\n"); | |
423 | + for (i = 0; i < USB_MAX_DEVICE; i++) { | |
424 | + dev = usb_get_dev_index(i); | |
425 | + if (dev == NULL) | |
426 | + break; | |
427 | + if (dev->parent == NULL) | |
428 | + usb_show_tree(dev); | |
429 | + } | |
422 | 430 | return 0; |
423 | 431 | } |
424 | 432 | if (strncmp(argv[1], "inf", 3) == 0) { |
common/usb.c
... | ... | @@ -72,45 +72,72 @@ |
72 | 72 | |
73 | 73 | static struct usb_device usb_dev[USB_MAX_DEVICE]; |
74 | 74 | static int dev_index; |
75 | -static int running; | |
76 | 75 | static int asynch_allowed; |
77 | 76 | |
78 | 77 | char usb_started; /* flag for the started/stopped USB status */ |
79 | -void *ctrl; /* goes away in a following commit, but don't break bisect */ | |
80 | 78 | |
81 | -/********************************************************************** | |
82 | - * some forward declerations... | |
83 | - */ | |
84 | -static void usb_scan_devices(void); | |
79 | +#ifndef CONFIG_USB_MAX_CONTROLLER_COUNT | |
80 | +#define CONFIG_USB_MAX_CONTROLLER_COUNT 1 | |
81 | +#endif | |
85 | 82 | |
86 | 83 | /*************************************************************************** |
87 | 84 | * Init USB Device |
88 | 85 | */ |
89 | - | |
90 | 86 | int usb_init(void) |
91 | 87 | { |
92 | - int result; | |
88 | + void *ctrl; | |
89 | + struct usb_device *dev; | |
90 | + int i, start_index = 0; | |
93 | 91 | |
94 | - running = 0; | |
95 | 92 | dev_index = 0; |
96 | 93 | asynch_allowed = 1; |
97 | 94 | usb_hub_reset(); |
95 | + | |
96 | + /* first make all devices unknown */ | |
97 | + for (i = 0; i < USB_MAX_DEVICE; i++) { | |
98 | + memset(&usb_dev[i], 0, sizeof(struct usb_device)); | |
99 | + usb_dev[i].devnum = -1; | |
100 | + } | |
101 | + | |
98 | 102 | /* init low_level USB */ |
99 | - printf("USB: "); | |
100 | - result = usb_lowlevel_init(0, &ctrl); | |
101 | - /* if lowlevel init is OK, scan the bus for devices | |
102 | - * i.e. search HUBs and configure them */ | |
103 | - if (result == 0) { | |
104 | - printf("scanning bus for devices... "); | |
105 | - running = 1; | |
106 | - usb_scan_devices(); | |
103 | + for (i = 0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++) { | |
104 | + /* init low_level USB */ | |
105 | + printf("USB%d: ", i); | |
106 | + if (usb_lowlevel_init(i, &ctrl)) { | |
107 | + puts("lowlevel init failed\n"); | |
108 | + continue; | |
109 | + } | |
110 | + /* | |
111 | + * lowlevel init is OK, now scan the bus for devices | |
112 | + * i.e. search HUBs and configure them | |
113 | + */ | |
114 | + start_index = dev_index; | |
115 | + printf("scanning bus %d for devices... ", i); | |
116 | + dev = usb_alloc_new_device(ctrl); | |
117 | + /* | |
118 | + * device 0 is always present | |
119 | + * (root hub, so let it analyze) | |
120 | + */ | |
121 | + if (dev) | |
122 | + usb_new_device(dev); | |
123 | + | |
124 | + if (start_index == dev_index) | |
125 | + puts("No USB Device found\n"); | |
126 | + else | |
127 | + printf("%d USB Device(s) found\n", | |
128 | + dev_index - start_index); | |
129 | + | |
107 | 130 | usb_started = 1; |
108 | - return 0; | |
109 | - } else { | |
110 | - printf("Error, couldn't init Lowlevel part\n"); | |
111 | - usb_started = 0; | |
131 | + } | |
132 | + | |
133 | + USB_PRINTF("scan end\n"); | |
134 | + /* if we were not able to find at least one working bus, bail out */ | |
135 | + if (!usb_started) { | |
136 | + puts("USB error: all controllers failed lowlevel init\n"); | |
112 | 137 | return -1; |
113 | 138 | } |
139 | + | |
140 | + return 0; | |
114 | 141 | } |
115 | 142 | |
116 | 143 | /****************************************************************************** |
117 | 144 | |
118 | 145 | |
... | ... | @@ -118,15 +145,20 @@ |
118 | 145 | */ |
119 | 146 | int usb_stop(void) |
120 | 147 | { |
121 | - int res = 0; | |
148 | + int i; | |
122 | 149 | |
123 | 150 | if (usb_started) { |
124 | 151 | asynch_allowed = 1; |
125 | 152 | usb_started = 0; |
126 | 153 | usb_hub_reset(); |
127 | - res = usb_lowlevel_stop(0); | |
154 | + | |
155 | + for (i = 0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++) { | |
156 | + if (usb_lowlevel_stop(i)) | |
157 | + printf("failed to stop USB controller %d\n", i); | |
158 | + } | |
128 | 159 | } |
129 | - return res; | |
160 | + | |
161 | + return 0; | |
130 | 162 | } |
131 | 163 | |
132 | 164 | /* |
... | ... | @@ -751,7 +783,6 @@ |
751 | 783 | return &usb_dev[index]; |
752 | 784 | } |
753 | 785 | |
754 | - | |
755 | 786 | /* returns a pointer of a new device structure or NULL, if |
756 | 787 | * no device struct is available |
757 | 788 | */ |
... | ... | @@ -945,31 +976,6 @@ |
945 | 976 | /* now prode if the device is a hub */ |
946 | 977 | usb_hub_probe(dev, 0); |
947 | 978 | return 0; |
948 | -} | |
949 | - | |
950 | -/* build device Tree */ | |
951 | -static void usb_scan_devices(void) | |
952 | -{ | |
953 | - int i; | |
954 | - struct usb_device *dev; | |
955 | - | |
956 | - /* first make all devices unknown */ | |
957 | - for (i = 0; i < USB_MAX_DEVICE; i++) { | |
958 | - memset(&usb_dev[i], 0, sizeof(struct usb_device)); | |
959 | - usb_dev[i].devnum = -1; | |
960 | - } | |
961 | - dev_index = 0; | |
962 | - /* device 0 is always present (root hub, so let it analyze) */ | |
963 | - dev = usb_alloc_new_device(ctrl); | |
964 | - if (usb_new_device(dev)) | |
965 | - printf("No USB Device found\n"); | |
966 | - else | |
967 | - printf("%d USB Device(s) found\n", dev_index); | |
968 | - /* insert "driver" if possible */ | |
969 | -#ifdef CONFIG_USB_KEYBOARD | |
970 | - drv_usb_kbd_init(); | |
971 | -#endif | |
972 | - USB_PRINTF("scan end\n"); | |
973 | 979 | } |
974 | 980 | |
975 | 981 | /* EOF */ |
common/usb_storage.c
drivers/usb/eth/usb_ether.c