Commit 6a1b206dc48d435c6394cf3a8acc8a883516dd9d

Authored by Simon Glass
1 parent 79b5888729

dm: usb: Convert 'usb' command to support driver model

Adjust this command to work with the new driver model uclass. It needs to
iterate through multiple independent controllers to find hubs, and work
through their children recursively in a different way. Otherwise the
functionality is much the same.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Marek Vasut <marex@denx.de>

Showing 1 changed file with 145 additions and 2 deletions Side-by-side Diff

... ... @@ -2,6 +2,9 @@
2 2 * (C) Copyright 2001
3 3 * Denis Peter, MPL AG Switzerland
4 4 *
  5 + * Adapted for U-Boot driver model
  6 + * (C) Copyright 2015 Google, Inc
  7 + *
5 8 * Most of this source has been derived from the Linux USB
6 9 * project.
7 10 *
... ... @@ -10,6 +13,7 @@
10 13  
11 14 #include <common.h>
12 15 #include <command.h>
  16 +#include <dm.h>
13 17 #include <asm/byteorder.h>
14 18 #include <asm/unaligned.h>
15 19 #include <part.h>
16 20  
17 21  
... ... @@ -252,9 +256,47 @@
252 256 printf("\n");
253 257 }
254 258  
  259 +/*
  260 + * With driver model this isn't right since we can have multiple controllers
  261 + * and the device numbering starts at 1 on each bus.
  262 + * TODO(sjg@chromium.org): Add a way to specify the controller/bus.
  263 + */
255 264 static struct usb_device *usb_find_device(int devnum)
256 265 {
  266 +#ifdef CONFIG_DM_USB
257 267 struct usb_device *udev;
  268 + struct udevice *hub;
  269 + struct uclass *uc;
  270 + int ret;
  271 +
  272 + /* Device addresses start at 1 */
  273 + devnum++;
  274 + ret = uclass_get(UCLASS_USB_HUB, &uc);
  275 + if (ret)
  276 + return NULL;
  277 +
  278 + uclass_foreach_dev(hub, uc) {
  279 + struct udevice *dev;
  280 +
  281 + if (!device_active(hub))
  282 + continue;
  283 + udev = dev_get_parentdata(hub);
  284 + if (udev->devnum == devnum)
  285 + return udev;
  286 +
  287 + for (device_find_first_child(hub, &dev);
  288 + dev;
  289 + device_find_next_child(&dev)) {
  290 + if (!device_active(hub))
  291 + continue;
  292 +
  293 + udev = dev_get_parentdata(dev);
  294 + if (udev->devnum == devnum)
  295 + return udev;
  296 + }
  297 + }
  298 +#else
  299 + struct usb_device *udev;
258 300 int d;
259 301  
260 302 for (d = 0; d < USB_MAX_DEVICE; d++) {
... ... @@ -264,6 +306,7 @@
264 306 if (udev->devnum == devnum)
265 307 return udev;
266 308 }
  309 +#endif
267 310  
268 311 return NULL;
269 312 }
270 313  
271 314  
272 315  
273 316  
274 317  
275 318  
... ... @@ -293,20 +336,31 @@
293 336 /* shows the device tree recursively */
294 337 static void usb_show_tree_graph(struct usb_device *dev, char *pre)
295 338 {
296   - int i, index;
  339 + int index;
297 340 int has_child, last_child;
298 341  
299 342 index = strlen(pre);
300 343 printf(" %s", pre);
  344 +#ifdef CONFIG_DM_USB
  345 + has_child = device_has_active_children(dev->dev);
  346 +#else
301 347 /* check if the device has connected children */
  348 + int i;
  349 +
302 350 has_child = 0;
303 351 for (i = 0; i < dev->maxchild; i++) {
304 352 if (dev->children[i] != NULL)
305 353 has_child = 1;
306 354 }
  355 +#endif
307 356 /* check if we are the last one */
  357 +#ifdef CONFIG_DM_USB
  358 + last_child = device_is_last_sibling(dev->dev);
  359 +#else
308 360 last_child = (dev->parent != NULL);
  361 +#endif
309 362 if (last_child) {
  363 +#ifndef CONFIG_DM_USB
310 364 for (i = 0; i < dev->parent->maxchild; i++) {
311 365 /* search for children */
312 366 if (dev->parent->children[i] == dev) {
... ... @@ -322,6 +376,7 @@
322 376 } /* while */
323 377 } /* device found */
324 378 } /* for all children of the parent */
  379 +#endif
325 380 printf("\b+-");
326 381 /* correct last child */
327 382 if (last_child && index)
... ... @@ -340,6 +395,26 @@
340 395 if (strlen(dev->mf) || strlen(dev->prod) || strlen(dev->serial))
341 396 printf(" %s %s %s %s\n", pre, dev->mf, dev->prod, dev->serial);
342 397 printf(" %s\n", pre);
  398 +#ifdef CONFIG_DM_USB
  399 + struct udevice *child;
  400 +
  401 + for (device_find_first_child(dev->dev, &child);
  402 + child;
  403 + device_find_next_child(&child)) {
  404 + struct usb_device *udev;
  405 +
  406 + if (!device_active(child))
  407 + continue;
  408 +
  409 + udev = dev_get_parentdata(child);
  410 +
  411 + /* Ignore emulators, we only want real devices */
  412 + if (device_get_uclass_id(child) != UCLASS_USB_EMUL) {
  413 + usb_show_tree_graph(udev, pre);
  414 + pre[index] = 0;
  415 + }
  416 + }
  417 +#else
343 418 if (dev->maxchild > 0) {
344 419 for (i = 0; i < dev->maxchild; i++) {
345 420 if (dev->children[i] != NULL) {
... ... @@ -348,6 +423,7 @@
348 423 }
349 424 }
350 425 }
  426 +#endif
351 427 }
352 428  
353 429 /* main routine for the tree command */
354 430  
... ... @@ -448,10 +524,13 @@
448 524 if (usb_init() < 0)
449 525 return;
450 526  
  527 + /* Driver model will probe the devices as they are found */
  528 +#ifndef CONFIG_DM_USB
