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