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