X-Git-Url: https://git.kernelconcepts.de/?a=blobdiff_plain;ds=sidebyside;f=common%2Fcmd_usb.c;h=6874af7547148276f8b9564aa1e4b4e01ba8c7e1;hb=ffcdbd85b18e0e34ce296a4bfa90ec441e9db6c8;hp=27813f0d7af680fffa67b0dba509da1ba020e43a;hpb=4608f37918e5d93d6b2b6909b325a5e6fb0a2346;p=karo-tx-uboot.git diff --git a/common/cmd_usb.c b/common/cmd_usb.c index 27813f0d7a..6874af7547 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -2,6 +2,9 @@ * (C) Copyright 2001 * Denis Peter, MPL AG Switzerland * + * Adapted for U-Boot driver model + * (C) Copyright 2015 Google, Inc + * * Most of this source has been derived from the Linux USB * project. * @@ -10,6 +13,7 @@ #include #include +#include #include #include #include @@ -18,8 +22,8 @@ #ifdef CONFIG_USB_STORAGE static int usb_stor_curr_dev = -1; /* current device */ #endif -#ifdef CONFIG_USB_HOST_ETHER -static int usb_ether_curr_dev = -1; /* current ethernet device */ +#if defined(CONFIG_USB_HOST_ETHER) && !defined(CONFIG_DM_ETH) +static int __maybe_unused usb_ether_curr_dev = -1; /* current ethernet device */ #endif /* some display routines (info command) */ @@ -252,18 +256,57 @@ static void usb_display_config(struct usb_device *dev) printf("\n"); } +/* + * With driver model this isn't right since we can have multiple controllers + * and the device numbering starts at 1 on each bus. + * TODO(sjg@chromium.org): Add a way to specify the controller/bus. + */ static struct usb_device *usb_find_device(int devnum) { - struct usb_device *dev; +#ifdef CONFIG_DM_USB + struct usb_device *udev; + struct udevice *hub; + struct uclass *uc; + int ret; + + /* Device addresses start at 1 */ + devnum++; + ret = uclass_get(UCLASS_USB_HUB, &uc); + if (ret) + return NULL; + + uclass_foreach_dev(hub, uc) { + struct udevice *dev; + + if (!device_active(hub)) + continue; + udev = dev_get_parentdata(hub); + if (udev->devnum == devnum) + return udev; + + for (device_find_first_child(hub, &dev); + dev; + device_find_next_child(&dev)) { + if (!device_active(hub)) + continue; + + udev = dev_get_parentdata(dev); + if (udev->devnum == devnum) + return udev; + } + } +#else + struct usb_device *udev; int d; for (d = 0; d < USB_MAX_DEVICE; d++) { - dev = usb_get_dev_index(d); - if (dev == NULL) + udev = usb_get_dev_index(d); + if (udev == NULL) return NULL; - if (dev->devnum == devnum) - return dev; + if (udev->devnum == devnum) + return udev; } +#endif return NULL; } @@ -293,20 +336,31 @@ static inline char *portspeed(int speed) /* shows the device tree recursively */ static void usb_show_tree_graph(struct usb_device *dev, char *pre) { - int i, index; + int index; int has_child, last_child; index = strlen(pre); printf(" %s", pre); +#ifdef CONFIG_DM_USB + has_child = device_has_active_children(dev->dev); +#else /* check if the device has connected children */ + int i; + has_child = 0; for (i = 0; i < dev->maxchild; i++) { if (dev->children[i] != NULL) has_child = 1; } +#endif /* check if we are the last one */ - last_child = 1; - if (dev->parent != NULL) { +#ifdef CONFIG_DM_USB + /* Not the root of the usb tree? */ + if (device_get_uclass_id(dev->dev->parent) != UCLASS_USB) { + last_child = device_is_last_sibling(dev->dev); +#else + if (dev->parent != NULL) { /* not root? */ + last_child = 1; for (i = 0; i < dev->parent->maxchild; i++) { /* search for children */ if (dev->parent->children[i] == dev) { @@ -322,9 +376,10 @@ static void usb_show_tree_graph(struct usb_device *dev, char *pre) } /* while */ } /* device found */ } /* for all children of the parent */ +#endif printf("\b+-"); /* correct last child */ - if (last_child) + if (last_child && index) pre[index-1] = ' '; } /* if not root hub */ else @@ -340,6 +395,26 @@ static void usb_show_tree_graph(struct usb_device *dev, char *pre) if (strlen(dev->mf) || strlen(dev->prod) || strlen(dev->serial)) printf(" %s %s %s %s\n", pre, dev->mf, dev->prod, dev->serial); printf(" %s\n", pre); +#ifdef CONFIG_DM_USB + struct udevice *child; + + for (device_find_first_child(dev->dev, &child); + child; + device_find_next_child(&child)) { + struct usb_device *udev; + + if (!device_active(child)) + continue; + + udev = dev_get_parentdata(child); + + /* Ignore emulators, we only want real devices */ + if (device_get_uclass_id(child) != UCLASS_USB_EMUL) { + usb_show_tree_graph(udev, pre); + pre[index] = 0; + } + } +#else if (dev->maxchild > 0) { for (i = 0; i < dev->maxchild; i++) { if (dev->children[i] != NULL) { @@ -348,6 +423,7 @@ static void usb_show_tree_graph(struct usb_device *dev, char *pre) } } } +#endif } /* main routine for the tree command */ @@ -355,7 +431,7 @@ static void usb_show_tree(struct usb_device *dev) { char preamble[32]; - memset(preamble, 0, 32); + memset(preamble, '\0', sizeof(preamble)); usb_show_tree_graph(dev, &preamble[0]); } @@ -448,27 +524,72 @@ static void do_usb_start(void) if (usb_init() < 0) return; + /* Driver model will probe the devices as they are found */ +#ifndef CONFIG_DM_USB #ifdef CONFIG_USB_STORAGE /* try to recognize storage devices immediately */ usb_stor_curr_dev = usb_stor_scan(1); #endif +#endif #ifdef CONFIG_USB_HOST_ETHER +# ifdef CONFIG_DM_ETH +# ifndef CONFIG_DM_USB +# error "You must use CONFIG_DM_USB if you want to use CONFIG_USB_HOST_ETHER with CONFIG_DM_ETH" +# endif +# else /* try to recognize ethernet devices immediately */ usb_ether_curr_dev = usb_host_eth_scan(1); +# endif #endif #ifdef CONFIG_USB_KEYBOARD drv_usb_kbd_init(); #endif } +#ifdef CONFIG_DM_USB +static void show_info(struct udevice *dev) +{ + struct udevice *child; + struct usb_device *udev; + + udev = dev_get_parentdata(dev); + usb_display_desc(udev); + usb_display_config(udev); + for (device_find_first_child(dev, &child); + child; + device_find_next_child(&child)) { + if (device_active(child)) + show_info(child); + } +} + +static int usb_device_info(void) +{ + struct udevice *bus; + + for (uclass_first_device(UCLASS_USB, &bus); + bus; + uclass_next_device(&bus)) { + struct udevice *hub; + + device_find_first_child(bus, &hub); + if (device_get_uclass_id(hub) == UCLASS_USB_HUB && + device_active(hub)) { + show_info(hub); + } + } + + return 0; +} +#endif + /****************************************************************************** * usb command intepreter */ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - + struct usb_device *udev = NULL; int i; - struct usb_device *dev = NULL; extern char usb_started; #ifdef CONFIG_USB_STORAGE block_dev_desc_t *stor_dev; @@ -508,36 +629,62 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } if (strncmp(argv[1], "tree", 4) == 0) { puts("USB device tree:\n"); +#ifdef CONFIG_DM_USB + struct udevice *bus; + + for (uclass_first_device(UCLASS_USB, &bus); + bus; + uclass_next_device(&bus)) { + struct usb_device *udev; + struct udevice *dev; + + device_find_first_child(bus, &dev); + if (dev && device_active(dev)) { + udev = dev_get_parentdata(dev); + usb_show_tree(udev); + } + } +#else for (i = 0; i < USB_MAX_DEVICE; i++) { - dev = usb_get_dev_index(i); - if (dev == NULL) + udev = usb_get_dev_index(i); + if (udev == NULL) break; - if (dev->parent == NULL) - usb_show_tree(dev); + if (udev->parent == NULL) + usb_show_tree(udev); } +#endif return 0; } if (strncmp(argv[1], "inf", 3) == 0) { - int d; if (argc == 2) { +#ifdef CONFIG_DM_USB + usb_device_info(); +#else + int d; for (d = 0; d < USB_MAX_DEVICE; d++) { - dev = usb_get_dev_index(d); - if (dev == NULL) + udev = usb_get_dev_index(d); + if (udev == NULL) break; - usb_display_desc(dev); - usb_display_config(dev); + usb_display_desc(udev); + usb_display_config(udev); } +#endif return 0; } else { + /* + * With driver model this isn't right since we can + * have multiple controllers and the device numbering + * starts at 1 on each bus. + */ i = simple_strtoul(argv[2], NULL, 10); printf("config for device %d\n", i); - dev = usb_find_device(i); - if (dev == NULL) { + udev = usb_find_device(i); + if (udev == NULL) { printf("*** No device available ***\n"); return 0; } else { - usb_display_desc(dev); - usb_display_config(dev); + usb_display_desc(udev); + usb_display_config(udev); } } return 0; @@ -546,13 +693,13 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (argc < 5) return CMD_RET_USAGE; i = simple_strtoul(argv[2], NULL, 10); - dev = usb_find_device(i); - if (dev == NULL) { + udev = usb_find_device(i); + if (udev == NULL) { printf("Device %d does not exist.\n", i); return 1; } i = simple_strtoul(argv[3], NULL, 10); - return usb_test(dev, i, argv[4]); + return usb_test(udev, i, argv[4]); } #ifdef CONFIG_USB_STORAGE if (strncmp(argv[1], "stor", 4) == 0)