diff options
Diffstat (limited to 'common/cmd_usb.c')
| -rw-r--r-- | common/cmd_usb.c | 145 | 
1 files changed, 116 insertions, 29 deletions
| diff --git a/common/cmd_usb.c b/common/cmd_usb.c index dacdc2d5b..70e803b5b 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -269,14 +269,42 @@ 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) -		return "480 Mb/s"; -	else if (speed == USB_SPEED_LOW) -		return "1.5 Mb/s"; -	else -		return "12 Mb/s"; +	char *speed_str; + +	switch (speed) { +	case USB_SPEED_SUPER: +		speed_str = "5 Gb/s"; +		break; +	case USB_SPEED_HIGH: +		speed_str = "480 Mb/s"; +		break; +	case USB_SPEED_LOW: +		speed_str = "1.5 Mb/s"; +		break; +	default: +		speed_str = "12 Mb/s"; +		break; +	} + +	return speed_str;  }  /* shows the device tree recursively */ @@ -348,6 +376,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 +529,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 +542,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 +663,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 +671,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 */ |