2 * Originally released under the Be Sample Code License.
3 * Copyright 2000, Be Incorporated. All rights reserved.
5 * Modified for Haiku by François Revol and Michael Lotz.
6 * Copyright 2007-2008, Haiku Inc. All rights reserved.
11 #include <MediaDefs.h>
16 #include <usb/USB_audio.h>
17 #include <usb/USB_midi.h>
19 #include "usbspec_private.h"
20 #include "usb-utils.h"
24 ClassName(int classNumber
) {
25 switch (classNumber
) {
27 return "Per-interface classes";
31 return "Communication";
41 return "Mass storage";
49 return "Content security";
53 return "Personal Healthcare";
55 return "Diagnostic device";
57 return "Wireless controller";
59 return "Miscellaneous";
61 return "Application specific";
63 return "Vendor specific";
71 DumpDescriptorData(const usb_generic_descriptor
* descriptor
)
73 printf(" Type ............. 0x%02x\n",
74 descriptor
->descriptor_type
);
76 printf(" Data ............. ");
77 // len includes len and descriptor_type field
78 for (int32 i
= 0; i
< descriptor
->length
- 2; i
++)
79 printf("%02x ", descriptor
->data
[i
]);
85 DumpAudioCSInterfaceDescriptorHeader(
86 const usb_audiocontrol_header_descriptor
* descriptor
)
88 printf(" Subtype ........... 0x%02x (Header)\n",
89 descriptor
->descriptor_subtype
);
90 printf(" bcdADC Release date 0x%04x\n",
91 descriptor
->bcd_release_no
);
92 printf(" Total Length ...... %u\n",
93 descriptor
->r1
.total_length
);
94 printf(" Interfaces ........ ");
96 for (uint8 i
= 0; i
< descriptor
->r1
.in_collection
; i
++)
97 printf("%u, ", descriptor
->r1
.interface_numbers
[i
]);
103 DumpChannelConfig(uint32 wChannelConfig
)
109 { "Front .......... ", B_CHANNEL_LEFT
| B_CHANNEL_RIGHT
110 | B_CHANNEL_CENTER
},
111 { "L.F.E .......... ", B_CHANNEL_SUB
},
112 { "Back ........... ", B_CHANNEL_REARLEFT
| B_CHANNEL_REARRIGHT
113 | B_CHANNEL_BACK_CENTER
},
114 { "Center ......... ", B_CHANNEL_FRONT_LEFT_CENTER
115 | B_CHANNEL_FRONT_RIGHT_CENTER
},
116 { "Side ........... ", B_CHANNEL_SIDE_LEFT
| B_CHANNEL_SIDE_RIGHT
},
117 { "Top ............ ", B_CHANNEL_TOP_CENTER
},
118 { "Top Front ...... ", B_CHANNEL_TOP_FRONT_LEFT
119 | B_CHANNEL_TOP_FRONT_CENTER
| B_CHANNEL_TOP_FRONT_RIGHT
},
120 { "Top Back ....... ", B_CHANNEL_TOP_BACK_LEFT
121 | B_CHANNEL_TOP_BACK_CENTER
| B_CHANNEL_TOP_BACK_RIGHT
}
124 struct _Entry aChannels
[] = {
125 { "Left", B_CHANNEL_LEFT
| B_CHANNEL_FRONT_LEFT_CENTER
126 | B_CHANNEL_REARLEFT
| B_CHANNEL_SIDE_LEFT
| B_CHANNEL_TOP_BACK_LEFT
127 | B_CHANNEL_TOP_FRONT_LEFT
},
128 { "Right", B_CHANNEL_FRONT_RIGHT_CENTER
| B_CHANNEL_TOP_FRONT_RIGHT
129 | B_CHANNEL_REARRIGHT
| B_CHANNEL_RIGHT
| B_CHANNEL_SIDE_RIGHT
130 | B_CHANNEL_TOP_BACK_RIGHT
},
131 { "Center", B_CHANNEL_BACK_CENTER
| B_CHANNEL_CENTER
132 | B_CHANNEL_TOP_BACK_CENTER
| B_CHANNEL_TOP_CENTER
133 | B_CHANNEL_TOP_FRONT_CENTER
},
134 { "L.F.E.", B_CHANNEL_SUB
}
137 for (size_t i
= 0; i
< sizeof(aClusters
) / sizeof(aClusters
[0]); i
++) {
138 uint32 mask
= aClusters
[i
].mask
& wChannelConfig
;
140 printf(" %s", aClusters
[i
].name
);
141 for (size_t j
= 0; j
< sizeof(aChannels
) / sizeof(aChannels
[0]); j
++)
142 if ((aChannels
[j
].mask
& mask
) != 0)
143 printf("%s ", aChannels
[j
].name
);
151 TerminalTypeName(uint16 terminalType
)
153 switch (terminalType
) {
154 case USB_AUDIO_UNDEFINED_USB_IO
:
155 return "USB Undefined";
156 case USB_AUDIO_STREAMING_USB_IO
:
157 return "USB Streaming";
158 case USB_AUDIO_VENDOR_USB_IO
:
159 return "USB vendor specific";
161 case USB_AUDIO_UNDEFINED_IN
:
163 case USB_AUDIO_MICROPHONE_IN
:
165 case USB_AUDIO_DESKTOPMIC_IN
:
166 return "Desktop microphone";
167 case USB_AUDIO_PERSONALMIC_IN
:
168 return "Personal microphone";
169 case USB_AUDIO_OMNI_MIC_IN
:
170 return "Omni-directional microphone";
171 case USB_AUDIO_MICS_ARRAY_IN
:
172 return "Microphone array";
173 case USB_AUDIO_PROC_MICS_ARRAY_IN
:
174 return "Processing microphone array";
175 case USB_AUDIO_LINE_CONNECTOR_IO
:
177 case USB_AUDIO_SPDIF_INTERFACE_IO
:
180 case USB_AUDIO_UNDEFINED_OUT
:
182 case USB_AUDIO_SPEAKER_OUT
:
184 case USB_AUDIO_HEAD_PHONES_OUT
:
186 case USB_AUDIO_HMD_AUDIO_OUT
:
187 return "Head Mounted Display Audio";
188 case USB_AUDIO_DESKTOP_SPEAKER
:
189 return "Desktop speaker";
190 case USB_AUDIO_ROOM_SPEAKER
:
191 return "Room speaker";
192 case USB_AUDIO_COMM_SPEAKER
:
193 return "Communication speaker";
194 case USB_AUDIO_LFE_SPEAKER
:
195 return "Low frequency effects speaker";
204 DumpAudioCSInterfaceDescriptorInputTerminal(
205 const usb_audio_input_terminal_descriptor
* descriptor
)
207 printf(" Subtype ........... 0x%02x (Input Terminal)\n",
208 descriptor
->descriptor_subtype
);
209 printf(" Terminal ID ....... %u\n",
210 descriptor
->terminal_id
);
211 printf(" Terminal Type ..... 0x%04x (%s)\n",
212 descriptor
->terminal_type
,
213 TerminalTypeName(descriptor
->terminal_type
));
214 printf(" Associated Terminal %u\n",
215 descriptor
->assoc_terminal
);
216 printf(" Nr Channels ....... %u\n",
217 descriptor
->r1
.num_channels
);
218 printf(" Channel Config .... 0x%x\n",
219 descriptor
->r1
.channel_config
);
220 DumpChannelConfig(descriptor
->r1
.channel_config
);
222 printf(" Channel Names ..... %u\n",
223 descriptor
->r1
.channel_names
);
224 printf(" Terminal .......... %u\n",
225 descriptor
->r1
.terminal
);
230 DumpAudioCSInterfaceDescriptorOutputTerminal(
231 const usb_audio_output_terminal_descriptor
* descriptor
)
233 printf(" Subtype ........... 0x%02x (Output Terminal)\n",
234 descriptor
->descriptor_subtype
);
235 printf(" Terminal ID ....... %u\n",
236 descriptor
->terminal_id
);
237 printf(" Terminal Type ..... 0x%04x (%s)\n",
238 descriptor
->terminal_type
,
239 TerminalTypeName(descriptor
->terminal_type
));
240 printf(" Associated Terminal %u\n",
241 descriptor
->assoc_terminal
);
242 printf(" Source ID ......... %u\n",
243 descriptor
->source_id
);
244 printf(" Terminal .......... %u\n",
245 descriptor
->r1
.terminal
);
250 DumpAudioCSInterfaceDescriptorMixerUnit(
251 const usb_audio_mixer_unit_descriptor
* descriptor
)
253 printf(" Subtype ........... 0x%02x (Mixer Unit)\n",
254 descriptor
->descriptor_subtype
);
255 printf(" Unit ID ........... %u\n",
256 descriptor
->unit_id
);
258 printf(" Source IDs ........ ");
259 for (uint8 i
= 0; i
< descriptor
->num_input_pins
; i
++)
260 printf("%u, ", descriptor
->input_pins
[i
]);
263 usb_audio_output_channels_descriptor_r1
* channels
264 = (usb_audio_output_channels_descriptor_r1
*)
265 &descriptor
->input_pins
[descriptor
->num_input_pins
];
267 printf(" Channels .......... %u\n",
268 channels
->num_output_pins
);
269 printf(" Channel Config .... 0x%x\n",
270 channels
->channel_config
);
271 DumpChannelConfig(channels
->channel_config
);
272 printf(" Channel Names ..... %u\n",
273 channels
->channel_names
);
275 usb_generic_descriptor
* generic
= (usb_generic_descriptor
*)descriptor
;
276 uint8 idx
= 7 + descriptor
->num_input_pins
;
277 printf(" Bitmap Control .... 0x");
278 for (uint i
= 1; idx
< descriptor
->length
- 3; idx
++, i
++)
279 printf("%02x ", (uint8
)generic
->data
[idx
]);
282 printf(" Mixer ............. %u\n",
283 generic
->data
[generic
->length
- 3]);
288 DumpAudioCSInterfaceDescriptorSelectorUnit(
289 const usb_audio_selector_unit_descriptor
* descriptor
)
291 printf(" Subtype ........... 0x%02x (Selector Unit)\n",
292 descriptor
->descriptor_subtype
);
293 printf(" Unit ID ........... %u\n",
294 descriptor
->unit_id
);
296 printf(" Source IDs ........ ");
297 for (uint8 i
= 0; i
< descriptor
->num_input_pins
; i
++)
298 printf("%u, ", descriptor
->input_pins
[i
]);
301 usb_generic_descriptor
* generic
= (usb_generic_descriptor
*)descriptor
;
302 printf(" Selector .......... %u\n",
303 (uint8
)generic
->data
[descriptor
->num_input_pins
+ 2]);
308 DumpBMAControl(uint8 channel
, uint32 bma
)
310 const char* BMAControls
[] = {
327 printf(" Master Channel . ");
329 printf(" Channel %u ...... ", channel
);
333 i
< sizeof(BMAControls
) / sizeof(BMAControls
[0]); i
++, mask
<<= 1)
335 printf("%s ", BMAControls
[i
]);
341 DumpAudioCSInterfaceDescriptorFeatureUnit(
342 const usb_audio_feature_unit_descriptor
* descriptor
)
344 printf(" Subtype ........... 0x%02x (Feature Unit)\n",
345 descriptor
->descriptor_subtype
);
346 printf(" Unit ID ........... %u\n",
347 descriptor
->unit_id
);
348 printf(" Source ID ......... %u\n",
349 descriptor
->source_id
);
351 printf(" Control Size ...... %u\n",
352 descriptor
->r1
.control_size
);
355 uint8 channels
= (descriptor
->length
- 6) / descriptor
->r1
.control_size
;
356 for (uint8 i
= 0; i
< channels
; i
++) {
357 switch (descriptor
->r1
.control_size
) {
359 DumpBMAControl(i
, descriptor
->r1
.bma_controls
[i
]);
362 DumpBMAControl(i
, *(uint16
*)&descriptor
->r1
.bma_controls
[i
* 2]);
365 DumpBMAControl(i
, *(uint32
*)&descriptor
->r1
.bma_controls
[i
* 4]);
368 printf(" BMA Channel %u ... ", i
);
369 for (uint8 j
= 0; j
< descriptor
->r1
.control_size
; j
++)
370 printf("%02x ", descriptor
->r1
.bma_controls
[i
+ j
]);
375 usb_generic_descriptor
* generic
= (usb_generic_descriptor
*)descriptor
;
376 printf(" Feature ........... %u\n",
377 (uint8
)generic
->data
[descriptor
->length
- 3]);
382 DumpAudioCSInterfaceDescriptorAssociated(
383 const usb_generic_descriptor
* descriptor
)
385 printf(" Subtype ........... 0x%02x (Associate Interface)\n",
386 (uint8
)descriptor
->data
[0]);
387 printf(" Interface ......... %u\n",
388 (uint8
)descriptor
->data
[1]);
390 printf(" Data .............. ");
391 for (uint8 i
= 0; i
< descriptor
->length
- 2; i
++)
392 printf("%02x ", descriptor
->data
[i
]);
397 DumpAudioControlCSInterfaceDescriptor(const usb_generic_descriptor
* descriptor
)
399 uint8 descriptorSubtype
= descriptor
->data
[0];
400 switch (descriptorSubtype
) {
401 case USB_AUDIO_AC_HEADER
:
402 DumpAudioCSInterfaceDescriptorHeader(
403 (usb_audiocontrol_header_descriptor
*)descriptor
);
405 case USB_AUDIO_AC_INPUT_TERMINAL
:
406 DumpAudioCSInterfaceDescriptorInputTerminal(
407 (usb_audio_input_terminal_descriptor
*)descriptor
);
409 case USB_AUDIO_AC_OUTPUT_TERMINAL
:
410 DumpAudioCSInterfaceDescriptorOutputTerminal(
411 (usb_audio_output_terminal_descriptor
*)descriptor
);
413 case USB_AUDIO_AC_MIXER_UNIT
:
414 DumpAudioCSInterfaceDescriptorMixerUnit(
415 (usb_audio_mixer_unit_descriptor
*)descriptor
);
417 case USB_AUDIO_AC_SELECTOR_UNIT
:
418 DumpAudioCSInterfaceDescriptorSelectorUnit(
419 (usb_audio_selector_unit_descriptor
*)descriptor
);
421 case USB_AUDIO_AC_FEATURE_UNIT
:
422 DumpAudioCSInterfaceDescriptorFeatureUnit(
423 (usb_audio_feature_unit_descriptor
*)descriptor
);
425 case USB_AUDIO_AC_EXTENSION_UNIT
:
426 DumpAudioCSInterfaceDescriptorAssociated(descriptor
);
429 DumpDescriptorData(descriptor
);
435 DumpGeneralASInterfaceDescriptor(
436 const usb_audio_streaming_interface_descriptor
* descriptor
)
438 printf(" Subtype ........... %u (AS_GENERAL)\n",
439 descriptor
->descriptor_subtype
);
440 printf(" Terminal link ..... %u\n",
441 descriptor
->terminal_link
);
442 printf(" Delay ............. %u\n",
443 descriptor
->r1
.delay
);
444 printf(" Format tag ........ %u\n",
445 descriptor
->r1
.format_tag
);
450 GetSamplingFrequency(const usb_audio_sampling_freq
& freq
)
452 return freq
.bytes
[0] | freq
.bytes
[1] << 8 | freq
.bytes
[2] << 16;
457 DumpSamplingFrequencies(uint8 type
, const usb_audio_sampling_freq
* freqs
)
460 printf(" Sampling Freq ..... ");
461 for (uint8 i
= 0; i
< type
; i
++)
462 printf("%lu, ", GetSamplingFrequency(freqs
[i
]));
465 printf(" Sampling Freq ..... %lu to %lu\n",
466 GetSamplingFrequency(freqs
[0]), GetSamplingFrequency(freqs
[1]));
471 DumpASFormatTypeI(const usb_audio_format_descriptor
* descriptor
)
473 printf(" Subtype ........... %u (FORMAT_TYPE)\n",
474 descriptor
->descriptor_subtype
);
475 printf(" Format Type ....... %u (FORMAT_TYPE_I)\n",
476 descriptor
->format_type
);
477 printf(" Channels .......... %u\n",
478 descriptor
->typeI
.nr_channels
);
479 printf(" Subframe size ..... %u\n",
480 descriptor
->typeI
.subframe_size
);
481 printf(" Bit resoultion .... %u\n",
482 descriptor
->typeI
.bit_resolution
);
484 DumpSamplingFrequencies(descriptor
->typeI
.sam_freq_type
,
485 descriptor
->typeI
.sam_freqs
);
490 DumpASFormatTypeIII(const usb_audio_format_descriptor
* descriptor
)
492 printf(" Subtype ........... %u (FORMAT_TYPE)\n",
493 descriptor
->descriptor_subtype
);
494 printf(" Format Type ....... %u (FORMAT_TYPE_III)\n",
495 descriptor
->format_type
);
496 printf(" Channels .......... %u\n",
497 descriptor
->typeIII
.nr_channels
);
498 printf(" Subframe size ..... %u\n",
499 descriptor
->typeIII
.subframe_size
);
500 printf(" Bit resoultion .... %u\n",
501 descriptor
->typeIII
.bit_resolution
);
503 DumpSamplingFrequencies(descriptor
->typeIII
.sam_freq_type
,
504 descriptor
->typeIII
.sam_freqs
);
509 DumpASFormatTypeII(const usb_audio_format_descriptor
* descriptor
)
511 printf(" Subtype ........... %u (FORMAT_TYPE)\n",
512 descriptor
->descriptor_subtype
);
513 printf(" Format Type ....... %u (FORMAT_TYPE_II)\n",
514 descriptor
->format_type
);
515 printf(" Max Bitrate ....... %u\n",
516 descriptor
->typeII
.max_bit_rate
);
517 printf(" Samples per Frame . %u\n",
518 descriptor
->typeII
.samples_per_frame
);
520 DumpSamplingFrequencies(descriptor
->typeII
.sam_freq_type
,
521 descriptor
->typeII
.sam_freqs
);
526 DumpASFmtType(const usb_audio_format_descriptor
* descriptor
)
528 uint8 format
= descriptor
->format_type
;
530 case USB_AUDIO_FORMAT_TYPE_I
:
531 DumpASFormatTypeI(descriptor
);
533 case USB_AUDIO_FORMAT_TYPE_II
:
534 DumpASFormatTypeII(descriptor
);
536 case USB_AUDIO_FORMAT_TYPE_III
:
537 DumpASFormatTypeIII(descriptor
);
540 DumpDescriptorData((usb_generic_descriptor
*)descriptor
);
547 DumpMPEGCapabilities(uint16 capabilities
)
549 const char* MPEGCapabilities
[] = {
555 "MPEG-1 dual-channel",
556 "MPEG-2 second stereo",
557 "MPEG-2 7.1 channel augumentation",
558 "Adaptive multi-channel predicion"
563 i
< sizeof(MPEGCapabilities
) / sizeof(MPEGCapabilities
[0]); i
++) {
564 if (capabilities
& mask
)
565 printf(" %s\n", MPEGCapabilities
[i
]);
569 mask
= 0x300; // bits 8 and 9
570 uint16 multilingualSupport
= (capabilities
& mask
) >> 8;
571 switch (multilingualSupport
) {
573 printf(" No Multilingual support\n");
576 printf(" Supported at Fs\n");
579 printf(" Supported at Fs and 1/2Fs\n");
588 DumpMPEGFeatures(uint8 features
)
590 uint8 mask
= 0x30; // bits 4 and 5
591 uint8 dynRangeControl
= (features
& mask
) >> 4;
592 switch (dynRangeControl
) {
594 printf(" Not supported\n");
597 printf(" Supported, not scalable\n");
600 printf(" Scalable, common boost, "
601 "cut scaling value\n");
604 printf(" Scalable, separate boost, "
605 "cut scaling value\n");
613 DumpASFmtSpecificMPEG(const usb_generic_descriptor
* descriptor
)
615 printf(" Subtype ........... %u (FORMAT_SPECIFIC)\n",
616 descriptor
->data
[0]);
617 printf(" Format Tag ........ %u\n",
618 *(uint16
*)&descriptor
->data
[1]);
619 printf(" MPEG Capabilities . %u\n",
620 *(uint16
*)&descriptor
->data
[3]);
621 DumpMPEGCapabilities(*(uint16
*)&descriptor
->data
[3]);
622 printf(" MPEG Features ..... %u\n",
623 descriptor
->data
[5]);
624 DumpMPEGFeatures(descriptor
->data
[5]);
629 DumpAC_3Features(uint8 features
)
631 const char* featuresStr
[] = {
639 for (uint8 i
= 0; i
< sizeof(featuresStr
) / sizeof(const char*); i
++) {
641 printf(" %s\n", featuresStr
[i
]);
645 mask
= 0x30; // bits 4 and 5
646 uint8 dynRangeControl
= (features
& mask
) >> 4;
647 switch (dynRangeControl
) {
649 printf(" Not supported\n");
652 printf(" Supported, not scalable\n");
655 printf(" Scalable, common boost, "
656 "cut scaling value\n");
659 printf(" Scalable, separate boost, "
660 "cut scaling value\n");
668 DumpASFmtSpecificAC_3(const usb_generic_descriptor
* descriptor
)
670 printf(" Subtype ........... %u (FORMAT_TYPE)\n",
671 descriptor
->data
[0]);
672 printf(" Format Tag ........ %u\n",
673 *(uint16
*)&descriptor
->data
[1]);
674 printf(" BSID .............. %lx\n",
675 *(uint32
*)&descriptor
->data
[2]);
676 printf(" AC3 Features ...... %u\n",
677 descriptor
->data
[6]);
678 DumpAC_3Features(descriptor
->data
[6]);
683 DumpASFmtSpecific(const usb_generic_descriptor
* descriptor
)
686 TYPE_II_UNDEFINED
= 0x1000,
691 uint16 formatTag
= *(uint16
*)&descriptor
->data
[1];
694 DumpASFmtSpecificMPEG(descriptor
);
697 DumpASFmtSpecificAC_3(descriptor
);
700 DumpDescriptorData(descriptor
);
707 DumpAudioStreamCSInterfaceDescriptor(const usb_generic_descriptor
* descriptor
)
709 uint8 subtype
= descriptor
->data
[0];
711 case USB_AUDIO_AS_GENERAL
:
712 DumpGeneralASInterfaceDescriptor(
713 (usb_audio_streaming_interface_descriptor
*)descriptor
);
715 case USB_AUDIO_AS_FORMAT_TYPE
:
717 (usb_audio_format_descriptor
*)descriptor
);
719 case USB_AUDIO_AS_FORMAT_SPECIFIC
:
720 DumpASFmtSpecific(descriptor
);
723 DumpDescriptorData(descriptor
);
730 DumpAudioStreamCSEndpointDescriptor(
731 const usb_audio_streaming_endpoint_descriptor
* descriptor
)
733 printf(" Type .............. 0x%02x (CS_ENDPOINT)\n",
734 descriptor
->descriptor_type
);
735 printf(" Subtype ........... 0x%02x (EP_GENERAL)\n",
736 descriptor
->descriptor_subtype
);
737 printf(" Attributes ........ 0x%02x ",
738 descriptor
->attributes
);
740 const char* attributes
[] = {
741 "Sampling Frequency",
748 for (uint8 i
= 0; i
< sizeof(attributes
) / sizeof(attributes
[0]); i
++) {
749 if ((descriptor
->attributes
& mask
) != 0)
750 printf("%s ", attributes
[i
]);
755 const char* aUnits
[] = {
758 "Decoded PCM samples",
762 const char* units
= descriptor
->lock_delay_units
>= 4
763 ? aUnits
[3] : aUnits
[descriptor
->lock_delay_units
];
765 printf(" Lock Delay Units .. %u (%s)\n",
766 descriptor
->lock_delay_units
, units
);
767 printf(" Lock Delay ........ %u\n",
768 descriptor
->lock_delay
);
773 DumpMidiInterfaceHeaderDescriptor(
774 const usb_midi_interface_header_descriptor
* descriptor
)
776 printf(" Type .............. 0x%02x (CS_ENDPOINT)\n",
777 descriptor
->descriptor_type
);
778 printf(" Subtype ........... 0x%02x (MS_HEADER)\n",
779 descriptor
->descriptor_subtype
);
780 printf(" MSC Version ....... 0x%04x\n",
781 descriptor
->ms_version
);
782 printf(" Length ............ 0x%04x\n",
783 descriptor
->total_length
);
788 DumpMidiInJackDescriptor(
789 const usb_midi_in_jack_descriptor
* descriptor
)
791 printf(" Type .............. 0x%02x (CS_INTERFACE)\n",
792 descriptor
->descriptor_type
);
793 printf(" Subtype ........... 0x%02x (MIDI_IN_JACK)\n",
794 descriptor
->descriptor_subtype
);
795 printf(" Jack ID ........... 0x%02x\n",
797 // TODO can we get the string?
798 printf(" String ............ 0x%02x\n",
799 descriptor
->string_descriptor
);
801 switch (descriptor
->type
) {
802 case USB_MIDI_EMBEDDED_JACK
:
803 printf(" Jack Type ......... Embedded\n");
805 case USB_MIDI_EXTERNAL_JACK
:
806 printf(" Jack Type ......... External\n");
809 printf(" Jack Type ......... 0x%02x (unknown)\n",
817 DumpMidiOutJackDescriptor(
818 const usb_midi_out_jack_descriptor
* descriptor
)
820 printf(" Type .............. 0x%02x (CS_INTERFACE)\n",
821 descriptor
->descriptor_type
);
822 printf(" Subtype ........... 0x%02x (MIDI_OUT_JACK)\n",
823 descriptor
->descriptor_subtype
);
824 printf(" Jack ID ........... 0x%02x\n",
827 switch (descriptor
->type
) {
828 case USB_MIDI_EMBEDDED_JACK
:
829 printf(" Jack Type ......... Embedded\n");
831 case USB_MIDI_EXTERNAL_JACK
:
832 printf(" Jack Type ......... External\n");
835 printf(" Jack Type ......... 0x%02x (unknown)\n",
840 for (int i
= 0; i
< descriptor
->inputs_count
; i
++) {
841 printf(" Pin %02d ............ (%d,%d)\n", i
,
842 descriptor
->input_source
[i
].source_id
,
843 descriptor
->input_source
[i
].source_pin
);
849 DumpMidiStreamCSInterfaceDescriptor(const usb_generic_descriptor
* descriptor
)
851 uint8 subtype
= descriptor
->data
[0];
853 case USB_MS_HEADER_DESCRIPTOR
:
854 DumpMidiInterfaceHeaderDescriptor(
855 (usb_midi_interface_header_descriptor
*)descriptor
);
857 case USB_MS_MIDI_IN_JACK_DESCRIPTOR
:
858 DumpMidiInJackDescriptor(
859 (usb_midi_in_jack_descriptor
*)descriptor
);
861 case USB_MS_MIDI_OUT_JACK_DESCRIPTOR
:
862 DumpMidiOutJackDescriptor(
863 (usb_midi_out_jack_descriptor
*)descriptor
);
865 case USB_MS_ELEMENT_DESCRIPTOR
:
867 DumpDescriptorData(descriptor
);
870 DumpDescriptorData(descriptor
);
877 DumpMidiStreamCSEndpointDescriptor(
878 const usb_midi_endpoint_descriptor
* descriptor
)
880 printf(" Type .............. 0x%02x (CS_ENDPOINT)\n",
881 descriptor
->descriptor_type
);
882 printf(" Subtype ........... 0x%02x (MS_GENERAL)\n",
883 descriptor
->descriptor_subtype
);
884 printf(" Jacks ............. ");
886 for (int i
= 0; i
< descriptor
->jacks_count
; i
++)
887 printf("%d, ", descriptor
->jacks_id
[i
]);
894 DumpAudioStreamInterfaceDescriptor(const usb_interface_descriptor
* descriptor
)
896 printf(" Type .............. %u (INTERFACE)\n",
897 descriptor
->descriptor_type
);
898 printf(" Interface ........... %u\n",
899 descriptor
->interface_number
);
900 printf(" Alternate setting ... %u\n",
901 descriptor
->alternate_setting
);
902 printf(" Endpoints ........... %u\n",
903 descriptor
->num_endpoints
);
904 printf(" Interface class ..... %u (AUDIO)\n",
905 descriptor
->interface_class
);
906 printf(" Interface subclass .. %u (AUDIO_STREAMING)\n",
907 descriptor
->interface_subclass
);
908 printf(" Interface ........... %u\n",
909 descriptor
->interface
);
914 DumpAudioDescriptor(const usb_generic_descriptor
* descriptor
, int subclass
)
916 const uint8 USB_AUDIO_INTERFACE
= 0x04;
919 case USB_AUDIO_INTERFACE_AUDIOCONTROL_SUBCLASS
:
920 switch (descriptor
->descriptor_type
) {
921 case USB_AUDIO_CS_INTERFACE
:
922 DumpAudioControlCSInterfaceDescriptor(descriptor
);
925 DumpDescriptorData(descriptor
);
929 case USB_AUDIO_INTERFACE_AUDIOSTREAMING_SUBCLASS
:
930 switch (descriptor
->descriptor_type
) {
931 case USB_AUDIO_INTERFACE
:
932 DumpAudioStreamInterfaceDescriptor(
933 (const usb_interface_descriptor
*)descriptor
);
935 case USB_AUDIO_CS_INTERFACE
:
936 DumpAudioStreamCSInterfaceDescriptor(descriptor
);
938 case USB_AUDIO_CS_ENDPOINT
:
939 DumpAudioStreamCSEndpointDescriptor(
940 (const usb_audio_streaming_endpoint_descriptor
*)descriptor
);
943 DumpDescriptorData(descriptor
);
947 case USB_AUDIO_INTERFACE_MIDISTREAMING_SUBCLASS
:
948 switch (descriptor
->descriptor_type
) {
949 case USB_AUDIO_CS_INTERFACE
:
950 DumpMidiStreamCSInterfaceDescriptor(descriptor
);
952 case USB_AUDIO_CS_ENDPOINT
:
953 DumpMidiStreamCSEndpointDescriptor(
954 (const usb_midi_endpoint_descriptor
*)descriptor
);
957 DumpDescriptorData(descriptor
);
962 DumpDescriptorData(descriptor
);
969 DumpDescriptor(const usb_generic_descriptor
* descriptor
,
970 int classNum
, int subclass
)
973 case USB_AUDIO_DEVICE_CLASS
:
974 DumpAudioDescriptor(descriptor
, subclass
);
977 DumpDescriptorData(descriptor
);
984 DumpInterface(const BUSBInterface
* interface
)
989 printf(" Class .............. 0x%02x (%s)\n",
990 interface
->Class(), ClassName(interface
->Class()));
991 printf(" Subclass ........... 0x%02x\n",
992 interface
->Subclass());
993 printf(" Protocol ........... 0x%02x\n",
994 interface
->Protocol());
995 printf(" Interface String ... \"%s\"\n",
996 interface
->InterfaceString());
998 for (uint32 i
= 0; i
< interface
->CountEndpoints(); i
++) {
999 const BUSBEndpoint
* endpoint
= interface
->EndpointAt(i
);
1003 printf(" [Endpoint %lu]\n", i
);
1004 printf(" MaxPacketSize .... %d\n",
1005 endpoint
->MaxPacketSize());
1006 printf(" Interval ......... %d\n",
1007 endpoint
->Interval());
1009 if (endpoint
->IsControl())
1010 printf(" Type ............. Control\n");
1011 else if (endpoint
->IsBulk())
1012 printf(" Type ............. Bulk\n");
1013 else if (endpoint
->IsIsochronous())
1014 printf(" Type ............. Isochronous\n");
1015 else if (endpoint
->IsInterrupt())
1016 printf(" Type ............. Interrupt\n");
1018 if (endpoint
->IsInput())
1019 printf(" Direction ........ Input\n");
1021 printf(" Direction ........ Output\n");
1025 usb_descriptor
* generic
= (usb_descriptor
*)buffer
;
1027 interface
->OtherDescriptorAt(i
, generic
, 256) == B_OK
; i
++) {
1028 printf(" [Descriptor %lu]\n", i
);
1029 DumpDescriptor(&generic
->generic
, interface
->Class(), interface
->Subclass());
1035 DumpConfiguration(const BUSBConfiguration
* configuration
)
1040 printf(" Configuration String . \"%s\"\n",
1041 configuration
->ConfigurationString());
1042 for (uint32 i
= 0; i
< configuration
->CountInterfaces(); i
++) {
1043 printf(" [Interface %lu]\n", i
);
1044 const BUSBInterface
* interface
= configuration
->InterfaceAt(i
);
1046 for (uint32 j
= 0; j
< interface
->CountAlternates(); j
++) {
1047 const BUSBInterface
* alternate
= interface
->AlternateAt(j
);
1048 printf(" [Alternate %lu%s]\n", j
,
1049 j
== interface
->AlternateIndex() ? " active" : "");
1050 DumpInterface(alternate
);
1057 DumpInfo(BUSBDevice
& device
, bool verbose
)
1059 const char* vendorName
= NULL
;
1060 const char* deviceName
= NULL
;
1061 usb_get_vendor_info(device
.VendorID(), &vendorName
);
1062 usb_get_device_info(device
.VendorID(), device
.ProductID(), &deviceName
);
1065 printf("%04x:%04x /dev/bus/usb%s \"%s\" \"%s\" ver. %04x\n",
1066 device
.VendorID(), device
.ProductID(), device
.Location(),
1067 vendorName
? vendorName
: device
.ManufacturerString(),
1068 deviceName
? deviceName
: device
.ProductString(),
1073 printf("[Device /dev/bus/usb%s]\n", device
.Location());
1074 printf(" Class .................. 0x%02x (%s)\n", device
.Class(),
1075 ClassName(device
.Class()));
1076 printf(" Subclass ............... 0x%02x\n", device
.Subclass());
1077 printf(" Protocol ............... 0x%02x\n", device
.Protocol());
1078 printf(" Max Endpoint 0 Packet .. %d\n", device
.MaxEndpoint0PacketSize());
1079 printf(" USB Version ............ 0x%04x\n", device
.USBVersion());
1080 printf(" Vendor ID .............. 0x%04x", device
.VendorID());
1081 if (vendorName
!= NULL
)
1082 printf(" (%s)", vendorName
);
1083 printf("\n Product ID ............. 0x%04x", device
.ProductID());
1084 if (deviceName
!= NULL
)
1085 printf(" (%s)", deviceName
);
1086 printf("\n Product Version ........ 0x%04x\n", device
.Version());
1087 printf(" Manufacturer String .... \"%s\"\n", device
.ManufacturerString());
1088 printf(" Product String ......... \"%s\"\n", device
.ProductString());
1089 printf(" Serial Number .......... \"%s\"\n", device
.SerialNumberString());
1091 for (uint32 i
= 0; i
< device
.CountConfigurations(); i
++) {
1092 printf(" [Configuration %lu]\n", i
);
1093 DumpConfiguration(device
.ConfigurationAt(i
));
1096 if (device
.Class() != 0x09)
1099 usb_hub_descriptor hubDescriptor
;
1100 size_t size
= device
.GetDescriptor(USB_DESCRIPTOR_HUB
, 0, 0,
1101 (void*)&hubDescriptor
, sizeof(usb_hub_descriptor
));
1102 if (size
== sizeof(usb_hub_descriptor
)) {
1103 printf(" Hub ports count......... %d\n", hubDescriptor
.num_ports
);
1104 printf(" Hub Controller Current.. %dmA\n", hubDescriptor
.max_power
);
1106 for (int index
= 1; index
<= hubDescriptor
.num_ports
; index
++) {
1107 usb_port_status portStatus
;
1108 size_t actualLength
= device
.ControlTransfer(USB_REQTYPE_CLASS
1109 | USB_REQTYPE_OTHER_IN
, USB_REQUEST_GET_STATUS
, 0,
1110 index
, sizeof(portStatus
), (void*)&portStatus
);
1111 if (actualLength
!= sizeof(portStatus
))
1113 printf(" Port %d status....... %04x.%04x%s%s%s%s%s%s%s%s%s\n",
1114 index
, portStatus
.status
, portStatus
.change
,
1115 portStatus
.status
& PORT_STATUS_CONNECTION
? " Connect": "",
1116 portStatus
.status
& PORT_STATUS_ENABLE
? " Enable": "",
1117 portStatus
.status
& PORT_STATUS_SUSPEND
? " Suspend": "",
1118 portStatus
.status
& PORT_STATUS_OVER_CURRENT
? " Overcurrent": "",
1119 portStatus
.status
& PORT_STATUS_RESET
? " Reset": "",
1120 portStatus
.status
& PORT_STATUS_POWER
? " Power": "",
1121 portStatus
.status
& PORT_STATUS_CONNECTION
1122 ? (portStatus
.status
& PORT_STATUS_LOW_SPEED
? " Lowspeed"
1123 : (portStatus
.status
& PORT_STATUS_HIGH_SPEED
? " Highspeed"
1124 : " Fullspeed")) : "",
1125 portStatus
.status
& PORT_STATUS_TEST
? " Test": "",
1126 portStatus
.status
& PORT_STATUS_INDICATOR
? " Indicator": "");
1132 class DumpRoster
: public BUSBRoster
{
1134 DumpRoster(bool verbose
)
1140 virtual status_t
DeviceAdded(BUSBDevice
* device
)
1142 DumpInfo(*device
, fVerbose
);
1147 virtual void DeviceRemoved(BUSBDevice
* device
)
1158 main(int argc
, char* argv
[])
1160 bool verbose
= false;
1161 BString devname
= "";
1162 for (int i
= 1; i
< argc
; i
++) {
1163 if (argv
[i
][0] == '-') {
1164 if (argv
[i
][1] == 'v')
1167 printf("Usage: listusb [-v] [device]\n\n");
1168 printf("-v: Show more detailed information including "
1169 "interfaces, configurations, etc.\n\n");
1170 printf("If a device is not specified, "
1171 "all devices found on the bus will be listed\n");
1178 if (devname
.Length() > 0) {
1179 BUSBDevice
device(devname
.String());
1180 if (device
.InitCheck() < B_OK
) {
1181 printf("Cannot open USB device: %s\n", devname
.String());
1184 DumpInfo(device
, verbose
);
1188 DumpRoster
roster(verbose
);