1 /*****************************************************************************/
4 * lsusb.c -- lspci like utility for the USB bus
6 * Copyright (C) 1999-2001, 2003
7 * Thomas Sailer (t.sailer@alumni.ethz.ch)
8 * Copyright (C) 2003-2005 David Brownell
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.
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.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 /*****************************************************************************/
28 #include <sys/types.h>
44 #if (__BYTE_ORDER == __LITTLE_ENDIAN)
45 #define le16_to_cpu(x) (x)
46 #elif (__BYTE_ORDER == __BIG_ENDIAN)
47 #define le16_to_cpu(x) bswap_16(x)
49 #error missing BYTE_ORDER
52 /* from USB 2.0 spec and updates */
53 #define USB_DT_DEVICE_QUALIFIER 0x06
54 #define USB_DT_OTHER_SPEED_CONFIG 0x07
55 #define USB_DT_OTG 0x09
56 #define USB_DT_DEBUG 0x0a
57 #define USB_DT_INTERFACE_ASSOCIATION 0x0b
58 #define USB_DT_SECURITY 0x0c
59 #define USB_DT_KEY 0x0d
60 #define USB_DT_ENCRYPTION_TYPE 0x0e
61 #define USB_DT_BOS 0x0f
62 #define USB_DT_DEVICE_CAPABILITY 0x10
63 #define USB_DT_WIRELESS_ENDPOINT_COMP 0x11
64 #define USB_DT_WIRE_ADAPTER 0x21
65 #define USB_DT_RPIPE 0x22
67 #define USB_DT_RC_INTERFACE 0x23
69 /* Conventional codes for class-specific descriptors. The convention is
70 * defined in the USB "Common Class" Spec (3.11). Individual class specs
71 * are authoritative for their usage, not the "common class" writeup.
73 #define USB_DT_CS_DEVICE (USB_TYPE_CLASS | USB_DT_DEVICE)
74 #define USB_DT_CS_CONFIG (USB_TYPE_CLASS | USB_DT_CONFIG)
75 #define USB_DT_CS_STRING (USB_TYPE_CLASS | USB_DT_STRING)
76 #define USB_DT_CS_INTERFACE (USB_TYPE_CLASS | USB_DT_INTERFACE)
77 #define USB_DT_CS_ENDPOINT (USB_TYPE_CLASS | USB_DT_ENDPOINT)
79 #ifndef USB_CLASS_CCID
80 #define USB_CLASS_CCID 0x0b
83 #ifndef USB_CLASS_VIDEO
84 #define USB_CLASS_VIDEO 0x0e
87 #ifndef USB_CLASS_APPLICATION
88 #define USB_CLASS_APPLICATION 0xfe
91 #define VERBLEVEL_DEFAULT 0 /* 0 gives lspci behaviour; 1, lsusb-0.9 */
93 #define CTRL_RETRIES 2
94 #define CTRL_TIMEOUT (5*1000) /* milliseconds */
96 #define HUB_STATUS_BYTELEN 3 /* max 3 bytes status = hub + 23 ports */
98 extern int lsusb_t(void);
99 static const char *procbususb = "/proc/bus/usb";
100 static unsigned int verblevel = VERBLEVEL_DEFAULT;
101 static int do_report_desc = 1;
102 static const char *encryption_type[] = {"UNSECURE", "WIRED", "CCM_1", "RSA_1", "RESERVED"};
104 static void dump_interface(struct usb_dev_handle *dev, struct usb_interface *interface);
105 static void dump_endpoint(struct usb_dev_handle *dev, struct usb_interface_descriptor *interface, struct usb_endpoint_descriptor *endpoint);
106 static void dump_audiocontrol_interface(struct usb_dev_handle *dev, unsigned char *buf);
107 static void dump_audiostreaming_interface(unsigned char *buf);
108 static void dump_midistreaming_interface(struct usb_dev_handle *dev, unsigned char *buf);
109 static void dump_videocontrol_interface(struct usb_dev_handle *dev, unsigned char *buf);
110 static void dump_videostreaming_interface(unsigned char *buf);
111 static void dump_dfu_interface(unsigned char *buf);
112 static char *dump_comm_descriptor(struct usb_dev_handle *dev, unsigned char *buf, char *indent);
113 static void dump_hid_device(struct usb_dev_handle *dev, struct usb_interface_descriptor *interface, unsigned char *buf);
114 static void dump_audiostreaming_endpoint(unsigned char *buf);
115 static void dump_midistreaming_endpoint(unsigned char *buf);
116 static void dump_hub(char *prefix, unsigned char *p, int has_tt);
117 static void dump_ccid_device(unsigned char *buf);
119 /* ---------------------------------------------------------------------- */
121 static unsigned int convert_le_u32 (const unsigned char *buf)
123 return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
126 /* ---------------------------------------------------------------------- */
128 /* workaround libusb API goofs: "byte" should never be sign extended;
129 * using "char" is trouble. Likewise, sizes should never be negative.
132 static inline int typesafe_control_msg(usb_dev_handle *dev,
133 unsigned char requesttype, unsigned char request,
134 int value, int index,
135 unsigned char *bytes, unsigned size, int timeout)
137 return usb_control_msg(dev, requesttype, request, value, index,
138 (char *) bytes, (int) size, timeout);
141 #define usb_control_msg typesafe_control_msg
143 /* ---------------------------------------------------------------------- */
145 int lprintf(unsigned int vl, const char *format, ...)
152 va_start(ap, format);
153 r = vfprintf(stderr, format, ap);
160 /* ---------------------------------------------------------------------- */
162 static int get_string(struct usb_dev_handle *dev, char* buf, size_t size, u_int8_t id)
172 ret = usb_get_string_simple(dev, id, buf, size);
187 static int get_vendor_string(char *buf, size_t size, u_int16_t vid)
194 if (!(cp = names_vendor(vid)))
196 return snprintf(buf, size, "%s", cp);
199 static int get_product_string(char *buf, size_t size, u_int16_t vid, u_int16_t pid)
206 if (!(cp = names_product(vid, pid)))
208 return snprintf(buf, size, "%s", cp);
211 static int get_class_string(char *buf, size_t size, u_int8_t cls)
218 if (!(cp = names_class(cls)))
220 return snprintf(buf, size, "%s", cp);
223 static int get_subclass_string(char *buf, size_t size, u_int8_t cls, u_int8_t subcls)
230 if (!(cp = names_subclass(cls, subcls)))
232 return snprintf(buf, size, "%s", cp);
235 static int get_protocol_string(char *buf, size_t size, u_int8_t cls, u_int8_t subcls, u_int8_t proto)
242 if (!(cp = names_protocol(cls, subcls, proto)))
244 return snprintf(buf, size, "%s", cp);
247 static int get_audioterminal_string(char *buf, size_t size, u_int16_t termt)
254 if (!(cp = names_audioterminal(termt)))
256 return snprintf(buf, size, "%s", cp);
259 static int get_videoterminal_string(char *buf, size_t size, u_int16_t termt)
266 if (!(cp = names_videoterminal(termt)))
268 return snprintf(buf, size, "%s", cp);
271 static const char *get_guid(unsigned char *buf)
273 static char guid[39];
275 /* NOTE: see RFC 4122 for more information about GUID/UUID
276 * structure. The first fields fields are historically big
277 * endian numbers, dating from Apollo mc68000 workstations.
279 sprintf(guid, "{%02x%02x%02x%02x"
283 "-%02x%02x%02x%02x%02x%02x}",
284 buf[0], buf[1], buf[2], buf[3],
288 buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]);
292 /* ---------------------------------------------------------------------- */
294 static void dump_bytes(unsigned char *buf, unsigned int len)
298 for (i = 0; i < len; i++)
299 printf(" %02x", buf[i]);
303 static void dump_junk(unsigned char *buf, const char *indent, unsigned int len)
309 printf("%sjunk at descriptor end:", indent);
310 for (i = len; i < buf[0]; i++)
311 printf(" %02x", buf[i]);
316 * General config descriptor dump
319 static void dump_device(
320 struct usb_dev_handle *dev,
321 struct usb_device_descriptor *descriptor
324 char vendor[128], product[128];
325 char cls[128], subcls[128], proto[128];
326 char mfg[128], prod[128], serial[128];
328 get_vendor_string(vendor, sizeof(vendor), descriptor->idVendor);
329 get_product_string(product, sizeof(product),
330 descriptor->idVendor, descriptor->idProduct);
331 get_class_string(cls, sizeof(cls), descriptor->bDeviceClass);
332 get_subclass_string(subcls, sizeof(subcls),
333 descriptor->bDeviceClass, descriptor->bDeviceSubClass);
334 get_protocol_string(proto, sizeof(proto), descriptor->bDeviceClass,
335 descriptor->bDeviceSubClass, descriptor->bDeviceProtocol);
336 get_string(dev, mfg, sizeof(mfg), descriptor->iManufacturer);
337 get_string(dev, prod, sizeof(prod), descriptor->iProduct);
338 get_string(dev, serial, sizeof(serial), descriptor->iSerialNumber);
339 printf("Device Descriptor:\n"
341 " bDescriptorType %5u\n"
343 " bDeviceClass %5u %s\n"
344 " bDeviceSubClass %5u %s\n"
345 " bDeviceProtocol %5u %s\n"
346 " bMaxPacketSize0 %5u\n"
347 " idVendor 0x%04x %s\n"
348 " idProduct 0x%04x %s\n"
349 " bcdDevice %2x.%02x\n"
350 " iManufacturer %5u %s\n"
353 " bNumConfigurations %5u\n",
354 descriptor->bLength, descriptor->bDescriptorType,
355 descriptor->bcdUSB >> 8, descriptor->bcdUSB & 0xff,
356 descriptor->bDeviceClass, cls,
357 descriptor->bDeviceSubClass, subcls,
358 descriptor->bDeviceProtocol, proto,
359 descriptor->bMaxPacketSize0,
360 descriptor->idVendor, vendor, descriptor->idProduct, product,
361 descriptor->bcdDevice >> 8, descriptor->bcdDevice & 0xff,
362 descriptor->iManufacturer, mfg,
363 descriptor->iProduct, prod,
364 descriptor->iSerialNumber, serial,
365 descriptor->bNumConfigurations);
368 static void dump_wire_adapter(unsigned char *buf)
371 printf( " Wire Adapter Class Descriptor:\n"
373 " bDescriptorType %5u\n"
374 " bcdWAVersion %2x.%02x\n"
376 " bmAttributes %5u\n"
378 " wRPipeMaxBlock %5u\n"
379 " bRPipeBlockSize %5u\n"
380 " bPwrOn2PwrGood %5u\n"
382 " DeviceRemovable %5u\n",
383 buf[0], buf[1], buf[3],
384 buf[2], buf[4], buf[5],
385 ( buf[6] | buf[7] << 8 ),
386 ( buf[8] | buf[9] << 8 ),
387 buf[10], buf[11], buf[12], buf[13]);
390 static void dump_rc_interface(unsigned char *buf)
392 printf( " Radio Control Interface Class Descriptor:\n"
394 " bDescriptorType %5u\n"
395 " bcdRCIVersion %2x.%02x\n",
396 buf[0], buf[1], buf[3], buf[2]);
400 static void dump_security(unsigned char *buf)
402 printf( " Security Descriptor:\n"
404 " bDescriptorType %5u\n"
405 " wTotalLength %5u\n"
406 " bNumEncryptionTypes %5u\n",
408 (buf[3]<< 8 | buf[2]),
412 static void dump_encryption_type(unsigned char *buf)
414 int b_encryption_type = buf[2] & 0x4;
416 printf( " Encryption Type Descriptor:\n"
418 " bDescriptorType %5u\n"
419 " bEncryptionType %5u %s\n"
420 " bEncryptionValue %5u\n"
421 " bAuthKeyIndex %5u\n",
423 buf[2], encryption_type[b_encryption_type],
427 static void dump_association(struct usb_dev_handle *dev, unsigned char *buf)
429 char cls[128], subcls[128], proto[128];
432 get_class_string(cls, sizeof(cls), buf[4]);
433 get_subclass_string(subcls, sizeof(subcls), buf[4], buf[5]);
434 get_protocol_string(proto, sizeof(proto), buf[4], buf[5], buf[6]);
435 get_string(dev, func, sizeof(func), buf[7]);
436 printf(" Interface Association:\n"
438 " bDescriptorType %5u\n"
439 " bFirstInterface %5u\n"
440 " bInterfaceCount %5u\n"
441 " bFunctionClass %5u %s\n"
442 " bFunctionSubClass %5u %s\n"
443 " bFunctionProtocol %5u %s\n"
444 " iFunction %5u %s\n",
453 static void dump_config(struct usb_dev_handle *dev, struct usb_config_descriptor *config)
458 get_string(dev, cfg, sizeof(cfg), config->iConfiguration);
459 printf(" Configuration Descriptor:\n"
461 " bDescriptorType %5u\n"
462 " wTotalLength %5u\n"
463 " bNumInterfaces %5u\n"
464 " bConfigurationValue %5u\n"
465 " iConfiguration %5u %s\n"
466 " bmAttributes 0x%02x\n",
467 config->bLength, config->bDescriptorType,
468 le16_to_cpu(config->wTotalLength),
469 config->bNumInterfaces, config->bConfigurationValue,
470 config->iConfiguration,
471 cfg, config->bmAttributes);
472 if (!(config->bmAttributes & 0x80))
473 printf(" (Missing must-be-set bit!)\n");
474 if (config->bmAttributes & 0x40)
475 printf(" Self Powered\n");
477 printf(" (Bus Powered)\n");
478 if (config->bmAttributes & 0x20)
479 printf(" Remote Wakeup\n");
480 if (config->bmAttributes & 0x10)
481 printf(" Battery Powered\n");
482 printf(" MaxPower %5umA\n", config->MaxPower * 2);
484 /* avoid re-ordering or hiding descriptors for display */
485 if (config->extralen) {
486 int size = config->extralen;
487 unsigned char *buf = config->extra;
491 dump_junk(buf, " ", size);
496 /* handled separately */
498 case USB_DT_INTERFACE_ASSOCIATION:
499 dump_association(dev, buf);
501 case USB_DT_SECURITY:
504 case USB_DT_ENCRYPTION_TYPE:
505 dump_encryption_type(buf);
508 /* often a misplaced class descriptor */
509 printf(" ** UNRECOGNIZED: ");
510 dump_bytes(buf, buf[0]);
517 for (i = 0 ; i < config->bNumInterfaces ; i++)
518 dump_interface(dev, &config->interface[i]);
521 static void dump_altsetting(struct usb_dev_handle *dev, struct usb_interface_descriptor *interface)
523 char cls[128], subcls[128], proto[128];
529 get_class_string(cls, sizeof(cls), interface->bInterfaceClass);
530 get_subclass_string(subcls, sizeof(subcls), interface->bInterfaceClass, interface->bInterfaceSubClass);
531 get_protocol_string(proto, sizeof(proto), interface->bInterfaceClass, interface->bInterfaceSubClass, interface->bInterfaceProtocol);
532 get_string(dev, ifstr, sizeof(ifstr), interface->iInterface);
533 printf(" Interface Descriptor:\n"
535 " bDescriptorType %5u\n"
536 " bInterfaceNumber %5u\n"
537 " bAlternateSetting %5u\n"
538 " bNumEndpoints %5u\n"
539 " bInterfaceClass %5u %s\n"
540 " bInterfaceSubClass %5u %s\n"
541 " bInterfaceProtocol %5u %s\n"
542 " iInterface %5u %s\n",
543 interface->bLength, interface->bDescriptorType, interface->bInterfaceNumber,
544 interface->bAlternateSetting, interface->bNumEndpoints, interface->bInterfaceClass, cls,
545 interface->bInterfaceSubClass, subcls, interface->bInterfaceProtocol, proto,
546 interface->iInterface, ifstr);
548 /* avoid re-ordering or hiding descriptors for display */
549 if (interface->extralen)
551 size = interface->extralen;
552 buf = interface->extra;
553 while (size >= 2 * sizeof(u_int8_t))
556 dump_junk(buf, " ", size);
562 /* This is the polite way to provide class specific
563 * descriptors: explicitly tagged, using common class
566 case USB_DT_CS_DEVICE:
567 case USB_DT_CS_INTERFACE:
568 switch (interface->bInterfaceClass) {
569 case USB_CLASS_AUDIO:
570 switch (interface->bInterfaceSubClass) {
572 dump_audiocontrol_interface(dev, buf);
575 dump_audiostreaming_interface(buf);
578 dump_midistreaming_interface(dev, buf);
585 dump_comm_descriptor(dev, buf,
588 case USB_CLASS_VIDEO:
589 switch (interface->bInterfaceSubClass) {
591 dump_videocontrol_interface(dev, buf);
594 dump_videostreaming_interface(buf);
600 case USB_CLASS_APPLICATION:
601 switch (interface->bInterfaceSubClass) {
603 dump_dfu_interface(buf);
610 dump_hid_device(dev, interface, buf);
613 dump_ccid_device(buf);
620 /* This is the ugly way: implicitly tagged,
621 * each class could redefine the type IDs.
624 switch (interface->bInterfaceClass) {
626 dump_hid_device(dev, interface, buf);
629 dump_ccid_device(buf);
631 case 0xe0: /* wireless */
632 switch (interface->bInterfaceSubClass) {
634 switch (interface->bInterfaceProtocol) {
636 dump_rc_interface(buf);
643 dump_wire_adapter(buf);
650 /* ... not everything is class-specific */
653 /* handled separately */
655 case USB_DT_INTERFACE_ASSOCIATION:
656 dump_association(dev, buf);
660 /* often a misplaced class descriptor */
661 printf(" ** UNRECOGNIZED: ");
662 dump_bytes(buf, buf[0]);
672 for (i = 0 ; i < interface->bNumEndpoints ; i++)
673 dump_endpoint(dev, interface, &interface->endpoint[i]);
676 static void dump_interface(struct usb_dev_handle *dev, struct usb_interface *interface)
680 for (i = 0; i < interface->num_altsetting; i++)
681 dump_altsetting(dev, &interface->altsetting[i]);
684 static void dump_endpoint(struct usb_dev_handle *dev, struct usb_interface_descriptor *interface, struct usb_endpoint_descriptor *endpoint)
686 static const char *typeattr[] = { "Control", "Isochronous", "Bulk", "Interrupt" };
687 static const char *syncattr[] = { "None", "Asynchronous", "Adaptive", "Synchronous" };
688 static const char *usage[] = { "Data", "Feedback", "Implicit feedback Data", "(reserved)" };
689 static const char *hb[] = { "1x", "2x", "3x", "(?\?)" };
692 unsigned wmax = le16_to_cpu(endpoint->wMaxPacketSize);
694 printf(" Endpoint Descriptor:\n"
696 " bDescriptorType %5u\n"
697 " bEndpointAddress 0x%02x EP %u %s\n"
698 " bmAttributes %5u\n"
699 " Transfer Type %s\n"
702 " wMaxPacketSize 0x%04x %s %d bytes\n"
704 endpoint->bLength, endpoint->bDescriptorType, endpoint->bEndpointAddress, endpoint->bEndpointAddress & 0x0f,
705 (endpoint->bEndpointAddress & 0x80) ? "IN" : "OUT", endpoint->bmAttributes,
706 typeattr[endpoint->bmAttributes & 3], syncattr[(endpoint->bmAttributes >> 2) & 3],
707 usage[(endpoint->bmAttributes >> 4) & 3],
708 wmax, hb[(wmax >> 11) & 3], wmax & 0x7ff,
709 endpoint->bInterval);
710 /* only for audio endpoints */
711 if (endpoint->bLength == 9)
712 printf(" bRefresh %5u\n"
713 " bSynchAddress %5u\n",
714 endpoint->bRefresh, endpoint->bSynchAddress);
716 /* avoid re-ordering or hiding descriptors for display */
717 if (endpoint->extralen)
719 size = endpoint->extralen;
720 buf = endpoint->extra;
721 while (size >= 2 * sizeof(u_int8_t))
724 dump_junk(buf, " ", size);
728 case USB_DT_CS_ENDPOINT:
729 if (interface->bInterfaceClass == 1 && interface->bInterfaceSubClass == 2)
730 dump_audiostreaming_endpoint(buf);
731 else if (interface->bInterfaceClass == 1 && interface->bInterfaceSubClass == 3)
732 dump_midistreaming_endpoint(buf);
734 case USB_DT_CS_INTERFACE:
735 /* MISPLACED DESCRIPTOR ... less indent */
736 switch (interface->bInterfaceClass) {
738 case USB_CLASS_DATA: // comm data
739 dump_comm_descriptor(dev, buf,
743 printf(" INTERFACE CLASS: ");
744 dump_bytes(buf, buf[0]);
748 /* handled separately */
750 case USB_DT_INTERFACE_ASSOCIATION:
751 dump_association(dev, buf);
754 /* often a misplaced class descriptor */
755 printf(" ** UNRECOGNIZED: ");
756 dump_bytes(buf, buf[0]);
765 static void dump_unit(unsigned int data, unsigned int len)
767 char *systems[5] = { "None", "SI Linear", "SI Rotation",
768 "English Linear", "English Rotation" };
770 char *units[5][8] = {
771 { "None", "None", "None", "None", "None",
772 "None", "None", "None" },
773 { "None", "Centimeter", "Gram", "Seconds", "Kelvin",
774 "Ampere", "Candela", "None" },
775 { "None", "Radians", "Gram", "Seconds", "Kelvin",
776 "Ampere", "Candela", "None" },
777 { "None", "Inch", "Slug", "Seconds", "Fahrenheit",
778 "Ampere", "Candela", "None" },
779 { "None", "Degrees", "Slug", "Seconds", "Fahrenheit",
780 "Ampere", "Candela", "None" },
785 int earlier_unit = 0;
787 /* First nibble tells us which system we're in. */
793 printf("System: Vendor defined, Unit: (unknown)\n");
795 printf("System: Reserved, Unit: (unknown)\n");
798 printf("System: %s, Unit: ", systems[sys]);
800 for (i=1 ; i<len*2 ; i++) {
801 char nibble = data & 0xf;
804 if(earlier_unit++ > 0)
806 printf("%s", units[sys][i]);
808 /* This is a _signed_ nibble(!) */
810 int val = nibble & 0x7;
812 val = -((0x7 & ~val) +1);
817 if(earlier_unit == 0)
822 /* ---------------------------------------------------------------------- */
825 * Audio Class descriptor dump
828 static void dump_audiocontrol_interface(struct usb_dev_handle *dev, unsigned char *buf)
830 static const char *chconfig[] = {
831 "Left Front (L)", "Right Front (R)", "Center Front (C)", "Low Freqency Enhancement (LFE)",
832 "Left Surround (LS)", "Right Surround (RS)", "Left of Center (LC)", "Right of Center (RC)",
833 "Surround (S)", "Side Left (SL)", "Side Right (SR)", "Top (T)"
835 static const char *chftrcontrols[] = {
836 "Mute", "Volume", "Bass", "Mid", "Treble", "Graphic Equalizer", "Automatic Gain", "Delay", "Bass Boost", "Loudness"
838 unsigned int i, chcfg, j, k, N, termt;
839 char chnames[128], term[128], termts[128];
841 if (buf[1] != USB_DT_CS_INTERFACE)
842 printf(" Warning: Invalid descriptor\n");
844 printf(" Warning: Descriptor too short\n");
845 printf(" AudioControl Interface Descriptor:\n"
847 " bDescriptorType %5u\n"
848 " bDescriptorSubtype %5u ",
849 buf[0], buf[1], buf[2]);
851 case 0x01: /* HEADER */
852 printf("(HEADER)\n");
853 if (buf[0] < 8+buf[7])
854 printf(" Warning: Descriptor too short\n");
855 printf(" bcdADC %2x.%02x\n"
856 " wTotalLength %5u\n"
857 " bInCollection %5u\n",
858 buf[4], buf[3], buf[5] | (buf[6] << 8), buf[7]);
859 for(i = 0; i < buf[7]; i++)
860 printf(" baInterfaceNr(%2u) %5u\n", i, buf[8+i]);
861 dump_junk(buf, " ", 8+buf[7]);
864 case 0x02: /* INPUT_TERMINAL */
865 printf("(INPUT_TERMINAL)\n");
866 get_string(dev, chnames, sizeof(chnames), buf[10]);
867 get_string(dev, term, sizeof(term), buf[11]);
868 termt = buf[4] | (buf[5] << 8);
869 get_audioterminal_string(termts, sizeof(termts), termt);
871 printf(" Warning: Descriptor too short\n");
872 chcfg = buf[8] | (buf[9] << 8);
873 printf(" bTerminalID %5u\n"
874 " wTerminalType 0x%04x %s\n"
875 " bAssocTerminal %5u\n"
877 " wChannelConfig 0x%04x\n",
878 buf[3], termt, termts, buf[6], buf[7], chcfg);
879 for (i = 0; i < 12; i++)
880 if ((chcfg >> i) & 1)
881 printf(" %s\n", chconfig[i]);
882 printf(" iChannelNames %5u %s\n"
883 " iTerminal %5u %s\n",
884 buf[10], chnames, buf[11], term);
885 dump_junk(buf, " ", 12);
888 case 0x03: /* OUTPUT_TERMINAL */
889 printf("(OUTPUT_TERMINAL)\n");
890 get_string(dev, term, sizeof(term), buf[8]);
891 termt = buf[4] | (buf[5] << 8);
892 get_audioterminal_string(termts, sizeof(termts), termt);
894 printf(" Warning: Descriptor too short\n");
895 printf(" bTerminalID %5u\n"
896 " wTerminalType 0x%04x %s\n"
897 " bAssocTerminal %5u\n"
899 " iTerminal %5u %s\n",
900 buf[3], termt, termts, buf[6], buf[7], buf[8], term);
901 dump_junk(buf, " ", 9);
904 case 0x04: /* MIXER_UNIT */
905 printf("(MIXER_UNIT)\n");
908 if (j == 0 || k == 0) {
909 printf(" Warning: mixer with %5u input and %5u output channels.\n", j, k);
914 get_string(dev, chnames, sizeof(chnames), buf[8+j]);
915 get_string(dev, term, sizeof(term), buf[9+j+N]);
917 printf(" Warning: Descriptor too short\n");
918 chcfg = buf[6+j] | (buf[7+j] << 8);
919 printf(" bUnitID %5u\n"
922 for (i = 0; i < j; i++)
923 printf(" baSourceID(%2u) %5u\n", i, buf[5+i]);
924 printf(" bNrChannels %5u\n"
925 " wChannelConfig 0x%04x\n",
927 for (i = 0; i < 12; i++)
928 if ((chcfg >> i) & 1)
929 printf(" %s\n", chconfig[i]);
930 printf(" iChannelNames %5u %s\n",
932 for (i = 0; i < N; i++)
933 printf(" bmControls 0x%02x\n", buf[9+j+i]);
934 printf(" iMixer %5u %s\n", buf[9+j+N], term);
935 dump_junk(buf, " ", 10+j+N);
938 case 0x05: /* SELECTOR_UNIT */
939 printf("(SELECTOR_UNIT)\n");
940 if (buf[0] < 6+buf[4])
941 printf(" Warning: Descriptor too short\n");
942 get_string(dev, term, sizeof(term), buf[5+buf[4]]);
944 printf(" bUnitID %5u\n"
947 for (i = 0; i < buf[4]; i++)
948 printf(" baSource(%2u) %5u\n", i, buf[5+i]);
949 printf(" iSelector %5u %s\n",
950 buf[5+buf[4]], term);
951 dump_junk(buf, " ", 6+buf[4]);
954 case 0x06: /* FEATURE_UNIT */
955 printf("(FEATURE_UNIT)\n");
959 k = (buf[0] - 7) / j;
960 if (buf[0] < 7+buf[5]*k)
961 printf(" Warning: Descriptor too short\n");
962 get_string(dev, term, sizeof(term), buf[6+buf[5]*k]);
963 printf(" bUnitID %5u\n"
965 " bControlSize %5u\n",
966 buf[3], buf[4], buf[5]);
967 for (i = 0; i < k; i++) {
968 chcfg = buf[6+buf[5]*i];
970 chcfg |= (buf[7+buf[5]*i] << 8);
971 for (j = 0; j < buf[5]; j++)
972 printf(" bmaControls(%2u) 0x%02x\n", i, buf[6+buf[5]*i+j]);
973 for (j = 0; j < 10; j++)
974 if ((chcfg >> j) & 1)
975 printf(" %s\n", chftrcontrols[j]);
977 printf(" iFeature %5u %s\n", buf[6+buf[5]*k], term);
978 dump_junk(buf, " ", 7+buf[5]*k);
981 case 0x07: /* PROCESSING_UNIT */
982 printf("(PROCESSING_UNIT)\n");
985 get_string(dev, chnames, sizeof(chnames), buf[10+j]);
986 get_string(dev, term, sizeof(term), buf[12+j+k]);
987 chcfg = buf[8+j] | (buf[9+j] << 8);
989 printf(" Warning: Descriptor too short\n");
990 printf(" bUnitID %5u\n"
991 " wProcessType %5u\n"
993 buf[3], buf[4] | (buf[5] << 8), buf[6]);
994 for (i = 0; i < j; i++)
995 printf(" baSourceID(%2u) %5u\n", i, buf[7+i]);
996 printf(" bNrChannels %5u\n"
997 " wChannelConfig 0x%04x\n", buf[7+j], chcfg);
998 for (i = 0; i < 12; i++)
999 if ((chcfg >> i) & 1)
1000 printf(" %s\n", chconfig[i]);
1001 printf(" iChannelNames %5u %s\n"
1002 " bControlSize %5u\n", buf[10+j], chnames, buf[11+j]);
1003 for (i = 0; i < k; i++)
1004 printf(" bmControls(%2u) 0x%02x\n", i, buf[12+j+i]);
1006 printf(" Enable Processing\n");
1007 printf(" iProcessing %5u %s\n"
1008 " Process-Specific ", buf[12+j+k], term);
1009 dump_bytes(buf+(13+j+k), buf[0]-(13+j+k));
1012 case 0x08: /* EXTENSION_UNIT */
1013 printf("(EXTENSION_UNIT)\n");
1016 get_string(dev, chnames, sizeof(chnames), buf[10+j]);
1017 get_string(dev, term, sizeof(term), buf[12+j+k]);
1018 chcfg = buf[8+j] | (buf[9+j] << 8);
1019 if (buf[0] < 13+j+k)
1020 printf(" Warning: Descriptor too short\n");
1021 printf(" bUnitID %5u\n"
1022 " wExtensionCode %5u\n"
1024 buf[3], buf[4] | (buf[5] << 8), buf[6]);
1025 for (i = 0; i < j; i++)
1026 printf(" baSourceID(%2u) %5u\n", i, buf[7+i]);
1027 printf(" bNrChannels %5u\n"
1028 " wChannelConfig %5u\n", buf[7+j], chcfg);
1029 for (i = 0; i < 12; i++)
1030 if ((chcfg >> i) & 1)
1031 printf(" %s\n", chconfig[i]);
1032 printf(" iChannelNames %5u %s\n"
1033 " bControlSize %5u\n", buf[10+j], chnames, buf[11+j]);
1034 for (i = 0; i < k; i++)
1035 printf(" bmControls(%2u) 0x%02x\n", i, buf[12+j+i]);
1037 printf(" Enable Processing\n");
1038 printf(" iExtension %5u %s\n",
1040 dump_junk(buf, " ", 13+j+k);
1044 printf("(unknown)\n"
1045 " Invalid desc subtype:");
1046 dump_bytes(buf+3, buf[0]-3);
1051 static void dump_audiostreaming_interface(unsigned char *buf)
1053 static const char *fmtItag[] = {
1054 "TYPE_I_UNDEFINED", "PCM", "PCM8", "IEEE_FLOAT", "ALAW", "MULAW" };
1055 static const char *fmtIItag[] = { "TYPE_II_UNDEFINED", "MPEG", "AC-3" };
1056 static const char *fmtIIItag[] = {
1057 "TYPE_III_UNDEFINED", "IEC1937_AC-3", "IEC1937_MPEG-1_Layer1",
1058 "IEC1937_MPEG-Layer2/3/NOEXT", "IEC1937_MPEG-2_EXT",
1059 "IEC1937_MPEG-2_Layer1_LS", "IEC1937_MPEG-2_Layer2/3_LS" };
1060 unsigned int i, j, fmttag;
1061 const char *fmtptr = "undefined";
1063 if (buf[1] != USB_DT_CS_INTERFACE)
1064 printf(" Warning: Invalid descriptor\n");
1065 else if (buf[0] < 3)
1066 printf(" Warning: Descriptor too short\n");
1067 printf(" AudioStreaming Interface Descriptor:\n"
1069 " bDescriptorType %5u\n"
1070 " bDescriptorSubtype %5u ",
1071 buf[0], buf[1], buf[2]);
1073 case 0x01: /* AS_GENERAL */
1074 printf("(AS_GENERAL)\n");
1076 printf(" Warning: Descriptor too short\n");
1077 fmttag = buf[5] | (buf[6] << 8);
1079 fmtptr = fmtItag[fmttag];
1080 else if (fmttag >= 0x1000 && fmttag <= 0x1002)
1081 fmtptr = fmtIItag[fmttag & 0xfff];
1082 else if (fmttag >= 0x2000 && fmttag <= 0x2006)
1083 fmtptr = fmtIIItag[fmttag & 0xfff];
1084 printf(" bTerminalLink %5u\n"
1085 " bDelay %5u frames\n"
1086 " wFormatTag %5u %s\n",
1087 buf[3], buf[4], fmttag, fmtptr);
1088 dump_junk(buf, " ", 7);
1091 case 0x02: /* FORMAT_TYPE */
1092 printf("(FORMAT_TYPE)\n");
1094 printf(" Warning: Descriptor too short\n");
1095 printf(" bFormatType %5u ", buf[3]);
1097 case 0x01: /* FORMAT_TYPE_I */
1098 printf("(FORMAT_TYPE_I)\n");
1099 j = buf[7] ? (buf[7]*3+8) : 14;
1101 printf(" Warning: Descriptor too short\n");
1102 printf(" bNrChannels %5u\n"
1103 " bSubframeSize %5u\n"
1104 " bBitResolution %5u\n"
1105 " bSamFreqType %5u %s\n",
1106 buf[4], buf[5], buf[6], buf[7], buf[7] ? "Discrete" : "Continuous");
1108 printf(" tLowerSamFreq %7u\n"
1109 " tUpperSamFreq %7u\n",
1110 buf[8] | (buf[9] << 8) | (buf[10] << 16), buf[11] | (buf[12] << 8) | (buf[13] << 16));
1112 for (i = 0; i < buf[7]; i++)
1113 printf(" tSamFreq[%2u] %7u\n", i,
1114 buf[8+3*i] | (buf[9+3*i] << 8) | (buf[10+3*i] << 16));
1115 dump_junk(buf, " ", j);
1118 case 0x02: /* FORMAT_TYPE_II */
1119 printf("(FORMAT_TYPE_II)\n");
1120 j = buf[8] ? (buf[7]*3+9) : 15;
1122 printf(" Warning: Descriptor too short\n");
1123 printf(" wMaxBitRate %5u\n"
1124 " wSamplesPerFrame %5u\n"
1125 " bSamFreqType %5u %s\n",
1126 buf[4] | (buf[5] << 8), buf[6] | (buf[7] << 8), buf[8], buf[8] ? "Discrete" : "Continuous");
1128 printf(" tLowerSamFreq %7u\n"
1129 " tUpperSamFreq %7u\n",
1130 buf[9] | (buf[10] << 8) | (buf[11] << 16), buf[12] | (buf[13] << 8) | (buf[14] << 16));
1132 for (i = 0; i < buf[8]; i++)
1133 printf(" tSamFreq[%2u] %7u\n", i,
1134 buf[9+3*i] | (buf[10+3*i] << 8) | (buf[11+3*i] << 16));
1135 dump_junk(buf, " ", j);
1138 case 0x03: /* FORMAT_TYPE_III */
1139 printf("(FORMAT_TYPE_III)\n");
1140 j = buf[7] ? (buf[7]*3+8) : 14;
1142 printf(" Warning: Descriptor too short\n");
1143 printf(" bNrChannels %5u\n"
1144 " bSubframeSize %5u\n"
1145 " bBitResolution %5u\n"
1146 " bSamFreqType %5u %s\n",
1147 buf[4], buf[5], buf[6], buf[7], buf[7] ? "Discrete" : "Continuous");
1149 printf(" tLowerSamFreq %7u\n"
1150 " tUpperSamFreq %7u\n",
1151 buf[8] | (buf[9] << 8) | (buf[10] << 16), buf[11] | (buf[12] << 8) | (buf[13] << 16));
1153 for (i = 0; i < buf[7]; i++)
1154 printf(" tSamFreq[%2u] %7u\n", i,
1155 buf[8+3*i] | (buf[9+3*i] << 8) | (buf[10+3*i] << 16));
1156 dump_junk(buf, " ", j);
1160 printf("(unknown)\n"
1161 " Invalid desc format type:");
1162 dump_bytes(buf+4, buf[0]-4);
1166 case 0x03: /* FORMAT_SPECIFIC */
1167 printf("(FORMAT_SPECIFIC)\n");
1169 printf(" Warning: Descriptor too short\n");
1170 fmttag = buf[3] | (buf[4] << 8);
1172 fmtptr = fmtItag[fmttag];
1173 else if (fmttag >= 0x1000 && fmttag <= 0x1002)
1174 fmtptr = fmtIItag[fmttag & 0xfff];
1175 else if (fmttag >= 0x2000 && fmttag <= 0x2006)
1176 fmtptr = fmtIIItag[fmttag & 0xfff];
1177 printf(" wFormatTag %5u %s\n", fmttag, fmtptr);
1179 case 0x1001: /* MPEG */
1181 printf(" Warning: Descriptor too short\n");
1182 printf(" bmMPEGCapabilities 0x%04x\n",
1183 buf[5] | (buf[6] << 8));
1185 printf(" Layer I\n");
1187 printf(" Layer II\n");
1189 printf(" Layer III\n");
1191 printf(" MPEG-1 only\n");
1193 printf(" MPEG-1 dual-channel\n");
1195 printf(" MPEG-2 second stereo\n");
1197 printf(" MPEG-2 7.1 channel augmentation\n");
1199 printf(" Adaptive multi-channel prediction\n");
1200 printf(" MPEG-2 multilingual support: ");
1201 switch (buf[6] & 3) {
1203 printf("Not supported\n");
1207 printf("Supported at Fs\n");
1211 printf("Reserved\n");
1215 printf("Supported at Fs and 1/2Fs\n");
1218 printf(" bmMPEGFeatures 0x%02x\n", buf[7]);
1219 printf(" Internal Dynamic Range Control: ");
1220 switch ((buf[7] << 4) & 3) {
1222 printf("not supported\n");
1226 printf("supported but not scalable\n");
1230 printf("scalable, common boost and cut scaling value\n");
1234 printf("scalable, separate boost and cut scaling value\n");
1237 dump_junk(buf, " ", 8);
1240 case 0x1002: /* AC-3 */
1242 printf(" Warning: Descriptor too short\n");
1243 printf(" bmBSID 0x%08x\n"
1244 " bmAC3Features 0x%02x\n",
1245 buf[5] | (buf[6] << 8) | (buf[7] << 16) | (buf[8] << 24), buf[9]);
1247 printf(" RF mode\n");
1249 printf(" Line mode\n");
1251 printf(" Custom0 mode\n");
1253 printf(" Custom1 mode\n");
1254 printf(" Internal Dynamic Range Control: ");
1255 switch ((buf[9] >> 4) & 3) {
1257 printf("not supported\n");
1261 printf("supported but not scalable\n");
1265 printf("scalable, common boost and cut scaling value\n");
1269 printf("scalable, separate boost and cut scaling value\n");
1272 dump_junk(buf, " ", 8);
1276 printf("(unknown)\n"
1277 " Invalid desc format type:");
1278 dump_bytes(buf+4, buf[0]-4);
1283 printf(" Invalid desc subtype:");
1284 dump_bytes(buf+3, buf[0]-3);
1289 static void dump_audiostreaming_endpoint(unsigned char *buf)
1291 static const char *lockdelunits[] = { "Undefined", "Milliseconds", "Decoded PCM samples", "Reserved" };
1292 unsigned int lckdelidx;
1294 if (buf[1] != USB_DT_CS_ENDPOINT)
1295 printf(" Warning: Invalid descriptor\n");
1296 else if (buf[0] < 7)
1297 printf(" Warning: Descriptor too short\n");
1298 printf(" AudioControl Endpoint Descriptor:\n"
1300 " bDescriptorType %5u\n"
1301 " bDescriptorSubtype %5u (%s)\n"
1302 " bmAttributes 0x%02x\n",
1303 buf[0], buf[1], buf[2], buf[2] == 1 ? "EP_GENERAL" : "invalid", buf[3]);
1305 printf(" Sampling Frequency\n");
1309 printf(" MaxPacketsOnly\n");
1313 printf(" bLockDelayUnits %5u %s\n"
1314 " wLockDelay %5u %s\n",
1315 buf[4], lockdelunits[lckdelidx], buf[5] | (buf[6] << 8), lockdelunits[lckdelidx]);
1316 dump_junk(buf, " ", 7);
1319 static void dump_midistreaming_interface(struct usb_dev_handle *dev, unsigned char *buf)
1321 static const char *jacktypes[] = {"Undefined", "Embedded", "External"};
1323 unsigned int j, tlength, capssize;
1326 if (buf[1] != USB_DT_CS_INTERFACE)
1327 printf(" Warning: Invalid descriptor\n");
1328 else if (buf[0] < 3)
1329 printf(" Warning: Descriptor too short\n");
1330 printf( " MIDIStreaming Interface Descriptor:\n"
1332 " bDescriptorType %5u\n"
1333 " bDescriptorSubtype %5u ",
1334 buf[0], buf[1], buf[2]);
1337 printf("(HEADER)\n");
1339 printf(" Warning: Descriptor too short\n");
1340 tlength = buf[5] | (buf[6] << 8);
1341 printf( " bcdADC %2x.%02x\n"
1342 " wTotalLength %5u\n",
1343 buf[4], buf[3], tlength);
1344 dump_junk(buf, " ", 7);
1348 printf("(MIDI_IN_JACK)\n");
1350 printf(" Warning: Descriptor too short\n");
1351 get_string(dev, jackstr, sizeof(jackstr), buf[5]);
1352 printf( " bJackType %5u %s\n"
1355 buf[3], buf[3] < 3 ? jacktypes[buf[3]] : "Invalid",
1356 buf[4], buf[5], jackstr);
1357 dump_junk(buf, " ", 6);
1361 printf("(MIDI_OUT_JACK)\n");
1363 printf(" Warning: Descriptor too short\n");
1364 printf( " bJackType %5u %s\n"
1366 " bNrInputPins %5u\n",
1367 buf[3], buf[3] < 3 ? jacktypes[buf[3]] : "Invalid",
1369 for (j=0; j < buf[5]; j++) {
1370 printf( " baSourceID(%2u) %5u\n"
1371 " BaSourcePin(%2u) %5u\n",
1372 j, buf[2*j+6], j, buf[2*j+7]);
1374 j = 6+buf[5]*2; /* midi10.pdf says, incorrectly: 5+2*p */
1375 get_string(dev, jackstr, sizeof(jackstr), buf[j]);
1376 printf( " iJack %5u %s\n",
1378 dump_junk(buf, " ", j+1);
1382 printf("(ELEMENT)\n");
1384 printf(" Warning: Descriptor too short\n");
1385 printf( " bElementID %5u\n"
1386 " bNrInputPins %5u\n",
1388 for(j=0; j < buf[4]; j++) {
1389 printf( " baSourceID(%2u) %5u\n"
1390 " BaSourcePin(%2u) %5u\n",
1391 j, buf[2*j+5], j, buf[2*j+6]);
1394 printf( " bNrOutputPins %5u\n"
1395 " bInTerminalLink %5u\n"
1396 " bOutTerminalLink %5u\n"
1397 " bElCapsSize %5u\n",
1398 buf[j], buf[j+1], buf[j+2], buf[j+3]);
1399 capssize = buf[j+3];
1401 for(j=0; j < capssize; j++) {
1402 caps |= (buf[j+9+buf[4]*2] << (8*j));
1404 printf( " bmElementCaps 0x%08lx\n", caps);
1406 printf( " Undefined\n");
1408 printf( " MIDI Clock\n");
1410 printf( " MTC (MIDI Time Code)\n");
1412 printf( " MMC (MIDI Machine Control)\n");
1414 printf( " GM1 (General MIDI v.1)\n");
1416 printf( " GM2 (General MIDI v.2)\n");
1418 printf( " GS MIDI Extension\n");
1420 printf( " XG MIDI Extension\n");
1424 printf( " MIDI Patch Bay\n");
1426 printf( " DLS1 (Downloadable Sounds Level 1)\n");
1428 printf( " DLS2 (Downloadable Sounds Level 2)\n");
1429 j = 9+2*buf[4]+capssize;
1430 get_string(dev, jackstr, sizeof(jackstr), buf[j]);
1431 printf( " iElement %5u %s\n", buf[j], jackstr);
1432 dump_junk(buf, " ", j+1);
1436 printf("\n Invalid desc subtype: ");
1437 dump_bytes(buf+3, buf[0]-3);
1442 static void dump_midistreaming_endpoint(unsigned char *buf)
1446 if (buf[1] != USB_DT_CS_ENDPOINT)
1447 printf(" Warning: Invalid descriptor\n");
1448 else if (buf[0] < 5)
1449 printf(" Warning: Descriptor too short\n");
1450 printf(" MIDIStreaming Endpoint Descriptor:\n"
1452 " bDescriptorType %5u\n"
1453 " bDescriptorSubtype %5u (%s)\n"
1454 " bNumEmbMIDIJack %5u\n",
1455 buf[0], buf[1], buf[2], buf[2] == 1 ? "GENERAL" : "Invalid", buf[3]);
1456 for (j=0; j<buf[3]; j++) {
1457 printf(" baAssocJackID(%2u) %5u\n", j, buf[4+j]);
1459 dump_junk(buf, " ", 4+buf[3]);
1463 * Video Class descriptor dump
1466 static void dump_videocontrol_interface(struct usb_dev_handle *dev, unsigned char *buf)
1468 static const char *ctrlnames[] = {
1469 "Brightness", "Contrast", "Hue", "Saturation", "Sharpness", "Gamma",
1470 "White Balance Temperature", "White Balance Component", "Backlight Compensation",
1471 "Gain", "Power Line Frequency", "Hue, Auto", "White Balance Temperature, Auto",
1472 "White Balance Component, Auto", "Digital Multiplier", "Digital Multiplier Limit",
1473 "Analog Video Standard", "Analog Video Lock Status"
1475 static const char *camctrlnames[] = {
1476 "Scanning Mode", "Auto-Exposure Mode", "Auto-Exposure Priority",
1477 "Exposure Time (Absolute)", "Exposure Time (Relative)", "Focus (Absolute)",
1478 "Focus (Relative)", "Iris (Absolute)", "Iris (Relative)", "Zoom (Absolute)",
1479 "Zoom (Relative)", "PanTilt (Absolute)", "PanTilt (Relative)",
1480 "Roll (Absolute)", "Roll (Relative)", "Reserved", "Reserved", "Focus, Auto",
1483 static const char *stdnames[] = {
1484 "None", "NTSC - 525/60", "PAL - 625/50", "SECAM - 625/50",
1485 "NTSC - 625/50", "PAL - 525/60" };
1486 unsigned int i, ctrls, stds, n, p, termt, freq;
1487 char term[128], termts[128];
1489 if (buf[1] != USB_DT_CS_INTERFACE)
1490 printf(" Warning: Invalid descriptor\n");
1491 else if (buf[0] < 3)
1492 printf(" Warning: Descriptor too short\n");
1493 printf(" VideoControl Interface Descriptor:\n"
1495 " bDescriptorType %5u\n"
1496 " bDescriptorSubtype %5u ",
1497 buf[0], buf[1], buf[2]);
1499 case 0x01: /* HEADER */
1500 printf("(HEADER)\n");
1503 printf(" Warning: Descriptor too short\n");
1504 freq = buf[7] | (buf[8] << 8) | (buf[9] << 16) | (buf[10] << 24);
1505 printf(" bcdUVC %2x.%02x\n"
1506 " wTotalLength %5u\n"
1507 " dwClockFrequency %5u.%06uMHz\n"
1508 " bInCollection %5u\n",
1509 buf[4], buf[3], buf[5] | (buf[6] << 8), freq / 1000000,
1511 for(i = 0; i < n; i++)
1512 printf(" baInterfaceNr(%2u) %5u\n", i, buf[12+i]);
1513 dump_junk(buf, " ", 12+n);
1516 case 0x02: /* INPUT_TERMINAL */
1517 printf("(INPUT_TERMINAL)\n");
1518 get_string(dev, term, sizeof(term), buf[7]);
1519 termt = buf[4] | (buf[5] << 8);
1520 n = termt == 0x0201 ? 7 : 0;
1521 get_videoterminal_string(termts, sizeof(termts), termt);
1523 printf(" Warning: Descriptor too short\n");
1524 printf(" bTerminalID %5u\n"
1525 " wTerminalType 0x%04x %s\n"
1526 " bAssocTerminal %5u\n",
1527 buf[3], termt, termts, buf[6]);
1528 printf(" iTerminal %5u %s\n",
1530 if (termt == 0x0201) {
1532 printf(" wObjectiveFocalLengthMin %5u\n"
1533 " wObjectiveFocalLengthMax %5u\n"
1534 " wOcularFocalLength %5u\n"
1535 " bControlSize %5u\n",
1536 buf[8] | (buf[9] << 8), buf[10] | (buf[11] << 8),
1537 buf[12] | (buf[13] << 8), buf[14]);
1539 for (i = 0; i < 3 && i < buf[14]; i++)
1540 ctrls = (ctrls << 8) | buf[8+n-i-1];
1541 printf(" bmControls 0x%08x\n", ctrls);
1542 for (i = 0; i < 19; i++)
1543 if ((ctrls >> i) & 1)
1544 printf(" %s\n", camctrlnames[i]);
1546 dump_junk(buf, " ", 8+n);
1549 case 0x03: /* OUTPUT_TERMINAL */
1550 printf("(OUTPUT_TERMINAL)\n");
1551 get_string(dev, term, sizeof(term), buf[8]);
1552 termt = buf[4] | (buf[5] << 8);
1553 get_audioterminal_string(termts, sizeof(termts), termt);
1555 printf(" Warning: Descriptor too short\n");
1556 printf(" bTerminalID %5u\n"
1557 " wTerminalType 0x%04x %s\n"
1558 " bAssocTerminal %5u\n"
1560 " iTerminal %5u %s\n",
1561 buf[3], termt, termts, buf[6], buf[7], buf[8], term);
1562 dump_junk(buf, " ", 9);
1565 case 0x04: /* SELECTOR_UNIT */
1566 printf("(SELECTOR_UNIT)\n");
1569 printf(" Warning: Descriptor too short\n");
1570 get_string(dev, term, sizeof(term), buf[5+p]);
1572 printf(" bUnitID %5u\n"
1575 for (i = 0; i < p; i++)
1576 printf(" baSource(%2u) %5u\n", i, buf[5+i]);
1577 printf(" iSelector %5u %s\n",
1579 dump_junk(buf, " ", 6+p);
1582 case 0x05: /* PROCESSING_UNIT */
1583 printf("(PROCESSING_UNIT)\n");
1585 get_string(dev, term, sizeof(term), buf[8+n]);
1587 printf(" Warning: Descriptor too short\n");
1588 printf(" bUnitID %5u\n"
1590 " wMaxMultiplier %5u\n"
1591 " bControlSize %5u\n",
1592 buf[3], buf[4], buf[5] | (buf[6] << 8), n);
1594 for (i = 0; i < 3 && i < n; i++)
1595 ctrls = (ctrls << 8) | buf[8+n-i-1];
1596 printf(" bmControls 0x%08x\n", ctrls);
1597 for (i = 0; i < 18; i++)
1598 if ((ctrls >> i) & 1)
1599 printf(" %s\n", ctrlnames[i]);
1601 printf(" iProcessing %5u %s\n"
1602 " bmVideoStandards 0x%2x\n", buf[8+n], term, stds);
1603 for (i = 0; i < 6; i++)
1604 if ((stds >> i) & 1)
1605 printf(" %s\n", stdnames[i]);
1608 case 0x06: /* EXTENSION_UNIT */
1609 printf("(EXTENSION_UNIT)\n");
1612 get_string(dev, term, sizeof(term), buf[23+p+n]);
1613 if (buf[0] < 24+p+n)
1614 printf(" Warning: Descriptor too short\n");
1615 printf(" bUnitID %5u\n"
1616 " guidExtensionCode %s\n"
1617 " bNumControl %5u\n"
1619 buf[3], get_guid(&buf[4]), buf[20], buf[21]);
1620 for (i = 0; i < p; i++)
1621 printf(" baSourceID(%2u) %5u\n", i, buf[22+i]);
1622 printf(" bControlSize %5u\n", buf[22+p]);
1623 for (i = 0; i < n; i++)
1624 printf(" bmControls(%2u) 0x%02x\n", i, buf[23+p+i]);
1625 printf(" iExtension %5u %s\n",
1627 dump_junk(buf, " ", 24+p+n);
1631 printf("(unknown)\n"
1632 " Invalid desc subtype:");
1633 dump_bytes(buf+3, buf[0]-3);
1638 static void dump_videostreaming_interface(unsigned char *buf)
1640 static const char *colorPrims[] = { "Unspecified", "BT.709,sRGB",
1641 "BT.470-2 (M)", "BT.470-2 (B,G)", "SMPTE 170M", "SMPTE 240M" };
1642 static const char *transferChars[] = { "Unspecified", "BT.709",
1643 "BT.470-2 (M)", "BT.470-2 (B,G)", "SMPTE 170M", "SMPTE 240M",
1645 static const char *matrixCoeffs[] = { "Unspecified", "BT.709",
1646 "FCC", "BT.470-2 (B,G)", "SMPTE 170M (BT.601)", "SMPTE 240M" };
1647 unsigned int i, m, n, p, flags, len;
1649 if (buf[1] != USB_DT_CS_INTERFACE)
1650 printf(" Warning: Invalid descriptor\n");
1651 else if (buf[0] < 3)
1652 printf(" Warning: Descriptor too short\n");
1653 printf(" VideoStreaming Interface Descriptor:\n"
1655 " bDescriptorType %5u\n"
1656 " bDescriptorSubtype %5u ",
1657 buf[0], buf[1], buf[2]);
1659 case 0x01: /* INPUT_HEADER */
1660 printf("(INPUT_HEADER)\n");
1663 if (buf[0] < 13+p*n)
1664 printf(" Warning: Descriptor too short\n");
1665 printf(" bNumFormats %5u\n"
1666 " wTotalLength %5u\n"
1667 " bEndPointAddress %5u\n"
1669 " bTerminalLink %5u\n"
1670 " bStillCaptureMethod %5u\n"
1671 " bTriggerSupport %5u\n"
1672 " bTriggerUsage %5u\n"
1673 " bControlSize %5u\n",
1674 p, buf[4] | (buf[5] << 8), buf[6], buf[7], buf[8],
1675 buf[9], buf[10], buf[11], n);
1676 for(i = 0; i < p; i++)
1678 " bmaControls(%2u) %5u\n",
1680 dump_junk(buf, " ", 13+p*n);
1683 case 0x02: /* OUTPUT_HEADER */
1684 printf("(OUTPUT_HEADER)\n");
1688 printf(" Warning: Descriptor too short\n");
1689 printf(" bNumFormats %5u\n"
1690 " wTotalLength %5u\n"
1691 " bEndpointAddress %5u\n"
1692 " bTerminalLink %5u\n"
1693 " bControlSize %5u\n",
1694 p, buf[4] | (buf[5] << 8), buf[6], buf[7], n);
1695 for(i = 0; i < p; i++)
1697 " bmaControls(%2u) %5u\n",
1699 dump_junk(buf, " ", 9+p*n);
1702 case 0x03: /* STILL_IMAGE_FRAME */
1703 printf("(STILL_IMAGE_FRAME)\n");
1706 if (buf[0] < 6+4*n+m)
1707 printf(" Warning: Descriptor too short\n");
1708 printf(" bEndpointAddress %5u\n"
1709 " bNumImageSizePatterns %3u\n",
1711 for (i = 0; i < n; i++)
1712 printf(" wWidth(%2u) %5u\n"
1713 " wHeight(%2u) %5u\n",
1714 i, buf[5+4*i] | (buf[6+4*i] << 8),
1715 i, buf[7+4*i] | (buf[8+4*i] << 8));
1716 printf(" bNumCompressionPatterns %3u\n", n);
1717 for (i = 0; i < m; i++)
1718 printf(" bCompression(%2u) %5u\n",
1720 dump_junk(buf, " ", 6+4*n+m);
1723 case 0x04: /* FORMAT_UNCOMPRESSED */
1724 printf("(FORMAT_UNCOMPRESSED)\n");
1726 printf(" Warning: Descriptor too short\n");
1728 printf(" bFormatIndex %5u\n"
1729 " bNumFrameDescriptors %5u\n"
1731 " bBitsPerPixel %5u\n"
1732 " bDefaultFrameIndex %5u\n"
1733 " bAspectRatioX %5u\n"
1734 " bAspectRatioY %5u\n"
1735 " bmInterlaceFlags 0x%02x\n",
1736 buf[3], buf[4], get_guid(&buf[5]), buf[21], buf[22],
1737 buf[23], buf[24], flags);
1738 printf(" Interlaced stream or variable: %s\n",
1739 (flags & (1 << 0)) ? "Yes" : "No");
1740 printf(" Fields per frame: %u fields\n",
1741 (flags & (1 << 1)) ? 2 : 1);
1742 printf(" Field 1 first: %s\n",
1743 (flags & (1 << 2)) ? "Yes" : "No");
1744 printf(" Field pattern: ");
1745 switch((flags >> 4) & 0x03)
1748 printf("Field 1 only\n");
1751 printf("Field 2 only\n");
1754 printf("Regular pattern of fields 1 and 2\n");
1757 printf("Random pattern of fields 1 and 2\n");
1760 printf(" bCopyProtect %5u\n", buf[26]);
1761 dump_junk(buf, " ", 27);
1764 case 0x05: /* FRAME UNCOMPRESSED */
1765 case 0x07: /* FRAME_MJPEG */
1767 printf("(FRAME_UNCOMPRESSED)\n");
1769 printf("(FRAME_MJPEG)\n");
1770 len = (buf[25] != 0) ? (26+buf[25]*4) : 38;
1772 printf(" Warning: Descriptor too short\n");
1774 printf(" bFrameIndex %5u\n"
1775 " bmCapabilities 0x%02x\n",
1777 printf(" Still image %ssupported\n",
1778 (flags & (1 << 0)) ? "" : "un");
1779 if (flags & (1 << 1))
1780 printf(" Fixed frame-rate\n");
1781 printf(" wWidth %5u\n"
1783 " dwMinBitRate %9u\n"
1784 " dwMaxBitRate %9u\n"
1785 " dwMaxVideoFrameBufferSize %9u\n"
1786 " dwDefaultFrameInterval %9u\n"
1787 " bFrameIntervalType %5u\n",
1788 buf[5] | (buf[6] << 8), buf[7] | (buf[8] << 8),
1789 buf[9] | (buf[10] << 8) | (buf[11] << 16) | (buf[12] << 24),
1790 buf[13] | (buf[14] << 8) | (buf[15] << 16) | (buf[16] << 24),
1791 buf[17] | (buf[18] << 8) | (buf[19] << 16) | (buf[20] << 24),
1792 buf[21] | (buf[22] << 8) | (buf[23] << 16) | (buf[24] << 24),
1795 printf(" dwMinFrameInterval %9u\n"
1796 " dwMaxFrameInterval %9u\n"
1797 " dwFrameIntervalStep %9u\n",
1798 buf[26] | (buf[27] << 8) | (buf[28] << 16) | (buf[29] << 24),
1799 buf[30] | (buf[31] << 8) | (buf[32] << 16) | (buf[33] << 24),
1800 buf[34] | (buf[35] << 8) | (buf[36] << 16) | (buf[37] << 24));
1802 for (i = 0; i < buf[25]; i++)
1803 printf(" dwFrameInterval(%2u) %9u\n",
1804 i, buf[26+4*i] | (buf[27+4*i] << 8) |
1805 (buf[28+4*i] << 16) | (buf[29+4*i] << 24));
1806 dump_junk(buf, " ", len);
1809 case 0x06: /* FORMAT_MJPEG */
1810 printf("(FORMAT_MJPEG)\n");
1812 printf(" Warning: Descriptor too short\n");
1814 printf(" bFormatIndex %5u\n"
1815 " bNumFrameDescriptors %5u\n"
1817 buf[3], buf[4], flags);
1818 printf(" Fixed-size samples: %s\n",
1819 (flags & (1 << 0)) ? "Yes" : "No");
1821 printf(" bDefaultFrameIndex %5u\n"
1822 " bAspectRatioX %5u\n"
1823 " bAspectRatioY %5u\n"
1824 " bmInterlaceFlags 0x%02x\n",
1825 buf[6], buf[7], buf[8], flags);
1826 printf(" Interlaced stream or variable: %s\n",
1827 (flags & (1 << 0)) ? "Yes" : "No");
1828 printf(" Fields per frame: %u fields\n",
1829 (flags & (1 << 1)) ? 2 : 1);
1830 printf(" Field 1 first: %s\n",
1831 (flags & (1 << 2)) ? "Yes" : "No");
1832 printf(" Field pattern: ");
1833 switch((flags >> 4) & 0x03)
1836 printf("Field 1 only\n");
1839 printf("Field 2 only\n");
1842 printf("Regular pattern of fields 1 and 2\n");
1845 printf("Random pattern of fields 1 and 2\n");
1848 printf(" bCopyProtect %5u\n", buf[10]);
1849 dump_junk(buf, " ", 11);
1852 case 0x0d: /* COLORFORMAT */
1853 printf("(COLORFORMAT)\n");
1855 printf(" Warning: Descriptor too short\n");
1856 printf(" bColorPrimaries %5u (%s)\n",
1857 buf[3], (buf[3] <= 5) ? colorPrims[buf[3]] : "Unknown");
1858 printf(" bTransferCharacteristics %5u (%s)\n",
1859 buf[4], (buf[4] <= 7) ? transferChars[buf[4]] : "Unknown");
1860 printf(" bMatrixCoefficients %5u (%s)\n",
1861 buf[5], (buf[5] <= 5) ? matrixCoeffs[buf[5]] : "Unknown");
1862 dump_junk(buf, " ", 6);
1866 printf(" Invalid desc subtype:");
1867 dump_bytes(buf+3, buf[0]-3);
1872 static void dump_dfu_interface(unsigned char *buf)
1874 if (buf[1] != USB_DT_CS_DEVICE)
1875 printf(" Warning: Invalid descriptor\n");
1876 else if (buf[0] < 7)
1877 printf(" Warning: Descriptor too short\n");
1878 printf(" Device Firmware Upgrade Interface Descriptor:\n"
1880 " bDescriptorType %5u\n"
1881 " bmAttributes %5u\n",
1882 buf[0], buf[1], buf[2]);
1884 printf(" (unknown attributes!)\n");
1885 printf(" Will %sDetach\n", (buf[2] & 0x08) ? "" : "Not ");
1886 printf(" Manifestation %s\n", (buf[2] & 0x04) ? "Tolerant" : "Intolerant");
1887 printf(" Upload %s\n", (buf[2] & 0x02) ? "Supported" : "Unsupported");
1888 printf(" Download %s\n", (buf[2] & 0x01) ? "Supported" : "Unsupported");
1889 printf(" wDetachTimeout %5u milliseconds\n"
1890 " wTransferSize %5u bytes\n",
1891 buf[3] | (buf[4] << 8), buf[5] | (buf[6] << 8));
1893 /* DFU 1.0 defines no version code, DFU 1.1 does */
1896 printf(" bcdDFUVersion %x.%02x\n",
1900 static void dump_hub(char *prefix, unsigned char *p, int has_tt)
1902 unsigned int l, i, j;
1903 unsigned int wHubChar = (p[4] << 8) | p[3];
1905 printf("%sHub Descriptor:\n", prefix);
1906 printf("%s bLength %3u\n", prefix, p[0]);
1907 printf("%s bDescriptorType %3u\n", prefix, p[1]);
1908 printf("%s nNbrPorts %3u\n", prefix, p[2]);
1909 printf("%s wHubCharacteristic 0x%04x\n", prefix, wHubChar);
1910 switch (wHubChar & 0x03) {
1912 printf("%s Ganged power switching\n", prefix);
1915 printf("%s Per-port power switching\n", prefix);
1918 printf("%s No power switching (usb 1.0)\n", prefix);
1921 if (wHubChar & 0x04)
1922 printf("%s Compound device\n", prefix);
1923 switch ((wHubChar >> 3) & 0x03) {
1925 printf("%s Ganged overcurrent protection\n", prefix);
1928 printf("%s Per-port overcurrent protection\n", prefix);
1931 printf("%s No overcurrent protection\n", prefix);
1935 l = (wHubChar >> 5) & 0x03;
1936 printf("%s TT think time %d FS bits\n", prefix, (l + 1) * 8);
1938 if (wHubChar & (1<<7))
1939 printf("%s Port indicators\n", prefix);
1940 printf("%s bPwrOn2PwrGood %3u * 2 milli seconds\n", prefix, p[5]);
1941 printf("%s bHubContrCurrent %3u milli Ampere\n", prefix, p[6]);
1942 l= (p[2] >> 3) + 1; /* this determines the variable number of bytes following */
1943 if (l > HUB_STATUS_BYTELEN)
1944 l = HUB_STATUS_BYTELEN;
1945 printf("%s DeviceRemovable ", prefix);
1946 for(i = 0; i < l; i++)
1947 printf(" 0x%02x", p[7+i]);
1948 printf("\n%s PortPwrCtrlMask ", prefix);
1949 for(j = 0; j < l; j++)
1950 printf(" 0x%02x", p[7+i+j]);
1954 static void dump_ccid_device(unsigned char *buf)
1959 printf(" Warning: Descriptor too short\n");
1962 printf(" ChipCard Interface Descriptor:\n"
1964 " bDescriptorType %5u\n"
1965 " bcdCCID %2x.%02x",
1966 buf[0], buf[1], buf[3], buf[2]);
1967 if (buf[3] != 1 || buf[2] != 0)
1968 fputs(" (Warning: Only accurate for version 1.0)", stdout);
1971 printf(" nMaxSlotIndex %5u\n"
1972 " bVoltageSupport %5u %s%s%s\n",
1975 (buf[5] & 1) ? "5.0V " : "",
1976 (buf[5] & 2) ? "3.0V " : "",
1977 (buf[5] & 4) ? "1.8V " : "");
1979 us = convert_le_u32 (buf+6);
1980 printf(" dwProtocols %5u ", us);
1982 fputs(" T=0", stdout);
1984 fputs(" T=1", stdout);
1986 fputs(" (Invalid values detected)", stdout);
1989 us = convert_le_u32(buf+10);
1990 printf(" dwDefaultClock %5u\n", us);
1991 us = convert_le_u32(buf+14);
1992 printf(" dwMaxiumumClock %5u\n", us);
1993 printf(" bNumClockSupported %5u\n", buf[18]);
1994 us = convert_le_u32(buf+19);
1995 printf(" dwDataRate %7u bps\n", us);
1996 us = convert_le_u32(buf+23);
1997 printf(" dwMaxDataRate %7u bps\n", us);
1998 printf(" bNumDataRatesSupp. %5u\n", buf[27]);
2000 us = convert_le_u32(buf+28);
2001 printf(" dwMaxIFSD %5u\n", us);
2003 us = convert_le_u32(buf+32);
2004 printf(" dwSyncProtocols %08X ", us);
2006 fputs(" 2-wire", stdout);
2008 fputs(" 3-wire", stdout);
2010 fputs(" I2C", stdout);
2013 us = convert_le_u32(buf+36);
2014 printf(" dwMechanical %08X ", us);
2016 fputs(" accept", stdout);
2018 fputs(" eject", stdout);
2020 fputs(" capture", stdout);
2022 fputs(" lock", stdout);
2025 us = convert_le_u32(buf+40);
2026 printf(" dwFeatures %08X\n", us);
2028 fputs(" Auto configuration based on ATR\n",stdout);
2030 fputs(" Auto activation on insert\n",stdout);
2032 fputs(" Auto voltage selection\n",stdout);
2034 fputs(" Auto clock change\n",stdout);
2036 fputs(" Auto baud rate change\n",stdout);
2038 fputs(" Auto parameter negotation made by CCID\n",stdout);
2039 else if ((us & 0x0080))
2040 fputs(" Auto PPS made by CCID\n",stdout);
2041 else if ((us & (0x0040 | 0x0080)))
2042 fputs(" WARNING: conflicting negotation features\n",stdout);
2045 fputs(" CCID can set ICC in clock stop mode\n",stdout);
2047 fputs(" NAD value other than 0x00 accpeted\n",stdout);
2049 fputs(" Auto IFSD exchange\n",stdout);
2051 if ((us & 0x00010000))
2052 fputs(" TPDU level exchange\n",stdout);
2053 else if ((us & 0x00020000))
2054 fputs(" Short APDU level exchange\n",stdout);
2055 else if ((us & 0x00040000))
2056 fputs(" Short and extended APDU level exchange\n",stdout);
2057 else if ((us & 0x00070000))
2058 fputs(" WARNING: conflicting exchange levels\n",stdout);
2060 us = convert_le_u32(buf+44);
2061 printf(" dwMaxCCIDMsgLen %5u\n", us);
2063 printf(" bClassGetResponse ");
2064 if (buf[48] == 0xff)
2065 fputs("echo\n", stdout);
2067 printf(" %02X\n", buf[48]);
2069 printf(" bClassEnvelope ");
2070 if (buf[49] == 0xff)
2071 fputs("echo\n", stdout);
2073 printf(" %02X\n", buf[48]);
2075 printf(" wlcdLayout ");
2076 if (!buf[50] && !buf[51])
2077 fputs("none\n", stdout);
2079 printf("%u cols %u lines\n", buf[50], buf[51]);
2081 printf(" bPINSupport %5u ", buf[52]);
2083 fputs(" verification", stdout);
2085 fputs(" modification", stdout);
2088 printf(" bMaxCCIDBusySlots %5u\n", buf[53]);
2091 fputs(" junk ", stdout);
2092 dump_bytes(buf+54, buf[0]-54);
2096 /* ---------------------------------------------------------------------- */
2102 static void dump_report_desc(unsigned char *b, int l)
2104 unsigned int t, j, bsize, btag, btype, data = 0xffff, hut = 0xffff;
2106 char *types[4] = { "Main", "Global", "Local", "reserved" };
2107 char indent[] = " ";
2109 printf(" Report Descriptor: (length is %d)\n", l);
2110 for(i = 0; i < l; ) {
2112 bsize = b[i] & 0x03;
2115 btype = b[i] & (0x03 << 2);
2116 btag = b[i] & ~0x03; /* 2 LSB bits encode length */
2117 printf(" Item(%-6s): %s, data=", types[btype>>2],
2118 names_reporttag(btag));
2122 for(j = 0; j < bsize; j++) {
2123 printf("0x%02x ", b[i+1+j]);
2124 data += (b[i+1+j] << (8*j));
2126 printf("] %d", data);
2131 case 0x04 : /* Usage Page */
2132 printf("%s%s\n", indent, names_huts(data));
2136 case 0x08 : /* Usage */
2137 case 0x18 : /* Usage Minimum */
2138 case 0x28 : /* Usage Maximum */
2139 printf("%s%s\n", indent,
2140 names_hutus((hut << 16) + data));
2143 case 0x54 : /* Unit Exponent */
2144 printf("%sUnit Exponent: %i\n", indent,
2148 case 0x64 : /* Unit */
2149 printf("%s", indent);
2150 dump_unit(data, bsize);
2153 case 0xa0 : /* Collection */
2154 printf("%s", indent);
2157 printf("Physical\n");
2161 printf("Application\n");
2165 printf("Logical\n");
2173 printf("Named Array\n");
2177 printf("Usage Switch\n");
2181 printf("Usage Modifier\n");
2186 printf("Vendor defined\n");
2188 printf("Reserved for future use.\n");
2191 case 0x80: /* Input */
2192 case 0x90: /* Output */
2193 case 0xb0: /* Feature */
2194 printf("%s%s %s %s %s %s\n%s%s %s %s %s\n",
2196 data & 0x01 ? "Constant": "Data",
2197 data & 0x02 ? "Variable": "Array",
2198 data & 0x04 ? "Relative": "Absolute",
2199 data & 0x08 ? "Wrap" : "No_Wrap",
2200 data & 0x10 ? "Non_Linear": "Linear",
2202 data & 0x20 ? "No_Preferred_State": "Preferred_State",
2203 data & 0x40 ? "Null_State": "No_Null_Position",
2204 data & 0x80 ? "Volatile": "Non_Volatile",
2205 data &0x100 ? "Buffered Bytes": "Bitfield"
2213 static void dump_hid_device(struct usb_dev_handle *dev, struct usb_interface_descriptor *interface, unsigned char *buf)
2215 unsigned int i, len;
2217 unsigned char dbuf[8192];
2219 if (buf[1] != USB_DT_HID)
2220 printf(" Warning: Invalid descriptor\n");
2221 else if (buf[0] < 6+3*buf[5])
2222 printf(" Warning: Descriptor too short\n");
2223 printf(" HID Device Descriptor:\n"
2225 " bDescriptorType %5u\n"
2226 " bcdHID %2x.%02x\n"
2227 " bCountryCode %5u %s\n"
2228 " bNumDescriptors %5u\n",
2229 buf[0], buf[1], buf[3], buf[2], buf[4],
2230 names_countrycode(buf[4]) ? : "Unknown", buf[5]);
2231 for (i = 0; i < buf[5]; i++)
2232 printf(" bDescriptorType %5u %s\n"
2233 " wDescriptorLength %5u\n",
2234 buf[6+3*i], names_hid(buf[6+3*i]),
2235 buf[7+3*i] | (buf[8+3*i] << 8));
2236 dump_junk(buf, " ", 6+3*buf[5]);
2237 if (!do_report_desc)
2241 printf( " Report Descriptors: \n"
2242 " ** UNAVAILABLE **\n");
2246 for (i = 0; i < buf[5]; i++) {
2247 /* we are just interested in report descriptors*/
2248 if (buf[6+3*i] != USB_DT_REPORT)
2250 len = buf[7+3*i] | (buf[8+3*i] << 8);
2251 if (len > sizeof(dbuf)) {
2252 printf("report descriptor too long\n");
2255 if (usb_claim_interface(dev, interface->bInterfaceNumber) == 0) {
2258 while (n < len && retries--)
2259 n = usb_control_msg(dev,
2260 USB_ENDPOINT_IN | USB_TYPE_STANDARD
2261 | USB_RECIP_INTERFACE,
2262 USB_REQ_GET_DESCRIPTOR,
2263 (USB_DT_REPORT << 8),
2264 interface->bInterfaceNumber,
2270 printf(" Warning: incomplete report descriptor\n");
2271 dump_report_desc(dbuf, n);
2273 usb_release_interface(dev, interface->bInterfaceNumber);
2275 /* recent Linuxes require claim() for RECIP_INTERFACE,
2276 * so "rmmod hid" will often make these available.
2278 printf( " Report Descriptors: \n"
2279 " ** UNAVAILABLE **\n");
2285 dump_comm_descriptor(struct usb_dev_handle *dev, unsigned char *buf, char *indent)
2296 printf("%sCDC Header:\n"
2297 "%s bcdCDC %x.%02x\n",
2299 indent, buf[4], buf[3]);
2301 case 0x01: /* call management functional desc */
2302 type = "Call Management";
2305 printf("%sCDC Call Management:\n"
2306 "%s bmCapabilities 0x%02x\n",
2310 printf("%s call management\n", indent);
2312 printf("%s use DataInterface\n", indent);
2313 printf("%s bDataInterface %d\n", indent, buf[4]);
2315 case 0x02: /* acm functional desc */
2319 printf("%sCDC ACM:\n"
2320 "%s bmCapabilities 0x%02x\n",
2324 printf("%s connection notifications\n", indent);
2326 printf("%s sends break\n", indent);
2328 printf("%s line coding and serial state\n", indent);
2330 printf("%s get/set/clear comm features\n", indent);
2332 // case 0x03: /* direct line management */
2333 // case 0x04: /* telephone ringer */
2334 // case 0x05: /* telephone call and line state reporting */
2335 case 0x06: /* union desc */
2339 printf("%sCDC Union:\n"
2340 "%s bMasterInterface %d\n"
2341 "%s bSlaveInterface ",
2345 for (tmp = 4; tmp < buf [0]; tmp++)
2346 printf("%d ", buf [tmp]);
2349 case 0x07: /* country selection functional desc */
2350 type = "Country Selection";
2351 if (buf [0] < 6 || (buf[0] & 1) != 0)
2353 get_string(dev, str, sizeof str, buf[3]);
2354 printf("%sCountry Selection:\n"
2355 "%s iCountryCodeRelDate %4d %s\n",
2357 indent, buf[3], (buf[3] && *str) ? str : "(?\?)");
2358 for (tmp = 4; tmp < buf [0]; tmp += 2) {
2359 printf("%s wCountryCode 0x%02x%02x\n",
2360 indent, buf[tmp], buf[tmp + 1]);
2363 case 0x08: /* telephone operational modes */
2364 type = "Telephone Operations";
2367 printf("%sCDC Telephone operations:\n"
2368 "%s bmCapabilities 0x%02x\n",
2372 printf("%s computer centric mode\n", indent);
2374 printf("%s standalone mode\n", indent);
2376 printf("%s simple mode\n", indent);
2378 // case 0x09: /* USB terminal */
2379 case 0x0a: /* network channel terminal */
2380 type = "Network Channel Terminal";
2383 get_string(dev, str, sizeof str, buf[4]);
2384 printf("%sNetwork Channel Terminal:\n"
2385 "%s bEntityId %3d\n"
2387 "%s bChannelIndex %3d\n"
2388 "%s bPhysicalInterface %3d\n",
2391 indent, buf[4], str,
2395 // case 0x0b: /* protocol unit */
2396 // case 0x0c: /* extension unit */
2397 // case 0x0d: /* multi-channel management */
2398 // case 0x0e: /* CAPI control management*/
2399 case 0x0f: /* ethernet functional desc */
2403 get_string(dev, str, sizeof str, buf[3]);
2405 tmp |= buf [6]; tmp <<= 8;
2406 tmp |= buf [5]; tmp <<= 8;
2408 printf("%sCDC Ethernet:\n"
2409 "%s iMacAddress %10d %s\n"
2410 "%s bmEthernetStatistics 0x%08x\n",
2412 indent, buf[3], (buf[3] && *str) ? str : "(?\?)",
2414 /* FIXME dissect ALL 28 bits */
2415 printf("%s wMaxSegmentSize %10d\n"
2416 "%s wNumberMCFilters 0x%04x\n"
2417 "%s bNumberPowerFilters %10d\n",
2418 indent, (buf[9]<<8)|buf[8],
2419 indent, (buf[11]<<8)|buf[10],
2422 // case 0x10: /* ATM networking */
2423 case 0x11: /* WHCM functional desc */
2424 type = "WHCM version";
2427 printf("%sCDC WHCM:\n"
2428 "%s bcdVersion %x.%02x\n",
2430 indent, buf[4], buf[3]);
2432 case 0x12: /* MDLM functional desc */
2436 printf("%sCDC MDLM:\n"
2437 "%s bcdCDC %x.%02x\n"
2440 indent, buf[4], buf[3],
2441 indent, get_guid(buf + 5));
2443 case 0x13: /* MDLM detail desc */
2444 type = "MDLM detail";
2447 printf("%sCDC MDLM detail:\n"
2448 "%s bGuidDescriptorType %02x\n"
2453 dump_bytes(buf + 4, buf[0] - 4);
2455 case 0x14: /* device management functional desc */
2456 type = "Device Management";
2459 printf("%sCDC Device Management:\n"
2460 "%s bcdVersion %x.%02x\n"
2461 "%s wMaxCommand %d\n",
2463 indent, buf[4], buf[3],
2464 indent, (buf[6]<<8)| buf[5]);
2466 case 0x15: /* OBEX functional desc */
2470 printf("%sCDC OBEX:\n"
2471 "%s bcdVersion %x.%02x\n",
2473 indent, buf[4], buf[3]);
2475 // case 0x16: /* command set functional desc */
2476 // case 0x17: /* command set detail desc */
2477 // case 0x18: /* telephone control model functional desc */
2479 /* FIXME there are about a dozen more descriptor types */
2480 printf("%sUNRECOGNIZED CDC: ", indent);
2481 dump_bytes(buf, buf[0]);
2482 return "unrecognized comm descriptor";
2487 printf("%sINVALID CDC (%s): ", indent, type);
2488 dump_bytes(buf, buf[0]);
2489 return "corrupt comm descriptor";
2492 /* ---------------------------------------------------------------------- */
2494 static void do_hub(struct usb_dev_handle *fd, unsigned has_tt)
2496 unsigned char buf [7 /* base descriptor */
2497 + 2 /* bitmasks */ * HUB_STATUS_BYTELEN ];
2500 ret = usb_control_msg(fd,
2501 USB_ENDPOINT_IN | USB_TYPE_CLASS | USB_RECIP_DEVICE,
2502 USB_REQ_GET_DESCRIPTOR,
2504 buf, sizeof buf, CTRL_TIMEOUT);
2505 if (ret < 9 /* at least one port's bitmasks */) {
2508 "incomplete hub descriptor, %d bytes\n",
2510 /* Linux returns EHOSTUNREACH for suspended devices */
2511 else if (errno != EHOSTUNREACH)
2512 perror ("can't get hub descriptor");
2515 dump_hub("", buf, has_tt);
2517 printf(" Hub Port Status:\n");
2518 for (i = 0; i < buf[2]; i++) {
2519 unsigned char stat [4];
2521 ret = usb_control_msg(fd,
2522 USB_ENDPOINT_IN | USB_TYPE_CLASS
2530 "cannot read port %d status, %s (%d)\n",
2531 i + 1, strerror(errno), errno);
2535 printf(" Port %d: %02x%02x.%02x%02x", i + 1,
2538 /* CAPS are used to highlight "transient" states */
2539 printf("%s%s%s%s%s",
2540 (stat[2] & 0x10) ? " C_RESET" : "",
2541 (stat[2] & 0x08) ? " C_OC" : "",
2542 (stat[2] & 0x04) ? " C_SUSPEND" : "",
2543 (stat[2] & 0x02) ? " C_ENABLE" : "",
2544 (stat[2] & 0x01) ? " C_CONNECT" : "");
2545 printf("%s%s%s%s%s%s%s%s%s%s\n",
2546 (stat[1] & 0x10) ? " indicator" : "",
2547 (stat[1] & 0x08) ? " test" : "",
2548 (stat[1] & 0x04) ? " highspeed" : "",
2549 (stat[1] & 0x02) ? " lowspeed" : "",
2550 (stat[1] & 0x01) ? " power" : "",
2551 (stat[0] & 0x10) ? " RESET" : "",
2552 (stat[0] & 0x08) ? " oc" : "",
2553 (stat[0] & 0x04) ? " suspend" : "",
2554 (stat[0] & 0x02) ? " enable" : "",
2555 (stat[0] & 0x01) ? " connect" : "");
2559 static void do_dualspeed(struct usb_dev_handle *fd)
2561 unsigned char buf [10];
2562 char cls[128], subcls[128], proto[128];
2565 ret = usb_control_msg(fd,
2566 USB_ENDPOINT_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
2567 USB_REQ_GET_DESCRIPTOR,
2568 USB_DT_DEVICE_QUALIFIER << 8, 0,
2569 buf, sizeof buf, CTRL_TIMEOUT);
2570 if (ret < 0 && errno != EPIPE)
2571 perror ("can't get device qualifier");
2573 /* all dual-speed devices have a qualifier */
2574 if (ret != sizeof buf
2576 || buf[1] != USB_DT_DEVICE_QUALIFIER)
2579 get_class_string(cls, sizeof(cls),
2581 get_subclass_string(subcls, sizeof(subcls),
2583 get_protocol_string(proto, sizeof(proto),
2584 buf[4], buf[5], buf[6]);
2585 printf("Device Qualifier (for other device speed):\n"
2587 " bDescriptorType %5u\n"
2588 " bcdUSB %2x.%02x\n"
2589 " bDeviceClass %5u %s\n"
2590 " bDeviceSubClass %5u %s\n"
2591 " bDeviceProtocol %5u %s\n"
2592 " bMaxPacketSize0 %5u\n"
2593 " bNumConfigurations %5u\n",
2601 /* FIXME also show the OTHER_SPEED_CONFIG descriptors */
2604 static void do_debug(struct usb_dev_handle *fd)
2606 unsigned char buf [4];
2609 ret = usb_control_msg(fd,
2610 USB_ENDPOINT_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
2611 USB_REQ_GET_DESCRIPTOR,
2612 USB_DT_DEBUG << 8, 0,
2613 buf, sizeof buf, CTRL_TIMEOUT);
2614 if (ret < 0 && errno != EPIPE)
2615 perror ("can't get debug descriptor");
2617 /* some high speed devices are also "USB2 debug devices", meaning
2618 * you can use them with some EHCI implementations as another kind
2619 * of system debug channel: like JTAG, RS232, or a console.
2621 if (ret != sizeof buf
2623 || buf[1] != USB_DT_DEBUG)
2626 printf("Debug descriptor:\n"
2628 " bDescriptorType %4u\n"
2629 " bDebugInEndpoint 0x%02x\n"
2630 " bDebugOutEndpoint 0x%02x\n",
2635 static unsigned char *find_otg(unsigned char *buf, int buflen)
2639 while (buflen >= 3) {
2640 if (buf[0] == 3 && buf[1] == USB_DT_OTG)
2642 if (buf[0] > buflen)
2650 static int do_otg(struct usb_config_descriptor *config)
2654 unsigned char *desc;
2656 /* each config of an otg device has an OTG descriptor */
2657 desc = find_otg(config->extra, config->extralen);
2658 for (i = 0; !desc && i < config->bNumInterfaces; i++) {
2659 struct usb_interface *intf;
2661 intf = &config->interface [i];
2662 for (j = 0; !desc && j < intf->num_altsetting; j++) {
2663 struct usb_interface_descriptor *alt;
2665 alt = &intf->altsetting[j];
2666 desc = find_otg(alt->extra, alt->extralen);
2667 for (k = 0; !desc && k < alt->bNumEndpoints; k++) {
2668 struct usb_endpoint_descriptor *ep;
2670 ep = &alt->endpoint[k];
2671 desc = find_otg(ep->extra, ep->extralen);
2678 printf("OTG Descriptor:\n"
2680 " bDescriptorType %3u\n"
2681 " bmAttributes 0x%02x\n"
2683 desc[0], desc[1], desc[2],
2685 ? " SRP (Session Request Protocol)\n" : "",
2687 ? " HNP (Host Negotiation Protocol)\n" : "");
2692 dump_device_status(struct usb_dev_handle *fd, int otg, int wireless)
2694 unsigned char status[8];
2697 ret = usb_control_msg(fd, USB_ENDPOINT_IN | USB_TYPE_STANDARD
2705 "cannot read device status, %s (%d)\n",
2706 strerror(errno), errno);
2710 printf("Device Status: 0x%02x%02x\n",
2711 status[1], status[0]);
2712 if (status[0] & (1 << 0))
2713 printf(" Self Powered\n");
2715 printf(" (Bus Powered)\n");
2716 if (status[0] & (1 << 1))
2717 printf(" Remote Wakeup Enabled\n");
2718 if (status[0] & (1 << 2)) {
2719 /* for high speed devices */
2721 printf(" Test Mode\n");
2722 /* for devices with Wireless USB support */
2724 printf(" Battery Powered\n");
2726 /* if both HOST and DEVICE support OTG */
2728 if (status[0] & (1 << 3))
2729 printf(" HNP Enabled\n");
2730 if (status[0] & (1 << 4))
2731 printf(" HNP Capable\n");
2732 if (status[0] & (1 << 5))
2733 printf(" ALT port is HNP Capable\n");
2735 /* for high speed devices with debug descriptors */
2736 if (status[0] & (1 << 6))
2737 printf(" Debug Mode\n");
2742 /* Wireless USB exposes FIVE different types of device status,
2743 * accessed by distinct wIndex values.
2745 ret = usb_control_msg(fd, USB_ENDPOINT_IN | USB_TYPE_STANDARD
2748 0, 1 /* wireless status */,
2753 "cannot read wireless %s, %s (%d)\n",
2755 strerror(errno), errno);
2758 printf("Wireless Status: 0x%02x\n", status[0]);
2759 if (status[0] & (1 << 0))
2760 printf(" TX Drp IE\n");
2761 if (status[0] & (1 << 1))
2762 printf(" Transmit Packet\n");
2763 if (status[0] & (1 << 2))
2764 printf(" Count Packets\n");
2765 if (status[0] & (1 << 3))
2766 printf(" Capture Packet\n");
2768 ret = usb_control_msg(fd, USB_ENDPOINT_IN | USB_TYPE_STANDARD
2771 0, 2 /* Channel Info */,
2776 "cannot read wireless %s, %s (%d)\n",
2778 strerror(errno), errno);
2781 printf("Channel Info: 0x%02x\n", status[0]);
2783 /* 3=Received data: many bytes, for count packets or capture packet */
2785 ret = usb_control_msg(fd, USB_ENDPOINT_IN | USB_TYPE_STANDARD
2788 0, 3 /* MAS Availability */,
2793 "cannot read wireless %s, %s (%d)\n",
2795 strerror(errno), errno);
2798 printf("MAS Availability: ");
2799 dump_bytes(status, 8);
2801 ret = usb_control_msg(fd, USB_ENDPOINT_IN | USB_TYPE_STANDARD
2804 0, 5 /* Current Transmit Power */,
2809 "cannot read wireless %s, %s (%d)\n",
2811 strerror(errno), errno);
2814 printf("Transmit Power:\n");
2815 printf(" TxNotification: 0x%02x\n", status[0]);
2816 printf(" TxBeacon: : 0x%02x\n", status[1]);
2819 static int do_wireless(struct usb_dev_handle *fd)
2821 /* FIXME fetch and dump BOS etc */
2827 static void dumpdev(struct usb_device *dev)
2829 struct usb_dev_handle *udev;
2834 udev = usb_open(dev);
2836 fprintf(stderr, "Couldn't open device, some information "
2837 "will be missing\n");
2839 dump_device(udev, &dev->descriptor);
2840 if (dev->descriptor.bcdUSB >= 0x0250)
2841 wireless = do_wireless(udev);
2843 otg = do_otg(&dev->config[0]) || otg;
2844 for (i = 0; i < dev->descriptor.bNumConfigurations;
2846 dump_config(udev, &dev->config[i]);
2852 if (dev->descriptor.bDeviceClass == USB_CLASS_HUB)
2853 do_hub(udev, dev->descriptor.bDeviceProtocol);
2854 if (dev->descriptor.bcdUSB >= 0x0200) {
2858 dump_device_status(udev, otg, wireless);
2862 /* ---------------------------------------------------------------------- */
2864 static int dump_one_device(const char *path)
2866 struct usb_device *dev;
2867 char vendor[128], product[128];
2869 dev = get_usb_device(path);
2871 fprintf(stderr, "Cannot open %s\n", path);
2874 get_vendor_string(vendor, sizeof(vendor), dev->descriptor.idVendor);
2875 get_product_string(product, sizeof(product), dev->descriptor.idVendor, dev->descriptor.idProduct);
2876 printf("Device: ID %04x:%04x %s %s\n", dev->descriptor.idVendor,
2877 dev->descriptor.idProduct,
2884 static int list_devices(int busnum, int devnum, int vendorid, int productid)
2886 struct usb_bus *bus;
2887 struct usb_device *dev;
2888 char vendor[128], product[128];
2891 status=1; /* 1 device not found, 0 device found */
2893 for (bus = usb_busses; bus; bus = bus->next) {
2894 if (busnum != -1 && strtol(bus->dirname, NULL, 10) != busnum)
2896 for (dev = bus->devices; dev; dev = dev->next) {
2897 if (devnum != -1 && strtol(dev->filename, NULL, 10)
2900 if ((vendorid != -1 && vendorid
2901 != dev->descriptor.idVendor)
2902 || (productid != -1 && productid
2903 != dev->descriptor.idProduct))
2906 get_vendor_string(vendor, sizeof(vendor),
2907 dev->descriptor.idVendor);
2908 get_product_string(product, sizeof(product),
2909 dev->descriptor.idVendor,
2910 dev->descriptor.idProduct);
2913 printf("Bus %s Device %s: ID %04x:%04x %s %s\n",
2914 bus->dirname, dev->filename,
2915 dev->descriptor.idVendor,
2916 dev->descriptor.idProduct,
2925 /* ---------------------------------------------------------------------- */
2927 void devtree_busconnect(struct usbbusnode *bus)
2929 bus = bus; /* reduce compiler warnings */
2932 void devtree_busdisconnect(struct usbbusnode *bus)
2934 bus = bus; /* reduce compiler warnings */
2937 void devtree_devconnect(struct usbdevnode *dev)
2939 dev = dev; /* reduce compiler warnings */
2942 void devtree_devdisconnect(struct usbdevnode *dev)
2944 dev = dev; /* reduce compiler warnings */
2947 static int treedump(void)
2952 snprintf(buf, sizeof(buf), "%s/devices", procbususb);
2953 if (access(buf, R_OK) < 0)
2955 if ((fd = open(buf, O_RDONLY)) == -1) {
2956 fprintf(stderr, "cannot open %s, %s (%d)\n", buf, strerror(errno), errno);
2959 devtree_parsedevfile(fd);
2965 /* ---------------------------------------------------------------------- */
2967 int main(int argc, char *argv[])
2969 static const struct option long_options[] = {
2970 { "version", 0, 0, 'V' },
2971 { "verbose", 0, 0, 'v' },
2975 unsigned int allowctrlmsg = 0, treemode = 0;
2976 int bus = -1, devnum = -1, vendor = -1, product = -1;
2977 const char *devdump = NULL;
2981 while ((c = getopt_long(argc, argv, "D:vxtP:p:s:d:V",
2982 long_options, NULL)) != EOF) {
2985 printf("lsusb (" PACKAGE ") " VERSION "\n");
3001 cp = strchr(optarg, ':');
3005 bus = strtoul(optarg, NULL, 10);
3007 devnum = strtoul(cp, NULL, 10);
3010 devnum = strtoul(optarg, NULL, 10);
3015 cp = strchr(optarg, ':');
3022 vendor = strtoul(optarg, NULL, 16);
3024 product = strtoul(cp, NULL, 16);
3037 if (err || argc > optind) {
3038 fprintf(stderr, "Usage: lsusb [options]...\n"
3039 "List USB devices\n"
3041 " Increase verbosity (show descriptors)\n"
3042 " -s [[bus]:][devnum]\n"
3043 " Show only devices with specified device and/or\n"
3044 " bus numbers (in decimal)\n"
3045 " -d vendor:[product]\n"
3046 " Show only devices with the specified vendor and\n"
3047 " product ID numbers (in hexadecimal)\n"
3049 " Selects which device lsusb will examine\n"
3051 " Dump the physical USB device hierarchy as a tree\n"
3053 " Show version of program\n"
3058 /* by default, print names as well as numbers */
3059 err = names_init(DATADIR "/usb.ids");
3062 err = names_init(DATADIR "/usb.ids.gz");
3065 fprintf(stderr, "%s: cannot open \"%s\", %s\n",
3077 /* treemode requires at least verblevel 1 */
3078 verblevel += 1 - VERBLEVEL_DEFAULT;
3079 status = treedump();
3081 status = dump_one_device(devdump);
3083 status = list_devices(bus, devnum, vendor, product);