PERFORCE change 152996 for review

Hans Petter Selasky hselasky at FreeBSD.org
Sat Nov 15 02:10:20 PST 2008


http://perforce.freebsd.org/chv.cgi?CH=152996

Change 152996 by hselasky at hselasky_laptop001 on 2008/11/15 10:09:50

	
	Add two new commands to usbconfig:
	1) Command for dumping USB strings from the command line.
	2) Command for doing custom control requests from the command line.
	
	Wrap some long lines.
	
	Fix some spelling.

Affected files ...

.. //depot/projects/usb/src/usr.sbin/usbconfig/usbconfig.c#8 edit

Differences ...

==== //depot/projects/usb/src/usr.sbin/usbconfig/usbconfig.c#8 (text+ko) ====

@@ -40,10 +40,12 @@
 
 struct options {
 	const char *quirkname;
+	void   *buffer;
 	gid_t	gid;
 	uid_t	uid;
 	mode_t	mode;
 	uint32_t got_any;
+	struct LIBUSB20_CONTROL_SETUP_DECODED setup;
 	uint16_t bus;
 	uint16_t addr;
 	uint16_t iface;
@@ -51,6 +53,7 @@
 	uint16_t pid;
 	uint16_t lo_rev;		/* inclusive */
 	uint16_t hi_rev;		/* inclusive */
+	uint8_t	string_index;
 	uint8_t	config_index;
 	uint8_t	alt_index;
 	uint8_t	got_list:1;
@@ -76,6 +79,8 @@
 	uint8_t	got_dump_access:1;
 	uint8_t	got_remove_device_quirk:1;
 	uint8_t	got_add_device_quirk:1;
+	uint8_t	got_dump_string:1;
+	uint8_t	got_do_request:1;
 };
 
 struct token {
@@ -99,6 +104,7 @@
 	T_DUMP_DEVICE_DESC,
 	T_DUMP_CURR_CONFIG_DESC,
 	T_DUMP_ALL_CONFIG_DESC,
+	T_DUMP_STRING,
 	T_DUMP_ACCESS,
 	T_DUMP_INFO,
 	T_SUSPEND,
@@ -108,6 +114,7 @@
 	T_POWER_ON,
 	T_RESET,
 	T_LIST,
+	T_DO_REQUEST,
 };
 
 static struct options options;
@@ -127,6 +134,7 @@
 	{"dump_device_desc", T_DUMP_DEVICE_DESC, 0},
 	{"dump_curr_config_desc", T_DUMP_CURR_CONFIG_DESC, 0},
 	{"dump_all_config_desc", T_DUMP_ALL_CONFIG_DESC, 0},
+	{"dump_string", T_DUMP_STRING, 1},
 	{"dump_access", T_DUMP_ACCESS, 0},
 	{"dump_info", T_DUMP_INFO, 0},
 	{"suspend", T_SUSPEND, 0},
@@ -136,6 +144,7 @@
 	{"power_on", T_POWER_ON, 0},
 	{"reset", T_RESET, 0},
 	{"list", T_LIST, 0},
+	{"do_request", T_DO_REQUEST, 5},
 };
 
 static void
@@ -192,7 +201,7 @@
 	for (n = 0; n != (sizeof(token) / sizeof(token[0])); n++) {
 		if (strcasecmp(str, token[n].name) == 0) {
 			if (token[n].narg > narg) {
-				/* to little arguments */
+				/* too few arguments */
 				break;
 			}
 			return (token[n].value);
@@ -277,6 +286,7 @@
 	    "  dump_device_desc" "\n"
 	    "  dump_curr_config_desc" "\n"
 	    "  dump_all_config_desc" "\n"
+	    "  dump_string <index>" "\n"
 	    "  dump_access" "\n"
 	    "  dump_info" "\n"
 	    "  suspend" "\n"
@@ -286,6 +296,7 @@
 	    "  power_on" "\n"
 	    "  reset" "\n"
 	    "  list" "\n"
+	    "  do_request <bmReqTyp> <bReq> <wVal> <wIdx> <wLen> <data...>" "\n"
 	);
 	exit(1);
 }
@@ -293,6 +304,8 @@
 static void
 reset_options(struct options *opt)
 {
+	if (opt->buffer)
+		free(opt->buffer);
 	memset(opt, 0, sizeof(*opt));
 	return;
 }
@@ -418,6 +431,54 @@
 		if (libusb20_dev_open(pdev, 0)) {
 			err(1, "could not open device");
 		}
