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