451 529 #ifdef CONFIG_USB_STORAGE
452 530 /* try to recognize storage devices immediately */
453 531 usb_stor_curr_dev = usb_stor_scan(1);
454 532 #endif
  533 +#endif
455 534 #ifdef CONFIG_USB_HOST_ETHER
456 535 /* try to recognize ethernet devices immediately */
457 536 usb_ether_curr_dev = usb_host_eth_scan(1);
... ... @@ -461,6 +540,43 @@
461 540 #endif
462 541 }
463 542  
  543 +#ifdef CONFIG_DM_USB
  544 +static void show_info(struct udevice *dev)
  545 +{
  546 + struct udevice *child;
  547 + struct usb_device *udev;
  548 +
  549 + udev = dev_get_parentdata(dev);
  550 + usb_display_desc(udev);
  551 + usb_display_config(udev);
  552 + for (device_find_first_child(dev, &child);
  553 + child;
  554 + device_find_next_child(&child)) {
  555 + if (device_active(child))
  556 + show_info(child);
  557 + }
  558 +}
  559 +
  560 +static int usb_device_info(void)
  561 +{
  562 + struct udevice *bus;
  563 +
  564 + for (uclass_first_device(UCLASS_USB, &bus);
  565 + bus;
  566 + uclass_next_device(&bus)) {
  567 + struct udevice *hub;
  568 +
  569 + device_find_first_child(bus, &hub);
  570 + if (device_get_uclass_id(hub) == UCLASS_USB_HUB &&
  571 + device_active(hub)) {
  572 + show_info(hub);
  573 + }
  574 + }
  575 +
  576 + return 0;
  577 +}
  578 +#endif
  579 +
464 580 /******************************************************************************
465 581 * usb command intepreter
466 582 */
... ... @@ -507,6 +623,23 @@
507 623 }
508 624 if (strncmp(argv[1], "tree", 4) == 0) {
509 625 puts("USB device tree:\n");
  626 +#ifdef CONFIG_DM_USB
  627 + struct udevice *bus;
  628 +
  629 + for (uclass_first_device(UCLASS_USB, &bus);
  630 + bus;
  631 + uclass_next_device(&bus)) {
  632 + struct usb_device *udev;
  633 + struct udevice *hub;
  634 +
  635 + device_find_first_child(bus, &hub);
  636 + if (device_get_uclass_id(hub) == UCLASS_USB_HUB &&
  637 + device_active(hub)) {
  638 + udev = dev_get_parentdata(hub);
  639 + usb_show_tree(udev);
  640 + }
  641 + }
  642 +#else
510 643 for (i = 0; i < USB_MAX_DEVICE; i++) {
511 644 udev = usb_get_dev_index(i);
512 645 if (udev == NULL)
513 646  
514 647  
... ... @@ -514,11 +647,15 @@
514 647 if (udev->parent == NULL)
515 648 usb_show_tree(udev);
516 649 }
  650 +#endif
517 651 return 0;
518 652 }
519 653 if (strncmp(argv[1], "inf", 3) == 0) {
520   - int d;
521 654 if (argc == 2) {
  655 +#ifdef CONFIG_DM_USB
  656 + usb_device_info();
  657 +#else
  658 + int d;
522 659 for (d = 0; d < USB_MAX_DEVICE; d++) {
523 660 udev = usb_get_dev_index(d);
524 661 if (udev == NULL)
525 662  
... ... @@ -526,8 +663,14 @@
526 663 usb_display_desc(udev);
527 664 usb_display_config(udev);
528 665 }
  666 +#endif
529 667 return 0;
530 668 } else {
  669 + /*
  670 + * With driver model this isn't right since we can
  671 + * have multiple controllers and the device numbering
  672 + * starts at 1 on each bus.
  673 + */
531 674 i = simple_strtoul(argv[2], NULL, 10);
532 675 printf("config for device %d\n", i);
533 676 udev = usb_find_device(i);