+		if (opt->got_dump_string) {
+			char *pbuf;
+
+			pbuf = malloc(256);
+			if (pbuf == NULL) {
+				err(1, "out of memory");
+			}
+			if (libusb20_dev_req_string_simple_sync(pdev,
+			    opt->string_index, pbuf, 256)) {
+				printf("STRING_0x%02x = <read error>\n",
+				    opt->string_index);
+			} else {
+				printf("STRING_0x%02x = <%s>\n",
+				    opt->string_index, pbuf);
+			}
+			free(pbuf);
+		}
+		if (opt->got_do_request) {
+			uint16_t actlen;
+			uint16_t t;
+
+			if (libusb20_dev_request_sync(pdev, &opt->setup,
+			    opt->buffer, &actlen, 5000 /* 5 seconds */ , 0)) {
+				printf("REQUEST = <ERROR>\n");
+			} else if (!(opt->setup.bmRequestType &
+			    LIBUSB20_ENDPOINT_IN)) {
+				printf("REQUEST = <OK>\n");
+			} else {
+				t = actlen;
+				printf("REQUEST = <");
+				for (t = 0; t != actlen; t++) {
+					printf("0x%02x%s",
+					    ((uint8_t *)opt->buffer)[t],
+					    (t == (actlen - 1)) ? "" : " ");
+				}
+				printf("><");
+				for (t = 0; t != actlen; t++) {
+					char c;
+
+					c = ((uint8_t *)opt->buffer)[t];
+					if ((c != '<') &&
+					    (c != '>') && isprint(c)) {
+						putchar(c);
+					}
+				}
+				printf(">\n");
+			}
+		}
 		if (opt->got_set_config) {
 			if (libusb20_dev_set_config_index(pdev,
 			    opt->config_index)) {
@@ -425,7 +486,8 @@
 			}
 		}
 		if (opt->got_set_alt) {
-			if (libusb20_dev_set_alt_index(pdev, opt->iface, opt->alt_index)) {
+			if (libusb20_dev_set_alt_index(pdev, opt->iface,
+			    opt->alt_index)) {
 				err(1, "could not set alternate setting");
 			}
 		}
@@ -435,27 +497,32 @@
 			}
 		}
 		if (opt->got_suspend) {
-			if (libusb20_dev_set_power_mode(pdev, LIBUSB20_POWER_SUSPEND)) {
+			if (libusb20_dev_set_power_mode(pdev,
+			    LIBUSB20_POWER_SUSPEND)) {
 				err(1, "could not set suspend");
 			}
 		}
 		if (opt->got_resume) {
-			if (libusb20_dev_set_power_mode(pdev, LIBUSB20_POWER_RESUME)) {
+			if (libusb20_dev_set_power_mode(pdev,
+			    LIBUSB20_POWER_RESUME)) {
 				err(1, "could not set resume");
 			}
 		}
 		if (opt->got_power_off) {
-			if (libusb20_dev_set_power_mode(pdev, LIBUSB20_POWER_OFF)) {
+			if (libusb20_dev_set_power_mode(pdev,
+			    LIBUSB20_POWER_OFF)) {
 				err(1, "could not set power OFF");
 			}
 		}
 		if (opt->got_power_save) {
-			if (libusb20_dev_set_power_mode(pdev, LIBUSB20_POWER_SAVE)) {
+			if (libusb20_dev_set_power_mode(pdev,
+			    LIBUSB20_POWER_SAVE)) {
 				err(1, "could not set power SAVE");
 			}
 		}
 		if (opt->got_power_on) {
-			if (libusb20_dev_set_power_mode(pdev, LIBUSB20_POWER_ON)) {
+			if (libusb20_dev_set_power_mode(pdev,
+			    LIBUSB20_POWER_ON)) {
 				err(1, "could not set power ON");
 			}
 		}
@@ -584,13 +651,13 @@
 			n++;
 			break;
 		case T_SET_CONFIG:
-			opt->config_index = num_id(argv[n + 1], "confindex");
+			opt->config_index = num_id(argv[n + 1], "cfg_index");
 			opt->got_set_config = 1;
 			opt->got_any++;
 			n++;
 			break;
 		case T_SET_ALT:
-			opt->alt_index = num_id(argv[n + 1], "confindex");
+			opt->alt_index = num_id(argv[n + 1], "cfg_index");
 			opt->got_set_alt = 1;
 			opt->got_any++;
 			n++;
@@ -630,6 +697,15 @@
 			opt->got_dump_info = 1;
 			opt->got_any++;
 			break;
+		case T_DUMP_STRING:
+			if (opt->got_dump_string) {
+				flush_command(pbe, opt);
+			}
+			opt->string_index = num_id(argv[n + 1], "str_index");
+			opt->got_dump_string = 1;
+			opt->got_any++;
+			n++;
+			break;
 		case T_DUMP_ACCESS:
 			opt->got_dump_access = 1;
 			opt->got_any += 2;
@@ -662,6 +738,41 @@
 			opt->got_list = 1;
 			opt->got_any++;
 			break;
+		case T_DO_REQUEST:
+			if (opt->got_do_request) {
+				flush_command(pbe, opt);
+			}
+			LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &opt->setup);
+			opt->setup.bmRequestType = num_id(argv[n + 1], "bmReqTyp");
+			opt->setup.bRequest = num_id(argv[n + 2], "bReq");
+			opt->setup.wValue = num_id(argv[n + 3], "wVal");
+			opt->setup.wIndex = num_id(argv[n + 4], "wIndex");
+			opt->setup.wLength = num_id(argv[n + 5], "wLen");
+			if (opt->setup.wLength != 0) {
+				opt->buffer = malloc(opt->setup.wLength);
+			} else {
+				opt->buffer = NULL;
+			}
+
+			n += 5;
+
+			if (!(opt->setup.bmRequestType &
+			    LIBUSB20_ENDPOINT_IN)) {
+				/* copy in data */
+				t = (argc - n - 1);
+				if (t < opt->setup.wLength) {
+					err(1, "request data missing");
+				}
+				t = opt->setup.wLength;
+				while (t--) {
+					((uint8_t *)opt->buffer)[t] =
+					    num_id(argv[n + t + 1], "req_data");
+				}
+				n += opt->setup.wLength;
+			}
+			opt->got_do_request = 1;
+			opt->got_any++;
+			break;
 		default:
 			usage();
 			break;


More information about the p4-projects mailing list