1*2e192b24SSimon Glass /* 2*2e192b24SSimon Glass * (C) Copyright 2001 3*2e192b24SSimon Glass * Denis Peter, MPL AG Switzerland 4*2e192b24SSimon Glass * 5*2e192b24SSimon Glass * Adapted for U-Boot driver model 6*2e192b24SSimon Glass * (C) Copyright 2015 Google, Inc 7*2e192b24SSimon Glass * 8*2e192b24SSimon Glass * Most of this source has been derived from the Linux USB 9*2e192b24SSimon Glass * project. 10*2e192b24SSimon Glass * 11*2e192b24SSimon Glass * SPDX-License-Identifier: GPL-2.0+ 12*2e192b24SSimon Glass */ 13*2e192b24SSimon Glass 14*2e192b24SSimon Glass #include <common.h> 15*2e192b24SSimon Glass #include <command.h> 16*2e192b24SSimon Glass #include <console.h> 17*2e192b24SSimon Glass #include <dm.h> 18*2e192b24SSimon Glass #include <memalign.h> 19*2e192b24SSimon Glass #include <asm/byteorder.h> 20*2e192b24SSimon Glass #include <asm/unaligned.h> 21*2e192b24SSimon Glass #include <part.h> 22*2e192b24SSimon Glass #include <usb.h> 23*2e192b24SSimon Glass 24*2e192b24SSimon Glass #ifdef CONFIG_USB_STORAGE 25*2e192b24SSimon Glass static int usb_stor_curr_dev = -1; /* current device */ 26*2e192b24SSimon Glass #endif 27*2e192b24SSimon Glass #if defined(CONFIG_USB_HOST_ETHER) && !defined(CONFIG_DM_ETH) 28*2e192b24SSimon Glass static int __maybe_unused usb_ether_curr_dev = -1; /* current ethernet device */ 29*2e192b24SSimon Glass #endif 30*2e192b24SSimon Glass 31*2e192b24SSimon Glass /* some display routines (info command) */ 32*2e192b24SSimon Glass static char *usb_get_class_desc(unsigned char dclass) 33*2e192b24SSimon Glass { 34*2e192b24SSimon Glass switch (dclass) { 35*2e192b24SSimon Glass case USB_CLASS_PER_INTERFACE: 36*2e192b24SSimon Glass return "See Interface"; 37*2e192b24SSimon Glass case USB_CLASS_AUDIO: 38*2e192b24SSimon Glass return "Audio"; 39*2e192b24SSimon Glass case USB_CLASS_COMM: 40*2e192b24SSimon Glass return "Communication"; 41*2e192b24SSimon Glass case USB_CLASS_HID: 42*2e192b24SSimon Glass return "Human Interface"; 43*2e192b24SSimon Glass case USB_CLASS_PRINTER: 44*2e192b24SSimon Glass return "Printer"; 45*2e192b24SSimon Glass case USB_CLASS_MASS_STORAGE: 46*2e192b24SSimon Glass return "Mass Storage"; 47*2e192b24SSimon Glass case USB_CLASS_HUB: 48*2e192b24SSimon Glass return "Hub"; 49*2e192b24SSimon Glass case USB_CLASS_DATA: 50*2e192b24SSimon Glass return "CDC Data"; 51*2e192b24SSimon Glass case USB_CLASS_VENDOR_SPEC: 52*2e192b24SSimon Glass return "Vendor specific"; 53*2e192b24SSimon Glass default: 54*2e192b24SSimon Glass return ""; 55*2e192b24SSimon Glass } 56*2e192b24SSimon Glass } 57*2e192b24SSimon Glass 58*2e192b24SSimon Glass static void usb_display_class_sub(unsigned char dclass, unsigned char subclass, 59*2e192b24SSimon Glass unsigned char proto) 60*2e192b24SSimon Glass { 61*2e192b24SSimon Glass switch (dclass) { 62*2e192b24SSimon Glass case USB_CLASS_PER_INTERFACE: 63*2e192b24SSimon Glass printf("See Interface"); 64*2e192b24SSimon Glass break; 65*2e192b24SSimon Glass case USB_CLASS_HID: 66*2e192b24SSimon Glass printf("Human Interface, Subclass: "); 67*2e192b24SSimon Glass switch (subclass) { 68*2e192b24SSimon Glass case USB_SUB_HID_NONE: 69*2e192b24SSimon Glass printf("None"); 70*2e192b24SSimon Glass break; 71*2e192b24SSimon Glass case USB_SUB_HID_BOOT: 72*2e192b24SSimon Glass printf("Boot "); 73*2e192b24SSimon Glass switch (proto) { 74*2e192b24SSimon Glass case USB_PROT_HID_NONE: 75*2e192b24SSimon Glass printf("None"); 76*2e192b24SSimon Glass break; 77*2e192b24SSimon Glass case USB_PROT_HID_KEYBOARD: 78*2e192b24SSimon Glass printf("Keyboard"); 79*2e192b24SSimon Glass break; 80*2e192b24SSimon Glass case USB_PROT_HID_MOUSE: 81*2e192b24SSimon Glass printf("Mouse"); 82*2e192b24SSimon Glass break; 83*2e192b24SSimon Glass default: 84*2e192b24SSimon Glass printf("reserved"); 85*2e192b24SSimon Glass break; 86*2e192b24SSimon Glass } 87*2e192b24SSimon Glass break; 88*2e192b24SSimon Glass default: 89*2e192b24SSimon Glass printf("reserved"); 90*2e192b24SSimon Glass break; 91*2e192b24SSimon Glass } 92*2e192b24SSimon Glass break; 93*2e192b24SSimon Glass case USB_CLASS_MASS_STORAGE: 94*2e192b24SSimon Glass printf("Mass Storage, "); 95*2e192b24SSimon Glass switch (subclass) { 96*2e192b24SSimon Glass case US_SC_RBC: 97*2e192b24SSimon Glass printf("RBC "); 98*2e192b24SSimon Glass break; 99*2e192b24SSimon Glass case US_SC_8020: 100*2e192b24SSimon Glass printf("SFF-8020i (ATAPI)"); 101*2e192b24SSimon Glass break; 102*2e192b24SSimon Glass case US_SC_QIC: 103*2e192b24SSimon Glass printf("QIC-157 (Tape)"); 104*2e192b24SSimon Glass break; 105*2e192b24SSimon Glass case US_SC_UFI: 106*2e192b24SSimon Glass printf("UFI"); 107*2e192b24SSimon Glass break; 108*2e192b24SSimon Glass case US_SC_8070: 109*2e192b24SSimon Glass printf("SFF-8070"); 110*2e192b24SSimon Glass break; 111*2e192b24SSimon Glass case US_SC_SCSI: 112*2e192b24SSimon Glass printf("Transp. SCSI"); 113*2e192b24SSimon Glass break; 114*2e192b24SSimon Glass default: 115*2e192b24SSimon Glass printf("reserved"); 116*2e192b24SSimon Glass break; 117*2e192b24SSimon Glass } 118*2e192b24SSimon Glass printf(", "); 119*2e192b24SSimon Glass switch (proto) { 120*2e192b24SSimon Glass case US_PR_CB: 121*2e192b24SSimon Glass printf("Command/Bulk"); 122*2e192b24SSimon Glass break; 123*2e192b24SSimon Glass case US_PR_CBI: 124*2e192b24SSimon Glass printf("Command/Bulk/Int"); 125*2e192b24SSimon Glass break; 126*2e192b24SSimon Glass case US_PR_BULK: 127*2e192b24SSimon Glass printf("Bulk only"); 128*2e192b24SSimon Glass break; 129*2e192b24SSimon Glass default: 130*2e192b24SSimon Glass printf("reserved"); 131*2e192b24SSimon Glass break; 132*2e192b24SSimon Glass } 133*2e192b24SSimon Glass break; 134*2e192b24SSimon Glass default: 135*2e192b24SSimon Glass printf("%s", usb_get_class_desc(dclass)); 136*2e192b24SSimon Glass break; 137*2e192b24SSimon Glass } 138*2e192b24SSimon Glass } 139*2e192b24SSimon Glass 140*2e192b24SSimon Glass static void usb_display_string(struct usb_device *dev, int index) 141*2e192b24SSimon Glass { 142*2e192b24SSimon Glass ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256); 143*2e192b24SSimon Glass 144*2e192b24SSimon Glass if (index != 0) { 145*2e192b24SSimon Glass if (usb_string(dev, index, &buffer[0], 256) > 0) 146*2e192b24SSimon Glass printf("String: \"%s\"", buffer); 147*2e192b24SSimon Glass } 148*2e192b24SSimon Glass } 149*2e192b24SSimon Glass 150*2e192b24SSimon Glass static void usb_display_desc(struct usb_device *dev) 151*2e192b24SSimon Glass { 152*2e192b24SSimon Glass if (dev->descriptor.bDescriptorType == USB_DT_DEVICE) { 153*2e192b24SSimon Glass printf("%d: %s, USB Revision %x.%x\n", dev->devnum, 154*2e192b24SSimon Glass usb_get_class_desc(dev->config.if_desc[0].desc.bInterfaceClass), 155*2e192b24SSimon Glass (dev->descriptor.bcdUSB>>8) & 0xff, 156*2e192b24SSimon Glass dev->descriptor.bcdUSB & 0xff); 157*2e192b24SSimon Glass 158*2e192b24SSimon Glass if (strlen(dev->mf) || strlen(dev->prod) || 159*2e192b24SSimon Glass strlen(dev->serial)) 160*2e192b24SSimon Glass printf(" - %s %s %s\n", dev->mf, dev->prod, 161*2e192b24SSimon Glass dev->serial); 162*2e192b24SSimon Glass if (dev->descriptor.bDeviceClass) { 163*2e192b24SSimon Glass printf(" - Class: "); 164*2e192b24SSimon Glass usb_display_class_sub(dev->descriptor.bDeviceClass, 165*2e192b24SSimon Glass dev->descriptor.bDeviceSubClass, 166*2e192b24SSimon Glass dev->descriptor.bDeviceProtocol); 167*2e192b24SSimon Glass printf("\n"); 168*2e192b24SSimon Glass } else { 169*2e192b24SSimon Glass printf(" - Class: (from Interface) %s\n", 170*2e192b24SSimon Glass usb_get_class_desc( 171*2e192b24SSimon Glass dev->config.if_desc[0].desc.bInterfaceClass)); 172*2e192b24SSimon Glass } 173*2e192b24SSimon Glass printf(" - PacketSize: %d Configurations: %d\n", 174*2e192b24SSimon Glass dev->descriptor.bMaxPacketSize0, 175*2e192b24SSimon Glass dev->descriptor.bNumConfigurations); 176*2e192b24SSimon Glass printf(" - Vendor: 0x%04x Product 0x%04x Version %d.%d\n", 177*2e192b24SSimon Glass dev->descriptor.idVendor, dev->descriptor.idProduct, 178*2e192b24SSimon Glass (dev->descriptor.bcdDevice>>8) & 0xff, 179*2e192b24SSimon Glass dev->descriptor.bcdDevice & 0xff); 180*2e192b24SSimon Glass } 181*2e192b24SSimon Glass 182*2e192b24SSimon Glass } 183*2e192b24SSimon Glass 184*2e192b24SSimon Glass static void usb_display_conf_desc(struct usb_config_descriptor *config, 185*2e192b24SSimon Glass struct usb_device *dev) 186*2e192b24SSimon Glass { 187*2e192b24SSimon Glass printf(" Configuration: %d\n", config->bConfigurationValue); 188*2e192b24SSimon Glass printf(" - Interfaces: %d %s%s%dmA\n", config->bNumInterfaces, 189*2e192b24SSimon Glass (config->bmAttributes & 0x40) ? "Self Powered " : "Bus Powered ", 190*2e192b24SSimon Glass (config->bmAttributes & 0x20) ? "Remote Wakeup " : "", 191*2e192b24SSimon Glass config->bMaxPower*2); 192*2e192b24SSimon Glass if (config->iConfiguration) { 193*2e192b24SSimon Glass printf(" - "); 194*2e192b24SSimon Glass usb_display_string(dev, config->iConfiguration); 195*2e192b24SSimon Glass printf("\n"); 196*2e192b24SSimon Glass } 197*2e192b24SSimon Glass } 198*2e192b24SSimon Glass 199*2e192b24SSimon Glass static void usb_display_if_desc(struct usb_interface_descriptor *ifdesc, 200*2e192b24SSimon Glass struct usb_device *dev) 201*2e192b24SSimon Glass { 202*2e192b24SSimon Glass printf(" Interface: %d\n", ifdesc->bInterfaceNumber); 203*2e192b24SSimon Glass printf(" - Alternate Setting %d, Endpoints: %d\n", 204*2e192b24SSimon Glass ifdesc->bAlternateSetting, ifdesc->bNumEndpoints); 205*2e192b24SSimon Glass printf(" - Class "); 206*2e192b24SSimon Glass usb_display_class_sub(ifdesc->bInterfaceClass, 207*2e192b24SSimon Glass ifdesc->bInterfaceSubClass, ifdesc->bInterfaceProtocol); 208*2e192b24SSimon Glass printf("\n"); 209*2e192b24SSimon Glass if (ifdesc->iInterface) { 210*2e192b24SSimon Glass printf(" - "); 211*2e192b24SSimon Glass usb_display_string(dev, ifdesc->iInterface); 212*2e192b24SSimon Glass printf("\n"); 213*2e192b24SSimon Glass } 214*2e192b24SSimon Glass } 215*2e192b24SSimon Glass 216*2e192b24SSimon Glass static void usb_display_ep_desc(struct usb_endpoint_descriptor *epdesc) 217*2e192b24SSimon Glass { 218*2e192b24SSimon Glass printf(" - Endpoint %d %s ", epdesc->bEndpointAddress & 0xf, 219*2e192b24SSimon Glass (epdesc->bEndpointAddress & 0x80) ? "In" : "Out"); 220*2e192b24SSimon Glass switch ((epdesc->bmAttributes & 0x03)) { 221*2e192b24SSimon Glass case 0: 222*2e192b24SSimon Glass printf("Control"); 223*2e192b24SSimon Glass break; 224*2e192b24SSimon Glass case 1: 225*2e192b24SSimon Glass printf("Isochronous"); 226*2e192b24SSimon Glass break; 227*2e192b24SSimon Glass case 2: 228*2e192b24SSimon Glass printf("Bulk"); 229*2e192b24SSimon Glass break; 230*2e192b24SSimon Glass case 3: 231*2e192b24SSimon Glass printf("Interrupt"); 232*2e192b24SSimon Glass break; 233*2e192b24SSimon Glass } 234*2e192b24SSimon Glass printf(" MaxPacket %d", get_unaligned(&epdesc->wMaxPacketSize)); 235*2e192b24SSimon Glass if ((epdesc->bmAttributes & 0x03) == 0x3) 236*2e192b24SSimon Glass printf(" Interval %dms", epdesc->bInterval); 237*2e192b24SSimon Glass printf("\n"); 238*2e192b24SSimon Glass } 239*2e192b24SSimon Glass 240*2e192b24SSimon Glass /* main routine to diasplay the configs, interfaces and endpoints */ 241*2e192b24SSimon Glass static void usb_display_config(struct usb_device *dev) 242*2e192b24SSimon Glass { 243*2e192b24SSimon Glass struct usb_config *config; 244*2e192b24SSimon Glass struct usb_interface *ifdesc; 245*2e192b24SSimon Glass struct usb_endpoint_descriptor *epdesc; 246*2e192b24SSimon Glass int i, ii; 247*2e192b24SSimon Glass 248*2e192b24SSimon Glass config = &dev->config; 249*2e192b24SSimon Glass usb_display_conf_desc(&config->desc, dev); 250*2e192b24SSimon Glass for (i = 0; i < config->no_of_if; i++) { 251*2e192b24SSimon Glass ifdesc = &config->if_desc[i]; 252*2e192b24SSimon Glass usb_display_if_desc(&ifdesc->desc, dev); 253*2e192b24SSimon Glass for (ii = 0; ii < ifdesc->no_of_ep; ii++) { 254*2e192b24SSimon Glass epdesc = &ifdesc->ep_desc[ii]; 255*2e192b24SSimon Glass usb_display_ep_desc(epdesc); 256*2e192b24SSimon Glass } 257*2e192b24SSimon Glass } 258*2e192b24SSimon Glass printf("\n"); 259*2e192b24SSimon Glass } 260*2e192b24SSimon Glass 261*2e192b24SSimon Glass /* 262*2e192b24SSimon Glass * With driver model this isn't right since we can have multiple controllers 263*2e192b24SSimon Glass * and the device numbering starts at 1 on each bus. 264*2e192b24SSimon Glass * TODO(sjg@chromium.org): Add a way to specify the controller/bus. 265*2e192b24SSimon Glass */ 266*2e192b24SSimon Glass static struct usb_device *usb_find_device(int devnum) 267*2e192b24SSimon Glass { 268*2e192b24SSimon Glass #ifdef CONFIG_DM_USB 269*2e192b24SSimon Glass struct usb_device *udev; 270*2e192b24SSimon Glass struct udevice *hub; 271*2e192b24SSimon Glass struct uclass *uc; 272*2e192b24SSimon Glass int ret; 273*2e192b24SSimon Glass 274*2e192b24SSimon Glass /* Device addresses start at 1 */ 275*2e192b24SSimon Glass devnum++; 276*2e192b24SSimon Glass ret = uclass_get(UCLASS_USB_HUB, &uc); 277*2e192b24SSimon Glass if (ret) 278*2e192b24SSimon Glass return NULL; 279*2e192b24SSimon Glass 280*2e192b24SSimon Glass uclass_foreach_dev(hub, uc) { 281*2e192b24SSimon Glass struct udevice *dev; 282*2e192b24SSimon Glass 283*2e192b24SSimon Glass if (!device_active(hub)) 284*2e192b24SSimon Glass continue; 285*2e192b24SSimon Glass udev = dev_get_parent_priv(hub); 286*2e192b24SSimon Glass if (udev->devnum == devnum) 287*2e192b24SSimon Glass return udev; 288*2e192b24SSimon Glass 289*2e192b24SSimon Glass for (device_find_first_child(hub, &dev); 290*2e192b24SSimon Glass dev; 291*2e192b24SSimon Glass device_find_next_child(&dev)) { 292*2e192b24SSimon Glass if (!device_active(hub)) 293*2e192b24SSimon Glass continue; 294*2e192b24SSimon Glass 295*2e192b24SSimon Glass udev = dev_get_parent_priv(dev); 296*2e192b24SSimon Glass if (udev->devnum == devnum) 297*2e192b24SSimon Glass return udev; 298*2e192b24SSimon Glass } 299*2e192b24SSimon Glass } 300*2e192b24SSimon Glass #else 301*2e192b24SSimon Glass struct usb_device *udev; 302*2e192b24SSimon Glass int d; 303*2e192b24SSimon Glass 304*2e192b24SSimon Glass for (d = 0; d < USB_MAX_DEVICE; d++) { 305*2e192b24SSimon Glass udev = usb_get_dev_index(d); 306*2e192b24SSimon Glass if (udev == NULL) 307*2e192b24SSimon Glass return NULL; 308*2e192b24SSimon Glass if (udev->devnum == devnum) 309*2e192b24SSimon Glass return udev; 310*2e192b24SSimon Glass } 311*2e192b24SSimon Glass #endif 312*2e192b24SSimon Glass 313*2e192b24SSimon Glass return NULL; 314*2e192b24SSimon Glass } 315*2e192b24SSimon Glass 316*2e192b24SSimon Glass static inline char *portspeed(int speed) 317*2e192b24SSimon Glass { 318*2e192b24SSimon Glass char *speed_str; 319*2e192b24SSimon Glass 320*2e192b24SSimon Glass switch (speed) { 321*2e192b24SSimon Glass case USB_SPEED_SUPER: 322*2e192b24SSimon Glass speed_str = "5 Gb/s"; 323*2e192b24SSimon Glass break; 324*2e192b24SSimon Glass case USB_SPEED_HIGH: 325*2e192b24SSimon Glass speed_str = "480 Mb/s"; 326*2e192b24SSimon Glass break; 327*2e192b24SSimon Glass case USB_SPEED_LOW: 328*2e192b24SSimon Glass speed_str = "1.5 Mb/s"; 329*2e192b24SSimon Glass break; 330*2e192b24SSimon Glass default: 331*2e192b24SSimon Glass speed_str = "12 Mb/s"; 332*2e192b24SSimon Glass break; 333*2e192b24SSimon Glass } 334*2e192b24SSimon Glass 335*2e192b24SSimon Glass return speed_str; 336*2e192b24SSimon Glass } 337*2e192b24SSimon Glass 338*2e192b24SSimon Glass /* shows the device tree recursively */ 339*2e192b24SSimon Glass static void usb_show_tree_graph(struct usb_device *dev, char *pre) 340*2e192b24SSimon Glass { 341*2e192b24SSimon Glass int index; 342*2e192b24SSimon Glass int has_child, last_child; 343*2e192b24SSimon Glass 344*2e192b24SSimon Glass index = strlen(pre); 345*2e192b24SSimon Glass printf(" %s", pre); 346*2e192b24SSimon Glass #ifdef CONFIG_DM_USB 347*2e192b24SSimon Glass has_child = device_has_active_children(dev->dev); 348*2e192b24SSimon Glass #else 349*2e192b24SSimon Glass /* check if the device has connected children */ 350*2e192b24SSimon Glass int i; 351*2e192b24SSimon Glass 352*2e192b24SSimon Glass has_child = 0; 353*2e192b24SSimon Glass for (i = 0; i < dev->maxchild; i++) { 354*2e192b24SSimon Glass if (dev->children[i] != NULL) 355*2e192b24SSimon Glass has_child = 1; 356*2e192b24SSimon Glass } 357*2e192b24SSimon Glass #endif 358*2e192b24SSimon Glass /* check if we are the last one */ 359*2e192b24SSimon Glass #ifdef CONFIG_DM_USB 360*2e192b24SSimon Glass /* Not the root of the usb tree? */ 361*2e192b24SSimon Glass if (device_get_uclass_id(dev->dev->parent) != UCLASS_USB) { 362*2e192b24SSimon Glass last_child = device_is_last_sibling(dev->dev); 363*2e192b24SSimon Glass #else 364*2e192b24SSimon Glass if (dev->parent != NULL) { /* not root? */ 365*2e192b24SSimon Glass last_child = 1; 366*2e192b24SSimon Glass for (i = 0; i < dev->parent->maxchild; i++) { 367*2e192b24SSimon Glass /* search for children */ 368*2e192b24SSimon Glass if (dev->parent->children[i] == dev) { 369*2e192b24SSimon Glass /* found our pointer, see if we have a 370*2e192b24SSimon Glass * little sister 371*2e192b24SSimon Glass */ 372*2e192b24SSimon Glass while (i++ < dev->parent->maxchild) { 373*2e192b24SSimon Glass if (dev->parent->children[i] != NULL) { 374*2e192b24SSimon Glass /* found a sister */ 375*2e192b24SSimon Glass last_child = 0; 376*2e192b24SSimon Glass break; 377*2e192b24SSimon Glass } /* if */ 378*2e192b24SSimon Glass } /* while */ 379*2e192b24SSimon Glass } /* device found */ 380*2e192b24SSimon Glass } /* for all children of the parent */ 381*2e192b24SSimon Glass #endif 382*2e192b24SSimon Glass printf("\b+-"); 383*2e192b24SSimon Glass /* correct last child */ 384*2e192b24SSimon Glass if (last_child && index) 385*2e192b24SSimon Glass pre[index-1] = ' '; 386*2e192b24SSimon Glass } /* if not root hub */ 387*2e192b24SSimon Glass else 388*2e192b24SSimon Glass printf(" "); 389*2e192b24SSimon Glass printf("%d ", dev->devnum); 390*2e192b24SSimon Glass pre[index++] = ' '; 391*2e192b24SSimon Glass pre[index++] = has_child ? '|' : ' '; 392*2e192b24SSimon Glass pre[index] = 0; 393*2e192b24SSimon Glass printf(" %s (%s, %dmA)\n", usb_get_class_desc( 394*2e192b24SSimon Glass dev->config.if_desc[0].desc.bInterfaceClass), 395*2e192b24SSimon Glass portspeed(dev->speed), 396*2e192b24SSimon Glass dev->config.desc.bMaxPower * 2); 397*2e192b24SSimon Glass if (strlen(dev->mf) || strlen(dev->prod) || strlen(dev->serial)) 398*2e192b24SSimon Glass printf(" %s %s %s %s\n", pre, dev->mf, dev->prod, dev->serial); 399*2e192b24SSimon Glass printf(" %s\n", pre); 400*2e192b24SSimon Glass #ifdef CONFIG_DM_USB 401*2e192b24SSimon Glass struct udevice *child; 402*2e192b24SSimon Glass 403*2e192b24SSimon Glass for (device_find_first_child(dev->dev, &child); 404*2e192b24SSimon Glass child; 405*2e192b24SSimon Glass device_find_next_child(&child)) { 406*2e192b24SSimon Glass struct usb_device *udev; 407*2e192b24SSimon Glass 408*2e192b24SSimon Glass if (!device_active(child)) 409*2e192b24SSimon Glass continue; 410*2e192b24SSimon Glass 411*2e192b24SSimon Glass udev = dev_get_parent_priv(child); 412*2e192b24SSimon Glass 413*2e192b24SSimon Glass /* Ignore emulators, we only want real devices */ 414*2e192b24SSimon Glass if (device_get_uclass_id(child) != UCLASS_USB_EMUL) { 415*2e192b24SSimon Glass usb_show_tree_graph(udev, pre); 416*2e192b24SSimon Glass pre[index] = 0; 417*2e192b24SSimon Glass } 418*2e192b24SSimon Glass } 419*2e192b24SSimon Glass #else 420*2e192b24SSimon Glass if (dev->maxchild > 0) { 421*2e192b24SSimon Glass for (i = 0; i < dev->maxchild; i++) { 422*2e192b24SSimon Glass if (dev->children[i] != NULL) { 423*2e192b24SSimon Glass usb_show_tree_graph(dev->children[i], pre); 424*2e192b24SSimon Glass pre[index] = 0; 425*2e192b24SSimon Glass } 426*2e192b24SSimon Glass } 427*2e192b24SSimon Glass } 428*2e192b24SSimon Glass #endif 429*2e192b24SSimon Glass } 430*2e192b24SSimon Glass 431*2e192b24SSimon Glass /* main routine for the tree command */ 432*2e192b24SSimon Glass static void usb_show_subtree(struct usb_device *dev) 433*2e192b24SSimon Glass { 434*2e192b24SSimon Glass char preamble[32]; 435*2e192b24SSimon Glass 436*2e192b24SSimon Glass memset(preamble, '\0', sizeof(preamble)); 437*2e192b24SSimon Glass usb_show_tree_graph(dev, &preamble[0]); 438*2e192b24SSimon Glass } 439*2e192b24SSimon Glass 440*2e192b24SSimon Glass void usb_show_tree(void) 441*2e192b24SSimon Glass { 442*2e192b24SSimon Glass #ifdef CONFIG_DM_USB 443*2e192b24SSimon Glass struct udevice *bus; 444*2e192b24SSimon Glass 445*2e192b24SSimon Glass for (uclass_first_device(UCLASS_USB, &bus); 446*2e192b24SSimon Glass bus; 447*2e192b24SSimon Glass uclass_next_device(&bus)) { 448*2e192b24SSimon Glass struct usb_device *udev; 449*2e192b24SSimon Glass struct udevice *dev; 450*2e192b24SSimon Glass 451*2e192b24SSimon Glass device_find_first_child(bus, &dev); 452*2e192b24SSimon Glass if (dev && device_active(dev)) { 453*2e192b24SSimon Glass udev = dev_get_parent_priv(dev); 454*2e192b24SSimon Glass usb_show_subtree(udev); 455*2e192b24SSimon Glass } 456*2e192b24SSimon Glass } 457*2e192b24SSimon Glass #else 458*2e192b24SSimon Glass struct usb_device *udev; 459*2e192b24SSimon Glass int i; 460*2e192b24SSimon Glass 461*2e192b24SSimon Glass for (i = 0; i < USB_MAX_DEVICE; i++) { 462*2e192b24SSimon Glass udev = usb_get_dev_index(i); 463*2e192b24SSimon Glass if (udev == NULL) 464*2e192b24SSimon Glass break; 465*2e192b24SSimon Glass if (udev->parent == NULL) 466*2e192b24SSimon Glass usb_show_subtree(udev); 467*2e192b24SSimon Glass } 468*2e192b24SSimon Glass #endif 469*2e192b24SSimon Glass } 470*2e192b24SSimon Glass 471*2e192b24SSimon Glass static int usb_test(struct usb_device *dev, int port, char* arg) 472*2e192b24SSimon Glass { 473*2e192b24SSimon Glass int mode; 474*2e192b24SSimon Glass 475*2e192b24SSimon Glass if (port > dev->maxchild) { 476*2e192b24SSimon Glass printf("Device is no hub or does not have %d ports.\n", port); 477*2e192b24SSimon Glass return 1; 478*2e192b24SSimon Glass } 479*2e192b24SSimon Glass 480*2e192b24SSimon Glass switch (arg[0]) { 481*2e192b24SSimon Glass case 'J': 482*2e192b24SSimon Glass case 'j': 483*2e192b24SSimon Glass printf("Setting Test_J mode"); 484*2e192b24SSimon Glass mode = USB_TEST_MODE_J; 485*2e192b24SSimon Glass break; 486*2e192b24SSimon Glass case 'K': 487*2e192b24SSimon Glass case 'k': 488*2e192b24SSimon Glass printf("Setting Test_K mode"); 489*2e192b24SSimon Glass mode = USB_TEST_MODE_K; 490*2e192b24SSimon Glass break; 491*2e192b24SSimon Glass case 'S': 492*2e192b24SSimon Glass case 's': 493*2e192b24SSimon Glass printf("Setting Test_SE0_NAK mode"); 494*2e192b24SSimon Glass mode = USB_TEST_MODE_SE0_NAK; 495*2e192b24SSimon Glass break; 496*2e192b24SSimon Glass case 'P': 497*2e192b24SSimon Glass case 'p': 498*2e192b24SSimon Glass printf("Setting Test_Packet mode"); 499*2e192b24SSimon Glass mode = USB_TEST_MODE_PACKET; 500*2e192b24SSimon Glass break; 501*2e192b24SSimon Glass case 'F': 502*2e192b24SSimon Glass case 'f': 503*2e192b24SSimon Glass printf("Setting Test_Force_Enable mode"); 504*2e192b24SSimon Glass mode = USB_TEST_MODE_FORCE_ENABLE; 505*2e192b24SSimon Glass break; 506*2e192b24SSimon Glass default: 507*2e192b24SSimon Glass printf("Unrecognized test mode: %s\nAvailable modes: " 508*2e192b24SSimon Glass "J, K, S[E0_NAK], P[acket], F[orce_Enable]\n", arg); 509*2e192b24SSimon Glass return 1; 510*2e192b24SSimon Glass } 511*2e192b24SSimon Glass 512*2e192b24SSimon Glass if (port) 513*2e192b24SSimon Glass printf(" on downstream facing port %d...\n", port); 514*2e192b24SSimon Glass else 515*2e192b24SSimon Glass printf(" on upstream facing port...\n"); 516*2e192b24SSimon Glass 517*2e192b24SSimon Glass if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_FEATURE, 518*2e192b24SSimon Glass port ? USB_RT_PORT : USB_RECIP_DEVICE, 519*2e192b24SSimon Glass port ? USB_PORT_FEAT_TEST : USB_FEAT_TEST, 520*2e192b24SSimon Glass (mode << 8) | port, 521*2e192b24SSimon Glass NULL, 0, USB_CNTL_TIMEOUT) == -1) { 522*2e192b24SSimon Glass printf("Error during SET_FEATURE.\n"); 523*2e192b24SSimon Glass return 1; 524*2e192b24SSimon Glass } else { 525*2e192b24SSimon Glass printf("Test mode successfully set. Use 'usb start' " 526*2e192b24SSimon Glass "to return to normal operation.\n"); 527*2e192b24SSimon Glass return 0; 528*2e192b24SSimon Glass } 529*2e192b24SSimon Glass } 530*2e192b24SSimon Glass 531*2e192b24SSimon Glass 532*2e192b24SSimon Glass /****************************************************************************** 533*2e192b24SSimon Glass * usb boot command intepreter. Derived from diskboot 534*2e192b24SSimon Glass */ 535*2e192b24SSimon Glass #ifdef CONFIG_USB_STORAGE 536*2e192b24SSimon Glass static int do_usbboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 537*2e192b24SSimon Glass { 538*2e192b24SSimon Glass return common_diskboot(cmdtp, "usb", argc, argv); 539*2e192b24SSimon Glass } 540*2e192b24SSimon Glass #endif /* CONFIG_USB_STORAGE */ 541*2e192b24SSimon Glass 542*2e192b24SSimon Glass static int do_usb_stop_keyboard(int force) 543*2e192b24SSimon Glass { 544*2e192b24SSimon Glass #ifdef CONFIG_USB_KEYBOARD 545*2e192b24SSimon Glass if (usb_kbd_deregister(force) != 0) { 546*2e192b24SSimon Glass printf("USB not stopped: usbkbd still using USB\n"); 547*2e192b24SSimon Glass return 1; 548*2e192b24SSimon Glass } 549*2e192b24SSimon Glass #endif 550*2e192b24SSimon Glass return 0; 551*2e192b24SSimon Glass } 552*2e192b24SSimon Glass 553*2e192b24SSimon Glass static void do_usb_start(void) 554*2e192b24SSimon Glass { 555*2e192b24SSimon Glass bootstage_mark_name(BOOTSTAGE_ID_USB_START, "usb_start"); 556*2e192b24SSimon Glass 557*2e192b24SSimon Glass if (usb_init() < 0) 558*2e192b24SSimon Glass return; 559*2e192b24SSimon Glass 560*2e192b24SSimon Glass /* Driver model will probe the devices as they are found */ 561*2e192b24SSimon Glass #ifndef CONFIG_DM_USB 562*2e192b24SSimon Glass # ifdef CONFIG_USB_STORAGE 563*2e192b24SSimon Glass /* try to recognize storage devices immediately */ 564*2e192b24SSimon Glass usb_stor_curr_dev = usb_stor_scan(1); 565*2e192b24SSimon Glass # endif 566*2e192b24SSimon Glass # ifdef CONFIG_USB_KEYBOARD 567*2e192b24SSimon Glass drv_usb_kbd_init(); 568*2e192b24SSimon Glass # endif 569*2e192b24SSimon Glass #endif /* !CONFIG_DM_USB */ 570*2e192b24SSimon Glass #ifdef CONFIG_USB_HOST_ETHER 571*2e192b24SSimon Glass # ifdef CONFIG_DM_ETH 572*2e192b24SSimon Glass # ifndef CONFIG_DM_USB 573*2e192b24SSimon Glass # error "You must use CONFIG_DM_USB if you want to use CONFIG_USB_HOST_ETHER with CONFIG_DM_ETH" 574*2e192b24SSimon Glass # endif 575*2e192b24SSimon Glass # else 576*2e192b24SSimon Glass /* try to recognize ethernet devices immediately */ 577*2e192b24SSimon Glass usb_ether_curr_dev = usb_host_eth_scan(1); 578*2e192b24SSimon Glass # endif 579*2e192b24SSimon Glass #endif 580*2e192b24SSimon Glass } 581*2e192b24SSimon Glass 582*2e192b24SSimon Glass #ifdef CONFIG_DM_USB 583*2e192b24SSimon Glass static void show_info(struct udevice *dev) 584*2e192b24SSimon Glass { 585*2e192b24SSimon Glass struct udevice *child; 586*2e192b24SSimon Glass struct usb_device *udev; 587*2e192b24SSimon Glass 588*2e192b24SSimon Glass udev = dev_get_parent_priv(dev); 589*2e192b24SSimon Glass usb_display_desc(udev); 590*2e192b24SSimon Glass usb_display_config(udev); 591*2e192b24SSimon Glass for (device_find_first_child(dev, &child); 592*2e192b24SSimon Glass child; 593*2e192b24SSimon Glass device_find_next_child(&child)) { 594*2e192b24SSimon Glass if (device_active(child)) 595*2e192b24SSimon Glass show_info(child); 596*2e192b24SSimon Glass } 597*2e192b24SSimon Glass } 598*2e192b24SSimon Glass 599*2e192b24SSimon Glass static int usb_device_info(void) 600*2e192b24SSimon Glass { 601*2e192b24SSimon Glass struct udevice *bus; 602*2e192b24SSimon Glass 603*2e192b24SSimon Glass for (uclass_first_device(UCLASS_USB, &bus); 604*2e192b24SSimon Glass bus; 605*2e192b24SSimon Glass uclass_next_device(&bus)) { 606*2e192b24SSimon Glass struct udevice *hub; 607*2e192b24SSimon Glass 608*2e192b24SSimon Glass device_find_first_child(bus, &hub); 609*2e192b24SSimon Glass if (device_get_uclass_id(hub) == UCLASS_USB_HUB && 610*2e192b24SSimon Glass device_active(hub)) { 611*2e192b24SSimon Glass show_info(hub); 612*2e192b24SSimon Glass } 613*2e192b24SSimon Glass } 614*2e192b24SSimon Glass 615*2e192b24SSimon Glass return 0; 616*2e192b24SSimon Glass } 617*2e192b24SSimon Glass #endif 618*2e192b24SSimon Glass 619*2e192b24SSimon Glass /****************************************************************************** 620*2e192b24SSimon Glass * usb command intepreter 621*2e192b24SSimon Glass */ 622*2e192b24SSimon Glass static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 623*2e192b24SSimon Glass { 624*2e192b24SSimon Glass struct usb_device *udev = NULL; 625*2e192b24SSimon Glass int i; 626*2e192b24SSimon Glass extern char usb_started; 627*2e192b24SSimon Glass #ifdef CONFIG_USB_STORAGE 628*2e192b24SSimon Glass block_dev_desc_t *stor_dev; 629*2e192b24SSimon Glass #endif 630*2e192b24SSimon Glass 631*2e192b24SSimon Glass if (argc < 2) 632*2e192b24SSimon Glass return CMD_RET_USAGE; 633*2e192b24SSimon Glass 634*2e192b24SSimon Glass if (strncmp(argv[1], "start", 5) == 0) { 635*2e192b24SSimon Glass if (usb_started) 636*2e192b24SSimon Glass return 0; /* Already started */ 637*2e192b24SSimon Glass printf("starting USB...\n"); 638*2e192b24SSimon Glass do_usb_start(); 639*2e192b24SSimon Glass return 0; 640*2e192b24SSimon Glass } 641*2e192b24SSimon Glass 642*2e192b24SSimon Glass if (strncmp(argv[1], "reset", 5) == 0) { 643*2e192b24SSimon Glass printf("resetting USB...\n"); 644*2e192b24SSimon Glass if (do_usb_stop_keyboard(1) != 0) 645*2e192b24SSimon Glass return 1; 646*2e192b24SSimon Glass usb_stop(); 647*2e192b24SSimon Glass do_usb_start(); 648*2e192b24SSimon Glass return 0; 649*2e192b24SSimon Glass } 650*2e192b24SSimon Glass if (strncmp(argv[1], "stop", 4) == 0) { 651*2e192b24SSimon Glass if (argc != 2) 652*2e192b24SSimon Glass console_assign(stdin, "serial"); 653*2e192b24SSimon Glass if (do_usb_stop_keyboard(0) != 0) 654*2e192b24SSimon Glass return 1; 655*2e192b24SSimon Glass printf("stopping USB..\n"); 656*2e192b24SSimon Glass usb_stop(); 657*2e192b24SSimon Glass return 0; 658*2e192b24SSimon Glass } 659*2e192b24SSimon Glass if (!usb_started) { 660*2e192b24SSimon Glass printf("USB is stopped. Please issue 'usb start' first.\n"); 661*2e192b24SSimon Glass return 1; 662*2e192b24SSimon Glass } 663*2e192b24SSimon Glass if (strncmp(argv[1], "tree", 4) == 0) { 664*2e192b24SSimon Glass puts("USB device tree:\n"); 665*2e192b24SSimon Glass usb_show_tree(); 666*2e192b24SSimon Glass return 0; 667*2e192b24SSimon Glass } 668*2e192b24SSimon Glass if (strncmp(argv[1], "inf", 3) == 0) { 669*2e192b24SSimon Glass if (argc == 2) { 670*2e192b24SSimon Glass #ifdef CONFIG_DM_USB 671*2e192b24SSimon Glass usb_device_info(); 672*2e192b24SSimon Glass #else 673*2e192b24SSimon Glass int d; 674*2e192b24SSimon Glass for (d = 0; d < USB_MAX_DEVICE; d++) { 675*2e192b24SSimon Glass udev = usb_get_dev_index(d); 676*2e192b24SSimon Glass if (udev == NULL) 677*2e192b24SSimon Glass break; 678*2e192b24SSimon Glass usb_display_desc(udev); 679*2e192b24SSimon Glass usb_display_config(udev); 680*2e192b24SSimon Glass } 681*2e192b24SSimon Glass #endif 682*2e192b24SSimon Glass return 0; 683*2e192b24SSimon Glass } else { 684*2e192b24SSimon Glass /* 685*2e192b24SSimon Glass * With driver model this isn't right since we can 686*2e192b24SSimon Glass * have multiple controllers and the device numbering 687*2e192b24SSimon Glass * starts at 1 on each bus. 688*2e192b24SSimon Glass */ 689*2e192b24SSimon Glass i = simple_strtoul(argv[2], NULL, 10); 690*2e192b24SSimon Glass printf("config for device %d\n", i); 691*2e192b24SSimon Glass udev = usb_find_device(i); 692*2e192b24SSimon Glass if (udev == NULL) { 693*2e192b24SSimon Glass printf("*** No device available ***\n"); 694*2e192b24SSimon Glass return 0; 695*2e192b24SSimon Glass } else { 696*2e192b24SSimon Glass usb_display_desc(udev); 697*2e192b24SSimon Glass usb_display_config(udev); 698*2e192b24SSimon Glass } 699*2e192b24SSimon Glass } 700*2e192b24SSimon Glass return 0; 701*2e192b24SSimon Glass } 702*2e192b24SSimon Glass if (strncmp(argv[1], "test", 4) == 0) { 703*2e192b24SSimon Glass if (argc < 5) 704*2e192b24SSimon Glass return CMD_RET_USAGE; 705*2e192b24SSimon Glass i = simple_strtoul(argv[2], NULL, 10); 706*2e192b24SSimon Glass udev = usb_find_device(i); 707*2e192b24SSimon Glass if (udev == NULL) { 708*2e192b24SSimon Glass printf("Device %d does not exist.\n", i); 709*2e192b24SSimon Glass return 1; 710*2e192b24SSimon Glass } 711*2e192b24SSimon Glass i = simple_strtoul(argv[3], NULL, 10); 712*2e192b24SSimon Glass return usb_test(udev, i, argv[4]); 713*2e192b24SSimon Glass } 714*2e192b24SSimon Glass #ifdef CONFIG_USB_STORAGE 715*2e192b24SSimon Glass if (strncmp(argv[1], "stor", 4) == 0) 716*2e192b24SSimon Glass return usb_stor_info(); 717*2e192b24SSimon Glass 718*2e192b24SSimon Glass if (strncmp(argv[1], "part", 4) == 0) { 719*2e192b24SSimon Glass int devno, ok = 0; 720*2e192b24SSimon Glass if (argc == 2) { 721*2e192b24SSimon Glass for (devno = 0; ; ++devno) { 722*2e192b24SSimon Glass stor_dev = usb_stor_get_dev(devno); 723*2e192b24SSimon Glass if (stor_dev == NULL) 724*2e192b24SSimon Glass break; 725*2e192b24SSimon Glass if (stor_dev->type != DEV_TYPE_UNKNOWN) { 726*2e192b24SSimon Glass ok++; 727*2e192b24SSimon Glass if (devno) 728*2e192b24SSimon Glass printf("\n"); 729*2e192b24SSimon Glass debug("print_part of %x\n", devno); 730*2e192b24SSimon Glass print_part(stor_dev); 731*2e192b24SSimon Glass } 732*2e192b24SSimon Glass } 733*2e192b24SSimon Glass } else { 734*2e192b24SSimon Glass devno = simple_strtoul(argv[2], NULL, 16); 735*2e192b24SSimon Glass stor_dev = usb_stor_get_dev(devno); 736*2e192b24SSimon Glass if (stor_dev != NULL && 737*2e192b24SSimon Glass stor_dev->type != DEV_TYPE_UNKNOWN) { 738*2e192b24SSimon Glass ok++; 739*2e192b24SSimon Glass debug("print_part of %x\n", devno); 740*2e192b24SSimon Glass print_part(stor_dev); 741*2e192b24SSimon Glass } 742*2e192b24SSimon Glass } 743*2e192b24SSimon Glass if (!ok) { 744*2e192b24SSimon Glass printf("\nno USB devices available\n"); 745*2e192b24SSimon Glass return 1; 746*2e192b24SSimon Glass } 747*2e192b24SSimon Glass return 0; 748*2e192b24SSimon Glass } 749*2e192b24SSimon Glass if (strcmp(argv[1], "read") == 0) { 750*2e192b24SSimon Glass if (usb_stor_curr_dev < 0) { 751*2e192b24SSimon Glass printf("no current device selected\n"); 752*2e192b24SSimon Glass return 1; 753*2e192b24SSimon Glass } 754*2e192b24SSimon Glass if (argc == 5) { 755*2e192b24SSimon Glass unsigned long addr = simple_strtoul(argv[2], NULL, 16); 756*2e192b24SSimon Glass unsigned long blk = simple_strtoul(argv[3], NULL, 16); 757*2e192b24SSimon Glass unsigned long cnt = simple_strtoul(argv[4], NULL, 16); 758*2e192b24SSimon Glass unsigned long n; 759*2e192b24SSimon Glass printf("\nUSB read: device %d block # %ld, count %ld" 760*2e192b24SSimon Glass " ... ", usb_stor_curr_dev, blk, cnt); 761*2e192b24SSimon Glass stor_dev = usb_stor_get_dev(usb_stor_curr_dev); 762*2e192b24SSimon Glass n = stor_dev->block_read(stor_dev, blk, cnt, 763*2e192b24SSimon Glass (ulong *)addr); 764*2e192b24SSimon Glass printf("%ld blocks read: %s\n", n, 765*2e192b24SSimon Glass (n == cnt) ? "OK" : "ERROR"); 766*2e192b24SSimon Glass if (n == cnt) 767*2e192b24SSimon Glass return 0; 768*2e192b24SSimon Glass return 1; 769*2e192b24SSimon Glass } 770*2e192b24SSimon Glass } 771*2e192b24SSimon Glass if (strcmp(argv[1], "write") == 0) { 772*2e192b24SSimon Glass if (usb_stor_curr_dev < 0) { 773*2e192b24SSimon Glass printf("no current device selected\n"); 774*2e192b24SSimon Glass return 1; 775*2e192b24SSimon Glass } 776*2e192b24SSimon Glass if (argc == 5) { 777*2e192b24SSimon Glass unsigned long addr = simple_strtoul(argv[2], NULL, 16); 778*2e192b24SSimon Glass unsigned long blk = simple_strtoul(argv[3], NULL, 16); 779*2e192b24SSimon Glass unsigned long cnt = simple_strtoul(argv[4], NULL, 16); 780*2e192b24SSimon Glass unsigned long n; 781*2e192b24SSimon Glass printf("\nUSB write: device %d block # %ld, count %ld" 782*2e192b24SSimon Glass " ... ", usb_stor_curr_dev, blk, cnt); 783*2e192b24SSimon Glass stor_dev = usb_stor_get_dev(usb_stor_curr_dev); 784*2e192b24SSimon Glass n = stor_dev->block_write(stor_dev, blk, cnt, 785*2e192b24SSimon Glass (ulong *)addr); 786*2e192b24SSimon Glass printf("%ld blocks write: %s\n", n, 787*2e192b24SSimon Glass (n == cnt) ? "OK" : "ERROR"); 788*2e192b24SSimon Glass if (n == cnt) 789*2e192b24SSimon Glass return 0; 790*2e192b24SSimon Glass return 1; 791*2e192b24SSimon Glass } 792*2e192b24SSimon Glass } 793*2e192b24SSimon Glass if (strncmp(argv[1], "dev", 3) == 0) { 794*2e192b24SSimon Glass if (argc == 3) { 795*2e192b24SSimon Glass int dev = (int)simple_strtoul(argv[2], NULL, 10); 796*2e192b24SSimon Glass printf("\nUSB device %d: ", dev); 797*2e192b24SSimon Glass stor_dev = usb_stor_get_dev(dev); 798*2e192b24SSimon Glass if (stor_dev == NULL) { 799*2e192b24SSimon Glass printf("unknown device\n"); 800*2e192b24SSimon Glass return 1; 801*2e192b24SSimon Glass } 802*2e192b24SSimon Glass printf("\n Device %d: ", dev); 803*2e192b24SSimon Glass dev_print(stor_dev); 804*2e192b24SSimon Glass if (stor_dev->type == DEV_TYPE_UNKNOWN) 805*2e192b24SSimon Glass return 1; 806*2e192b24SSimon Glass usb_stor_curr_dev = dev; 807*2e192b24SSimon Glass printf("... is now current device\n"); 808*2e192b24SSimon Glass return 0; 809*2e192b24SSimon Glass } else { 810*2e192b24SSimon Glass printf("\nUSB device %d: ", usb_stor_curr_dev); 811*2e192b24SSimon Glass stor_dev = usb_stor_get_dev(usb_stor_curr_dev); 812*2e192b24SSimon Glass dev_print(stor_dev); 813*2e192b24SSimon Glass if (stor_dev->type == DEV_TYPE_UNKNOWN) 814*2e192b24SSimon Glass return 1; 815*2e192b24SSimon Glass return 0; 816*2e192b24SSimon Glass } 817*2e192b24SSimon Glass return 0; 818*2e192b24SSimon Glass } 819*2e192b24SSimon Glass #endif /* CONFIG_USB_STORAGE */ 820*2e192b24SSimon Glass return CMD_RET_USAGE; 821*2e192b24SSimon Glass } 822*2e192b24SSimon Glass 823*2e192b24SSimon Glass U_BOOT_CMD( 824*2e192b24SSimon Glass usb, 5, 1, do_usb, 825*2e192b24SSimon Glass "USB sub-system", 826*2e192b24SSimon Glass "start - start (scan) USB controller\n" 827*2e192b24SSimon Glass "usb reset - reset (rescan) USB controller\n" 828*2e192b24SSimon Glass "usb stop [f] - stop USB [f]=force stop\n" 829*2e192b24SSimon Glass "usb tree - show USB device tree\n" 830*2e192b24SSimon Glass "usb info [dev] - show available USB devices\n" 831*2e192b24SSimon Glass "usb test [dev] [port] [mode] - set USB 2.0 test mode\n" 832*2e192b24SSimon Glass " (specify port 0 to indicate the device's upstream port)\n" 833*2e192b24SSimon Glass " Available modes: J, K, S[E0_NAK], P[acket], F[orce_Enable]\n" 834*2e192b24SSimon Glass #ifdef CONFIG_USB_STORAGE 835*2e192b24SSimon Glass "usb storage - show details of USB storage devices\n" 836*2e192b24SSimon Glass "usb dev [dev] - show or set current USB storage device\n" 837*2e192b24SSimon Glass "usb part [dev] - print partition table of one or all USB storage" 838*2e192b24SSimon Glass " devices\n" 839*2e192b24SSimon Glass "usb read addr blk# cnt - read `cnt' blocks starting at block `blk#'\n" 840*2e192b24SSimon Glass " to memory address `addr'\n" 841*2e192b24SSimon Glass "usb write addr blk# cnt - write `cnt' blocks starting at block `blk#'\n" 842*2e192b24SSimon Glass " from memory address `addr'" 843*2e192b24SSimon Glass #endif /* CONFIG_USB_STORAGE */ 844*2e192b24SSimon Glass ); 845*2e192b24SSimon Glass 846*2e192b24SSimon Glass 847*2e192b24SSimon Glass #ifdef CONFIG_USB_STORAGE 848*2e192b24SSimon Glass U_BOOT_CMD( 849*2e192b24SSimon Glass usbboot, 3, 1, do_usbboot, 850*2e192b24SSimon Glass "boot from USB device", 851*2e192b24SSimon Glass "loadAddr dev:part" 852*2e192b24SSimon Glass ); 853*2e192b24SSimon Glass #endif /* CONFIG_USB_STORAGE */ 854