diff options
Diffstat (limited to 'common/cmd_usb.c')
-rw-r--r-- | common/cmd_usb.c | 121 |
1 files changed, 98 insertions, 23 deletions
diff --git a/common/cmd_usb.c b/common/cmd_usb.c index dacdc2d5b1c..adc5f02a2cb 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -269,6 +269,22 @@ static void usb_display_config(struct usb_device *dev) printf("\n"); } +static struct usb_device *usb_find_device(int devnum) +{ + struct usb_device *dev; + int d; + + for (d = 0; d < USB_MAX_DEVICE; d++) { + dev = usb_get_dev_index(d); + if (dev == NULL) + return NULL; + if (dev->devnum == devnum) + return dev; + } + + return NULL; +} + static inline char *portspeed(int speed) { if (speed == USB_SPEED_HIGH) @@ -348,6 +364,66 @@ static void usb_show_tree(struct usb_device *dev) usb_show_tree_graph(dev, &preamble[0]); } +static int usb_test(struct usb_device *dev, int port, char* arg) +{ + int mode; + + if (port > dev->maxchild) { + printf("Device is no hub or does not have %d ports.\n", port); + return 1; + } + + switch (arg[0]) { + case 'J': + case 'j': + printf("Setting Test_J mode"); + mode = USB_TEST_MODE_J; + break; + case 'K': + case 'k': + printf("Setting Test_K mode"); + mode = USB_TEST_MODE_K; + break; + case 'S': + case 's': + printf("Setting Test_SE0_NAK mode"); + mode = USB_TEST_MODE_SE0_NAK; + break; + case 'P': + case 'p': + printf("Setting Test_Packet mode"); + mode = USB_TEST_MODE_PACKET; + break; + case 'F': + case 'f': + printf("Setting Test_Force_Enable mode"); + mode = USB_TEST_MODE_FORCE_ENABLE; + break; + default: + printf("Unrecognized test mode: %s\nAvailable modes: " + "J, K, S[E0_NAK], P[acket], F[orce_Enable]\n", arg); + return 1; + } + + if (port) + printf(" on downstream facing port %d...\n", port); + else + printf(" on upstream facing port...\n"); + + if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_FEATURE, + port ? USB_RT_PORT : USB_RECIP_DEVICE, + port ? USB_PORT_FEAT_TEST : USB_FEAT_TEST, + (mode << 8) | port, + NULL, 0, USB_CNTL_TIMEOUT) == -1) { + printf("Error during SET_FEATURE.\n"); + return 1; + } else { + printf("Test mode successfully set. Use 'usb start' " + "to return to normal operation.\n"); + return 0; + } +} + /****************************************************************************** * usb boot command intepreter. Derived from diskboot @@ -441,17 +517,9 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } return 0; } else { - int d; - - i = simple_strtoul(argv[2], NULL, 16); + i = simple_strtoul(argv[2], NULL, 10); printf("config for device %d\n", i); - for (d = 0; d < USB_MAX_DEVICE; d++) { - dev = usb_get_dev_index(d); - if (dev == NULL) - break; - if (dev->devnum == i) - break; - } + dev = usb_find_device(i); if (dev == NULL) { printf("*** No device available ***\n"); return 0; @@ -462,6 +530,18 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } return 0; } + if (strncmp(argv[1], "test", 4) == 0) { + if (argc < 5) + return CMD_RET_USAGE; + i = simple_strtoul(argv[2], NULL, 10); + dev = usb_find_device(i); + if (dev == 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]); + } #ifdef CONFIG_USB_STORAGE if (strncmp(argv[1], "stor", 4) == 0) return usb_stor_info(); @@ -571,7 +651,6 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return CMD_RET_USAGE; } -#ifdef CONFIG_USB_STORAGE U_BOOT_CMD( usb, 5, 1, do_usb, "USB sub-system", @@ -580,30 +659,26 @@ U_BOOT_CMD( "usb stop [f] - stop USB [f]=force stop\n" "usb tree - show USB device tree\n" "usb info [dev] - show available USB devices\n" + "usb test [dev] [port] [mode] - set USB 2.0 test mode\n" + " (specify port 0 to indicate the device's upstream port)\n" + " Available modes: J, K, S[E0_NAK], P[acket], F[orce_Enable]\n" +#ifdef CONFIG_USB_STORAGE "usb storage - show details of USB storage devices\n" "usb dev [dev] - show or set current USB storage device\n" "usb part [dev] - print partition table of one or all USB storage" - " devices\n" + " devices\n" "usb read addr blk# cnt - read `cnt' blocks starting at block `blk#'\n" " to memory address `addr'\n" "usb write addr blk# cnt - write `cnt' blocks starting at block `blk#'\n" " from memory address `addr'" +#endif /* CONFIG_USB_STORAGE */ ); +#ifdef CONFIG_USB_STORAGE U_BOOT_CMD( usbboot, 3, 1, do_usbboot, "boot from USB device", "loadAddr dev:part" ); - -#else -U_BOOT_CMD( - usb, 5, 1, do_usb, - "USB sub-system", - "start - start (scan) USB controller\n" - "usb reset - reset (rescan) USB controller\n" - "usb tree - show USB device tree\n" - "usb info [dev] - show available USB devices" -); -#endif +#endif /* CONFIG_USB_STORAGE */ |