1 /*****************************************************************************/
2 
3 /*
4  *      lsusb.c  --  lspci like utility for the USB bus
5  *
6  *      Copyright (C) 1999-2001, 2003
7  *        Thomas Sailer (t.sailer@alumni.ethz.ch)
8  *      Copyright (C) 2003-2005 David Brownell
9  *
10  *      This program is free software; you can redistribute it and/or modify
11  *      it under the terms of the GNU General Public License as published by
12  *      the Free Software Foundation; either version 2 of the License, or
13  *      (at your option) any later version.
14  *
15  *      This program is distributed in the hope that it will be useful,
16  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *      GNU General Public License for more details.
19  *
20  *      You should have received a copy of the GNU General Public License
21  *      along with this program; if not, write to the Free Software
22  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24 
25 /*****************************************************************************/
26 
27 #include "config.h"
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <fcntl.h>
31 #include <string.h>
32 #include <errno.h>
33 #include <stdio.h>
34 #include <stdarg.h>
35 
36 #ifdef HAVE_BYTESWAP_H
37 #include <byteswap.h>
38 #endif
39 
40 #include <usb.h>
41 #include <unistd.h>
42 
43 #include "names.h"
44 #include "devtree.h"
45 #include "usbmisc.h"
46 
47 #include <getopt.h>
48 
49 #if (__BYTE_ORDER == __LITTLE_ENDIAN)
50   #define le16_to_cpu(x) (x)
51 #elif (__BYTE_ORDER == __BIG_ENDIAN)
52   #define le16_to_cpu(x) bswap_16(x)
53 #else
54   #error missing BYTE_ORDER
55 #endif
56 
57 /* from USB 2.0 spec and updates */
58 #define USB_DT_DEVICE_QUALIFIER		0x06
59 #define USB_DT_OTHER_SPEED_CONFIG	0x07
60 #define USB_DT_OTG			0x09
61 #define USB_DT_DEBUG			0x0a
62 #define USB_DT_INTERFACE_ASSOCIATION	0x0b
63 #define USB_DT_SECURITY			0x0c
64 #define USB_DT_KEY			0x0d
65 #define USB_DT_ENCRYPTION_TYPE		0x0e
66 #define USB_DT_BOS			0x0f
67 #define USB_DT_DEVICE_CAPABILITY	0x10
68 #define USB_DT_WIRELESS_ENDPOINT_COMP	0x11
69 #define USB_DT_WIRE_ADAPTER		0x21
70 #define USB_DT_RPIPE			0x22
71 #define USB_DT_RC_INTERFACE		0x23
72 #define USB_DT_SS_ENDPOINT_COMP		0x30
73 
74 /* Device Capability Type Codes (Wireless USB spec and USB 3.0 bus spec) */
75 #define USB_DC_WIRELESS_USB		0x01
76 #define USB_DC_20_EXTENSION		0x02
77 #define USB_DC_SUPERSPEED		0x03
78 #define USB_DC_CONTAINER_ID		0x04
79 
80 /* Conventional codes for class-specific descriptors.  The convention is
81  * defined in the USB "Common Class" Spec (3.11).  Individual class specs
82  * are authoritative for their usage, not the "common class" writeup.
83  */
84 #define USB_DT_CS_DEVICE		(USB_TYPE_CLASS | USB_DT_DEVICE)
85 #define USB_DT_CS_CONFIG		(USB_TYPE_CLASS | USB_DT_CONFIG)
86 #define USB_DT_CS_STRING		(USB_TYPE_CLASS | USB_DT_STRING)
87 #define USB_DT_CS_INTERFACE		(USB_TYPE_CLASS | USB_DT_INTERFACE)
88 #define USB_DT_CS_ENDPOINT		(USB_TYPE_CLASS | USB_DT_ENDPOINT)
89 
90 #ifndef USB_CLASS_CCID
91 #define USB_CLASS_CCID			0x0b
92 #endif
93 
94 #ifndef USB_CLASS_VIDEO
95 #define USB_CLASS_VIDEO			0x0e
96 #endif
97 
98 #ifndef USB_CLASS_APPLICATION
99 #define USB_CLASS_APPLICATION	       	0xfe
100 #endif
101 
102 #ifndef USB_AUDIO_CLASS_1
103 #define USB_AUDIO_CLASS_1		0x00
104 #endif
105 
106 #ifndef USB_AUDIO_CLASS_2
107 #define USB_AUDIO_CLASS_2		0x20
108 #endif
109 
110 #define VERBLEVEL_DEFAULT 0	/* 0 gives lspci behaviour; 1, lsusb-0.9 */
111 
112 #define CTRL_RETRIES	 2
113 #define CTRL_TIMEOUT	(5*1000)	/* milliseconds */
114 
115 #define	HUB_STATUS_BYTELEN	3	/* max 3 bytes status = hub + 23 ports */
116 
117 extern int lsusb_t(void);
118 static const char *procbususb = "/proc/bus/usb";
119 static unsigned int verblevel = VERBLEVEL_DEFAULT;
120 static int do_report_desc = 1;
121 static const char *encryption_type[] = {"UNSECURE", "WIRED", "CCM_1", "RSA_1", "RESERVED"};
122 
123 static void dump_interface(struct usb_dev_handle *dev, struct usb_interface *interface);
124 static void dump_endpoint(struct usb_dev_handle *dev, struct usb_interface_descriptor *interface, struct usb_endpoint_descriptor *endpoint);
125 static void dump_audiocontrol_interface(struct usb_dev_handle *dev, unsigned char *buf, int protocol);
126 static void dump_audiostreaming_interface(struct usb_dev_handle *dev, unsigned char *buf, int protocol);
127 static void dump_midistreaming_interface(struct usb_dev_handle *dev, unsigned char *buf);
128 static void dump_videocontrol_interface(struct usb_dev_handle *dev, unsigned char *buf);
129 static void dump_videostreaming_interface(unsigned char *buf);
130 static void dump_dfu_interface(unsigned char *buf);
131 static char *dump_comm_descriptor(struct usb_dev_handle *dev, unsigned char *buf, char *indent);
132 static void dump_hid_device(struct usb_dev_handle *dev, struct usb_interface_descriptor *interface, unsigned char *buf);
133 static void dump_audiostreaming_endpoint(unsigned char *buf, int protocol);
134 static void dump_midistreaming_endpoint(unsigned char *buf);
135 static void dump_hub(char *prefix, unsigned char *p, int tt_type);
136 static void dump_ccid_device(unsigned char *buf);
137 
138 /* ---------------------------------------------------------------------- */
139 
convert_le_u32(const unsigned char * buf)140 static unsigned int convert_le_u32 (const unsigned char *buf)
141 {
142 	return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
143 }
144 
145 /* ---------------------------------------------------------------------- */
146 
147 /* workaround libusb API goofs:  "byte" should never be sign extended;
148  * using "char" is trouble.  Likewise, sizes should never be negative.
149  */
150 
typesafe_control_msg(usb_dev_handle * dev,unsigned char requesttype,unsigned char request,int value,int idx,unsigned char * bytes,unsigned size,int timeout)151 static inline int typesafe_control_msg(usb_dev_handle *dev,
152 	unsigned char requesttype, unsigned char request,
153 	int value, int idx,
154 	unsigned char *bytes, unsigned size, int timeout)
155 {
156 	return usb_control_msg(dev, requesttype, request, value, idx,
157 		(char *)bytes, (int)size, timeout);
158 }
159 
160 #define usb_control_msg		typesafe_control_msg
161 
162 /* ---------------------------------------------------------------------- */
163 
lprintf(unsigned int vl,const char * format,...)164 int lprintf(unsigned int vl, const char *format, ...)
165 {
166 	va_list ap;
167 	int r;
168 
169 	if (vl > verblevel)
170 		return 0;
171 	va_start(ap, format);
172 	r = vfprintf(stderr, format, ap);
173 	va_end(ap);
174 	if (!vl)
175 		exit(1);
176 	return r;
177 }
178 
179 /* ---------------------------------------------------------------------- */
180 
get_string(struct usb_dev_handle * dev,char * buf,size_t size,u_int8_t id)181 static int get_string(struct usb_dev_handle *dev, char* buf, size_t size, u_int8_t id)
182 {
183 	int ret;
184 
185 	if (!dev) {
186 		buf[0] = 0;
187 		return 0;
188 	}
189 
190 	if (id) {
191 		ret = usb_get_string_simple(dev, id, buf, size);
192 		if (ret <= 0) {
193 			buf[0] = 0;
194 			return 0;
195 		} else
196 			return ret;
197 
198 	} else {
199 		buf[0] = 0;
200 		return 0;
201 	}
202 }
203 
get_vendor_string(char * buf,size_t size,u_int16_t vid)204 static int get_vendor_string(char *buf, size_t size, u_int16_t vid)
205 {
206 	const char *cp;
207 
208 	if (size < 1)
209 		return 0;
210 	*buf = 0;
211 	if (!(cp = names_vendor(vid)))
212 		return 0;
213 	return snprintf(buf, size, "%s", cp);
214 }
215 
get_product_string(char * buf,size_t size,u_int16_t vid,u_int16_t pid)216 static int get_product_string(char *buf, size_t size, u_int16_t vid, u_int16_t pid)
217 {
218 	const char *cp;
219 
220 	if (size < 1)
221 		return 0;
222 	*buf = 0;
223 	if (!(cp = names_product(vid, pid)))
224 		return 0;
225 	return snprintf(buf, size, "%s", cp);
226 }
227 
get_class_string(char * buf,size_t size,u_int8_t cls)228 static int get_class_string(char *buf, size_t size, u_int8_t cls)
229 {
230 	const char *cp;
231 
232 	if (size < 1)
233 		return 0;
234 	*buf = 0;
235 	if (!(cp = names_class(cls)))
236 		return 0;
237 	return snprintf(buf, size, "%s", cp);
238 }
239 
get_subclass_string(char * buf,size_t size,u_int8_t cls,u_int8_t subcls)240 static int get_subclass_string(char *buf, size_t size, u_int8_t cls, u_int8_t subcls)
241 {
242 	const char *cp;
243 
244 	if (size < 1)
245 		return 0;
246 	*buf = 0;
247 	if (!(cp = names_subclass(cls, subcls)))
248 		return 0;
249 	return snprintf(buf, size, "%s", cp);
250 }
251 
get_protocol_string(char * buf,size_t size,u_int8_t cls,u_int8_t subcls,u_int8_t proto)252 static int get_protocol_string(char *buf, size_t size, u_int8_t cls, u_int8_t subcls, u_int8_t proto)
253 {
254 	const char *cp;
255 
256 	if (size < 1)
257 		return 0;
258 	*buf = 0;
259 	if (!(cp = names_protocol(cls, subcls, proto)))
260 		return 0;
261 	return snprintf(buf, size, "%s", cp);
262 }
263 
get_audioterminal_string(char * buf,size_t size,u_int16_t termt)264 static int get_audioterminal_string(char *buf, size_t size, u_int16_t termt)
265 {
266 	const char *cp;
267 
268 	if (size < 1)
269 		return 0;
270 	*buf = 0;
271 	if (!(cp = names_audioterminal(termt)))
272 		return 0;
273 	return snprintf(buf, size, "%s", cp);
274 }
275 
get_videoterminal_string(char * buf,size_t size,u_int16_t termt)276 static int get_videoterminal_string(char *buf, size_t size, u_int16_t termt)
277 {
278 	const char *cp;
279 
280 	if (size < 1)
281 		return 0;
282 	*buf = 0;
283 	if (!(cp = names_videoterminal(termt)))
284 		return 0;
285 	return snprintf(buf, size, "%s", cp);
286 }
287 
get_guid(unsigned char * buf)288 static const char *get_guid(unsigned char *buf)
289 {
290 	static char guid[39];
291 
292 	/* NOTE:  see RFC 4122 for more information about GUID/UUID
293 	 * structure.  The first fields fields are historically big
294 	 * endian numbers, dating from Apollo mc68000 workstations.
295 	 */
296 	sprintf(guid, "{%02x%02x%02x%02x"
297 			"-%02x%02x"
298 			"-%02x%02x"
299 			"-%02x%02x"
300 			"-%02x%02x%02x%02x%02x%02x}",
301 	       buf[0], buf[1], buf[2], buf[3],
302 	       buf[4], buf[5],
303 	       buf[6], buf[7],
304 	       buf[8], buf[9],
305 	       buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]);
306 	return guid;
307 }
308 
309 /* ---------------------------------------------------------------------- */
310 
dump_bytes(unsigned char * buf,unsigned int len)311 static void dump_bytes(unsigned char *buf, unsigned int len)
312 {
313 	unsigned int i;
314 
315 	for (i = 0; i < len; i++)
316 		printf(" %02x", buf[i]);
317 	printf("\n");
318 }
319 
dump_junk(unsigned char * buf,const char * indent,unsigned int len)320 static void dump_junk(unsigned char *buf, const char *indent, unsigned int len)
321 {
322 	unsigned int i;
323 
324 	if (buf[0] <= len)
325 		return;
326 	printf("%sjunk at descriptor end:", indent);
327 	for (i = len; i < buf[0]; i++)
328 		printf(" %02x", buf[i]);
329 	printf("\n");
330 }
331 
332 /*
333  * General config descriptor dump
334  */
335 
dump_device(struct usb_dev_handle * dev,struct usb_device_descriptor * descriptor)336 static void dump_device(
337 	struct usb_dev_handle *dev,
338 	struct usb_device_descriptor *descriptor
339 )
340 {
341 	char vendor[128], product[128];
342 	char cls[128], subcls[128], proto[128];
343 	char mfg[128], prod[128], serial[128];
344 
345 	get_vendor_string(vendor, sizeof(vendor), descriptor->idVendor);
346 	get_product_string(product, sizeof(product),
347 			descriptor->idVendor, descriptor->idProduct);
348 	get_class_string(cls, sizeof(cls), descriptor->bDeviceClass);
349 	get_subclass_string(subcls, sizeof(subcls),
350 			descriptor->bDeviceClass, descriptor->bDeviceSubClass);
351 	get_protocol_string(proto, sizeof(proto), descriptor->bDeviceClass,
352 			descriptor->bDeviceSubClass, descriptor->bDeviceProtocol);
353 	get_string(dev, mfg, sizeof(mfg), descriptor->iManufacturer);
354 	get_string(dev, prod, sizeof(prod), descriptor->iProduct);
355 	get_string(dev, serial, sizeof(serial), descriptor->iSerialNumber);
356 	printf("Device Descriptor:\n"
357 	       "  bLength             %5u\n"
358 	       "  bDescriptorType     %5u\n"
359 	       "  bcdUSB              %2x.%02x\n"
360 	       "  bDeviceClass        %5u %s\n"
361 	       "  bDeviceSubClass     %5u %s\n"
362 	       "  bDeviceProtocol     %5u %s\n"
363 	       "  bMaxPacketSize0     %5u\n"
364 	       "  idVendor           0x%04x %s\n"
365 	       "  idProduct          0x%04x %s\n"
366 	       "  bcdDevice           %2x.%02x\n"
367 	       "  iManufacturer       %5u %s\n"
368 	       "  iProduct            %5u %s\n"
369 	       "  iSerial             %5u %s\n"
370 	       "  bNumConfigurations  %5u\n",
371 	       descriptor->bLength, descriptor->bDescriptorType,
372 	       descriptor->bcdUSB >> 8, descriptor->bcdUSB & 0xff,
373 	       descriptor->bDeviceClass, cls,
374 	       descriptor->bDeviceSubClass, subcls,
375 	       descriptor->bDeviceProtocol, proto,
376 	       descriptor->bMaxPacketSize0,
377 	       descriptor->idVendor, vendor, descriptor->idProduct, product,
378 	       descriptor->bcdDevice >> 8, descriptor->bcdDevice & 0xff,
379 	       descriptor->iManufacturer, mfg,
380 	       descriptor->iProduct, prod,
381 	       descriptor->iSerialNumber, serial,
382 	       descriptor->bNumConfigurations);
383 }
384 
dump_wire_adapter(unsigned char * buf)385 static void dump_wire_adapter(unsigned char *buf)
386 {
387 
388 	printf("      Wire Adapter Class Descriptor:\n"
389 	       "        bLength             %5u\n"
390 	       "        bDescriptorType     %5u\n"
391 	       "        bcdWAVersion        %2x.%02x\n"
392 	       "	 bNumPorts	     %5u\n"
393 	       "	 bmAttributes	     %5u\n"
394 	       "	 wNumRPRipes	     %5u\n"
395 	       "	 wRPipeMaxBlock	     %5u\n"
396 	       "	 bRPipeBlockSize     %5u\n"
397 	       "	 bPwrOn2PwrGood	     %5u\n"
398 	       "	 bNumMMCIEs	     %5u\n"
399 	       "	 DeviceRemovable     %5u\n",
400 	       buf[0], buf[1], buf[3], buf[2], buf[4], buf[5],
401 	       (buf[6] | buf[7] << 8),
402 	       (buf[8] | buf[9] << 8),
403 	       buf[10], buf[11], buf[12], buf[13]);
404 }
405 
dump_rc_interface(unsigned char * buf)406 static void dump_rc_interface(unsigned char *buf)
407 {
408 	printf("      Radio Control Interface Class Descriptor:\n"
409 	       "        bLength             %5u\n"
410 	       "        bDescriptorType     %5u\n"
411 	       "        bcdRCIVersion       %2x.%02x\n",
412 	       buf[0], buf[1], buf[3], buf[2]);
413 
414 }
415 
dump_security(unsigned char * buf)416 static void dump_security(unsigned char *buf)
417 {
418 	printf("    Security Descriptor:\n"
419 	       "      bLength             %5u\n"
420 	       "      bDescriptorType     %5u\n"
421 	       "      wTotalLength        %5u\n"
422 	       "      bNumEncryptionTypes %5u\n",
423 	       buf[0], buf[1], (buf[3] << 8 | buf[2]), buf[4]);
424 }
425 
dump_encryption_type(unsigned char * buf)426 static void dump_encryption_type(unsigned char *buf)
427 {
428 	int b_encryption_type = buf[2] & 0x4;
429 
430 	printf("    Encryption Type Descriptor:\n"
431 	       "      bLength             %5u\n"
432 	       "      bDescriptorType     %5u\n"
433 	       "      bEncryptionType     %5u %s\n"
434 	       "      bEncryptionValue    %5u\n"
435 	       "      bAuthKeyIndex       %5u\n",
436 	       buf[0], buf[1], buf[2],
437 	       encryption_type[b_encryption_type], buf[3], buf[4]);
438 }
439 
dump_association(struct usb_dev_handle * dev,unsigned char * buf)440 static void dump_association(struct usb_dev_handle *dev, unsigned char *buf)
441 {
442 	char cls[128], subcls[128], proto[128];
443 	char func[128];
444 
445 	get_class_string(cls, sizeof(cls), buf[4]);
446 	get_subclass_string(subcls, sizeof(subcls), buf[4], buf[5]);
447 	get_protocol_string(proto, sizeof(proto), buf[4], buf[5], buf[6]);
448 	get_string(dev, func, sizeof(func), buf[7]);
449 	printf("    Interface Association:\n"
450 	       "      bLength             %5u\n"
451 	       "      bDescriptorType     %5u\n"
452 	       "      bFirstInterface     %5u\n"
453 	       "      bInterfaceCount     %5u\n"
454 	       "      bFunctionClass      %5u %s\n"
455 	       "      bFunctionSubClass   %5u %s\n"
456 	       "      bFunctionProtocol   %5u %s\n"
457 	       "      iFunction           %5u %s\n",
458 	       buf[0], buf[1],
459 	       buf[2], buf[3],
460 	       buf[4], cls,
461 	       buf[5], subcls,
462 	       buf[6], proto,
463 	       buf[7], func);
464 }
465 
dump_config(struct usb_dev_handle * dev,struct usb_config_descriptor * config)466 static void dump_config(struct usb_dev_handle *dev, struct usb_config_descriptor *config)
467 {
468 	char cfg[128];
469 	int i;
470 
471 	get_string(dev, cfg, sizeof(cfg), config->iConfiguration);
472 	printf("  Configuration Descriptor:\n"
473 	       "    bLength             %5u\n"
474 	       "    bDescriptorType     %5u\n"
475 	       "    wTotalLength        %5u\n"
476 	       "    bNumInterfaces      %5u\n"
477 	       "    bConfigurationValue %5u\n"
478 	       "    iConfiguration      %5u %s\n"
479 	       "    bmAttributes         0x%02x\n",
480 	       config->bLength, config->bDescriptorType,
481 	       le16_to_cpu(config->wTotalLength),
482 	       config->bNumInterfaces, config->bConfigurationValue,
483 	       config->iConfiguration,
484 	       cfg, config->bmAttributes);
485 	if (!(config->bmAttributes & 0x80))
486 		printf("      (Missing must-be-set bit!)\n");
487 	if (config->bmAttributes & 0x40)
488 		printf("      Self Powered\n");
489 	else
490 		printf("      (Bus Powered)\n");
491 	if (config->bmAttributes & 0x20)
492 		printf("      Remote Wakeup\n");
493 	if (config->bmAttributes & 0x10)
494 		printf("      Battery Powered\n");
495 	printf("    MaxPower            %5umA\n", config->MaxPower * 2);
496 
497 	/* avoid re-ordering or hiding descriptors for display */
498 	if (config->extralen) {
499 		int		size = config->extralen;
500 		unsigned char	*buf = config->extra;
501 
502 		while (size >= 2) {
503 			if (buf[0] < 2) {
504 				dump_junk(buf, "        ", size);
505 				break;
506 			}
507 			switch (buf[1]) {
508 			case USB_DT_OTG:
509 				/* handled separately */
510 				break;
511 			case USB_DT_INTERFACE_ASSOCIATION:
512 				dump_association(dev, buf);
513 				break;
514 			case USB_DT_SECURITY:
515 				dump_security(buf);
516 				break;
517 			case USB_DT_ENCRYPTION_TYPE:
518 				dump_encryption_type(buf);
519 				break;
520 			default:
521 				/* often a misplaced class descriptor */
522 				printf("    ** UNRECOGNIZED: ");
523 				dump_bytes(buf, buf[0]);
524 				break;
525 			}
526 			size -= buf[0];
527 			buf += buf[0];
528 		}
529 	}
530 	for (i = 0 ; i < config->bNumInterfaces ; i++)
531 		dump_interface(dev, &config->interface[i]);
532 }
533 
dump_altsetting(struct usb_dev_handle * dev,struct usb_interface_descriptor * interface)534 static void dump_altsetting(struct usb_dev_handle *dev, struct usb_interface_descriptor *interface)
535 {
536 	char cls[128], subcls[128], proto[128];
537 	char ifstr[128];
538 
539 	unsigned char *buf;
540 	unsigned size, i;
541 
542 	get_class_string(cls, sizeof(cls), interface->bInterfaceClass);
543 	get_subclass_string(subcls, sizeof(subcls), interface->bInterfaceClass, interface->bInterfaceSubClass);
544 	get_protocol_string(proto, sizeof(proto), interface->bInterfaceClass, interface->bInterfaceSubClass, interface->bInterfaceProtocol);
545 	get_string(dev, ifstr, sizeof(ifstr), interface->iInterface);
546 	printf("    Interface Descriptor:\n"
547 	       "      bLength             %5u\n"
548 	       "      bDescriptorType     %5u\n"
549 	       "      bInterfaceNumber    %5u\n"
550 	       "      bAlternateSetting   %5u\n"
551 	       "      bNumEndpoints       %5u\n"
552 	       "      bInterfaceClass     %5u %s\n"
553 	       "      bInterfaceSubClass  %5u %s\n"
554 	       "      bInterfaceProtocol  %5u %s\n"
555 	       "      iInterface          %5u %s\n",
556 	       interface->bLength, interface->bDescriptorType, interface->bInterfaceNumber,
557 	       interface->bAlternateSetting, interface->bNumEndpoints, interface->bInterfaceClass, cls,
558 	       interface->bInterfaceSubClass, subcls, interface->bInterfaceProtocol, proto,
559 	       interface->iInterface, ifstr);
560 
561 	/* avoid re-ordering or hiding descriptors for display */
562 	if (interface->extralen) {
563 		size = interface->extralen;
564 		buf = interface->extra;
565 		while (size >= 2 * sizeof(u_int8_t)) {
566 			if (buf[0] < 2) {
567 				dump_junk(buf, "      ", size);
568 				break;
569 			}
570 
571 			switch (buf[1]) {
572 
573 			/* This is the polite way to provide class specific
574 			 * descriptors: explicitly tagged, using common class
575 			 * spec conventions.
576 			 */
577 			case USB_DT_CS_DEVICE:
578 			case USB_DT_CS_INTERFACE:
579 				switch (interface->bInterfaceClass) {
580 				case USB_CLASS_AUDIO:
581 					switch (interface->bInterfaceSubClass) {
582 					case 1:
583 						dump_audiocontrol_interface(dev, buf, interface->bInterfaceProtocol);
584 						break;
585 					case 2:
586 						dump_audiostreaming_interface(dev, buf, interface->bInterfaceProtocol);
587 						break;
588 					case 3:
589 						dump_midistreaming_interface(dev, buf);
590 						break;
591 					default:
592 						goto dump;
593 					}
594 					break;
595 				case USB_CLASS_COMM:
596 					dump_comm_descriptor(dev, buf,
597 						"      ");
598 					break;
599 				case USB_CLASS_VIDEO:
600 					switch (interface->bInterfaceSubClass) {
601 					case 1:
602 						dump_videocontrol_interface(dev, buf);
603 						break;
604 					case 2:
605 						dump_videostreaming_interface(buf);
606 						break;
607 					default:
608 						goto dump;
609 					}
610 					break;
611 				case USB_CLASS_APPLICATION:
612 					switch (interface->bInterfaceSubClass) {
613 					case 1:
614 						dump_dfu_interface(buf);
615 						break;
616 					default:
617 						goto dump;
618 					}
619 					break;
620 				case USB_CLASS_HID:
621 					dump_hid_device(dev, interface, buf);
622 					break;
623 				case USB_CLASS_CCID:
624 					dump_ccid_device(buf);
625 					break;
626 				default:
627 					goto dump;
628 				}
629 				break;
630 
631 			/* This is the ugly way:  implicitly tagged,
632 			 * each class could redefine the type IDs.
633 			 */
634 			default:
635 				switch (interface->bInterfaceClass) {
636 				case USB_CLASS_HID:
637 					dump_hid_device(dev, interface, buf);
638 					break;
639 				case USB_CLASS_CCID:
640 					dump_ccid_device(buf);
641 					break;
642 				case 0xe0:	/* wireless */
643 					switch (interface->bInterfaceSubClass) {
644 					case 1:
645 						switch (interface->bInterfaceProtocol) {
646 						case 2:
647 							dump_rc_interface(buf);
648 							break;
649 						default:
650 							goto dump;
651 						}
652 						break;
653 					case 2:
654 						dump_wire_adapter(buf);
655 						break;
656 					default:
657 						goto dump;
658 					}
659 					break;
660 				default:
661 					/* ... not everything is class-specific */
662 					switch (buf[1]) {
663 					case USB_DT_OTG:
664 						/* handled separately */
665 						break;
666 					case USB_DT_INTERFACE_ASSOCIATION:
667 						dump_association(dev, buf);
668 						break;
669 					default:
670 dump:
671 						/* often a misplaced class descriptor */
672 						printf("      ** UNRECOGNIZED: ");
673 						dump_bytes(buf, buf[0]);
674 						break;
675 					}
676 				}
677 			}
678 			size -= buf[0];
679 			buf += buf[0];
680 		}
681 	}
682 
683 	for (i = 0 ; i < interface->bNumEndpoints ; i++)
684 		dump_endpoint(dev, interface, &interface->endpoint[i]);
685 }
686 
dump_interface(struct usb_dev_handle * dev,struct usb_interface * interface)687 static void dump_interface(struct usb_dev_handle *dev, struct usb_interface *interface)
688 {
689 	int i;
690 
691 	for (i = 0; i < interface->num_altsetting; i++)
692 		dump_altsetting(dev, &interface->altsetting[i]);
693 }
694 
dump_endpoint(struct usb_dev_handle * dev,struct usb_interface_descriptor * interface,struct usb_endpoint_descriptor * endpoint)695 static void dump_endpoint(struct usb_dev_handle *dev, struct usb_interface_descriptor *interface, struct usb_endpoint_descriptor *endpoint)
696 {
697 	static const char *typeattr[] = {
698 		"Control",
699 		"Isochronous",
700 		"Bulk",
701 		"Interrupt"
702 	};
703 	static const char *syncattr[] = {
704 		"None",
705 		"Asynchronous",
706 		"Adaptive",
707 		"Synchronous"
708 	};
709 	static const char *usage[] = {
710 		"Data",
711 		"Feedback",
712 		"Implicit feedback Data",
713 		"(reserved)"
714 	};
715 	static const char *hb[] = { "1x", "2x", "3x", "(?\?)" };
716 	unsigned char *buf;
717 	unsigned size;
718 	unsigned wmax = le16_to_cpu(endpoint->wMaxPacketSize);
719 
720 	printf("      Endpoint Descriptor:\n"
721 	       "        bLength             %5u\n"
722 	       "        bDescriptorType     %5u\n"
723 	       "        bEndpointAddress     0x%02x  EP %u %s\n"
724 	       "        bmAttributes        %5u\n"
725 	       "          Transfer Type            %s\n"
726 	       "          Synch Type               %s\n"
727 	       "          Usage Type               %s\n"
728 	       "        wMaxPacketSize     0x%04x  %s %d bytes\n"
729 	       "        bInterval           %5u\n",
730 	       endpoint->bLength,
731 	       endpoint->bDescriptorType,
732 	       endpoint->bEndpointAddress,
733 	       endpoint->bEndpointAddress & 0x0f,
734 	       (endpoint->bEndpointAddress & 0x80) ? "IN" : "OUT",
735 	       endpoint->bmAttributes,
736 	       typeattr[endpoint->bmAttributes & 3],
737 	       syncattr[(endpoint->bmAttributes >> 2) & 3],
738 	       usage[(endpoint->bmAttributes >> 4) & 3],
739 	       wmax, hb[(wmax >> 11) & 3], wmax & 0x7ff,
740 	       endpoint->bInterval);
741 	/* only for audio endpoints */
742 	if (endpoint->bLength == 9)
743 		printf("        bRefresh            %5u\n"
744 		       "        bSynchAddress       %5u\n",
745 		       endpoint->bRefresh, endpoint->bSynchAddress);
746 
747 	/* avoid re-ordering or hiding descriptors for display */
748 	if (endpoint->extralen) {
749 		size = endpoint->extralen;
750 		buf = endpoint->extra;
751 		while (size >= 2 * sizeof(u_int8_t)) {
752 			if (buf[0] < 2) {
753 				dump_junk(buf, "        ", size);
754 				break;
755 			}
756 			switch (buf[1]) {
757 			case USB_DT_CS_ENDPOINT:
758 				if (interface->bInterfaceClass == 1 && interface->bInterfaceSubClass == 2)
759 					dump_audiostreaming_endpoint(buf, interface->bInterfaceProtocol);
760 				else if (interface->bInterfaceClass == 1 && interface->bInterfaceSubClass == 3)
761 					dump_midistreaming_endpoint(buf);
762 				break;
763 			case USB_DT_CS_INTERFACE:
764 				/* MISPLACED DESCRIPTOR ... less indent */
765 				switch (interface->bInterfaceClass) {
766 				case USB_CLASS_COMM:
767 				case USB_CLASS_DATA:	/* comm data */
768 					dump_comm_descriptor(dev, buf,
769 						"      ");
770 					break;
771 				default:
772 					printf("        INTERFACE CLASS: ");
773 					dump_bytes(buf, buf[0]);
774 				}
775 				break;
776 			case USB_DT_OTG:
777 				/* handled separately */
778 				break;
779 			case USB_DT_INTERFACE_ASSOCIATION:
780 				dump_association(dev, buf);
781 				break;
782 			case USB_DT_SS_ENDPOINT_COMP:
783 				printf("        bMaxBurst %15u\n", buf[2] + 1);
784 				/* Print bulk streams info or isoc "Mult" */
785 				if ((endpoint->bmAttributes & 3) == 2 &&
786 						(buf[3] & 0x1f))
787 					printf("        MaxStreams %14u\n",
788 							(unsigned) 1 << buf[3]);
789 				if ((endpoint->bmAttributes & 3) == 1 &&
790 						(buf[3] & 0x3))
791 					printf("        Mult %20u\n",
792 							buf[3] & 0x3);
793 				break;
794 			default:
795 				/* often a misplaced class descriptor */
796 				printf("        ** UNRECOGNIZED: ");
797 				dump_bytes(buf, buf[0]);
798 				break;
799 			}
800 			size -= buf[0];
801 			buf += buf[0];
802 		}
803 	}
804 }
805 
dump_unit(unsigned int data,unsigned int len)806 static void dump_unit(unsigned int data, unsigned int len)
807 {
808 	char *systems[5] = { "None", "SI Linear", "SI Rotation",
809 			"English Linear", "English Rotation" };
810 
811 	char *units[5][8] = {
812 		{ "None", "None", "None", "None", "None",
813 				"None", "None", "None" },
814 		{ "None", "Centimeter", "Gram", "Seconds", "Kelvin",
815 				"Ampere", "Candela", "None" },
816 		{ "None", "Radians",    "Gram", "Seconds", "Kelvin",
817 				"Ampere", "Candela", "None" },
818 		{ "None", "Inch",       "Slug", "Seconds", "Fahrenheit",
819 				"Ampere", "Candela", "None" },
820 		{ "None", "Degrees",    "Slug", "Seconds", "Fahrenheit",
821 				"Ampere", "Candela", "None" },
822 	};
823 
824 	unsigned int i;
825 	unsigned int sys;
826 	int earlier_unit = 0;
827 
828 	/* First nibble tells us which system we're in. */
829 	sys = data & 0xf;
830 	data >>= 4;
831 
832 	if (sys > 4) {
833 		if (sys == 0xf)
834 			printf("System: Vendor defined, Unit: (unknown)\n");
835 		else
836 			printf("System: Reserved, Unit: (unknown)\n");
837 		return;
838 	} else {
839 		printf("System: %s, Unit: ", systems[sys]);
840 	}
841 	for (i = 1 ; i < len * 2 ; i++) {
842 		char nibble = data & 0xf;
843 		data >>= 4;
844 		if (nibble != 0) {
845 			if (earlier_unit++ > 0)
846 				printf("*");
847 			printf("%s", units[sys][i]);
848 			if (nibble != 1) {
849 				/* This is a _signed_ nibble(!) */
850 
851 				int val = nibble & 0x7;
852 				if (nibble & 0x08)
853 					val = -((0x7 & ~val) + 1);
854 				printf("^%d", val);
855 			}
856 		}
857 	}
858 	if (earlier_unit == 0)
859 		printf("(None)");
860 	printf("\n");
861 }
862 
863 /* ---------------------------------------------------------------------- */
864 
865 /*
866  * Audio Class descriptor dump
867  */
868 
869 struct bmcontrol {
870 	const char *name;
871 	unsigned int bit;
872 };
873 
874 static const struct bmcontrol uac2_interface_header_bmcontrols[] = {
875 	{ "Latency control",	0 },
876 	{ NULL }
877 };
878 
879 static const struct bmcontrol uac_fu_bmcontrols[] = {
880 	{ "Mute",		0 },
881 	{ "Volume",		1 },
882 	{ "Bass",		2 },
883 	{ "Mid",		3 },
884 	{ "Treble",		4 },
885 	{ "Graphic Equalizer",	5 },
886 	{ "Automatic Gain",	6 },
887 	{ "Delay",		7 },
888 	{ "Bass Boost",		8 },
889 	{ "Loudness",		9 },
890 	{ "Input gain",		10 },
891 	{ "Input gain pad",	11 },
892 	{ "Phase inverter",	12 },
893 	{ NULL }
894 };
895 
896 static const struct bmcontrol uac2_input_term_bmcontrols[] = {
897 	{ "Copy Protect",	0 },
898 	{ "Connector",		1 },
899 	{ "Overload",		2 },
900 	{ "Cluster",		3 },
901 	{ "Underflow",		4 },
902 	{ "Overflow",		5 },
903 	{ NULL }
904 };
905 
906 static const struct bmcontrol uac2_output_term_bmcontrols[] = {
907 	{ "Copy Protect",	0 },
908 	{ "Connector",		1 },
909 	{ "Overload",		2 },
910 	{ "Underflow",		3 },
911 	{ "Overflow",		4 },
912 	{ NULL }
913 };
914 
915 static const struct bmcontrol uac2_mixer_unit_bmcontrols[] = {
916 	{ "Cluster",		0 },
917 	{ "Underflow",		1 },
918 	{ "Overflow",		2 },
919 	{ NULL }
920 };
921 
922 static const struct bmcontrol uac2_extension_unit_bmcontrols[] = {
923 	{ "Enable",		0 },
924 	{ "Cluster",		1 },
925 	{ "Underflow",		2 },
926 	{ "Overflow",		3 },
927 	{ NULL }
928 };
929 
930 static const struct bmcontrol uac2_clock_source_bmcontrols[] = {
931 	{ "Clock Frequency",	0 },
932 	{ "Clock Validity",	1 },
933 	{ NULL }
934 };
935 
936 static const struct bmcontrol uac2_clock_selector_bmcontrols[] = {
937 	{ "Clock Selector",	0 },
938 	{ NULL }
939 };
940 
941 static const struct bmcontrol uac2_clock_multiplier_bmcontrols[] = {
942 	{ "Clock Numerator",	0 },
943 	{ "Clock Denominator",	1 },
944 	{ NULL }
945 };
946 
947 static const struct bmcontrol uac2_selector_bmcontrols[] = {
948 	{ "Selector",	0 },
949 	{ NULL }
950 };
951 
dump_audio_bmcontrols(const char * prefix,int bmcontrols,const struct bmcontrol * list,int protocol)952 static void dump_audio_bmcontrols(const char *prefix, int bmcontrols, const struct bmcontrol *list, int protocol)
953 {
954 	while (list->name) {
955 		switch (protocol) {
956 		case USB_AUDIO_CLASS_1:
957 			if (bmcontrols & (1 << list->bit))
958 				printf("%s%s Control\n", prefix, list->name);
959 
960 			break;
961 
962 		case USB_AUDIO_CLASS_2: {
963 			const char *ctrl_type[] = { "read-only", "ILLEGAL (0b10)", "read/write" };
964 			int ctrl = (bmcontrols >> (list->bit * 2)) & 0x3;
965 
966 			if (ctrl)
967 				printf("%s%s Control (%s)\n", prefix, list->name, ctrl_type[ctrl-1]);
968 
969 			break;
970 		}
971 
972 		} /* switch */
973 
974 		list++;
975 	}
976 }
977 
978 static const char *chconfig_uac2[] = {
979 	"Front Left (FL)", "Front Right (FR)", "Front Center (FC)", "Low Frequency Effects (LFE)",
980 	"Back Left (BL)", "Back Right (BR)", "Front Left of Center (FLC)", "Front Right of Center (FRC)", "Back Center (BC)",
981 	"Side Left (SL)", "Side Right (SR)",
982 	"Top Center (TC)", "Top Front Left (TFL)", "Top Front Center (TFC)", "Top Front Right (TFR)", "Top Back Left (TBL)",
983 	"Top Back Center (TBC)", "Top Back Right (TBR)", "Top Front Left of Center (TFLC)", "Top Front Right of Center (TFRC)",
984 	"Left Low Frequency Effects (LLFE)", "Right Low Frequency Effects (RLFE)",
985 	"Top Side Left (TSL)", "Top Side Right (TSR)", "Bottom Center (BC)",
986 	"Back Left of Center (BLC)", "Back Right of Center (BRC)"
987 };
988 
dump_audiocontrol_interface(struct usb_dev_handle * dev,unsigned char * buf,int protocol)989 static void dump_audiocontrol_interface(struct usb_dev_handle *dev, unsigned char *buf, int protocol)
990 {
991 	static const char *chconfig[] = {
992 		"Left Front (L)", "Right Front (R)", "Center Front (C)", "Low Freqency Enhancement (LFE)",
993 		"Left Surround (LS)", "Right Surround (RS)", "Left of Center (LC)", "Right of Center (RC)",
994 		"Surround (S)", "Side Left (SL)", "Side Right (SR)", "Top (T)"
995 	};
996 	static const char *clock_source_attrs[] = {
997 		"External", "Internal fixed", "Internal variable", "Internal programmable"
998 	};
999 	unsigned int i, chcfg, j, k, N, termt, subtype;
1000 	char chnames[128], term[128], termts[128];
1001 
1002 	if (buf[1] != USB_DT_CS_INTERFACE)
1003 		printf("      Warning: Invalid descriptor\n");
1004 	else if (buf[0] < 3)
1005 		printf("      Warning: Descriptor too short\n");
1006 	printf("      AudioControl Interface Descriptor:\n"
1007 	       "        bLength             %5u\n"
1008 	       "        bDescriptorType     %5u\n"
1009 	       "        bDescriptorSubtype  %5u ",
1010 	       buf[0], buf[1], buf[2]);
1011 
1012 	/*
1013 	 * This is an utter mess - UAC2 defines some bDescriptorSubtype differently, so we have to do some ugly remapping here:
1014 	 *
1015 	 * bDescriptorSubtype		UAC1			UAC2
1016 	 * ------------------------------------------------------------------------
1017 	 * 0x07				PROCESSING_UNIT		EFFECT_UNIT
1018 	 * 0x08				EXTENSION_UNIT		PROCESSING_UNIT
1019 	 * 0x09				-			EXTENSION_UNIT
1020 	 *
1021 	 */
1022 
1023 	if (protocol == USB_AUDIO_CLASS_2)
1024 		switch(buf[2]) {
1025 		case 0x07: subtype = 0xf0; break; /* effect unit */
1026 		case 0x08: subtype = 0x07; break; /* processing unit */
1027 		case 0x09: subtype = 0x08; break; /* extension unit */
1028 		default: subtype = buf[2]; break; /* everything else is identical */
1029 		}
1030 	else
1031 		subtype = buf[2];
1032 
1033 	switch (subtype) {
1034 	case 0x01:  /* HEADER */
1035 		printf("(HEADER)\n");
1036 		switch (protocol) {
1037 		case USB_AUDIO_CLASS_1:
1038 			if (buf[0] < 8+buf[7])
1039 				printf("      Warning: Descriptor too short\n");
1040 			printf("        bcdADC              %2x.%02x\n"
1041 			       "        wTotalLength        %5u\n"
1042 			       "        bInCollection       %5u\n",
1043 			       buf[4], buf[3], buf[5] | (buf[6] << 8), buf[7]);
1044 			for (i = 0; i < buf[7]; i++)
1045 				printf("        baInterfaceNr(%2u)   %5u\n", i, buf[8+i]);
1046 			dump_junk(buf, "        ", 8+buf[7]);
1047 			break;
1048 		case USB_AUDIO_CLASS_2:
1049 			if (buf[0] < 9)
1050 				printf("      Warning: Descriptor too short\n");
1051 			printf("        bcdADC              %2x.%02x\n"
1052 			       "        bCategory           %5u\n"
1053 			       "        wTotalLength        %5u\n"
1054 			       "        bmControl            0x%02x\n",
1055 			       buf[4], buf[3], buf[5], buf[6] | (buf[7] << 8), buf[8]);
1056 			dump_audio_bmcontrols("          ", buf[8], uac2_interface_header_bmcontrols, protocol);
1057 			break;
1058 		}
1059 		break;
1060 
1061 	case 0x02:  /* INPUT_TERMINAL */
1062 		printf("(INPUT_TERMINAL)\n");
1063 		termt = buf[4] | (buf[5] << 8);
1064 		get_audioterminal_string(termts, sizeof(termts), termt);
1065 
1066 		switch (protocol) {
1067 		case USB_AUDIO_CLASS_1:
1068 			get_string(dev, chnames, sizeof(chnames), buf[10]);
1069 			get_string(dev, term, sizeof(term), buf[11]);
1070 			if (buf[0] < 12)
1071 				printf("      Warning: Descriptor too short\n");
1072 			chcfg = buf[8] | (buf[9] << 8);
1073 			printf("        bTerminalID         %5u\n"
1074 			       "        wTerminalType      0x%04x %s\n"
1075 			       "        bAssocTerminal      %5u\n"
1076 			       "        bNrChannels         %5u\n"
1077 			       "        wChannelConfig     0x%04x\n",
1078 			       buf[3], termt, termts, buf[6], buf[7], chcfg);
1079 			for (i = 0; i < 12; i++)
1080 				if ((chcfg >> i) & 1)
1081 					printf("          %s\n", chconfig[i]);
1082 			printf("        iChannelNames       %5u %s\n"
1083 			       "        iTerminal           %5u %s\n",
1084 			       buf[10], chnames, buf[11], term);
1085 			dump_junk(buf, "        ", 12);
1086 			break;
1087 		case USB_AUDIO_CLASS_2:
1088 			get_string(dev, chnames, sizeof(chnames), buf[13]);
1089 			get_string(dev, term, sizeof(term), buf[16]);
1090 			if (buf[0] < 17)
1091 				printf("      Warning: Descriptor too short\n");
1092 			chcfg = buf[9] | (buf[10] << 8) | (buf[11] << 16) | (buf[12] << 24);
1093 			printf("        bTerminalID         %5u\n"
1094 			       "        wTerminalType      0x%04x %s\n"
1095 			       "        bAssocTerminal      %5u\n"
1096 			       "        bCSourceID          %5d\n"
1097 			       "        bNrChannels         %5u\n"
1098 			       "        bmChannelConfig   0x%08x\n",
1099 			       buf[3], termt, termts, buf[6], buf[7], buf[8], chcfg);
1100 			for (i = 0; i < 26; i++)
1101 				if ((chcfg >> i) & 1)
1102 					printf("          %s\n", chconfig_uac2[i]);
1103 			printf("        bmControls    0x%04x\n", buf[14] | (buf[15] << 8));
1104 			dump_audio_bmcontrols("          ", buf[14] | (buf[15] << 8), uac2_input_term_bmcontrols, protocol);
1105 			printf("        iChannelNames       %5u %s\n"
1106 			       "        iTerminal           %5u %s\n",
1107 			       buf[13], chnames, buf[16], term);
1108 			dump_junk(buf, "        ", 17);
1109 			break;
1110 		} /* switch (protocol) */
1111 
1112 		break;
1113 
1114 	case 0x03:  /* OUTPUT_TERMINAL */
1115 		printf("(OUTPUT_TERMINAL)\n");
1116 		switch (protocol) {
1117 		case USB_AUDIO_CLASS_1:
1118 			get_string(dev, term, sizeof(term), buf[8]);
1119 			termt = buf[4] | (buf[5] << 8);
1120 			get_audioterminal_string(termts, sizeof(termts), termt);
1121 			if (buf[0] < 9)
1122 				printf("      Warning: Descriptor too short\n");
1123 			printf("        bTerminalID         %5u\n"
1124 			       "        wTerminalType      0x%04x %s\n"
1125 			       "        bAssocTerminal      %5u\n"
1126 			       "        bSourceID           %5u\n"
1127 			       "        iTerminal           %5u %s\n",
1128 			       buf[3], termt, termts, buf[6], buf[7], buf[8], term);
1129 			dump_junk(buf, "        ", 9);
1130 			break;
1131 		case USB_AUDIO_CLASS_2:
1132 			get_string(dev, term, sizeof(term), buf[11]);
1133 			termt = buf[4] | (buf[5] << 8);
1134 			get_audioterminal_string(termts, sizeof(termts), termt);
1135 			if (buf[0] < 12)
1136 				printf("      Warning: Descriptor too short\n");
1137 			printf("        bTerminalID         %5u\n"
1138 			       "        wTerminalType      0x%04x %s\n"
1139 			       "        bAssocTerminal      %5u\n"
1140 			       "        bSourceID           %5u\n"
1141 			       "        bCSourceID          %5u\n"
1142 			       "        bmControls         0x%04x\n",
1143 			       buf[3], termt, termts, buf[6], buf[7], buf[8], buf[9] | (buf[10] << 8));
1144 			dump_audio_bmcontrols("          ", buf[9] | (buf[10] << 8), uac2_output_term_bmcontrols, protocol);
1145 			printf("        iTerminal           %5u %s\n", buf[11], term);
1146 			dump_junk(buf, "        ", 12);
1147 			break;
1148 		} /* switch (protocol) */
1149 
1150 		break;
1151 
1152 	case 0x04:  /* MIXER_UNIT */
1153 		printf("(MIXER_UNIT)\n");
1154 
1155 		switch (protocol) {
1156 		case USB_AUDIO_CLASS_1:
1157 			j = buf[4];
1158 			k = buf[j+5];
1159 			if (j == 0 || k == 0) {
1160 				printf("      Warning: mixer with %5u input and %5u output channels.\n", j, k);
1161 				N = 0;
1162 			} else {
1163 				N = 1+(j*k-1)/8;
1164 			}
1165 			get_string(dev, chnames, sizeof(chnames), buf[8+j]);
1166 			get_string(dev, term, sizeof(term), buf[9+j+N]);
1167 			if (buf[0] < 10+j+N)
1168 				printf("      Warning: Descriptor too short\n");
1169 			chcfg = buf[6+j] | (buf[7+j] << 8);
1170 			printf("        bUnitID             %5u\n"
1171 			       "        bNrInPins           %5u\n",
1172 			       buf[3], buf[4]);
1173 			for (i = 0; i < j; i++)
1174 				printf("        baSourceID(%2u)      %5u\n", i, buf[5+i]);
1175 			printf("        bNrChannels         %5u\n"
1176 			       "        wChannelConfig     0x%04x\n",
1177 			       buf[5+j], chcfg);
1178 			for (i = 0; i < 12; i++)
1179 				if ((chcfg >> i) & 1)
1180 					printf("          %s\n", chconfig[i]);
1181 			printf("        iChannelNames       %5u %s\n",
1182 			       buf[8+j], chnames);
1183 			for (i = 0; i < N; i++)
1184 				printf("        bmControls         0x%02x\n", buf[9+j+i]);
1185 			printf("        iMixer              %5u %s\n", buf[9+j+N], term);
1186 			dump_junk(buf, "        ", 10+j+N);
1187 			break;
1188 
1189 		case USB_AUDIO_CLASS_2:
1190 			j = buf[4];
1191 			k = buf[0] - 13 - j;
1192 			get_string(dev, chnames, sizeof(chnames), buf[10+j]);
1193 			get_string(dev, term, sizeof(term), buf[12+j+k]);
1194 			chcfg =  buf[6+j] | (buf[7+j] << 8) | (buf[8+j] << 16) | (buf[9+j] << 24);
1195 
1196 			printf("        bUnitID             %5u\n"
1197 			       "        bNrPins             %5u\n",
1198 			       buf[3], buf[4]);
1199 			for (i = 0; i < j; i++)
1200 				printf("        baSourceID(%2u)      %5u\n", i, buf[5+i]);
1201 			printf("        bNrChannels         %5u\n"
1202 			       "        bmChannelConfig    0x%08x\n", buf[5+j], chcfg);
1203 			for (i = 0; i < 26; i++)
1204 				if ((chcfg >> i) & 1)
1205 					printf("          %s\n", chconfig_uac2[i]);
1206 			printf("        iChannelNames       %5u %s\n", buf[10+j], chnames);
1207 
1208 			N = 0;
1209 			for (i = 0; i < k; i++)
1210 				N |= buf[11+j+i] << (i * 8);
1211 
1212 			dump_bytes(buf+11+j, k);
1213 
1214 			printf("        bmControls         %02x\n", buf[11+j+k]);
1215 			dump_audio_bmcontrols("          ", buf[11+j+k], uac2_mixer_unit_bmcontrols, protocol);
1216 
1217 			printf("        iMixer             %5u %s\n", buf[12+j+k], term);
1218 			dump_junk(buf, "        ", 13+j+k);
1219 			break;
1220 		} /* switch (protocol) */
1221 		break;
1222 
1223 	case 0x05:  /* SELECTOR_UNIT */
1224 		printf("(SELECTOR_UNIT)\n");
1225 		switch (protocol) {
1226 		case USB_AUDIO_CLASS_1:
1227 			if (buf[0] < 6+buf[4])
1228 				printf("      Warning: Descriptor too short\n");
1229 			get_string(dev, term, sizeof(term), buf[5+buf[4]]);
1230 
1231 			printf("        bUnitID             %5u\n"
1232 			       "        bNrInPins           %5u\n",
1233 			       buf[3], buf[4]);
1234 			for (i = 0; i < buf[4]; i++)
1235 				printf("        baSource(%2u)        %5u\n", i, buf[5+i]);
1236 			printf("        iSelector           %5u %s\n",
1237 			       buf[5+buf[4]], term);
1238 			dump_junk(buf, "        ", 6+buf[4]);
1239 			break;
1240 		case USB_AUDIO_CLASS_2:
1241 			if (buf[0] < 7+buf[4])
1242 				printf("      Warning: Descriptor too short\n");
1243 			get_string(dev, term, sizeof(term), buf[6+buf[4]]);
1244 
1245 			printf("        bUnitID             %5u\n"
1246 			       "        bNrInPins           %5u\n",
1247 			       buf[3], buf[4]);
1248 			for (i = 0; i < buf[4]; i++)
1249 				printf("        baSource(%2u)        %5u\n", i, buf[5+i]);
1250 			printf("        bmControls           0x%02x\n", buf[5+buf[4]]);
1251 			dump_audio_bmcontrols("          ", buf[5+buf[4]], uac2_selector_bmcontrols, protocol);
1252 			printf("        iSelector           %5u %s\n",
1253 			       buf[6+buf[4]], term);
1254 			dump_junk(buf, "        ", 7+buf[4]);
1255 			break;
1256 		} /* switch (protocol) */
1257 
1258 		break;
1259 
1260 	case 0x06:  /* FEATURE_UNIT */
1261 		printf("(FEATURE_UNIT)\n");
1262 
1263 		switch (protocol) {
1264 		case USB_AUDIO_CLASS_1:
1265 			j = buf[5];
1266 			if (!j)
1267 				j = 1;
1268 			k = (buf[0] - 7) / j;
1269 			if (buf[0] < 7+buf[5]*k)
1270 				printf("      Warning: Descriptor too short\n");
1271 			get_string(dev, term, sizeof(term), buf[6+buf[5]*k]);
1272 			printf("        bUnitID             %5u\n"
1273 			       "        bSourceID           %5u\n"
1274 			       "        bControlSize        %5u\n",
1275 			       buf[3], buf[4], buf[5]);
1276 			for (i = 0; i < k; i++) {
1277 				chcfg = buf[6+buf[5]*i];
1278 				if (buf[5] > 1)
1279 					chcfg |= (buf[7+buf[5]*i] << 8);
1280 				for (j = 0; j < buf[5]; j++)
1281 					printf("        bmaControls(%2u)      0x%02x\n", i, buf[6+buf[5]*i+j]);
1282 
1283 				dump_audio_bmcontrols("          ", chcfg, uac_fu_bmcontrols, protocol);
1284 			}
1285 			printf("        iFeature            %5u %s\n", buf[6+buf[5]*k], term);
1286 			dump_junk(buf, "        ", 7+buf[5]*k);
1287 			break;
1288 		case USB_AUDIO_CLASS_2:
1289 			if (buf[0] < 10)
1290 				printf("      Warning: Descriptor too short\n");
1291 			k = (buf[0] - 6) / 4;
1292 			printf("        bUnitID             %5u\n"
1293 			       "        bSourceID           %5u\n",
1294 			       buf[3], buf[4]);
1295 			for (i = 0; i < k; i++) {
1296 				chcfg = buf[5+(4*i)] |
1297 					buf[6+(4*i)] << 8 |
1298 					buf[7+(4*i)] << 16 |
1299 					buf[8+(4*i)] << 24;
1300 				printf("        bmaControls(%2u)      0x%08x\n", i, chcfg);
1301 				dump_audio_bmcontrols("          ", chcfg, uac_fu_bmcontrols, protocol);
1302 			}
1303 			get_string(dev, term, sizeof(term), buf[5+(k*4)]);
1304 			printf("        iFeature            %5u %s\n", buf[5+(k*4)], term);
1305 			dump_junk(buf, "        ", 6+(k*4));
1306 			break;
1307 		} /* switch (protocol) */
1308 
1309 		break;
1310 
1311 	case 0x07:  /* PROCESSING_UNIT */
1312 		printf("(PROCESSING_UNIT)\n");
1313 
1314 		switch (protocol) {
1315 		case USB_AUDIO_CLASS_1:
1316 			j = buf[6];
1317 			k = buf[11+j];
1318 			get_string(dev, chnames, sizeof(chnames), buf[10+j]);
1319 			get_string(dev, term, sizeof(term), buf[12+j+k]);
1320 			chcfg = buf[8+j] | (buf[9+j] << 8);
1321 			if (buf[0] < 13+j+k)
1322 				printf("      Warning: Descriptor too short\n");
1323 			printf("        bUnitID             %5u\n"
1324 			       "        wProcessType        %5u\n"
1325 			       "        bNrPins             %5u\n",
1326 			       buf[3], buf[4] | (buf[5] << 8), buf[6]);
1327 			for (i = 0; i < j; i++)
1328 				printf("        baSourceID(%2u)      %5u\n", i, buf[7+i]);
1329 			printf("        bNrChannels         %5u\n"
1330 			       "        wChannelConfig     0x%04x\n", buf[7+j], chcfg);
1331 			for (i = 0; i < 12; i++)
1332 				if ((chcfg >> i) & 1)
1333 					printf("          %s\n", chconfig[i]);
1334 			printf("        iChannelNames       %5u %s\n"
1335 			       "        bControlSize        %5u\n", buf[10+j], chnames, buf[11+j]);
1336 			for (i = 0; i < k; i++)
1337 				printf("        bmControls(%2u)       0x%02x\n", i, buf[12+j+i]);
1338 			if (buf[12+j] & 1)
1339 				printf("          Enable Processing\n");
1340 			printf("        iProcessing         %5u %s\n"
1341 			       "        Process-Specific    ", buf[12+j+k], term);
1342 			dump_bytes(buf+(13+j+k), buf[0]-(13+j+k));
1343 			break;
1344 		case USB_AUDIO_CLASS_2:
1345 			j = buf[6];
1346 			k = buf[0] - 17 - j;
1347 			get_string(dev, chnames, sizeof(chnames), buf[12+j]);
1348 			get_string(dev, term, sizeof(term), buf[15+j+k]);
1349 			chcfg =  buf[8+j] |
1350 				(buf[9+j] << 8) |
1351 				(buf[10+j] << 16) |
1352 				(buf[11+j] << 24);
1353 
1354 			printf("        bUnitID             %5u\n"
1355 			       "        wProcessType        %5u\n"
1356 			       "        bNrPins             %5u\n",
1357 			       buf[3], buf[4] | (buf[5] << 8), buf[6]);
1358 			for (i = 0; i < j; i++)
1359 				printf("        baSourceID(%2u)      %5u\n", i, buf[5+i]);
1360 			printf("        bNrChannels         %5u\n"
1361 			       "        bmChannelConfig    0x%08x\n", buf[7+j], chcfg);
1362 			for (i = 0; i < 26; i++)
1363 				if ((chcfg >> i) & 1)
1364 					printf("          %s\n", chconfig_uac2[i]);
1365 			printf("        iChannelNames       %5u %s\n"
1366 			       "        bmControls        0x%04x\n", buf[12+j], chnames, buf[13+j] | (buf[14+j] << 8));
1367 			if (buf[12+j] & 1)
1368 				printf("          Enable Processing\n");
1369 			printf("        iProcessing         %5u %s\n"
1370 			       "        Process-Specific    ", buf[15+j], term);
1371 			dump_bytes(buf+(16+j), k);
1372 			break;
1373 		} /* switch (protocol) */
1374 
1375 		break;
1376 
1377 	case 0x08:  /* EXTENSION_UNIT */
1378 		printf("(EXTENSION_UNIT)\n");
1379 
1380 		switch (protocol) {
1381 		case USB_AUDIO_CLASS_1:
1382 			j = buf[6];
1383 			k = buf[11+j];
1384 			get_string(dev, chnames, sizeof(chnames), buf[10+j]);
1385 			get_string(dev, term, sizeof(term), buf[12+j+k]);
1386 			chcfg = buf[8+j] | (buf[9+j] << 8);
1387 			if (buf[0] < 13+j+k)
1388 				printf("      Warning: Descriptor too short\n");
1389 			printf("        bUnitID             %5u\n"
1390 			       "        wExtensionCode      %5u\n"
1391 			       "        bNrPins             %5u\n",
1392 			       buf[3], buf[4] | (buf[5] << 8), buf[6]);
1393 			for (i = 0; i < j; i++)
1394 				printf("        baSourceID(%2u)      %5u\n", i, buf[7+i]);
1395 			printf("        bNrChannels         %5u\n"
1396 			       "        wChannelConfig      %5u\n", buf[7+j], chcfg);
1397 			for (i = 0; i < 12; i++)
1398 				if ((chcfg >> i) & 1)
1399 					printf("          %s\n", chconfig[i]);
1400 			printf("        iChannelNames       %5u %s\n"
1401 			       "        bControlSize        %5u\n", buf[10+j], chnames, buf[11+j]);
1402 			for (i = 0; i < k; i++)
1403 				printf("        bmControls(%2u)       0x%02x\n", i, buf[12+j+i]);
1404 			if (buf[12+j] & 1)
1405 				printf("          Enable Processing\n");
1406 			printf("        iExtension          %5u %s\n",
1407 			       buf[12+j+k], term);
1408 			dump_junk(buf, "        ", 13+j+k);
1409 			break;
1410 		case USB_AUDIO_CLASS_2:
1411 			j = buf[6];
1412 			get_string(dev, chnames, sizeof(chnames), buf[13+j]);
1413 			get_string(dev, term, sizeof(term), buf[15+j]);
1414 			chcfg = buf[9+j] | (buf[10+j] << 8) | (buf[11+j] << 16) | (buf[12+j] << 24);
1415 			if (buf[0] < 16+j)
1416 				printf("      Warning: Descriptor too short\n");
1417 			printf("        bUnitID             %5u\n"
1418 			       "        wExtensionCode      %5u\n"
1419 			       "        bNrPins             %5u\n",
1420 			       buf[3], buf[4] | (buf[5] << 8), buf[6]);
1421 			for (i = 0; i < j; i++)
1422 				printf("        baSourceID(%2u)      %5u\n", i, buf[7+i]);
1423 			printf("        bNrChannels         %5u\n"
1424 			       "        wChannelConfig      %5u\n", buf[7+j], chcfg);
1425 			for (i = 0; i < 26; i++)
1426 				if ((chcfg >> i) & 1)
1427 					printf("          %s\n", chconfig[i]);
1428 			printf("        iChannelNames       %5u %s\n"
1429 			       "        bmControls        0x%02x\n", buf[13+j], chnames, buf[14+j]);
1430 			dump_audio_bmcontrols("          ", buf[14+j], uac2_extension_unit_bmcontrols, protocol);
1431 
1432 			printf("        iExtension          %5u %s\n",
1433 			       buf[15+j+k], term);
1434 			dump_junk(buf, "        ", 16+j);
1435 			break;
1436 		} /* switch (protocol) */
1437 
1438 		break;
1439 
1440 	case 0x0a:  /* CLOCK_SOURCE */
1441 		printf ("(CLOCK_SOURCE)\n");
1442 		if (protocol != USB_AUDIO_CLASS_2)
1443 			printf("      Warning: CLOCK_SOURCE descriptors are illegal for UAC1\n");
1444 
1445 		if (buf[0] < 8)
1446 			printf("      Warning: Descriptor too short\n");
1447 
1448 		printf("        bClockID            %5u\n"
1449 		       "        bmAttributes         0x%02x %s Clock %s\n",
1450 		       buf[3], buf[4], clock_source_attrs[buf[4] & 3],
1451 		       (buf[4] & 4) ? "(synced to SOF)" : "");
1452 
1453 		printf("        bmControls           0x%02x\n", buf[5]);
1454 		dump_audio_bmcontrols("          ", buf[5], uac2_clock_source_bmcontrols, protocol);
1455 
1456 		get_string(dev, term, sizeof(term), buf[7]);
1457 		printf("        bAssocTerminal      %5u\n", buf[6]);
1458 		printf("        iClockSource        %5u %s\n", buf[7], term);
1459 		dump_junk(buf, "        ", 8);
1460 		break;
1461 
1462 	case 0x0b:  /* CLOCK_SELECTOR */
1463 		printf("(CLOCK_SELECTOR)\n");
1464 		if (protocol != USB_AUDIO_CLASS_2)
1465 			printf("      Warning: CLOCK_SELECTOR descriptors are illegal for UAC1\n");
1466 
1467 		if (buf[0] < 7+buf[4])
1468 			printf("      Warning: Descriptor too short\n");
1469 		get_string(dev, term, sizeof(term), buf[6+buf[4]]);
1470 
1471 		printf("        bUnitID             %5u\n"
1472 		       "        bNrInPins           %5u\n",
1473 		       buf[3], buf[4]);
1474 		for (i = 0; i < buf[4]; i++)
1475 			printf("        baCSourceID(%2u)     %5u\n", i, buf[5+i]);
1476 		printf("        bmControls           0x%02x\n", buf[5+buf[4]]);
1477 		dump_audio_bmcontrols("          ", buf[5+buf[4]], uac2_clock_selector_bmcontrols, protocol);
1478 
1479 		printf("        iClockSelector      %5u %s\n",
1480 		       buf[6+buf[4]], term);
1481 		dump_junk(buf, "        ", 7+buf[4]);
1482 		break;
1483 
1484 	case 0x0c:  /* CLOCK_MULTIPLIER */
1485 		printf("(CLOCK_MULTIPLIER)\n");
1486 		if (protocol != USB_AUDIO_CLASS_2)
1487 			printf("      Warning: CLOCK_MULTIPLIER descriptors are illegal for UAC1\n");
1488 
1489 		if (buf[0] < 7)
1490 			printf("      Warning: Descriptor too short\n");
1491 
1492 		printf("        bClockID            %5u\n"
1493 		       "        bCSourceID          %5u\n",
1494 		       buf[3], buf[4]);
1495 
1496 		printf("        bmControls           0x%02x\n", buf[5]);
1497 		dump_audio_bmcontrols("          ", buf[5], uac2_clock_multiplier_bmcontrols, protocol);
1498 
1499 		get_string(dev, term, sizeof(term), buf[6]);
1500 		printf("        iClockMultiplier    %5u %s\n", buf[6], term);
1501 		dump_junk(buf, "        ", 7);
1502 		break;
1503 
1504 	case 0x0d:  /* SAMPLE_RATE_CONVERTER_UNIT */
1505 		printf("(SAMPLE_RATE_CONVERTER_UNIT)\n");
1506 		if (protocol != USB_AUDIO_CLASS_2)
1507 			printf("      Warning: SAMPLE_RATE_CONVERTER_UNIT descriptors are illegal for UAC1\n");
1508 
1509 		if (buf[0] < 8)
1510 			printf("      Warning: Descriptor too short\n");
1511 
1512 		get_string(dev, term, sizeof(term), buf[7]);
1513 		printf("        bUnitID             %5u\n"
1514 		       "        bSourceID           %5u\n"
1515 		       "        bCSourceInID        %5u\n"
1516 		       "        bCSourceOutID       %5u\n"
1517 		       "        iSRC                %5u %s\n",
1518 		       buf[3], buf[4], buf[5], buf[6], buf[7], term);
1519 		dump_junk(buf, "        ", 8);
1520 		break;
1521 
1522 	case 0xf0:  /* EFFECT_UNIT - the real value is 0x07, see above for the reason for remapping */
1523 		printf("(EFFECT_UNIT)\n");
1524 
1525 		if (buf[0] < 16)
1526 			printf("      Warning: Descriptor too short\n");
1527 		k = (buf[0] - 16) / 4;
1528 		get_string(dev, term, sizeof(term), buf[15+(k*4)]);
1529 		printf("        bUnitID             %5u\n"
1530 		       "        wEffectType         %5u\n"
1531 		       "        bSourceID           %5u\n",
1532 		       buf[3], buf[4] | (buf[5] << 8), buf[6]);
1533 		for (i = 0; i < k; i++) {
1534 			chcfg = buf[7+(4*i)] |
1535 				buf[8+(4*i)] << 8 |
1536 				buf[9+(4*i)] << 16 |
1537 				buf[10+(4*i)] << 24;
1538 			printf("        bmaControls(%2u)      0x%08x\n", i, chcfg);
1539 			/* TODO: parse effect-specific controls */
1540 		}
1541 		printf("        iEffect             %5u %s\n", buf[15+(k*4)], term);
1542 		dump_junk(buf, "        ", 16+(k*4));
1543 		break;
1544 
1545 	default:
1546 		printf("(unknown)\n"
1547 		       "        Invalid desc subtype:");
1548 		dump_bytes(buf+3, buf[0]-3);
1549 		break;
1550 	}
1551 }
1552 
1553 static const struct bmcontrol uac2_as_interface_bmcontrols[] = {
1554 	{ "Active Alternate Setting",	0 },
1555 	{ "Valid Alternate Setting",	1 },
1556 	{ NULL }
1557 };
1558 
dump_audiostreaming_interface(struct usb_dev_handle * dev,unsigned char * buf,int protocol)1559 static void dump_audiostreaming_interface(struct usb_dev_handle *dev, unsigned char *buf, int protocol)
1560 {
1561 	static const char *fmtItag[] = {
1562 		"TYPE_I_UNDEFINED", "PCM", "PCM8", "IEEE_FLOAT", "ALAW", "MULAW" };
1563 	static const char *fmtIItag[] = { "TYPE_II_UNDEFINED", "MPEG", "AC-3" };
1564 	static const char *fmtIIItag[] = {
1565 		"TYPE_III_UNDEFINED", "IEC1937_AC-3", "IEC1937_MPEG-1_Layer1",
1566 		"IEC1937_MPEG-Layer2/3/NOEXT", "IEC1937_MPEG-2_EXT",
1567 		"IEC1937_MPEG-2_Layer1_LS", "IEC1937_MPEG-2_Layer2/3_LS" };
1568 	unsigned int i, j, fmttag;
1569 	const char *fmtptr = "undefined";
1570 	char name[128];
1571 
1572 	if (buf[1] != USB_DT_CS_INTERFACE)
1573 		printf("      Warning: Invalid descriptor\n");
1574 	else if (buf[0] < 3)
1575 		printf("      Warning: Descriptor too short\n");
1576 	printf("      AudioStreaming Interface Descriptor:\n"
1577 	       "        bLength             %5u\n"
1578 	       "        bDescriptorType     %5u\n"
1579 	       "        bDescriptorSubtype  %5u ",
1580 	       buf[0], buf[1], buf[2]);
1581 	switch (buf[2]) {
1582 	case 0x01: /* AS_GENERAL */
1583 		printf("(AS_GENERAL)\n");
1584 
1585 		switch (protocol) {
1586 		case USB_AUDIO_CLASS_1:
1587 			if (buf[0] < 7)
1588 				printf("      Warning: Descriptor too short\n");
1589 			fmttag = buf[5] | (buf[6] << 8);
1590 			if (fmttag <= 5)
1591 				fmtptr = fmtItag[fmttag];
1592 			else if (fmttag >= 0x1000 && fmttag <= 0x1002)
1593 				fmtptr = fmtIItag[fmttag & 0xfff];
1594 			else if (fmttag >= 0x2000 && fmttag <= 0x2006)
1595 				fmtptr = fmtIIItag[fmttag & 0xfff];
1596 			printf("        bTerminalLink       %5u\n"
1597 			       "        bDelay              %5u frames\n"
1598 			       "        wFormatTag          %5u %s\n",
1599 			       buf[3], buf[4], fmttag, fmtptr);
1600 			dump_junk(buf, "        ", 7);
1601 			break;
1602 		case USB_AUDIO_CLASS_2:
1603 			if (buf[0] < 16)
1604 				printf("      Warning: Descriptor too short\n");
1605 			printf("        bTerminalLink       %5u\n"
1606 			       "        bmControls           0x%02x\n",
1607 			       buf[3], buf[4]);
1608 			dump_audio_bmcontrols("          ", buf[4], uac2_as_interface_bmcontrols, protocol);
1609 
1610 			printf("        bFormatType         %5u\n", buf[5]);
1611 			fmttag = buf[6] | (buf[7] << 8) | (buf[8] << 16) | (buf[9] << 24);
1612 			printf("        bmFormats           %5u\n", fmttag);
1613 			for (i=0; i<5; i++)
1614 				if ((fmttag >> i) & 1)
1615 					printf("          %s\n", fmtItag[i+1]);
1616 
1617 			j = buf[11] | (buf[12] << 8) | (buf[13] << 16) | (buf[14] << 24);
1618 			printf("        bNrChannels         %5u\n"
1619 			       "        bmChannelConfig   0x%08x\n",
1620 			       buf[10], j);
1621 			for (i = 0; i < 26; i++)
1622 				if ((j >> i) & 1)
1623 					printf("          %s\n", chconfig_uac2[i]);
1624 
1625 			get_string(dev, name, sizeof(name), buf[15]);
1626 			printf("        iChannelNames       %5u %s\n", buf[15], name);
1627 			dump_junk(buf, "        ", 16);
1628 			break;
1629 		} /* switch (protocol) */
1630 
1631 		break;
1632 
1633 	case 0x02: /* FORMAT_TYPE */
1634 		printf("(FORMAT_TYPE)\n");
1635 		switch (protocol) {
1636 		case USB_AUDIO_CLASS_1:
1637 			if (buf[0] < 8)
1638 				printf("      Warning: Descriptor too short\n");
1639 			printf("        bFormatType         %5u ", buf[3]);
1640 			switch (buf[3]) {
1641 			case 0x01: /* FORMAT_TYPE_I */
1642 				printf("(FORMAT_TYPE_I)\n");
1643 				j = buf[7] ? (buf[7]*3+8) : 14;
1644 				if (buf[0] < j)
1645 					printf("      Warning: Descriptor too short\n");
1646 				printf("        bNrChannels         %5u\n"
1647 				       "        bSubframeSize       %5u\n"
1648 				       "        bBitResolution      %5u\n"
1649 				       "        bSamFreqType        %5u %s\n",
1650 				       buf[4], buf[5], buf[6], buf[7], buf[7] ? "Discrete" : "Continuous");
1651 				if (!buf[7])
1652 					printf("        tLowerSamFreq     %7u\n"
1653 					       "        tUpperSamFreq     %7u\n",
1654 					       buf[8] | (buf[9] << 8) | (buf[10] << 16), buf[11] | (buf[12] << 8) | (buf[13] << 16));
1655 				else
1656 					for (i = 0; i < buf[7]; i++)
1657 						printf("        tSamFreq[%2u]      %7u\n", i,
1658 						       buf[8+3*i] | (buf[9+3*i] << 8) | (buf[10+3*i] << 16));
1659 				dump_junk(buf, "        ", j);
1660 				break;
1661 
1662 			case 0x02: /* FORMAT_TYPE_II */
1663 				printf("(FORMAT_TYPE_II)\n");
1664 				j = buf[8] ? (buf[7]*3+9) : 15;
1665 				if (buf[0] < j)
1666 					printf("      Warning: Descriptor too short\n");
1667 				printf("        wMaxBitRate         %5u\n"
1668 				       "        wSamplesPerFrame    %5u\n"
1669 				       "        bSamFreqType        %5u %s\n",
1670 				       buf[4] | (buf[5] << 8), buf[6] | (buf[7] << 8), buf[8], buf[8] ? "Discrete" : "Continuous");
1671 				if (!buf[8])
1672 					printf("        tLowerSamFreq     %7u\n"
1673 					       "        tUpperSamFreq     %7u\n",
1674 					       buf[9] | (buf[10] << 8) | (buf[11] << 16), buf[12] | (buf[13] << 8) | (buf[14] << 16));
1675 				else
1676 					for (i = 0; i < buf[8]; i++)
1677 						printf("        tSamFreq[%2u]      %7u\n", i,
1678 						       buf[9+3*i] | (buf[10+3*i] << 8) | (buf[11+3*i] << 16));
1679 				dump_junk(buf, "        ", j);
1680 				break;
1681 
1682 			case 0x03: /* FORMAT_TYPE_III */
1683 				printf("(FORMAT_TYPE_III)\n");
1684 				j = buf[7] ? (buf[7]*3+8) : 14;
1685 				if (buf[0] < j)
1686 					printf("      Warning: Descriptor too short\n");
1687 				printf("        bNrChannels         %5u\n"
1688 				       "        bSubframeSize       %5u\n"
1689 				       "        bBitResolution      %5u\n"
1690 				       "        bSamFreqType        %5u %s\n",
1691 				       buf[4], buf[5], buf[6], buf[7], buf[7] ? "Discrete" : "Continuous");
1692 				if (!buf[7])
1693 					printf("        tLowerSamFreq     %7u\n"
1694 					       "        tUpperSamFreq     %7u\n",
1695 					       buf[8] | (buf[9] << 8) | (buf[10] << 16), buf[11] | (buf[12] << 8) | (buf[13] << 16));
1696 				else
1697 					for (i = 0; i < buf[7]; i++)
1698 						printf("        tSamFreq[%2u]      %7u\n", i,
1699 						       buf[8+3*i] | (buf[9+3*i] << 8) | (buf[10+3*i] << 16));
1700 				dump_junk(buf, "        ", j);
1701 				break;
1702 
1703 			default:
1704 				printf("(unknown)\n"
1705 				       "        Invalid desc format type:");
1706 				dump_bytes(buf+4, buf[0]-4);
1707 			}
1708 
1709 			break;
1710 
1711 		case USB_AUDIO_CLASS_2:
1712 			printf("        bFormatType         %5u ", buf[3]);
1713 			switch (buf[3]) {
1714 			case 0x01: /* FORMAT_TYPE_I */
1715 				printf("(FORMAT_TYPE_I)\n");
1716 				if (buf[0] < 6)
1717 					printf("      Warning: Descriptor too short\n");
1718 				printf("        bSubslotSize        %5u\n"
1719 				       "        bBitResolution      %5u\n",
1720 				       buf[4], buf[5]);
1721 				dump_junk(buf, "        ", 6);
1722 				break;
1723 
1724 			case 0x02: /* FORMAT_TYPE_II */
1725 				printf("(FORMAT_TYPE_II)\n");
1726 				if (buf[0] < 8)
1727 					printf("      Warning: Descriptor too short\n");
1728 				printf("        wMaxBitRate         %5u\n"
1729 				       "        wSlotsPerFrame      %5u\n",
1730 				       buf[4] | (buf[5] << 8),
1731 				       buf[6] | (buf[7] << 8));
1732 				dump_junk(buf, "        ", 8);
1733 				break;
1734 
1735 			case 0x03: /* FORMAT_TYPE_III */
1736 				printf("(FORMAT_TYPE_III)\n");
1737 				if (buf[0] < 6)
1738 					printf("      Warning: Descriptor too short\n");
1739 				printf("        bSubslotSize        %5u\n"
1740 				       "        bBitResolution      %5u\n",
1741 				       buf[4], buf[5]);
1742 				dump_junk(buf, "        ", 6);
1743 				break;
1744 
1745 			case 0x04: /* FORMAT_TYPE_IV */
1746 				printf("(FORMAT_TYPE_IV)\n");
1747 				if (buf[0] < 4)
1748 					printf("      Warning: Descriptor too short\n");
1749 				printf("        bFormatType         %5u\n", buf[3]);
1750 				dump_junk(buf, "        ", 4);
1751 				break;
1752 
1753 			default:
1754 				printf("(unknown)\n"
1755 				       "        Invalid desc format type:");
1756 				dump_bytes(buf+4, buf[0]-4);
1757 			}
1758 
1759 			break;
1760 		} /* switch (protocol) */
1761 
1762 		break;
1763 
1764 	case 0x03: /* FORMAT_SPECIFIC */
1765 		printf("(FORMAT_SPECIFIC)\n");
1766 		if (buf[0] < 5)
1767 			printf("      Warning: Descriptor too short\n");
1768 		fmttag = buf[3] | (buf[4] << 8);
1769 		if (fmttag <= 5)
1770 			fmtptr = fmtItag[fmttag];
1771 		else if (fmttag >= 0x1000 && fmttag <= 0x1002)
1772 			fmtptr = fmtIItag[fmttag & 0xfff];
1773 		else if (fmttag >= 0x2000 && fmttag <= 0x2006)
1774 			fmtptr = fmtIIItag[fmttag & 0xfff];
1775 		printf("        wFormatTag          %5u %s\n", fmttag, fmtptr);
1776 		switch (fmttag) {
1777 		case 0x1001: /* MPEG */
1778 			if (buf[0] < 8)
1779 				printf("      Warning: Descriptor too short\n");
1780 			printf("        bmMPEGCapabilities 0x%04x\n",
1781 			       buf[5] | (buf[6] << 8));
1782 			if (buf[5] & 0x01)
1783 				printf("          Layer I\n");
1784 			if (buf[5] & 0x02)
1785 				printf("          Layer II\n");
1786 			if (buf[5] & 0x04)
1787 				printf("          Layer III\n");
1788 			if (buf[5] & 0x08)
1789 				printf("          MPEG-1 only\n");
1790 			if (buf[5] & 0x10)
1791 				printf("          MPEG-1 dual-channel\n");
1792 			if (buf[5] & 0x20)
1793 				printf("          MPEG-2 second stereo\n");
1794 			if (buf[5] & 0x40)
1795 				printf("          MPEG-2 7.1 channel augmentation\n");
1796 			if (buf[5] & 0x80)
1797 				printf("          Adaptive multi-channel prediction\n");
1798 			printf("          MPEG-2 multilingual support: ");
1799 			switch (buf[6] & 3) {
1800 			case 0:
1801 				printf("Not supported\n");
1802 				break;
1803 
1804 			case 1:
1805 				printf("Supported at Fs\n");
1806 				break;
1807 
1808 			case 2:
1809 				printf("Reserved\n");
1810 				break;
1811 
1812 			default:
1813 				printf("Supported at Fs and 1/2Fs\n");
1814 				break;
1815 			}
1816 			printf("        bmMPEGFeatures       0x%02x\n", buf[7]);
1817 			printf("          Internal Dynamic Range Control: ");
1818 			switch ((buf[7] << 4) & 3) {
1819 			case 0:
1820 				printf("not supported\n");
1821 				break;
1822 
1823 			case 1:
1824 				printf("supported but not scalable\n");
1825 				break;
1826 
1827 			case 2:
1828 				printf("scalable, common boost and cut scaling value\n");
1829 				break;
1830 
1831 			default:
1832 				printf("scalable, separate boost and cut scaling value\n");
1833 				break;
1834 			}
1835 			dump_junk(buf, "        ", 8);
1836 			break;
1837 
1838 		case 0x1002: /* AC-3 */
1839 			if (buf[0] < 10)
1840 				printf("      Warning: Descriptor too short\n");
1841 			printf("        bmBSID         0x%08x\n"
1842 			       "        bmAC3Features        0x%02x\n",
1843 			       buf[5] | (buf[6] << 8) | (buf[7] << 16) | (buf[8] << 24), buf[9]);
1844 			if (buf[9] & 0x01)
1845 				printf("          RF mode\n");
1846 			if (buf[9] & 0x02)
1847 				printf("          Line mode\n");
1848 			if (buf[9] & 0x04)
1849 				printf("          Custom0 mode\n");
1850 			if (buf[9] & 0x08)
1851 				printf("          Custom1 mode\n");
1852 			printf("          Internal Dynamic Range Control: ");
1853 			switch ((buf[9] >> 4) & 3) {
1854 			case 0:
1855 				printf("not supported\n");
1856 				break;
1857 
1858 			case 1:
1859 				printf("supported but not scalable\n");
1860 				break;
1861 
1862 			case 2:
1863 				printf("scalable, common boost and cut scaling value\n");
1864 				break;
1865 
1866 			default:
1867 				printf("scalable, separate boost and cut scaling value\n");
1868 				break;
1869 			}
1870 			dump_junk(buf, "        ", 8);
1871 			break;
1872 
1873 		default:
1874 			printf("(unknown)\n"
1875 			       "        Invalid desc format type:");
1876 			dump_bytes(buf+4, buf[0]-4);
1877 		}
1878 		break;
1879 
1880 	default:
1881 		printf("        Invalid desc subtype:");
1882 		dump_bytes(buf+3, buf[0]-3);
1883 		break;
1884 	}
1885 }
1886 
1887 static const struct bmcontrol uac2_audio_endpoint_bmcontrols[] = {
1888 	{ "Pitch",		0 },
1889 	{ "Data Overrun",	1 },
1890 	{ "Data Underrun",	2 },
1891 	{ NULL }
1892 };
1893 
dump_audiostreaming_endpoint(unsigned char * buf,int protocol)1894 static void dump_audiostreaming_endpoint(unsigned char *buf, int protocol)
1895 {
1896 	static const char *lockdelunits[] = { "Undefined", "Milliseconds", "Decoded PCM samples", "Reserved" };
1897 	unsigned int lckdelidx;
1898 
1899 	if (buf[1] != USB_DT_CS_ENDPOINT)
1900 		printf("      Warning: Invalid descriptor\n");
1901 	else if (buf[0] < ((protocol == USB_AUDIO_CLASS_1) ? 7 : 8))
1902 		printf("      Warning: Descriptor too short\n");
1903 	printf("        AudioControl Endpoint Descriptor:\n"
1904 	       "          bLength             %5u\n"
1905 	       "          bDescriptorType     %5u\n"
1906 	       "          bDescriptorSubtype  %5u (%s)\n"
1907 	       "          bmAttributes         0x%02x\n",
1908 	       buf[0], buf[1], buf[2], buf[2] == 1 ? "EP_GENERAL" : "invalid", buf[3]);
1909 
1910 	switch (protocol) {
1911 	case USB_AUDIO_CLASS_1:
1912 		if (buf[3] & 1)
1913 			printf("            Sampling Frequency\n");
1914 		if (buf[3] & 2)
1915 			printf("            Pitch\n");
1916 		if (buf[3] & 128)
1917 			printf("            MaxPacketsOnly\n");
1918 		lckdelidx = buf[4];
1919 		if (lckdelidx > 3)
1920 			lckdelidx = 3;
1921 		printf("          bLockDelayUnits     %5u %s\n"
1922 		       "          wLockDelay          %5u %s\n",
1923 		       buf[4], lockdelunits[lckdelidx], buf[5] | (buf[6] << 8), lockdelunits[lckdelidx]);
1924 		dump_junk(buf, "        ", 7);
1925 		break;
1926 
1927 	case USB_AUDIO_CLASS_2:
1928 		if (buf[3] & 128)
1929 			printf("            MaxPacketsOnly\n");
1930 
1931 		printf("          bmControls           0x%02x\n", buf[4]);
1932 		dump_audio_bmcontrols("          ", buf[4], uac2_audio_endpoint_bmcontrols, protocol);
1933 
1934 		lckdelidx = buf[5];
1935 		if (lckdelidx > 3)
1936 			lckdelidx = 3;
1937 		printf("          bLockDelayUnits     %5u %s\n"
1938 		       "          wLockDelay          %5u\n",
1939 		       buf[5], lockdelunits[lckdelidx], buf[6] | (buf[7] << 8));
1940 		dump_junk(buf, "        ", 8);
1941 		break;
1942 	} /* switch protocol */
1943 }
1944 
dump_midistreaming_interface(struct usb_dev_handle * dev,unsigned char * buf)1945 static void dump_midistreaming_interface(struct usb_dev_handle *dev, unsigned char *buf)
1946 {
1947 	static const char *jacktypes[] = {"Undefined", "Embedded", "External"};
1948 	char jackstr[128];
1949 	unsigned int j, tlength, capssize;
1950 	unsigned long caps;
1951 
1952 	if (buf[1] != USB_DT_CS_INTERFACE)
1953 		printf("      Warning: Invalid descriptor\n");
1954 	else if (buf[0] < 3)
1955 		printf("      Warning: Descriptor too short\n");
1956 	printf("      MIDIStreaming Interface Descriptor:\n"
1957 	       "        bLength             %5u\n"
1958 	       "        bDescriptorType     %5u\n"
1959 	       "        bDescriptorSubtype  %5u ",
1960 	       buf[0], buf[1], buf[2]);
1961 	switch (buf[2]) {
1962 	case 0x01:
1963 		printf("(HEADER)\n");
1964 		if (buf[0] < 7)
1965 			printf("      Warning: Descriptor too short\n");
1966 		tlength = buf[5] | (buf[6] << 8);
1967 		printf("        bcdADC              %2x.%02x\n"
1968 		       "        wTotalLength        %5u\n",
1969 		       buf[4], buf[3], tlength);
1970 		dump_junk(buf, "        ", 7);
1971 		break;
1972 
1973 	case 0x02:
1974 		printf("(MIDI_IN_JACK)\n");
1975 		if (buf[0] < 6)
1976 			printf("      Warning: Descriptor too short\n");
1977 		get_string(dev, jackstr, sizeof(jackstr), buf[5]);
1978 		printf("        bJackType           %5u %s\n"
1979 		       "        bJackID             %5u\n"
1980 		       "        iJack               %5u %s\n",
1981 		       buf[3], buf[3] < 3 ? jacktypes[buf[3]] : "Invalid",
1982 		       buf[4], buf[5], jackstr);
1983 		dump_junk(buf, "        ", 6);
1984 		break;
1985 
1986 	case 0x03:
1987 		printf("(MIDI_OUT_JACK)\n");
1988 		if (buf[0] < 9)
1989 			printf("      Warning: Descriptor too short\n");
1990 		printf("        bJackType           %5u %s\n"
1991 		       "        bJackID             %5u\n"
1992 		       "        bNrInputPins        %5u\n",
1993 		       buf[3], buf[3] < 3 ? jacktypes[buf[3]] : "Invalid",
1994 		       buf[4], buf[5]);
1995 		for (j = 0; j < buf[5]; j++) {
1996 			printf("        baSourceID(%2u)      %5u\n"
1997 			       "        BaSourcePin(%2u)     %5u\n",
1998 			       j, buf[2*j+6], j, buf[2*j+7]);
1999 		}
2000 		j = 6+buf[5]*2; /* midi10.pdf says, incorrectly: 5+2*p */
2001 		get_string(dev, jackstr, sizeof(jackstr), buf[j]);
2002 		printf("        iJack               %5u %s\n",
2003 		       buf[j], jackstr);
2004 		dump_junk(buf, "        ", j+1);
2005 		break;
2006 
2007 	case 0x04:
2008 		printf("(ELEMENT)\n");
2009 		if (buf[0] < 12)
2010 			printf("      Warning: Descriptor too short\n");
2011 		printf("        bElementID          %5u\n"
2012 		       "        bNrInputPins        %5u\n",
2013 		       buf[3], buf[4]);
2014 		for (j = 0; j < buf[4]; j++) {
2015 			printf("        baSourceID(%2u)      %5u\n"
2016 			       "        BaSourcePin(%2u)     %5u\n",
2017 			       j, buf[2*j+5], j, buf[2*j+6]);
2018 		}
2019 		j = 5+buf[4]*2;
2020 		printf("        bNrOutputPins       %5u\n"
2021 		       "        bInTerminalLink     %5u\n"
2022 		       "        bOutTerminalLink    %5u\n"
2023 		       "        bElCapsSize         %5u\n",
2024 		       buf[j], buf[j+1], buf[j+2], buf[j+3]);
2025 		capssize = buf[j+3];
2026 		caps = 0;
2027 		for (j = 0; j < capssize; j++)
2028 			caps |= (buf[j+9+buf[4]*2] << (8*j));
2029 		printf("        bmElementCaps  0x%08lx\n", caps);
2030 		if (caps & 0x01)
2031 			printf("          Undefined\n");
2032 		if (caps & 0x02)
2033 			printf("          MIDI Clock\n");
2034 		if (caps & 0x04)
2035 			printf("          MTC (MIDI Time Code)\n");
2036 		if (caps & 0x08)
2037 			printf("          MMC (MIDI Machine Control)\n");
2038 		if (caps & 0x10)
2039 			printf("          GM1 (General MIDI v.1)\n");
2040 		if (caps & 0x20)
2041 			printf("          GM2 (General MIDI v.2)\n");
2042 		if (caps & 0x40)
2043 			printf("          GS MIDI Extension\n");
2044 		if (caps & 0x80)
2045 			printf("          XG MIDI Extension\n");
2046 		if (caps & 0x100)
2047 			printf("          EFX\n");
2048 		if (caps & 0x200)
2049 			printf("          MIDI Patch Bay\n");
2050 		if (caps & 0x400)
2051 			printf("          DLS1 (Downloadable Sounds Level 1)\n");
2052 		if (caps & 0x800)
2053 			printf("          DLS2 (Downloadable Sounds Level 2)\n");
2054 		j = 9+2*buf[4]+capssize;
2055 		get_string(dev, jackstr, sizeof(jackstr), buf[j]);
2056 		printf("        iElement            %5u %s\n", buf[j], jackstr);
2057 		dump_junk(buf, "        ", j+1);
2058 		break;
2059 
2060 	default:
2061 		printf("\n        Invalid desc subtype: ");
2062 		dump_bytes(buf+3, buf[0]-3);
2063 		break;
2064 	}
2065 }
2066 
dump_midistreaming_endpoint(unsigned char * buf)2067 static void dump_midistreaming_endpoint(unsigned char *buf)
2068 {
2069 	unsigned int j;
2070 
2071 	if (buf[1] != USB_DT_CS_ENDPOINT)
2072 		printf("      Warning: Invalid descriptor\n");
2073 	else if (buf[0] < 5)
2074 		printf("      Warning: Descriptor too short\n");
2075 	printf("        MIDIStreaming Endpoint Descriptor:\n"
2076 	       "          bLength             %5u\n"
2077 	       "          bDescriptorType     %5u\n"
2078 	       "          bDescriptorSubtype  %5u (%s)\n"
2079 	       "          bNumEmbMIDIJack     %5u\n",
2080 	       buf[0], buf[1], buf[2], buf[2] == 1 ? "GENERAL" : "Invalid", buf[3]);
2081 	for (j = 0; j < buf[3]; j++)
2082 		printf("          baAssocJackID(%2u)   %5u\n", j, buf[4+j]);
2083 	dump_junk(buf, "          ", 4+buf[3]);
2084 }
2085 
2086 /*
2087  * Video Class descriptor dump
2088  */
2089 
dump_videocontrol_interface(struct usb_dev_handle * dev,unsigned char * buf)2090 static void dump_videocontrol_interface(struct usb_dev_handle *dev, unsigned char *buf)
2091 {
2092 	static const char *ctrlnames[] = {
2093 		"Brightness", "Contrast", "Hue", "Saturation", "Sharpness", "Gamma",
2094 		"White Balance Temperature", "White Balance Component", "Backlight Compensation",
2095 		"Gain", "Power Line Frequency", "Hue, Auto", "White Balance Temperature, Auto",
2096 		"White Balance Component, Auto", "Digital Multiplier", "Digital Multiplier Limit",
2097 		"Analog Video Standard", "Analog Video Lock Status"
2098 	};
2099 	static const char *camctrlnames[] = {
2100 		"Scanning Mode", "Auto-Exposure Mode", "Auto-Exposure Priority",
2101 		"Exposure Time (Absolute)", "Exposure Time (Relative)", "Focus (Absolute)",
2102 		"Focus (Relative)", "Iris (Absolute)", "Iris (Relative)", "Zoom (Absolute)",
2103 		"Zoom (Relative)", "PanTilt (Absolute)", "PanTilt (Relative)",
2104 		"Roll (Absolute)", "Roll (Relative)", "Reserved", "Reserved", "Focus, Auto",
2105 		"Privacy"
2106 	};
2107 	static const char *stdnames[] = {
2108 		"None", "NTSC - 525/60", "PAL - 625/50", "SECAM - 625/50",
2109 		"NTSC - 625/50", "PAL - 525/60" };
2110 	unsigned int i, ctrls, stds, n, p, termt, freq;
2111 	char term[128], termts[128];
2112 
2113 	if (buf[1] != USB_DT_CS_INTERFACE)
2114 		printf("      Warning: Invalid descriptor\n");
2115 	else if (buf[0] < 3)
2116 		printf("      Warning: Descriptor too short\n");
2117 	printf("      VideoControl Interface Descriptor:\n"
2118 	       "        bLength             %5u\n"
2119 	       "        bDescriptorType     %5u\n"
2120 	       "        bDescriptorSubtype  %5u ",
2121 	       buf[0], buf[1], buf[2]);
2122 	switch (buf[2]) {
2123 	case 0x01:  /* HEADER */
2124 		printf("(HEADER)\n");
2125 		n = buf[11];
2126 		if (buf[0] < 12+n)
2127 			printf("      Warning: Descriptor too short\n");
2128 		freq = buf[7] | (buf[8] << 8) | (buf[9] << 16) | (buf[10] << 24);
2129 		printf("        bcdUVC              %2x.%02x\n"
2130 		       "        wTotalLength        %5u\n"
2131 		       "        dwClockFrequency    %5u.%06uMHz\n"
2132 		       "        bInCollection       %5u\n",
2133 		       buf[4], buf[3], buf[5] | (buf[6] << 8), freq / 1000000,
2134 		       freq % 1000000, n);
2135 		for (i = 0; i < n; i++)
2136 			printf("        baInterfaceNr(%2u)   %5u\n", i, buf[12+i]);
2137 		dump_junk(buf, "        ", 12+n);
2138 		break;
2139 
2140 	case 0x02:  /* INPUT_TERMINAL */
2141 		printf("(INPUT_TERMINAL)\n");
2142 		get_string(dev, term, sizeof(term), buf[7]);
2143 		termt = buf[4] | (buf[5] << 8);
2144 		n = termt == 0x0201 ? 7 : 0;
2145 		get_videoterminal_string(termts, sizeof(termts), termt);
2146 		if (buf[0] < 8 + n)
2147 			printf("      Warning: Descriptor too short\n");
2148 		printf("        bTerminalID         %5u\n"
2149 		       "        wTerminalType      0x%04x %s\n"
2150 		       "        bAssocTerminal      %5u\n",
2151 		       buf[3], termt, termts, buf[6]);
2152 		printf("        iTerminal           %5u %s\n",
2153 		       buf[7], term);
2154 		if (termt == 0x0201) {
2155 			n += buf[14];
2156 			printf("        wObjectiveFocalLengthMin  %5u\n"
2157 			       "        wObjectiveFocalLengthMax  %5u\n"
2158 			       "        wOcularFocalLength        %5u\n"
2159 			       "        bControlSize              %5u\n",
2160 			       buf[8] | (buf[9] << 8), buf[10] | (buf[11] << 8),
2161 			       buf[12] | (buf[13] << 8), buf[14]);
2162 			ctrls = 0;
2163 			for (i = 0; i < 3 && i < buf[14]; i++)
2164 				ctrls = (ctrls << 8) | buf[8+n-i-1];
2165 			printf("        bmControls           0x%08x\n", ctrls);
2166 			for (i = 0; i < 19; i++)
2167 				if ((ctrls >> i) & 1)
2168 					printf("          %s\n", camctrlnames[i]);
2169 		}
2170 		dump_junk(buf, "        ", 8+n);
2171 		break;
2172 
2173 	case 0x03:  /* OUTPUT_TERMINAL */
2174 		printf("(OUTPUT_TERMINAL)\n");
2175 		get_string(dev, term, sizeof(term), buf[8]);
2176 		termt = buf[4] | (buf[5] << 8);
2177 		get_audioterminal_string(termts, sizeof(termts), termt);
2178 		if (buf[0] < 9)
2179 			printf("      Warning: Descriptor too short\n");
2180 		printf("        bTerminalID         %5u\n"
2181 		       "        wTerminalType      0x%04x %s\n"
2182 		       "        bAssocTerminal      %5u\n"
2183 		       "        bSourceID           %5u\n"
2184 		       "        iTerminal           %5u %s\n",
2185 		       buf[3], termt, termts, buf[6], buf[7], buf[8], term);
2186 		dump_junk(buf, "        ", 9);
2187 		break;
2188 
2189 	case 0x04:  /* SELECTOR_UNIT */
2190 		printf("(SELECTOR_UNIT)\n");
2191 		p = buf[4];
2192 		if (buf[0] < 6+p)
2193 			printf("      Warning: Descriptor too short\n");
2194 		get_string(dev, term, sizeof(term), buf[5+p]);
2195 
2196 		printf("        bUnitID             %5u\n"
2197 		       "        bNrInPins           %5u\n",
2198 		       buf[3], p);
2199 		for (i = 0; i < p; i++)
2200 			printf("        baSource(%2u)        %5u\n", i, buf[5+i]);
2201 		printf("        iSelector           %5u %s\n",
2202 		       buf[5+p], term);
2203 		dump_junk(buf, "        ", 6+p);
2204 		break;
2205 
2206 	case 0x05:  /* PROCESSING_UNIT */
2207 		printf("(PROCESSING_UNIT)\n");
2208 		n = buf[7];
2209 		get_string(dev, term, sizeof(term), buf[8+n]);
2210 		if (buf[0] < 10+n)
2211 			printf("      Warning: Descriptor too short\n");
2212 		printf("        bUnitID             %5u\n"
2213 		       "        bSourceID           %5u\n"
2214 		       "        wMaxMultiplier      %5u\n"
2215 		       "        bControlSize        %5u\n",
2216 		       buf[3], buf[4], buf[5] | (buf[6] << 8), n);
2217 		ctrls = 0;
2218 		for (i = 0; i < 3 && i < n; i++)
2219 			ctrls = (ctrls << 8) | buf[8+n-i-1];
2220 		printf("        bmControls     0x%08x\n", ctrls);
2221 		for (i = 0; i < 18; i++)
2222 			if ((ctrls >> i) & 1)
2223 				printf("          %s\n", ctrlnames[i]);
2224 		stds = buf[9+n];
2225 		printf("        iProcessing         %5u %s\n"
2226 		       "        bmVideoStandards     0x%2x\n", buf[8+n], term, stds);
2227 		for (i = 0; i < 6; i++)
2228 			if ((stds >> i) & 1)
2229 				printf("          %s\n", stdnames[i]);
2230 		break;
2231 
2232 	case 0x06:  /* EXTENSION_UNIT */
2233 		printf("(EXTENSION_UNIT)\n");
2234 		p = buf[21];
2235 		n = buf[22+p];
2236 		get_string(dev, term, sizeof(term), buf[23+p+n]);
2237 		if (buf[0] < 24+p+n)
2238 			printf("      Warning: Descriptor too short\n");
2239 		printf("        bUnitID             %5u\n"
2240 		       "        guidExtensionCode         %s\n"
2241 		       "        bNumControl         %5u\n"
2242 		       "        bNrPins             %5u\n",
2243 		       buf[3], get_guid(&buf[4]), buf[20], buf[21]);
2244 		for (i = 0; i < p; i++)
2245 			printf("        baSourceID(%2u)      %5u\n", i, buf[22+i]);
2246 		printf("        bControlSize        %5u\n", buf[22+p]);
2247 		for (i = 0; i < n; i++)
2248 			printf("        bmControls(%2u)       0x%02x\n", i, buf[23+p+i]);
2249 		printf("        iExtension          %5u %s\n",
2250 		       buf[23+p+n], term);
2251 		dump_junk(buf, "        ", 24+p+n);
2252 		break;
2253 
2254 	default:
2255 		printf("(unknown)\n"
2256 		       "        Invalid desc subtype:");
2257 		dump_bytes(buf+3, buf[0]-3);
2258 		break;
2259 	}
2260 }
2261 
dump_videostreaming_interface(unsigned char * buf)2262 static void dump_videostreaming_interface(unsigned char *buf)
2263 {
2264 	static const char *colorPrims[] = { "Unspecified", "BT.709,sRGB",
2265 		"BT.470-2 (M)", "BT.470-2 (B,G)", "SMPTE 170M", "SMPTE 240M" };
2266 	static const char *transferChars[] = { "Unspecified", "BT.709",
2267 		"BT.470-2 (M)", "BT.470-2 (B,G)", "SMPTE 170M", "SMPTE 240M",
2268 		"Linear", "sRGB"};
2269 	static const char *matrixCoeffs[] = { "Unspecified", "BT.709",
2270 		"FCC", "BT.470-2 (B,G)", "SMPTE 170M (BT.601)", "SMPTE 240M" };
2271 	unsigned int i, m, n, p, flags, len;
2272 
2273 	if (buf[1] != USB_DT_CS_INTERFACE)
2274 		printf("      Warning: Invalid descriptor\n");
2275 	else if (buf[0] < 3)
2276 		printf("      Warning: Descriptor too short\n");
2277 	printf("      VideoStreaming Interface Descriptor:\n"
2278 	       "        bLength                         %5u\n"
2279 	       "        bDescriptorType                 %5u\n"
2280 	       "        bDescriptorSubtype              %5u ",
2281 	       buf[0], buf[1], buf[2]);
2282 	switch (buf[2]) {
2283 	case 0x01: /* INPUT_HEADER */
2284 		printf("(INPUT_HEADER)\n");
2285 		p = buf[3];
2286 		n = buf[12];
2287 		if (buf[0] < 13+p*n)
2288 			printf("      Warning: Descriptor too short\n");
2289 		printf("        bNumFormats                     %5u\n"
2290 		       "        wTotalLength                    %5u\n"
2291 		       "        bEndPointAddress                %5u\n"
2292 		       "        bmInfo                          %5u\n"
2293 		       "        bTerminalLink                   %5u\n"
2294 		       "        bStillCaptureMethod             %5u\n"
2295 		       "        bTriggerSupport                 %5u\n"
2296 		       "        bTriggerUsage                   %5u\n"
2297 		       "        bControlSize                    %5u\n",
2298 		       p, buf[4] | (buf[5] << 8), buf[6], buf[7], buf[8],
2299 		       buf[9], buf[10], buf[11], n);
2300 		for (i = 0; i < p; i++)
2301 			printf(
2302 			"        bmaControls(%2u)                 %5u\n",
2303 				i, buf[13+p*n]);
2304 		dump_junk(buf, "        ", 13+p*n);
2305 		break;
2306 
2307 	case 0x02: /* OUTPUT_HEADER */
2308 		printf("(OUTPUT_HEADER)\n");
2309 		p = buf[3];
2310 		n = buf[8];
2311 		if (buf[0] < 9+p*n)
2312 			printf("      Warning: Descriptor too short\n");
2313 		printf("        bNumFormats                 %5u\n"
2314 		       "        wTotalLength                %5u\n"
2315 		       "        bEndpointAddress            %5u\n"
2316 		       "        bTerminalLink               %5u\n"
2317 		       "        bControlSize                %5u\n",
2318 		       p, buf[4] | (buf[5] << 8), buf[6], buf[7], n);
2319 		for (i = 0; i < p; i++)
2320 			printf(
2321 			"        bmaControls(%2u)             %5u\n",
2322 				i, buf[9+p*n]);
2323 		dump_junk(buf, "        ", 9+p*n);
2324 		break;
2325 
2326 	case 0x03: /* STILL_IMAGE_FRAME */
2327 		printf("(STILL_IMAGE_FRAME)\n");
2328 		n = buf[4];
2329 		m = buf[5+4*n];
2330 		if (buf[0] < 6+4*n+m)
2331 			printf("      Warning: Descriptor too short\n");
2332 		printf("        bEndpointAddress                %5u\n"
2333 		       "        bNumImageSizePatterns             %3u\n",
2334 		       buf[3], n);
2335 		for (i = 0; i < n; i++)
2336 			printf("        wWidth(%2u)                      %5u\n"
2337 			       "        wHeight(%2u)                     %5u\n",
2338 			       i, buf[5+4*i] | (buf[6+4*i] << 8),
2339 			       i, buf[7+4*i] | (buf[8+4*i] << 8));
2340 		printf("        bNumCompressionPatterns           %3u\n", n);
2341 		for (i = 0; i < m; i++)
2342 			printf("        bCompression(%2u)                %5u\n",
2343 			       i, buf[6+4*n+i]);
2344 		dump_junk(buf, "        ", 6+4*n+m);
2345 		break;
2346 
2347 	case 0x04: /* FORMAT_UNCOMPRESSED */
2348 		printf("(FORMAT_UNCOMPRESSED)\n");
2349 		if (buf[0] < 27)
2350 			printf("      Warning: Descriptor too short\n");
2351 		flags = buf[25];
2352 		printf("        bFormatIndex                    %5u\n"
2353 		       "        bNumFrameDescriptors            %5u\n"
2354 		       "        guidFormat                            %s\n"
2355 		       "        bBitsPerPixel                   %5u\n"
2356 		       "        bDefaultFrameIndex              %5u\n"
2357 		       "        bAspectRatioX                   %5u\n"
2358 		       "        bAspectRatioY                   %5u\n"
2359 		       "        bmInterlaceFlags                 0x%02x\n",
2360 		       buf[3], buf[4], get_guid(&buf[5]), buf[21], buf[22],
2361 		       buf[23], buf[24], flags);
2362 		printf("          Interlaced stream or variable: %s\n",
2363 		       (flags & (1 << 0)) ? "Yes" : "No");
2364 		printf("          Fields per frame: %u fields\n",
2365 		       (flags & (1 << 1)) ? 1 : 2);
2366 		printf("          Field 1 first: %s\n",
2367 		       (flags & (1 << 2)) ? "Yes" : "No");
2368 		printf("          Field pattern: ");
2369 		switch ((flags >> 4) & 0x03) {
2370 		case 0:
2371 			printf("Field 1 only\n");
2372 			break;
2373 		case 1:
2374 			printf("Field 2 only\n");
2375 			break;
2376 		case 2:
2377 			printf("Regular pattern of fields 1 and 2\n");
2378 			break;
2379 		case 3:
2380 			printf("Random pattern of fields 1 and 2\n");
2381 			break;
2382 		}
2383 		printf("          bCopyProtect                  %5u\n", buf[26]);
2384 		dump_junk(buf, "        ", 27);
2385 		break;
2386 
2387 	case 0x05: /* FRAME UNCOMPRESSED */
2388 	case 0x07: /* FRAME_MJPEG */
2389 		if (buf[2] == 0x05)
2390 			printf("(FRAME_UNCOMPRESSED)\n");
2391 		else
2392 			printf("(FRAME_MJPEG)\n");
2393 		len = (buf[25] != 0) ? (26+buf[25]*4) : 38;
2394 		if (buf[0] < len)
2395 			printf("      Warning: Descriptor too short\n");
2396 		flags = buf[4];
2397 		printf("        bFrameIndex                     %5u\n"
2398 		       "        bmCapabilities                   0x%02x\n",
2399 		       buf[3], flags);
2400 		printf("          Still image %ssupported\n",
2401 		       (flags & (1 << 0)) ? "" : "un");
2402 		if (flags & (1 << 1))
2403 			printf("          Fixed frame-rate\n");
2404 		printf("        wWidth                          %5u\n"
2405 		       "        wHeight                         %5u\n"
2406 		       "        dwMinBitRate                %9u\n"
2407 		       "        dwMaxBitRate                %9u\n"
2408 		       "        dwMaxVideoFrameBufferSize   %9u\n"
2409 		       "        dwDefaultFrameInterval      %9u\n"
2410 		       "        bFrameIntervalType              %5u\n",
2411 		       buf[5] | (buf[6] <<  8), buf[7] | (buf[8] << 8),
2412 		       buf[9] | (buf[10] << 8) | (buf[11] << 16) | (buf[12] << 24),
2413 		       buf[13] | (buf[14] << 8) | (buf[15] << 16) | (buf[16] << 24),
2414 		       buf[17] | (buf[18] << 8) | (buf[19] << 16) | (buf[20] << 24),
2415 		       buf[21] | (buf[22] << 8) | (buf[23] << 16) | (buf[24] << 24),
2416 		       buf[25]);
2417 		if (buf[25] == 0)
2418 			printf("        dwMinFrameInterval          %9u\n"
2419 			       "        dwMaxFrameInterval          %9u\n"
2420 			       "        dwFrameIntervalStep         %9u\n",
2421 			       buf[26] | (buf[27] << 8) | (buf[28] << 16) | (buf[29] << 24),
2422 			       buf[30] | (buf[31] << 8) | (buf[32] << 16) | (buf[33] << 24),
2423 			       buf[34] | (buf[35] << 8) | (buf[36] << 16) | (buf[37] << 24));
2424 		else
2425 			for (i = 0; i < buf[25]; i++)
2426 				printf("        dwFrameInterval(%2u)         %9u\n",
2427 				       i, buf[26+4*i] | (buf[27+4*i] << 8) |
2428 				       (buf[28+4*i] << 16) | (buf[29+4*i] << 24));
2429 		dump_junk(buf, "        ", len);
2430 		break;
2431 
2432 	case 0x06: /* FORMAT_MJPEG */
2433 		printf("(FORMAT_MJPEG)\n");
2434 		if (buf[0] < 11)
2435 			printf("      Warning: Descriptor too short\n");
2436 		flags = buf[5];
2437 		printf("        bFormatIndex                    %5u\n"
2438 		       "        bNumFrameDescriptors            %5u\n"
2439 		       "        bFlags                          %5u\n",
2440 		       buf[3], buf[4], flags);
2441 		printf("          Fixed-size samples: %s\n",
2442 		       (flags & (1 << 0)) ? "Yes" : "No");
2443 		flags = buf[9];
2444 		printf("        bDefaultFrameIndex              %5u\n"
2445 		       "        bAspectRatioX                   %5u\n"
2446 		       "        bAspectRatioY                   %5u\n"
2447 		       "        bmInterlaceFlags                 0x%02x\n",
2448 		       buf[6], buf[7], buf[8], flags);
2449 		printf("          Interlaced stream or variable: %s\n",
2450 		       (flags & (1 << 0)) ? "Yes" : "No");
2451 		printf("          Fields per frame: %u fields\n",
2452 		       (flags & (1 << 1)) ? 2 : 1);
2453 		printf("          Field 1 first: %s\n",
2454 		       (flags & (1 << 2)) ? "Yes" : "No");
2455 		printf("          Field pattern: ");
2456 		switch ((flags >> 4) & 0x03) {
2457 		case 0:
2458 			printf("Field 1 only\n");
2459 			break;
2460 		case 1:
2461 			printf("Field 2 only\n");
2462 			break;
2463 		case 2:
2464 			printf("Regular pattern of fields 1 and 2\n");
2465 			break;
2466 		case 3:
2467 			printf("Random pattern of fields 1 and 2\n");
2468 			break;
2469 		}
2470 		printf("          bCopyProtect                  %5u\n", buf[10]);
2471 		dump_junk(buf, "        ", 11);
2472 		break;
2473 
2474 	case 0x0d: /* COLORFORMAT */
2475 		printf("(COLORFORMAT)\n");
2476 		if (buf[0] < 6)
2477 			printf("      Warning: Descriptor too short\n");
2478 		printf("        bColorPrimaries                 %5u (%s)\n",
2479 		       buf[3], (buf[3] <= 5) ? colorPrims[buf[3]] : "Unknown");
2480 		printf("        bTransferCharacteristics        %5u (%s)\n",
2481 		       buf[4], (buf[4] <= 7) ? transferChars[buf[4]] : "Unknown");
2482 		printf("        bMatrixCoefficients             %5u (%s)\n",
2483 		       buf[5], (buf[5] <= 5) ? matrixCoeffs[buf[5]] : "Unknown");
2484 		dump_junk(buf, "        ", 6);
2485 		break;
2486 
2487 	default:
2488 		printf("        Invalid desc subtype:");
2489 		dump_bytes(buf+3, buf[0]-3);
2490 		break;
2491 	}
2492 }
2493 
dump_dfu_interface(unsigned char * buf)2494 static void dump_dfu_interface(unsigned char *buf)
2495 {
2496 	if (buf[1] != USB_DT_CS_DEVICE)
2497 		printf("      Warning: Invalid descriptor\n");
2498 	else if (buf[0] < 7)
2499 		printf("      Warning: Descriptor too short\n");
2500 	printf("      Device Firmware Upgrade Interface Descriptor:\n"
2501 	       "        bLength                         %5u\n"
2502 	       "        bDescriptorType                 %5u\n"
2503 	       "        bmAttributes                    %5u\n",
2504 	       buf[0], buf[1], buf[2]);
2505 	if (buf[2] & 0xf0)
2506 		printf("          (unknown attributes!)\n");
2507 	printf("          Will %sDetach\n", (buf[2] & 0x08) ? "" : "Not ");
2508 	printf("          Manifestation %s\n", (buf[2] & 0x04) ? "Tolerant" : "Intolerant");
2509 	printf("          Upload %s\n", (buf[2] & 0x02) ? "Supported" : "Unsupported");
2510 	printf("          Download %s\n", (buf[2] & 0x01) ? "Supported" : "Unsupported");
2511 	printf("        wDetachTimeout                  %5u milliseconds\n"
2512 	       "        wTransferSize                   %5u bytes\n",
2513 	       buf[3] | (buf[4] << 8), buf[5] | (buf[6] << 8));
2514 
2515 	/* DFU 1.0 defines no version code, DFU 1.1 does */
2516 	if (buf[0] < 9)
2517 		return;
2518 	printf("        bcdDFUVersion                   %x.%02x\n",
2519 			buf[8], buf[7]);
2520 }
2521 
dump_hub(char * prefix,unsigned char * p,int tt_type)2522 static void dump_hub(char *prefix, unsigned char *p, int tt_type)
2523 {
2524 	unsigned int l, i, j;
2525 	unsigned int offset;
2526 	unsigned int wHubChar = (p[4] << 8) | p[3];
2527 
2528 	printf("%sHub Descriptor:\n", prefix);
2529 	printf("%s  bLength             %3u\n", prefix, p[0]);
2530 	printf("%s  bDescriptorType     %3u\n", prefix, p[1]);
2531 	printf("%s  nNbrPorts           %3u\n", prefix, p[2]);
2532 	printf("%s  wHubCharacteristic 0x%04x\n", prefix, wHubChar);
2533 	switch (wHubChar & 0x03) {
2534 	case 0:
2535 		printf("%s    Ganged power switching\n", prefix);
2536 		break;
2537 	case 1:
2538 		printf("%s    Per-port power switching\n", prefix);
2539 		break;
2540 	default:
2541 		printf("%s    No power switching (usb 1.0)\n", prefix);
2542 		break;
2543 	}
2544 	if (wHubChar & 0x04)
2545 		printf("%s    Compound device\n", prefix);
2546 	switch ((wHubChar >> 3) & 0x03) {
2547 	case 0:
2548 		printf("%s    Ganged overcurrent protection\n", prefix);
2549 		break;
2550 	case 1:
2551 		printf("%s    Per-port overcurrent protection\n", prefix);
2552 		break;
2553 	default:
2554 		printf("%s    No overcurrent protection\n", prefix);
2555 		break;
2556 	}
2557 	/* USB 3.0 hubs don't have TTs. */
2558 	if (tt_type >= 1 && tt_type < 3) {
2559 		l = (wHubChar >> 5) & 0x03;
2560 		printf("%s    TT think time %d FS bits\n", prefix, (l + 1) * 8);
2561 	}
2562 	/* USB 3.0 hubs don't have port indicators.  Sad face. */
2563 	if (tt_type != 3 && wHubChar & (1<<7))
2564 		printf("%s    Port indicators\n", prefix);
2565 	printf("%s  bPwrOn2PwrGood      %3u * 2 milli seconds\n", prefix, p[5]);
2566 
2567 	/* USB 3.0 hubs report current in units of aCurrentUnit, or 4 mA */
2568 	if (tt_type == 3)
2569 		printf("%s  bHubContrCurrent   %4u milli Ampere\n",
2570 				prefix, p[6]*4);
2571 	else
2572 		printf("%s  bHubContrCurrent    %3u milli Ampere\n",
2573 				prefix, p[6]);
2574 
2575 	if (tt_type == 3) {
2576 		printf("%s  bHubDecLat          0.%1u micro seconds\n",
2577 				prefix, p[7]);
2578 		printf("%s  wHubDelay          %4u nano seconds\n",
2579 				prefix, (p[8] << 4) +(p[7]));
2580 		offset = 10;
2581 	} else {
2582 		offset = 7;
2583 	}
2584 
2585 	l = (p[2] >> 3) + 1; /* this determines the variable number of bytes following */
2586 	if (l > HUB_STATUS_BYTELEN)
2587 		l = HUB_STATUS_BYTELEN;
2588 	printf("%s  DeviceRemovable   ", prefix);
2589 	for (i = 0; i < l; i++)
2590 		printf(" 0x%02x", p[offset+i]);
2591 
2592 	if (tt_type != 3) {
2593 		printf("\n%s  PortPwrCtrlMask   ", prefix);
2594 		for (j = 0; j < l; j++)
2595 			printf(" 0x%02x", p[offset+i+j]);
2596 	}
2597 	printf("\n");
2598 }
2599 
dump_ccid_device(unsigned char * buf)2600 static void dump_ccid_device(unsigned char *buf)
2601 {
2602 	unsigned int us;
2603 
2604 	if (buf[0] < 54) {
2605 		printf("      Warning: Descriptor too short\n");
2606 		return;
2607 	}
2608 	printf("      ChipCard Interface Descriptor:\n"
2609 	       "        bLength             %5u\n"
2610 	       "        bDescriptorType     %5u\n"
2611 	       "        bcdCCID             %2x.%02x",
2612 	       buf[0], buf[1], buf[3], buf[2]);
2613 	if (buf[3] != 1 || buf[2] != 0)
2614 		fputs("  (Warning: Only accurate for version 1.0)", stdout);
2615 	putchar('\n');
2616 
2617 	printf("        nMaxSlotIndex       %5u\n"
2618 		"        bVoltageSupport     %5u  %s%s%s\n",
2619 		buf[4],
2620 		buf[5],
2621 	       (buf[5] & 1) ? "5.0V " : "",
2622 	       (buf[5] & 2) ? "3.0V " : "",
2623 	       (buf[5] & 4) ? "1.8V " : "");
2624 
2625 	us = convert_le_u32 (buf+6);
2626 	printf("        dwProtocols         %5u ", us);
2627 	if ((us & 1))
2628 		fputs(" T=0", stdout);
2629 	if ((us & 2))
2630 		fputs(" T=1", stdout);
2631 	if ((us & ~3))
2632 		fputs(" (Invalid values detected)", stdout);
2633 	putchar('\n');
2634 
2635 	us = convert_le_u32(buf+10);
2636 	printf("        dwDefaultClock      %5u\n", us);
2637 	us = convert_le_u32(buf+14);
2638 	printf("        dwMaxiumumClock     %5u\n", us);
2639 	printf("        bNumClockSupported  %5u\n", buf[18]);
2640 	us = convert_le_u32(buf+19);
2641 	printf("        dwDataRate        %7u bps\n", us);
2642 	us = convert_le_u32(buf+23);
2643 	printf("        dwMaxDataRate     %7u bps\n", us);
2644 	printf("        bNumDataRatesSupp.  %5u\n", buf[27]);
2645 
2646 	us = convert_le_u32(buf+28);
2647 	printf("        dwMaxIFSD           %5u\n", us);
2648 
2649 	us = convert_le_u32(buf+32);
2650 	printf("        dwSyncProtocols  %08X ", us);
2651 	if ((us&1))
2652 		fputs(" 2-wire", stdout);
2653 	if ((us&2))
2654 		fputs(" 3-wire", stdout);
2655 	if ((us&4))
2656 		fputs(" I2C", stdout);
2657 	putchar('\n');
2658 
2659 	us = convert_le_u32(buf+36);
2660 	printf("        dwMechanical     %08X ", us);
2661 	if ((us & 1))
2662 		fputs(" accept", stdout);
2663 	if ((us & 2))
2664 		fputs(" eject", stdout);
2665 	if ((us & 4))
2666 		fputs(" capture", stdout);
2667 	if ((us & 8))
2668 		fputs(" lock", stdout);
2669 	putchar('\n');
2670 
2671 	us = convert_le_u32(buf+40);
2672 	printf("        dwFeatures       %08X\n", us);
2673 	if ((us & 0x0002))
2674 		fputs("          Auto configuration based on ATR\n", stdout);
2675 	if ((us & 0x0004))
2676 		fputs("          Auto activation on insert\n", stdout);
2677 	if ((us & 0x0008))
2678 		fputs("          Auto voltage selection\n", stdout);
2679 	if ((us & 0x0010))
2680 		fputs("          Auto clock change\n", stdout);
2681 	if ((us & 0x0020))
2682 		fputs("          Auto baud rate change\n", stdout);
2683 	if ((us & 0x0040))
2684 		fputs("          Auto parameter negotation made by CCID\n", stdout);
2685 	else if ((us & 0x0080))
2686 		fputs("          Auto PPS made by CCID\n", stdout);
2687 	else if ((us & (0x0040 | 0x0080)))
2688 		fputs("        WARNING: conflicting negotation features\n", stdout);
2689 
2690 	if ((us & 0x0100))
2691 		fputs("          CCID can set ICC in clock stop mode\n", stdout);
2692 	if ((us & 0x0200))
2693 		fputs("          NAD value other than 0x00 accpeted\n", stdout);
2694 	if ((us & 0x0400))
2695 		fputs("          Auto IFSD exchange\n", stdout);
2696 
2697 	if ((us & 0x00010000))
2698 		fputs("          TPDU level exchange\n", stdout);
2699 	else if ((us & 0x00020000))
2700 		fputs("          Short APDU level exchange\n", stdout);
2701 	else if ((us & 0x00040000))
2702 		fputs("          Short and extended APDU level exchange\n", stdout);
2703 	else if ((us & 0x00070000))
2704 		fputs("        WARNING: conflicting exchange levels\n", stdout);
2705 
2706 	us = convert_le_u32(buf+44);
2707 	printf("        dwMaxCCIDMsgLen     %5u\n", us);
2708 
2709 	printf("        bClassGetResponse    ");
2710 	if (buf[48] == 0xff)
2711 		fputs("echo\n", stdout);
2712 	else
2713 		printf("  %02X\n", buf[48]);
2714 
2715 	printf("        bClassEnvelope       ");
2716 	if (buf[49] == 0xff)
2717 		fputs("echo\n", stdout);
2718 	else
2719 		printf("  %02X\n", buf[48]);
2720 
2721 	printf("        wlcdLayout           ");
2722 	if (!buf[50] && !buf[51])
2723 		fputs("none\n", stdout);
2724 	else
2725 		printf("%u cols %u lines\n", buf[50], buf[51]);
2726 
2727 	printf("        bPINSupport         %5u ", buf[52]);
2728 	if ((buf[52] & 1))
2729 		fputs(" verification", stdout);
2730 	if ((buf[52] & 2))
2731 		fputs(" modification", stdout);
2732 	putchar('\n');
2733 
2734 	printf("        bMaxCCIDBusySlots   %5u\n", buf[53]);
2735 
2736 	if (buf[0] > 54) {
2737 		fputs("        junk             ", stdout);
2738 		dump_bytes(buf+54, buf[0]-54);
2739 	}
2740 }
2741 
2742 /* ---------------------------------------------------------------------- */
2743 
2744 /*
2745  * HID descriptor
2746  */
2747 
dump_report_desc(unsigned char * b,int l)2748 static void dump_report_desc(unsigned char *b, int l)
2749 {
2750 	unsigned int t, j, bsize, btag, btype, data = 0xffff, hut = 0xffff;
2751 	int i;
2752 	char *types[4] = { "Main", "Global", "Local", "reserved" };
2753 	char indent[] = "                            ";
2754 
2755 	printf("          Report Descriptor: (length is %d)\n", l);
2756 	for (i = 0; i < l; ) {
2757 		t = b[i];
2758 		bsize = b[i] & 0x03;
2759 		if (bsize == 3)
2760 			bsize = 4;
2761 		btype = b[i] & (0x03 << 2);
2762 		btag = b[i] & ~0x03; /* 2 LSB bits encode length */
2763 		printf("            Item(%-6s): %s, data=", types[btype>>2],
2764 				names_reporttag(btag));
2765 		if (bsize > 0) {
2766 			printf(" [ ");
2767 			data = 0;
2768 			for (j = 0; j < bsize; j++) {
2769 				printf("0x%02x ", b[i+1+j]);
2770 				data += (b[i+1+j] << (8*j));
2771 			}
2772 			printf("] %d", data);
2773 		} else
2774 			printf("none");
2775 		printf("\n");
2776 		switch (btag) {
2777 		case 0x04: /* Usage Page */
2778 			printf("%s%s\n", indent, names_huts(data));
2779 			hut = data;
2780 			break;
2781 
2782 		case 0x08: /* Usage */
2783 		case 0x18: /* Usage Minimum */
2784 		case 0x28: /* Usage Maximum */
2785 			printf("%s%s\n", indent,
2786 			       names_hutus((hut << 16) + data));
2787 			break;
2788 
2789 		case 0x54: /* Unit Exponent */
2790 			printf("%sUnit Exponent: %i\n", indent,
2791 			       (signed char)data);
2792 			break;
2793 
2794 		case 0x64: /* Unit */
2795 			printf("%s", indent);
2796 			dump_unit(data, bsize);
2797 			break;
2798 
2799 		case 0xa0: /* Collection */
2800 			printf("%s", indent);
2801 			switch (data) {
2802 			case 0x00:
2803 				printf("Physical\n");
2804 				break;
2805 
2806 			case 0x01:
2807 				printf("Application\n");
2808 				break;
2809 
2810 			case 0x02:
2811 				printf("Logical\n");
2812 				break;
2813 
2814 			case 0x03:
2815 				printf("Report\n");
2816 				break;
2817 
2818 			case 0x04:
2819 				printf("Named Array\n");
2820 				break;
2821 
2822 			case 0x05:
2823 				printf("Usage Switch\n");
2824 				break;
2825 
2826 			case 0x06:
2827 				printf("Usage Modifier\n");
2828 				break;
2829 
2830 			default:
2831 				if (data & 0x80)
2832 					printf("Vendor defined\n");
2833 				else
2834 					printf("Reserved for future use.\n");
2835 			}
2836 			break;
2837 		case 0x80: /* Input */
2838 		case 0x90: /* Output */
2839 		case 0xb0: /* Feature */
2840 			printf("%s%s %s %s %s %s\n%s%s %s %s %s\n",
2841 			       indent,
2842 			       data & 0x01 ? "Constant" : "Data",
2843 			       data & 0x02 ? "Variable" : "Array",
2844 			       data & 0x04 ? "Relative" : "Absolute",
2845 			       data & 0x08 ? "Wrap" : "No_Wrap",
2846 			       data & 0x10 ? "Non_Linear" : "Linear",
2847 			       indent,
2848 			       data & 0x20 ? "No_Preferred_State" : "Preferred_State",
2849 			       data & 0x40 ? "Null_State" : "No_Null_Position",
2850 			       data & 0x80 ? "Volatile" : "Non_Volatile",
2851 			       data & 0x100 ? "Buffered Bytes" : "Bitfield");
2852 			break;
2853 		}
2854 		i += 1 + bsize;
2855 	}
2856 }
2857 
dump_hid_device(struct usb_dev_handle * dev,struct usb_interface_descriptor * interface,unsigned char * buf)2858 static void dump_hid_device(struct usb_dev_handle *dev,
2859 			    struct usb_interface_descriptor *interface,
2860 			    unsigned char *buf)
2861 {
2862 	unsigned int i, len;
2863 	unsigned int n;
2864 	unsigned char dbuf[8192];
2865 
2866 	if (buf[1] != USB_DT_HID)
2867 		printf("      Warning: Invalid descriptor\n");
2868 	else if (buf[0] < 6+3*buf[5])
2869 		printf("      Warning: Descriptor too short\n");
2870 	printf("        HID Device Descriptor:\n"
2871 	       "          bLength             %5u\n"
2872 	       "          bDescriptorType     %5u\n"
2873 	       "          bcdHID              %2x.%02x\n"
2874 	       "          bCountryCode        %5u %s\n"
2875 	       "          bNumDescriptors     %5u\n",
2876 	       buf[0], buf[1], buf[3], buf[2], buf[4],
2877 	       names_countrycode(buf[4]) ? : "Unknown", buf[5]);
2878 	for (i = 0; i < buf[5]; i++)
2879 		printf("          bDescriptorType     %5u %s\n"
2880 		       "          wDescriptorLength   %5u\n",
2881 		       buf[6+3*i], names_hid(buf[6+3*i]),
2882 		       buf[7+3*i] | (buf[8+3*i] << 8));
2883 	dump_junk(buf, "        ", 6+3*buf[5]);
2884 	if (!do_report_desc)
2885 		return;
2886 
2887 	if (!dev) {
2888 		printf("         Report Descriptors: \n"
2889 		       "           ** UNAVAILABLE **\n");
2890 		return;
2891 	}
2892 
2893 	for (i = 0; i < buf[5]; i++) {
2894 		/* we are just interested in report descriptors*/
2895 		if (buf[6+3*i] != USB_DT_REPORT)
2896 			continue;
2897 		len = buf[7+3*i] | (buf[8+3*i] << 8);
2898 		if (len > (unsigned int)sizeof(dbuf)) {
2899 			printf("report descriptor too long\n");
2900 			continue;
2901 		}
2902 		if (usb_claim_interface(dev, interface->bInterfaceNumber) == 0) {
2903 			int retries = 4;
2904 			n = 0;
2905 			while (n < len && retries--)
2906 				n = usb_control_msg(dev,
2907 					 USB_ENDPOINT_IN | USB_TYPE_STANDARD
2908 						| USB_RECIP_INTERFACE,
2909 					 USB_REQ_GET_DESCRIPTOR,
2910 					 (USB_DT_REPORT << 8),
2911 					 interface->bInterfaceNumber,
2912 					 dbuf, len,
2913 					 CTRL_TIMEOUT);
2914 
2915 			if (n > 0) {
2916 				if (n < len)
2917 					printf("          Warning: incomplete report descriptor\n");
2918 				dump_report_desc(dbuf, n);
2919 			}
2920 			usb_release_interface(dev, interface->bInterfaceNumber);
2921 		} else {
2922 			/* recent Linuxes require claim() for RECIP_INTERFACE,
2923 			 * so "rmmod hid" will often make these available.
2924 			 */
2925 			printf("         Report Descriptors: \n"
2926 			       "           ** UNAVAILABLE **\n");
2927 		}
2928 	}
2929 }
2930 
2931 static char *
dump_comm_descriptor(struct usb_dev_handle * dev,unsigned char * buf,char * indent)2932 dump_comm_descriptor(struct usb_dev_handle *dev, unsigned char *buf, char *indent)
2933 {
2934 	int		tmp;
2935 	char		str[128];
2936 	char		*type;
2937 
2938 	switch (buf[2]) {
2939 	case 0:
2940 		type = "Header";
2941 		if (buf[0] != 5)
2942 			goto bad;
2943 		printf("%sCDC Header:\n"
2944 		       "%s  bcdCDC               %x.%02x\n",
2945 		       indent,
2946 		       indent, buf[4], buf[3]);
2947 		break;
2948 	case 0x01:		/* call management functional desc */
2949 		type = "Call Management";
2950 		if (buf[0] != 5)
2951 			goto bad;
2952 		printf("%sCDC Call Management:\n"
2953 		       "%s  bmCapabilities       0x%02x\n",
2954 		       indent,
2955 		       indent, buf[3]);
2956 		if (buf[3] & 0x01)
2957 			printf("%s    call management\n", indent);
2958 		if (buf[3] & 0x02)
2959 			printf("%s    use DataInterface\n", indent);
2960 		printf("%s  bDataInterface          %d\n", indent, buf[4]);
2961 		break;
2962 	case 0x02:		/* acm functional desc */
2963 		type = "ACM";
2964 		if (buf[0] != 4)
2965 			goto bad;
2966 		printf("%sCDC ACM:\n"
2967 		       "%s  bmCapabilities       0x%02x\n",
2968 		       indent,
2969 		       indent, buf[3]);
2970 		if (buf[3] & 0x08)
2971 			printf("%s    connection notifications\n", indent);
2972 		if (buf[3] & 0x04)
2973 			printf("%s    sends break\n", indent);
2974 		if (buf[3] & 0x02)
2975 			printf("%s    line coding and serial state\n", indent);
2976 		if (buf[3] & 0x01)
2977 			printf("%s    get/set/clear comm features\n", indent);
2978 		break;
2979 #if 0
2980 	case 0x03:		/* direct line management */
2981 	case 0x04:		/* telephone ringer */
2982 	case 0x05:		/* telephone call and line state reporting */
2983 #endif
2984 	case 0x06:		/* union desc */
2985 		type = "Union";
2986 		if (buf[0] < 5)
2987 			goto bad;
2988 		printf("%sCDC Union:\n"
2989 		       "%s  bMasterInterface        %d\n"
2990 		       "%s  bSlaveInterface         ",
2991 		       indent,
2992 		       indent, buf[3],
2993 		       indent);
2994 		for (tmp = 4; tmp < buf[0]; tmp++)
2995 			printf("%d ", buf[tmp]);
2996 		printf("\n");
2997 		break;
2998 	case 0x07:		/* country selection functional desc */
2999 		type = "Country Selection";
3000 		if (buf[0] < 6 || (buf[0] & 1) != 0)
3001 			goto bad;
3002 		get_string(dev, str, sizeof str, buf[3]);
3003 		printf("%sCountry Selection:\n"
3004 		       "%s  iCountryCodeRelDate     %4d %s\n",
3005 		       indent,
3006 		       indent, buf[3], (buf[3] && *str) ? str : "(?\?)");
3007 		for (tmp = 4; tmp < buf[0]; tmp += 2) {
3008 			printf("%s  wCountryCode          0x%02x%02x\n",
3009 				indent, buf[tmp], buf[tmp + 1]);
3010 		}
3011 		break;
3012 	case 0x08:		/* telephone operational modes */
3013 		type = "Telephone Operations";
3014 		if (buf[0] != 4)
3015 			goto bad;
3016 		printf("%sCDC Telephone operations:\n"
3017 		       "%s  bmCapabilities       0x%02x\n",
3018 		       indent,
3019 		       indent, buf[3]);
3020 		if (buf[3] & 0x04)
3021 			printf("%s    computer centric mode\n", indent);
3022 		if (buf[3] & 0x02)
3023 			printf("%s    standalone mode\n", indent);
3024 		if (buf[3] & 0x01)
3025 			printf("%s    simple mode\n", indent);
3026 		break;
3027 #if 0
3028 	case 0x09:		/* USB terminal */
3029 #endif
3030 	case 0x0a:		/* network channel terminal */
3031 		type = "Network Channel Terminal";
3032 		if (buf[0] != 7)
3033 			goto bad;
3034 		get_string(dev, str, sizeof str, buf[4]);
3035 		printf("%sNetwork Channel Terminal:\n"
3036 		       "%s  bEntityId               %3d\n"
3037 		       "%s  iName                   %3d %s\n"
3038 		       "%s  bChannelIndex           %3d\n"
3039 		       "%s  bPhysicalInterface      %3d\n",
3040 		       indent,
3041 		       indent, buf[3],
3042 		       indent, buf[4], str,
3043 		       indent, buf[5],
3044 		       indent, buf[6]);
3045 		break;
3046 #if 0
3047 	case 0x0b:		/* protocol unit */
3048 	case 0x0c:		/* extension unit */
3049 	case 0x0d:		/* multi-channel management */
3050 	case 0x0e:		/* CAPI control management*/
3051 #endif
3052 	case 0x0f:		/* ethernet functional desc */
3053 		type = "Ethernet";
3054 		if (buf[0] != 13)
3055 			goto bad;
3056 		get_string(dev, str, sizeof str, buf[3]);
3057 		tmp = buf[7] << 8;
3058 		tmp |= buf[6]; tmp <<= 8;
3059 		tmp |= buf[5]; tmp <<= 8;
3060 		tmp |= buf[4];
3061 		printf("%sCDC Ethernet:\n"
3062 		       "%s  iMacAddress             %10d %s\n"
3063 		       "%s  bmEthernetStatistics    0x%08x\n",
3064 		       indent,
3065 		       indent, buf[3], (buf[3] && *str) ? str : "(?\?)",
3066 		       indent, tmp);
3067 		/* FIXME dissect ALL 28 bits */
3068 		printf("%s  wMaxSegmentSize         %10d\n"
3069 		       "%s  wNumberMCFilters            0x%04x\n"
3070 		       "%s  bNumberPowerFilters     %10d\n",
3071 		       indent, (buf[9]<<8)|buf[8],
3072 		       indent, (buf[11]<<8)|buf[10],
3073 		       indent, buf[12]);
3074 		break;
3075 #if 0
3076 	case 0x10:		/* ATM networking */
3077 #endif
3078 	case 0x11:		/* WHCM functional desc */
3079 		type = "WHCM version";
3080 		if (buf[0] != 5)
3081 			goto bad;
3082 		printf("%sCDC WHCM:\n"
3083 		       "%s  bcdVersion           %x.%02x\n",
3084 		       indent,
3085 		       indent, buf[4], buf[3]);
3086 		break;
3087 	case 0x12:		/* MDLM functional desc */
3088 		type = "MDLM";
3089 		if (buf[0] != 21)
3090 			goto bad;
3091 		printf("%sCDC MDLM:\n"
3092 		       "%s  bcdCDC               %x.%02x\n"
3093 		       "%s  bGUID               %s\n",
3094 		       indent,
3095 		       indent, buf[4], buf[3],
3096 		       indent, get_guid(buf + 5));
3097 		break;
3098 	case 0x13:		/* MDLM detail desc */
3099 		type = "MDLM detail";
3100 		if (buf[0] < 5)
3101 			goto bad;
3102 		printf("%sCDC MDLM detail:\n"
3103 		       "%s  bGuidDescriptorType  %02x\n"
3104 		       "%s  bDetailData         ",
3105 		       indent,
3106 		       indent, buf[3],
3107 		       indent);
3108 		dump_bytes(buf + 4, buf[0] - 4);
3109 		break;
3110 	case 0x14:		/* device management functional desc */
3111 		type = "Device Management";
3112 		if (buf[0] != 7)
3113 			goto bad;
3114 		printf("%sCDC Device Management:\n"
3115 		       "%s  bcdVersion           %x.%02x\n"
3116 		       "%s  wMaxCommand          %d\n",
3117 		       indent,
3118 		       indent, buf[4], buf[3],
3119 		       indent, (buf[6] << 8) | buf[5]);
3120 		break;
3121 	case 0x15:		/* OBEX functional desc */
3122 		type = "OBEX";
3123 		if (buf[0] != 5)
3124 			goto bad;
3125 		printf("%sCDC OBEX:\n"
3126 		       "%s  bcdVersion           %x.%02x\n",
3127 		       indent,
3128 		       indent, buf[4], buf[3]);
3129 		break;
3130 #if 0
3131 	case 0x16:		/* command set functional desc */
3132 	case 0x17:		/* command set detail desc */
3133 	case 0x18:		/* telephone control model functional desc */
3134 #endif
3135 	default:
3136 		/* FIXME there are about a dozen more descriptor types */
3137 		printf("%sUNRECOGNIZED CDC: ", indent);
3138 		dump_bytes(buf, buf[0]);
3139 		return "unrecognized comm descriptor";
3140 	}
3141 	return 0;
3142 
3143 bad:
3144 	printf("%sINVALID CDC (%s): ", indent, type);
3145 	dump_bytes(buf, buf[0]);
3146 	return "corrupt comm descriptor";
3147 }
3148 
3149 /* ---------------------------------------------------------------------- */
3150 
do_hub(struct usb_dev_handle * fd,unsigned tt_type,unsigned speed)3151 static void do_hub(struct usb_dev_handle *fd, unsigned tt_type, unsigned speed)
3152 {
3153 	unsigned char buf[7 /* base descriptor */
3154 			+ 2 /* bitmasks */ * HUB_STATUS_BYTELEN];
3155 	int i, ret, value;
3156 	unsigned int link_state;
3157 	char *link_state_descriptions[] = {
3158 		" U0",
3159 		" U1",
3160 		" U2",
3161 		" suspend",
3162 		" SS.disabled",
3163 		" Rx.Detect",
3164 		" SS.Inactive",
3165 		" Polling",
3166 		" Recovery",
3167 		" Hot Reset",
3168 		" Compliance",
3169 		" Loopback",
3170 	};
3171 
3172 	/* USB 3.0 hubs have a slightly different descriptor */
3173 	if (speed == 0x0300)
3174 		value = 0x2A;
3175 	else
3176 		value = 0x29;
3177 
3178 	ret = usb_control_msg(fd,
3179 			USB_ENDPOINT_IN | USB_TYPE_CLASS | USB_RECIP_DEVICE,
3180 			USB_REQ_GET_DESCRIPTOR,
3181 			value << 8, 0,
3182 			buf, sizeof buf, CTRL_TIMEOUT);
3183 	if (ret < 9 /* at least one port's bitmasks */) {
3184 		if (ret >= 0)
3185 			fprintf(stderr,
3186 				"incomplete hub descriptor, %d bytes\n",
3187 				ret);
3188 		/* Linux returns EHOSTUNREACH for suspended devices */
3189 		else if (errno != EHOSTUNREACH)
3190 			perror("can't get hub descriptor");
3191 		return;
3192 	}
3193 	dump_hub("", buf, tt_type);
3194 
3195 	printf(" Hub Port Status:\n");
3196 	for (i = 0; i < buf[2]; i++) {
3197 		unsigned char status[4];
3198 
3199 		ret = usb_control_msg(fd,
3200 				USB_ENDPOINT_IN | USB_TYPE_CLASS
3201 					| USB_RECIP_OTHER,
3202 				USB_REQ_GET_STATUS,
3203 				0, i + 1,
3204 				status, sizeof status,
3205 				CTRL_TIMEOUT);
3206 		if (ret < 0) {
3207 			fprintf(stderr,
3208 				"cannot read port %d status, %s (%d)\n",
3209 				i + 1, strerror(errno), errno);
3210 			break;
3211 		}
3212 
3213 		printf("   Port %d: %02x%02x.%02x%02x", i + 1,
3214 			status[3], status[2],
3215 			status[1], status[0]);
3216 		/* CAPS are used to highlight "transient" states */
3217 		if (speed != 0x0300) {
3218 			printf("%s%s%s%s%s",
3219 					(status[2] & 0x10) ? " C_RESET" : "",
3220 					(status[2] & 0x08) ? " C_OC" : "",
3221 					(status[2] & 0x04) ? " C_SUSPEND" : "",
3222 					(status[2] & 0x02) ? " C_ENABLE" : "",
3223 					(status[2] & 0x01) ? " C_CONNECT" : "");
3224 			printf("%s%s%s%s%s%s%s%s%s%s\n",
3225 					(status[1] & 0x10) ? " indicator" : "",
3226 					(status[1] & 0x08) ? " test" : "",
3227 					(status[1] & 0x04) ? " highspeed" : "",
3228 					(status[1] & 0x02) ? " lowspeed" : "",
3229 					(status[1] & 0x01) ? " power" : "",
3230 					(status[0] & 0x10) ? " RESET" : "",
3231 					(status[0] & 0x08) ? " oc" : "",
3232 					(status[0] & 0x04) ? " suspend" : "",
3233 					(status[0] & 0x02) ? " enable" : "",
3234 					(status[0] & 0x01) ? " connect" : "");
3235 		} else {
3236 			link_state = ((status[0] & 0xe0) >> 5) +
3237 				((status[1] & 0x1) << 4);
3238 			printf("%s%s%s%s%s%s",
3239 					(status[2] & 0x80) ? " C_CONFIG_ERROR" : "",
3240 					(status[2] & 0x40) ? " C_LINK_STATE" : "",
3241 					(status[2] & 0x20) ? " C_BH_RESET" : "",
3242 					(status[2] & 0x10) ? " C_RESET" : "",
3243 					(status[2] & 0x08) ? " C_OC" : "",
3244 					(status[2] & 0x01) ? " C_CONNECT" : "");
3245 			printf("%s%s",
3246 					((status[1] & 0x1C) == 0) ? " 5Gbps" : " Unknown Speed",
3247 					(status[1] & 0x02) ? " power" : "");
3248 			/* Link state is bits 8:5 */
3249 			if (link_state < (sizeof(link_state_descriptions) /
3250 						sizeof(*link_state_descriptions)))
3251 				printf("%s", link_state_descriptions[link_state]);
3252 			printf("%s%s%s%s\n",
3253 					(status[0] & 0x10) ? " RESET" : "",
3254 					(status[0] & 0x08) ? " oc" : "",
3255 					(status[0] & 0x02) ? " enable" : "",
3256 					(status[0] & 0x01) ? " connect" : "");
3257 		}
3258 	}
3259 }
3260 
do_dualspeed(struct usb_dev_handle * fd)3261 static void do_dualspeed(struct usb_dev_handle *fd)
3262 {
3263 	unsigned char buf[10];
3264 	char cls[128], subcls[128], proto[128];
3265 	int ret;
3266 
3267 	ret = usb_control_msg(fd,
3268 			USB_ENDPOINT_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
3269 			USB_REQ_GET_DESCRIPTOR,
3270 			USB_DT_DEVICE_QUALIFIER << 8, 0,
3271 			buf, sizeof buf, CTRL_TIMEOUT);
3272 	if (ret < 0 && errno != EPIPE)
3273 		perror("can't get device qualifier");
3274 
3275 	/* all dual-speed devices have a qualifier */
3276 	if (ret != sizeof buf
3277 			|| buf[0] != ret
3278 			|| buf[1] != USB_DT_DEVICE_QUALIFIER)
3279 		return;
3280 
3281 	get_class_string(cls, sizeof(cls),
3282 			buf[4]);
3283 	get_subclass_string(subcls, sizeof(subcls),
3284 			buf[4], buf[5]);
3285 	get_protocol_string(proto, sizeof(proto),
3286 			buf[4], buf[5], buf[6]);
3287 	printf("Device Qualifier (for other device speed):\n"
3288 	       "  bLength             %5u\n"
3289 	       "  bDescriptorType     %5u\n"
3290 	       "  bcdUSB              %2x.%02x\n"
3291 	       "  bDeviceClass        %5u %s\n"
3292 	       "  bDeviceSubClass     %5u %s\n"
3293 	       "  bDeviceProtocol     %5u %s\n"
3294 	       "  bMaxPacketSize0     %5u\n"
3295 	       "  bNumConfigurations  %5u\n",
3296 	       buf[0], buf[1],
3297 	       buf[3], buf[2],
3298 	       buf[4], cls,
3299 	       buf[5], subcls,
3300 	       buf[6], proto,
3301 	       buf[7], buf[8]);
3302 
3303 	/* FIXME also show the OTHER_SPEED_CONFIG descriptors */
3304 }
3305 
do_debug(struct usb_dev_handle * fd)3306 static void do_debug(struct usb_dev_handle *fd)
3307 {
3308 	unsigned char buf[4];
3309 	int ret;
3310 
3311 	ret = usb_control_msg(fd,
3312 			USB_ENDPOINT_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
3313 			USB_REQ_GET_DESCRIPTOR,
3314 			USB_DT_DEBUG << 8, 0,
3315 			buf, sizeof buf, CTRL_TIMEOUT);
3316 	if (ret < 0 && errno != EPIPE)
3317 		perror("can't get debug descriptor");
3318 
3319 	/* some high speed devices are also "USB2 debug devices", meaning
3320 	 * you can use them with some EHCI implementations as another kind
3321 	 * of system debug channel:  like JTAG, RS232, or a console.
3322 	 */
3323 	if (ret != sizeof buf
3324 			|| buf[0] != ret
3325 			|| buf[1] != USB_DT_DEBUG)
3326 		return;
3327 
3328 	printf("Debug descriptor:\n"
3329 	       "  bLength              %4u\n"
3330 	       "  bDescriptorType      %4u\n"
3331 	       "  bDebugInEndpoint     0x%02x\n"
3332 	       "  bDebugOutEndpoint    0x%02x\n",
3333 	       buf[0], buf[1],
3334 	       buf[2], buf[3]);
3335 }
3336 
find_otg(unsigned char * buf,int buflen)3337 static unsigned char *find_otg(unsigned char *buf, int buflen)
3338 {
3339 	if (!buf)
3340 		return 0;
3341 	while (buflen >= 3) {
3342 		if (buf[0] == 3 && buf[1] == USB_DT_OTG)
3343 			return buf;
3344 		if (buf[0] > buflen)
3345 			return 0;
3346 		buflen -= buf[0];
3347 		buf += buf[0];
3348 	}
3349 	return 0;
3350 }
3351 
do_otg(struct usb_config_descriptor * config)3352 static int do_otg(struct usb_config_descriptor *config)
3353 {
3354 	unsigned	i, k;
3355 	int		j;
3356 	unsigned char	*desc;
3357 
3358 	/* each config of an otg device has an OTG descriptor */
3359 	desc = find_otg(config->extra, config->extralen);
3360 	for (i = 0; !desc && i < config->bNumInterfaces; i++) {
3361 		struct usb_interface *intf;
3362 
3363 		intf = &config->interface[i];
3364 		for (j = 0; !desc && j < intf->num_altsetting; j++) {
3365 			struct usb_interface_descriptor *alt;
3366 
3367 			alt = &intf->altsetting[j];
3368 			desc = find_otg(alt->extra, alt->extralen);
3369 			for (k = 0; !desc && k < alt->bNumEndpoints; k++) {
3370 				struct usb_endpoint_descriptor *ep;
3371 
3372 				ep = &alt->endpoint[k];
3373 				desc = find_otg(ep->extra, ep->extralen);
3374 			}
3375 		}
3376 	}
3377 	if (!desc)
3378 		return 0;
3379 
3380 	printf("OTG Descriptor:\n"
3381 		"  bLength               %3u\n"
3382 		"  bDescriptorType       %3u\n"
3383 		"  bmAttributes         0x%02x\n"
3384 		"%s%s",
3385 		desc[0], desc[1], desc[2],
3386 		(desc[2] & 0x01)
3387 			? "    SRP (Session Request Protocol)\n" : "",
3388 		(desc[2] & 0x02)
3389 			? "    HNP (Host Negotiation Protocol)\n" : "");
3390 	return 1;
3391 }
3392 
3393 static void
dump_device_status(struct usb_dev_handle * fd,int otg,int wireless)3394 dump_device_status(struct usb_dev_handle *fd, int otg, int wireless)
3395 {
3396 	unsigned char status[8];
3397 	int ret;
3398 
3399 	ret = usb_control_msg(fd, USB_ENDPOINT_IN | USB_TYPE_STANDARD
3400 				| USB_RECIP_DEVICE,
3401 			USB_REQ_GET_STATUS,
3402 			0, 0,
3403 			status, 2,
3404 			CTRL_TIMEOUT);
3405 	if (ret < 0) {
3406 		fprintf(stderr,
3407 			"cannot read device status, %s (%d)\n",
3408 			strerror(errno), errno);
3409 		return;
3410 	}
3411 
3412 	printf("Device Status:     0x%02x%02x\n",
3413 			status[1], status[0]);
3414 	if (status[0] & (1 << 0))
3415 		printf("  Self Powered\n");
3416 	else
3417 		printf("  (Bus Powered)\n");
3418 	if (status[0] & (1 << 1))
3419 		printf("  Remote Wakeup Enabled\n");
3420 	if (status[0] & (1 << 2)) {
3421 		/* for high speed devices */
3422 		if (!wireless)
3423 			printf("  Test Mode\n");
3424 		/* for devices with Wireless USB support */
3425 		else
3426 			printf("  Battery Powered\n");
3427 	}
3428 	/* if both HOST and DEVICE support OTG */
3429 	if (otg) {
3430 		if (status[0] & (1 << 3))
3431 			printf("  HNP Enabled\n");
3432 		if (status[0] & (1 << 4))
3433 			printf("  HNP Capable\n");
3434 		if (status[0] & (1 << 5))
3435 			printf("  ALT port is HNP Capable\n");
3436 	}
3437 	/* for high speed devices with debug descriptors */
3438 	if (status[0] & (1 << 6))
3439 		printf("  Debug Mode\n");
3440 
3441 	if (!wireless)
3442 		return;
3443 
3444 	/* Wireless USB exposes FIVE different types of device status,
3445 	 * accessed by distinct wIndex values.
3446 	 */
3447 	ret = usb_control_msg(fd, USB_ENDPOINT_IN | USB_TYPE_STANDARD
3448 				| USB_RECIP_DEVICE,
3449 			USB_REQ_GET_STATUS,
3450 			0, 1 /* wireless status */,
3451 			status, 1,
3452 			CTRL_TIMEOUT);
3453 	if (ret < 0) {
3454 		fprintf(stderr,
3455 			"cannot read wireless %s, %s (%d)\n",
3456 			"status",
3457 			strerror(errno), errno);
3458 		return;
3459 	}
3460 	printf("Wireless Status:     0x%02x\n", status[0]);
3461 	if (status[0] & (1 << 0))
3462 		printf("  TX Drp IE\n");
3463 	if (status[0] & (1 << 1))
3464 		printf("  Transmit Packet\n");
3465 	if (status[0] & (1 << 2))
3466 		printf("  Count Packets\n");
3467 	if (status[0] & (1 << 3))
3468 		printf("  Capture Packet\n");
3469 
3470 	ret = usb_control_msg(fd, USB_ENDPOINT_IN | USB_TYPE_STANDARD
3471 				| USB_RECIP_DEVICE,
3472 			USB_REQ_GET_STATUS,
3473 			0, 2 /* Channel Info */,
3474 			status, 1,
3475 			CTRL_TIMEOUT);
3476 	if (ret < 0) {
3477 		fprintf(stderr,
3478 			"cannot read wireless %s, %s (%d)\n",
3479 			"channel info",
3480 			strerror(errno), errno);
3481 		return;
3482 	}
3483 	printf("Channel Info:        0x%02x\n", status[0]);
3484 
3485 	/* 3=Received data: many bytes, for count packets or capture packet */
3486 
3487 	ret = usb_control_msg(fd, USB_ENDPOINT_IN | USB_TYPE_STANDARD
3488 				| USB_RECIP_DEVICE,
3489 			USB_REQ_GET_STATUS,
3490 			0, 3 /* MAS Availability */,
3491 			status, 8,
3492 			CTRL_TIMEOUT);
3493 	if (ret < 0) {
3494 		fprintf(stderr,
3495 			"cannot read wireless %s, %s (%d)\n",
3496 			"MAS info",
3497 			strerror(errno), errno);
3498 		return;
3499 	}
3500 	printf("MAS Availability:    ");
3501 	dump_bytes(status, 8);
3502 
3503 	ret = usb_control_msg(fd, USB_ENDPOINT_IN | USB_TYPE_STANDARD
3504 				| USB_RECIP_DEVICE,
3505 			USB_REQ_GET_STATUS,
3506 			0, 5 /* Current Transmit Power */,
3507 			status, 2,
3508 			CTRL_TIMEOUT);
3509 	if (ret < 0) {
3510 		fprintf(stderr,
3511 			"cannot read wireless %s, %s (%d)\n",
3512 			"transmit power",
3513 			strerror(errno), errno);
3514 		return;
3515 	}
3516 	printf("Transmit Power:\n");
3517 	printf(" TxNotification:     0x%02x\n", status[0]);
3518 	printf(" TxBeacon:     :     0x%02x\n", status[1]);
3519 }
3520 
do_wireless(struct usb_dev_handle * fd)3521 static int do_wireless(struct usb_dev_handle *fd)
3522 {
3523 	/* FIXME fetch and dump BOS etc */
3524 	if (fd)
3525 		return 0;
3526 	return 0;
3527 }
3528 
dump_usb2_device_capability_desc(unsigned char * buf)3529 static void dump_usb2_device_capability_desc(unsigned char *buf)
3530 {
3531 	unsigned int wide;
3532 
3533 	wide = buf[3] + (buf[4] << 8) +
3534 		(buf[5] << 8) + (buf[6] << 8);
3535 	printf("  USB 2.0 Extension Device Capability:\n"
3536 			"    bLength             %5u\n"
3537 			"    bDescriptorType     %5u\n"
3538 			"    bDevCapabilityType  %5u\n"
3539 			"    bmAttributes   0x%08x\n",
3540 			buf[0], buf[1], buf[2], wide);
3541 	if (!(wide & 0x02))
3542 		printf("      (Missing must-be-set LPM bit!)\n");
3543 	else
3544 		printf("      Link Power Management (LPM)"
3545 				" Supported\n");
3546 }
3547 
dump_ss_device_capability_desc(unsigned char * buf)3548 static void dump_ss_device_capability_desc(unsigned char *buf)
3549 {
3550 	if (buf[0] < 10) {
3551 		printf("  Bad SuperSpeed USB Device Capability descriptor.\n");
3552 		return;
3553 	}
3554 	printf("  SuperSpeed USB Device Capability:\n"
3555 			"    bLength             %5u\n"
3556 			"    bDescriptorType     %5u\n"
3557 			"    bDevCapabilityType  %5u\n"
3558 			"    bmAttributes         0x%02x\n",
3559 			buf[0], buf[1], buf[2], buf[3]);
3560 	if (!(buf[3] & 0x02))
3561 		printf("      Latency Tolerance Messages (LTM)"
3562 				" Supported\n");
3563 	printf("    wSpeedsSupported   0x%04x\n", buf[4]);
3564 	if (buf[4] & (1 << 0))
3565 		printf("      Device can operate at Low Speed (1Mbps)\n");
3566 	if (buf[4] & (1 << 1))
3567 		printf("      Device can operate at Full Speed (12Mbps)\n");
3568 	if (buf[4] & (1 << 2))
3569 		printf("      Device can operate at High Speed (480Mbps)\n");
3570 	if (buf[4] & (1 << 3))
3571 		printf("      Device can operate at SuperSpeed (5Gbps)\n");
3572 
3573 	printf("    bFunctionalitySupport %3u\n", buf[5]);
3574 	switch(buf[5]) {
3575 	case 0:
3576 		printf("      Lowest fully-functional device speed is "
3577 				"Low Speed (1Mbps)\n");
3578 		break;
3579 	case 1:
3580 		printf("      Lowest fully-functional device speed is "
3581 				"Full Speed (12Mbps)\n");
3582 		break;
3583 	case 2:
3584 		printf("      Lowest fully-functional device speed is "
3585 				"High Speed (480Mbps)\n");
3586 		break;
3587 	case 3:
3588 		printf("      Lowest fully-functional device speed is "
3589 				"SuperSpeed (5Gbps)\n");
3590 		break;
3591 	default:
3592 		printf("      Lowest fully-functional device speed is "
3593 				"at an unknown speed!\n");
3594 		break;
3595 	}
3596 	printf("    bU1DevExitLat        %4u micro seconds\n", buf[6]);
3597 	printf("    bU2DevExitLat    %8u micro seconds\n", buf[8] + (buf[7] << 8));
3598 }
3599 
dump_container_id_device_capability_desc(unsigned char * buf)3600 static void dump_container_id_device_capability_desc(unsigned char *buf)
3601 {
3602 	if (buf[0] < 20) {
3603 		printf("  Bad Container ID Device Capability descriptor.\n");
3604 		return;
3605 	}
3606 	printf("  Container ID Device Capability:\n"
3607 			"    bLength             %5u\n"
3608 			"    bDescriptorType     %5u\n"
3609 			"    bDevCapabilityType  %5u\n"
3610 			"    bReserved           %5u\n",
3611 			buf[0], buf[1], buf[2], buf[3]);
3612 	printf("    ContainerID             %s\n",
3613 			get_guid(&buf[4]));
3614 }
3615 
dump_bos_descriptor(struct usb_dev_handle * fd)3616 static void dump_bos_descriptor(struct usb_dev_handle *fd)
3617 {
3618 	/* Total for all known BOS descriptors is 43 bytes:
3619 	 * 6 bytes for Wireless USB, 7 bytes for USB 2.0 extension,
3620 	 * 10 bytes for SuperSpeed, 20 bytes for Container ID.
3621 	 */
3622 	unsigned char bos_desc[43];
3623 	unsigned int bos_desc_size;
3624 	int size, ret;
3625 	unsigned char *buf;
3626 
3627 	/* Get the first 5 bytes to get the wTotalLength field */
3628 	ret = usb_control_msg(fd,
3629 			USB_ENDPOINT_IN | USB_RECIP_DEVICE,
3630 			USB_REQ_GET_DESCRIPTOR,
3631 			USB_DT_BOS << 8, 0,
3632 			bos_desc, 5, CTRL_TIMEOUT);
3633 	if (ret < 0)
3634 		return;
3635 
3636 	bos_desc_size = bos_desc[2] + (bos_desc[3] << 8);
3637 	printf("Binary Object Store Descriptor:\n"
3638 	       "  bLength             %5u\n"
3639 	       "  bDescriptorType     %5u\n"
3640 	       "  wTotalLength        %5u\n"
3641 	       "  bNumDeviceCaps      %5u\n",
3642 	       bos_desc[0], bos_desc[1],
3643 	       bos_desc_size, bos_desc[4]);
3644 
3645 	if (bos_desc_size <= 5) {
3646 		if (bos_desc[4] > 0)
3647 			fprintf(stderr, "Couldn't get "
3648 					"device capability descriptors\n");
3649 		return;
3650 	}
3651 	if (bos_desc_size > sizeof bos_desc) {
3652 		fprintf(stderr, "FIXME: alloc bigger buffer for "
3653 				"device capability descriptors\n");
3654 		return;
3655 	}
3656 
3657 	ret = usb_control_msg(fd,
3658 			USB_ENDPOINT_IN | USB_RECIP_DEVICE,
3659 			USB_REQ_GET_DESCRIPTOR,
3660 			USB_DT_BOS << 8, 0,
3661 			bos_desc, bos_desc_size, CTRL_TIMEOUT);
3662 	if (ret < 0) {
3663 		fprintf(stderr, "Couldn't get device capability descriptors\n");
3664 		return;
3665 	}
3666 
3667 	size = bos_desc_size - 5;
3668 	buf = &bos_desc[5];
3669 
3670 	while (size >= 3) {
3671 		if (buf[0] < 3) {
3672 			printf("buf[0] = %u\n", buf[0]);
3673 			return;
3674 		}
3675 		switch (buf[2]) {
3676 		case USB_DC_WIRELESS_USB:
3677 			/* FIXME */
3678 			break;
3679 		case USB_DC_20_EXTENSION:
3680 			dump_usb2_device_capability_desc(buf);
3681 			break;
3682 		case USB_DC_SUPERSPEED:
3683 			dump_ss_device_capability_desc(buf);
3684 			break;
3685 		case USB_DC_CONTAINER_ID:
3686 			dump_container_id_device_capability_desc(buf);
3687 			break;
3688 		default:
3689 			printf("  ** UNRECOGNIZED: ");
3690 			dump_bytes(buf, buf[0]);
3691 			break;
3692 		}
3693 		size -= buf[0];
3694 		buf += buf[0];
3695 	}
3696 }
3697 
dumpdev(struct usb_device * dev)3698 static void dumpdev(struct usb_device *dev)
3699 {
3700 	struct usb_dev_handle *udev;
3701 	int i;
3702 	int otg, wireless;
3703 
3704 	otg = wireless = 0;
3705 	udev = usb_open(dev);
3706 	if (!udev)
3707 		fprintf(stderr, "Couldn't open device, some information "
3708 			"will be missing\n");
3709 
3710 	dump_device(udev, &dev->descriptor);
3711 	if (dev->descriptor.bcdUSB == 0x0250)
3712 		wireless = do_wireless(udev);
3713 	if (dev->config) {
3714 		otg = do_otg(&dev->config[0]) || otg;
3715 		for (i = 0; i < dev->descriptor.bNumConfigurations;
3716 				i++) {
3717 			dump_config(udev, &dev->config[i]);
3718 		}
3719 	}
3720 	if (!udev)
3721 		return;
3722 
3723 	if (dev->descriptor.bDeviceClass == USB_CLASS_HUB)
3724 		do_hub(udev, dev->descriptor.bDeviceProtocol, dev->descriptor.bcdUSB);
3725 	if (dev->descriptor.bcdUSB >= 0x0200) {
3726 		do_dualspeed(udev);
3727 		do_debug(udev);
3728 	}
3729 	dump_device_status(udev, otg, wireless);
3730 	dump_bos_descriptor(udev);
3731 	usb_close(udev);
3732 }
3733 
3734 /* ---------------------------------------------------------------------- */
3735 
dump_one_device(const char * path)3736 static int dump_one_device(const char *path)
3737 {
3738 	struct usb_device *dev;
3739 	char vendor[128], product[128];
3740 
3741 	dev = get_usb_device(path);
3742 	if (!dev) {
3743 		fprintf(stderr, "Cannot open %s\n", path);
3744 		return 1;
3745 	}
3746 	get_vendor_string(vendor, sizeof(vendor), dev->descriptor.idVendor);
3747 	get_product_string(product, sizeof(product), dev->descriptor.idVendor, dev->descriptor.idProduct);
3748 	printf("Device: ID %04x:%04x %s %s\n", dev->descriptor.idVendor,
3749 					       dev->descriptor.idProduct,
3750 					       vendor,
3751 					       product);
3752 	dumpdev(dev);
3753 	return 0;
3754 }
3755 
list_devices(int busnum,int devnum,int vendorid,int productid)3756 static int list_devices(int busnum, int devnum, int vendorid, int productid)
3757 {
3758 	struct usb_bus *bus;
3759 	struct usb_device *dev;
3760 	char vendor[128], product[128];
3761 	int status;
3762 
3763 	status = 1; /* 1 device not found, 0 device found */
3764 
3765 	for (bus = usb_busses; bus; bus = bus->next) {
3766 		if (busnum != -1 && strtol(bus->dirname, NULL, 10) != busnum)
3767 			continue;
3768 		for (dev = bus->devices; dev; dev = dev->next) {
3769 			if (devnum != -1 && strtol(dev->filename, NULL, 10)
3770 					!= devnum)
3771 				continue;
3772 			if ((vendorid != -1 && vendorid
3773 						!= dev->descriptor.idVendor)
3774 					|| (productid != -1 && productid
3775 						!= dev->descriptor.idProduct))
3776 				continue;
3777 			status = 0;
3778 			get_vendor_string(vendor, sizeof(vendor),
3779 					dev->descriptor.idVendor);
3780 			get_product_string(product, sizeof(product),
3781 					dev->descriptor.idVendor,
3782 					dev->descriptor.idProduct);
3783 			if (verblevel > 0)
3784 				printf("\n");
3785 			printf("Bus %s Device %s: ID %04x:%04x %s %s\n",
3786 					bus->dirname, dev->filename,
3787 					dev->descriptor.idVendor,
3788 					dev->descriptor.idProduct,
3789 					vendor, product);
3790 			if (verblevel > 0)
3791 				dumpdev(dev);
3792 		}
3793 	}
3794 	return status;
3795 }
3796 
3797 /* ---------------------------------------------------------------------- */
3798 
devtree_busconnect(struct usbbusnode * bus)3799 void devtree_busconnect(struct usbbusnode *bus)
3800 {
3801 	bus = bus;	/* reduce compiler warnings */
3802 }
3803 
devtree_busdisconnect(struct usbbusnode * bus)3804 void devtree_busdisconnect(struct usbbusnode *bus)
3805 {
3806 	bus = bus;	/* reduce compiler warnings */
3807 }
3808 
devtree_devconnect(struct usbdevnode * dev)3809 void devtree_devconnect(struct usbdevnode *dev)
3810 {
3811 	dev = dev;	/* reduce compiler warnings */
3812 }
3813 
devtree_devdisconnect(struct usbdevnode * dev)3814 void devtree_devdisconnect(struct usbdevnode *dev)
3815 {
3816 	dev = dev;	/* reduce compiler warnings */
3817 }
3818 
treedump(void)3819 static int treedump(void)
3820 {
3821 	int fd;
3822 	char buf[512];
3823 
3824 	snprintf(buf, sizeof(buf), "%s/devices", procbususb);
3825 	if (access(buf, R_OK) < 0)
3826 		return lsusb_t();
3827 	if ((fd = open(buf, O_RDONLY)) == -1) {
3828 		fprintf(stderr, "cannot open %s, %s (%d)\n", buf, strerror(errno), errno);
3829 		return 1;
3830 	}
3831 	devtree_parsedevfile(fd);
3832 	close(fd);
3833 	devtree_dump();
3834 	return 0;
3835 }
3836 
3837 /* ---------------------------------------------------------------------- */
3838 
main(int argc,char * argv[])3839 int main(int argc, char *argv[])
3840 {
3841 	static const struct option long_options[] = {
3842 		{ "version", 0, 0, 'V' },
3843 		{ "verbose", 0, 0, 'v' },
3844 		{ 0, 0, 0, 0 }
3845 	};
3846 	int c, err = 0;
3847 	unsigned int allowctrlmsg = 0, treemode = 0;
3848 	int bus = -1, devnum = -1, vendor = -1, product = -1;
3849 	const char *devdump = NULL;
3850 	char *cp;
3851 	int status;
3852 
3853 	while ((c = getopt_long(argc, argv, "D:vxtP:p:s:d:V",
3854 			long_options, NULL)) != EOF) {
3855 		switch (c) {
3856 		case 'V':
3857 			printf("lsusb (" PACKAGE ") " VERSION "\n");
3858 			exit(0);
3859 
3860 		case 'v':
3861 			verblevel++;
3862 			break;
3863 
3864 		case 'x':
3865 			allowctrlmsg = 1;
3866 			break;
3867 
3868 		case 't':
3869 			treemode = 1;
3870 			break;
3871 
3872 		case 's':
3873 			cp = strchr(optarg, ':');
3874 			if (cp) {
3875 				*cp++ = 0;
3876 				if (*optarg)
3877 					bus = strtoul(optarg, NULL, 10);
3878 				if (*cp)
3879 					devnum = strtoul(cp, NULL, 10);
3880 			} else {
3881 				if (*optarg)
3882 					devnum = strtoul(optarg, NULL, 10);
3883 			}
3884 			break;
3885 
3886 		case 'd':
3887 			cp = strchr(optarg, ':');
3888 			if (!cp) {
3889 				err++;
3890 				break;
3891 			}
3892 			*cp++ = 0;
3893 			if (*optarg)
3894 				vendor = strtoul(optarg, NULL, 16);
3895 			if (*cp)
3896 				product = strtoul(cp, NULL, 16);
3897 			break;
3898 
3899 		case 'D':
3900 			devdump = optarg;
3901 			break;
3902 
3903 		case '?':
3904 		default:
3905 			err++;
3906 			break;
3907 		}
3908 	}
3909 	if (err || argc > optind) {
3910 		fprintf(stderr, "Usage: lsusb [options]...\n"
3911 			"List USB devices\n"
3912 			"  -v, --verbose\n"
3913 			"      Increase verbosity (show descriptors)\n"
3914 			"  -s [[bus]:][devnum]\n"
3915 			"      Show only devices with specified device and/or\n"
3916 			"      bus numbers (in decimal)\n"
3917 			"  -d vendor:[product]\n"
3918 			"      Show only devices with the specified vendor and\n"
3919 			"      product ID numbers (in hexadecimal)\n"
3920 			"  -D device\n"
3921 			"      Selects which device lsusb will examine\n"
3922 			"  -t\n"
3923 			"      Dump the physical USB device hierarchy as a tree\n"
3924 			"  -V, --version\n"
3925 			"      Show version of program\n"
3926 			);
3927 		exit(1);
3928 	}
3929 
3930 	/* by default, print names as well as numbers */
3931 	err = names_init(DATADIR "/usb.ids");
3932 #ifdef HAVE_LIBZ
3933 	if (err != 0)
3934 		err = names_init(DATADIR "/usb.ids.gz");
3935 #endif
3936 	if (err != 0)
3937 		fprintf(stderr, "%s: cannot open \"%s\", %s\n",
3938 				argv[0],
3939 				DATADIR "/usb.ids",
3940 				strerror(err));
3941 	status = 0;
3942 
3943 	usb_init();
3944 
3945 	usb_find_busses();
3946 	usb_find_devices();
3947 
3948 	if (treemode) {
3949 		/* treemode requires at least verblevel 1 */
3950 		verblevel += 1 - VERBLEVEL_DEFAULT;
3951 		status = treedump();
3952 	} else if (devdump)
3953 		status = dump_one_device(devdump);
3954 	else
3955 		status = list_devices(bus, devnum, vendor, product);
3956 
3957 	names_exit();
3958 	return status;
3959 }
3960