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