diff --git a/headers/os/drivers/usb/USB_audio.h b/headers/os/drivers/usb/USB_audio.h index 77d5952894..c02a767b8a 100644 --- a/headers/os/drivers/usb/USB_audio.h +++ b/headers/os/drivers/usb/USB_audio.h @@ -14,18 +14,18 @@ enum { USB_AUDIO_INTERFACE_AUDIO_CLASS = 0x01 }; -enum { // Audio Interface Subclasses - USB_AUDIO_INTERFACE_UNDEFINED_SUBCLASS = 0x00, +enum { // Audio Interface Subclasses + USB_AUDIO_INTERFACE_UNDEFINED_SUBCLASS = 0x00, USB_AUDIO_INTERFACE_AUDIOCONTROL_SUBCLASS = 0x01, - USB_AUDIO_INTERFACE_AUDIOSTREAMING_SUBCLASS, // - USB_AUDIO_INTERFACE_MIDISTREAMING_SUBCLASS // + USB_AUDIO_INTERFACE_AUDIOSTREAMING_SUBCLASS, + USB_AUDIO_INTERFACE_MIDISTREAMING_SUBCLASS }; enum { // Audio Interface Protocol Codes - USB_AUDIO_PROTOCOL_UNDEFINED = 0x00 + USB_AUDIO_PROTOCOL_UNDEFINED = 0x00 }; -enum { // Audio Interface Protocol Codes +enum { // Audio Interface Class-Specific Descriptor Types USB_AUDIO_CS_UNDEFINED = 0x20, USB_AUDIO_CS_DEVICE = 0x21, USB_AUDIO_CS_CONFIGURATION = 0x22, @@ -66,7 +66,7 @@ typedef struct { struct { uint16 total_length; uint8 in_collection; - uint8 interface_numbers[1]; + uint8 interface_numbers[0]; } _PACKED r1; struct { diff --git a/headers/os/drivers/usb/USB_video.h b/headers/os/drivers/usb/USB_video.h new file mode 100644 index 0000000000..064e33ab58 --- /dev/null +++ b/headers/os/drivers/usb/USB_video.h @@ -0,0 +1,142 @@ +/* + * Copyright 2016, Adrien Destugues, pulkomandy@pulkomandy.tk + * Distributed under terms of the MIT license. + */ + + +#ifndef USB_VIDEO_H +#define USB_VIDEO_H + + +// Based on specification for UVC version 1.5. + + +#include + + +#define USB_VIDEO_DEVICE_CLASS 0x0E + +enum { // Video Interface Subclasses + USB_VIDEO_INTERFACE_UNDEFINED_SUBCLASS = 0x00, + USB_VIDEO_INTERFACE_VIDEOCONTROL_SUBCLASS = 0x01, + USB_VIDEO_INTERFACE_VIDEOSTREAMING_SUBCLASS, + USB_VIDEO_INTERFACE_COLLECTION_SUBCLASS, +}; + + +enum { // Video Interface Protocol Codes + USB_VIDEO_PROTOCOL_UNDEFINED = 0x00, + USB_VIDEO_PROTOCOL_15 = 0x01, +}; + + +enum { // Video Interface Class-Specific Descriptor Types + USB_VIDEO_CS_UNDEFINED = 0x20, + USB_VIDEO_CS_DEVICE = 0x21, + USB_VIDEO_CS_CONFIGURATION = 0x22, + USB_VIDEO_CS_STRING = 0x23, + USB_VIDEO_CS_INTERFACE = 0x24, + USB_VIDEO_CS_ENDPOINT = 0x25, +}; + + +enum { // Video Class-Specific VideoControl Interface descriptor subtypes + USB_VIDEO_VC_DESCRIPTOR_UNDEFINED = 0x00, + USB_VIDEO_VC_HEADER = 0x01, + USB_VIDEO_VC_INPUT_TERMINAL = 0x02, + USB_VIDEO_VC_OUTPUT_TERMINAL = 0x03, + USB_VIDEO_VC_SELECTOR_UNIT = 0x04, + USB_VIDEO_VC_PROCESSING_UNIT = 0x05, + USB_VIDEO_VC_EXTENSION_UNIT = 0x06, + USB_VIDEO_VC_ENCODING_UNIT = 0x07, +}; + + +enum { + // USB Terminal Types + USB_VIDEO_VENDOR_USB_IO = 0x100, + USB_VIDEO_STREAMING_USB_IO = 0x101, + // Input terminal types + USB_VIDEO_VENDOR_IN = 0x200, + USB_VIDEO_CAMERA_IN = 0x201, + USB_VIDEO_MEDIA_TRANSPORT_IN = 0x202, + // Output terminal types + USB_VIDEO_VENDOR_OUT = 0x300, + USB_VIDEO_DISPLAY_OUT = 0x301, + USB_VIDEO_MEDIA_TRANSPORT_OUT = 0x302, + // External terminal types + USB_VIDEO_VENDOR_EXT = 0x400, + USB_VIDEO_COMPOSITE_EXT = 0x401, + USB_VIDEO_SVIDEO_EXT = 0x402, + USB_VIDEO_COMPONENT_EXT = 0x403, +}; + + +// Class Specific Video Control Interface Header +// 1.5: Table 3-3 p.48 +typedef struct { + uint8 length; + uint8 descriptor_type; // USB_AUDIO_CS_INTERFACE + uint8 descriptor_subtype; // USB_AUDIO_AC_HEADER + uint16 bcd_release_no; + uint16 total_length; + uint32 clock_frequency; + uint8 in_collection; + uint8 interface_numbers[0]; +} _PACKED usb_videocontrol_header_descriptor; + + +// Input Terminal Descriptor +// 1.5: Table 3-4, page 50 +typedef struct { + uint8 length; + uint8 descriptor_type; // USB_VIDEO_CS_INTERFACE + uint8 descriptor_subtype; // USB_VIDEO_VC_INPUT_TERMINAL + uint8 terminal_id; + uint16 terminal_type; + uint8 assoc_terminal; + uint8 terminal; + + union { + struct { + uint16 focal_length_min; + uint16 focal_length_max; + uint16 focal_length; + uint8 control_size; + uint8 controls[3]; + } _PACKED camera; + }; +} _PACKED usb_video_input_terminal_descriptor; + + +// Output terminal descriptor +// 1.5: Table 3-5, page 51 +typedef struct { + uint8 length; + uint8 descriptor_type; // USB_VIDEO_CS_INTERFACE + uint8 descriptor_subtype; // USB_VIDEO_VC_OUTPUT_TERMINAL + uint8 terminal_id; + uint16 terminal_type; + uint8 assoc_terminal; + uint8 source_id; + uint8 terminal; +} _PACKED usb_video_output_terminal_descriptor; + + +// Processing unit descriptor +// 1.5: Table 3-8, page 54 +typedef struct { + uint8 length; + uint8 descriptor_type; + uint8 descriptor_subtype; + uint8 unit_id; + uint8 source_id; + uint16 max_multiplier; + uint8 control_size; + uint8 controls[3]; + uint8 processing; + uint8 video_standards; +} _PACKED usb_video_processing_unit_descriptor; + + +#endif /* !USB_VIDEO_H */ diff --git a/src/bin/listusb/Jamfile b/src/bin/listusb/Jamfile index ed14442330..a759a0df65 100644 --- a/src/bin/listusb/Jamfile +++ b/src/bin/listusb/Jamfile @@ -6,6 +6,7 @@ UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel bus_managers usb ] ; BinCommand listusb : listusb.cpp usb_audio.cpp + usb_video.cpp : be libdevice.so ; # Manually reference generated headers diff --git a/src/bin/listusb/listusb.cpp b/src/bin/listusb/listusb.cpp index 107ca51dea..2c21ef0e57 100644 --- a/src/bin/listusb/listusb.cpp +++ b/src/bin/listusb/listusb.cpp @@ -10,20 +10,22 @@ #include #include #include -#include #include #include +#include #include "usbspec_private.h" #include "usb-utils.h" +#include "listusb.h" + const char* ClassName(int classNumber) { switch (classNumber) { case 0: return "Per-interface classes"; - case 1: + case USB_AUDIO_DEVICE_CLASS: return "Audio"; case 2: return "Communication"; @@ -45,7 +47,7 @@ ClassName(int classNumber) { return "Smart card"; case 13: return "Content security"; - case 14: + case USB_VIDEO_DEVICE_CLASS: return "Video"; case 15: return "Personal Healthcare"; @@ -65,7 +67,58 @@ ClassName(int classNumber) { } -void DumpAudioDescriptor(const usb_generic_descriptor* descriptor, int subclass); +const char* +SubclassName(int classNumber, int subclass) +{ + if (classNumber == 0xEF) { + if (subclass == 0x02) + return " (Common)"; + } + + if (classNumber == USB_VIDEO_DEVICE_CLASS) { + switch (subclass) { + case USB_VIDEO_INTERFACE_UNDEFINED_SUBCLASS: + return " (Undefined)"; + case USB_VIDEO_INTERFACE_VIDEOCONTROL_SUBCLASS: + return " (Control)"; + case USB_VIDEO_INTERFACE_VIDEOSTREAMING_SUBCLASS: + return " (Streaming)"; + case USB_VIDEO_INTERFACE_COLLECTION_SUBCLASS: + return " (Collection)"; + } + } + return ""; +} + + +const char* +ProtocolName(int classNumber, int subclass, int protocol) +{ + switch (classNumber) { + case 0x09: + if (subclass == 0x00) + { + switch (protocol) { + case 0x00: + return " (Full speed)"; + case 0x01: + return " (Hi-speed, single TT)"; + case 0x02: + return " (Hi-speed, multiple TT)"; + case 0x03: + return " (Super speed)"; + } + } + case 0xE0: + if (subclass == 0x01 && protocol == 0x01) + return " (Bluetooth)"; + case 0xEF: + if (subclass == 0x02 && protocol == 0x01) + return " (Interface Association)"; + break; + } + return ""; +} void @@ -90,6 +143,9 @@ DumpDescriptor(const usb_generic_descriptor* descriptor, case USB_AUDIO_DEVICE_CLASS: DumpAudioDescriptor(descriptor, subclass); break; + case USB_VIDEO_DEVICE_CLASS: + DumpVideoDescriptor(descriptor, subclass); + break; default: DumpDescriptorData(descriptor); break; @@ -105,10 +161,12 @@ DumpInterface(const BUSBInterface* interface) printf(" Class .............. 0x%02x (%s)\n", interface->Class(), ClassName(interface->Class())); - printf(" Subclass ........... 0x%02x\n", - interface->Subclass()); - printf(" Protocol ........... 0x%02x\n", - interface->Protocol()); + printf(" Subclass ........... 0x%02x%s\n", + interface->Subclass(), + SubclassName(interface->Class(), interface->Subclass())); + printf(" Protocol ........... 0x%02x%s\n", + interface->Protocol(), ProtocolName(interface->Class(), + interface->Subclass(), interface->Protocol())); printf(" Interface String ... \"%s\"\n", interface->InterfaceString()); @@ -190,10 +248,13 @@ DumpInfo(BUSBDevice& device, bool verbose) printf("[Device /dev/bus/usb%s]\n", device.Location()); printf(" Class .................. 0x%02x (%s)\n", device.Class(), ClassName(device.Class())); - printf(" Subclass ............... 0x%02x\n", device.Subclass()); - printf(" Protocol ............... 0x%02x\n", device.Protocol()); + printf(" Subclass ............... 0x%02x%s\n", device.Subclass(), + SubclassName(device.Class(), device.Subclass())); + printf(" Protocol ............... 0x%02x%s\n", device.Protocol(), + ProtocolName(device.Class(), device.Subclass(), device.Protocol())); printf(" Max Endpoint 0 Packet .. %d\n", device.MaxEndpoint0PacketSize()); - printf(" USB Version ............ 0x%04x\n", device.USBVersion()); + uint32_t version = device.USBVersion(); + printf(" USB Version ............ %d.%d\n", version >> 8, version & 0xFF); printf(" Vendor ID .............. 0x%04x", device.VendorID()); if (vendorName != NULL) printf(" (%s)", vendorName); diff --git a/src/bin/listusb/listusb.h b/src/bin/listusb/listusb.h index 27ae00a4f0..cdc2740430 100644 --- a/src/bin/listusb/listusb.h +++ b/src/bin/listusb/listusb.h @@ -11,8 +11,13 @@ #define LISTUSB_H +#include + + void DumpDescriptorData(const usb_generic_descriptor* descriptor); + void DumpAudioDescriptor(const usb_generic_descriptor* descriptor, int subclass); +void DumpVideoDescriptor(const usb_generic_descriptor* descriptor, int subclass); #endif /* !LISTUSB_H */ diff --git a/src/bin/listusb/usb_audio.cpp b/src/bin/listusb/usb_audio.cpp index 58c11eb7fd..71025020be 100644 --- a/src/bin/listusb/usb_audio.cpp +++ b/src/bin/listusb/usb_audio.cpp @@ -19,10 +19,12 @@ void DumpAudioCSInterfaceDescriptorHeader( const usb_audiocontrol_header_descriptor* descriptor) { + printf(" Type .............. 0x%02x\n", + descriptor->descriptor_type); printf(" Subtype ........... 0x%02x (Header)\n", descriptor->descriptor_subtype); - printf(" bcdADC Release date 0x%04x\n", - descriptor->bcd_release_no); + printf(" ADC Release ....... %d.%d\n", + descriptor->bcd_release_no >> 8, descriptor->bcd_release_no & 0xFF); printf(" Total Length ...... %u\n", descriptor->r1.total_length); printf(" Interfaces ........ "); @@ -81,7 +83,7 @@ DumpChannelConfig(uint32 wChannelConfig) } -const char* +static const char* TerminalTypeName(uint16 terminalType) { switch (terminalType) { @@ -138,6 +140,8 @@ void DumpAudioCSInterfaceDescriptorInputTerminal( const usb_audio_input_terminal_descriptor* descriptor) { + printf(" Type .............. 0x%02x\n", + descriptor->descriptor_type); printf(" Subtype ........... 0x%02x (Input Terminal)\n", descriptor->descriptor_subtype); printf(" Terminal ID ....... %u\n", @@ -164,6 +168,8 @@ void DumpAudioCSInterfaceDescriptorOutputTerminal( const usb_audio_output_terminal_descriptor* descriptor) { + printf(" Type .............. 0x%02x\n", + descriptor->descriptor_type); printf(" Subtype ........... 0x%02x (Output Terminal)\n", descriptor->descriptor_subtype); printf(" Terminal ID ....... %u\n", @@ -184,6 +190,8 @@ void DumpAudioCSInterfaceDescriptorMixerUnit( const usb_audio_mixer_unit_descriptor* descriptor) { + printf(" Type .............. 0x%02x\n", + descriptor->descriptor_type); printf(" Subtype ........... 0x%02x (Mixer Unit)\n", descriptor->descriptor_subtype); printf(" Unit ID ........... %u\n", @@ -222,6 +230,8 @@ void DumpAudioCSInterfaceDescriptorSelectorUnit( const usb_audio_selector_unit_descriptor* descriptor) { + printf(" Type .............. 0x%02x\n", + descriptor->descriptor_type); printf(" Subtype ........... 0x%02x (Selector Unit)\n", descriptor->descriptor_subtype); printf(" Unit ID ........... %u\n", @@ -275,6 +285,8 @@ void DumpAudioCSInterfaceDescriptorFeatureUnit( const usb_audio_feature_unit_descriptor* descriptor) { + printf(" Type .............. 0x%02x\n", + descriptor->descriptor_type); printf(" Subtype ........... 0x%02x (Feature Unit)\n", descriptor->descriptor_subtype); printf(" Unit ID ........... %u\n", @@ -316,6 +328,8 @@ void DumpAudioCSInterfaceDescriptorAssociated( const usb_generic_descriptor* descriptor) { + printf(" Type .............. 0x%02x\n", + descriptor->descriptor_type); printf(" Subtype ........... 0x%02x (Associate Interface)\n", (uint8)descriptor->data[0]); printf(" Interface ......... %u\n", @@ -324,6 +338,7 @@ DumpAudioCSInterfaceDescriptorAssociated( printf(" Data .............. "); for (uint8 i = 0; i < descriptor->length - 2; i++) printf("%02x ", descriptor->data[i]); + printf("\n"); } diff --git a/src/bin/listusb/usb_video.cpp b/src/bin/listusb/usb_video.cpp new file mode 100644 index 0000000000..bab6996702 --- /dev/null +++ b/src/bin/listusb/usb_video.cpp @@ -0,0 +1,320 @@ +/* + * Copyright 2016, Adrien Destugues, pulkomandy@pulkomandy.tk + * Distributed under terms of the MIT license. + */ + +#include + +#include + +#include "listusb.h" + + +void +DumpVideoCSInterfaceDescriptorHeader( + const usb_videocontrol_header_descriptor* descriptor) +{ + printf(" Type .............. 0x%02x\n", + descriptor->descriptor_type); + printf(" Subtype ........... 0x%02x (Header)\n", + descriptor->descriptor_subtype); + printf(" UVC Release ....... %d.%d\n", + descriptor->bcd_release_no >> 8, descriptor->bcd_release_no & 0xFF); + printf(" Total Length ...... %u\n", + descriptor->total_length); + printf(" Clock Frequency ... %" B_PRIu32 "\n", + descriptor->clock_frequency); + printf(" Interfaces ........ "); + + for (uint8 i = 0; i < descriptor->in_collection; i++) + printf("%u, ", descriptor->interface_numbers[i]); + printf("\n"); +} + + +static const char* +TerminalTypeName(uint16 terminalType) +{ + switch (terminalType) { + case USB_VIDEO_VENDOR_USB_IO: + return "Vendor specific"; + case USB_VIDEO_STREAMING_USB_IO: + return "Streaming"; + + case USB_VIDEO_VENDOR_IN: + return "Vendor specific input"; + case USB_VIDEO_CAMERA_IN: + return "Camera"; + case USB_VIDEO_MEDIA_TRANSPORT_IN: + return "Media transport input"; + + case USB_VIDEO_VENDOR_OUT: + return "Vendor specific output"; + case USB_VIDEO_DISPLAY_OUT: + return "Display"; + case USB_VIDEO_MEDIA_TRANSPORT_OUT: + return "Media transport output"; + + case USB_VIDEO_VENDOR_EXT: + return "Vendor specific format"; + case USB_VIDEO_COMPOSITE_EXT: + return "Composite"; + case USB_VIDEO_SVIDEO_EXT: + return "S-Video"; + case USB_VIDEO_COMPONENT_EXT: + return "Component"; + + default: + return "Unknown"; + } +} + + +void +DumpVideoCSInterfaceDescriptorOutputTerminal( + const usb_video_output_terminal_descriptor* descriptor) +{ + printf(" Type .............. 0x%02x\n", + descriptor->descriptor_type); + printf(" Subtype ........... 0x%02x (Output Terminal)\n", + descriptor->descriptor_subtype); + printf(" Terminal ID ....... %u\n", + descriptor->terminal_id); + printf(" Terminal Type ..... 0x%04x (%s)\n", + descriptor->terminal_type, + TerminalTypeName(descriptor->terminal_type)); + printf(" Associated Terminal %u\n", + descriptor->assoc_terminal); + printf(" Source ID ......... %u\n", + descriptor->source_id); + printf(" Terminal .......... %u\n", + descriptor->terminal); +} + + +void +DumpVideoCSInterfaceDescriptorInputTerminal( + const usb_video_input_terminal_descriptor* descriptor) +{ + printf(" Type .............. 0x%02x\n", + descriptor->descriptor_type); + printf(" Subtype ........... 0x%02x (Input Terminal)\n", + descriptor->descriptor_subtype); + printf(" Terminal ID ....... %u\n", + descriptor->terminal_id); + printf(" Terminal Type ..... 0x%04x (%s)\n", + descriptor->terminal_type, + TerminalTypeName(descriptor->terminal_type)); + printf(" Terminal .......... %u\n", + descriptor->terminal); + + if (descriptor->terminal_type == USB_VIDEO_CAMERA_IN) + { + printf(" Min. Focal length . %u\n", + descriptor->camera.focal_length_min); + printf(" Max. Focal length . %u\n", + descriptor->camera.focal_length_min); + printf(" Focal length ...... %u\n", + descriptor->camera.focal_length); + printf(" Controls .......... %02x%02x%02x\n", + descriptor->camera.controls[0], + descriptor->camera.controls[1], + descriptor->camera.controls[2]); + } +} + + +static const char* +ProcessingControlString(int index) +{ + switch(index) + { + case 0: + return "Brightness, "; + case 1: + return "Contrast, "; + case 2: + return "Hue, "; + case 3: + return "Saturation, "; + case 4: + return "Sharpness, "; + case 5: + return "Gamma, "; + case 6: + return "White balance temp., "; + case 7: + return "White balance component, "; + case 8: + return "Backlight compensation, "; + case 9: + return "Gain, "; + case 10: + return "Power line frequency, "; + case 11: + return "Automatic hue, "; + case 12: + return "Automatic white balance temp., "; + case 13: + return "Automatic white balance component, "; + case 14: + return "Digital multiplier, "; + case 15: + return "Digital multiplier limit, "; + case 16: + return "Analog video standard, "; + case 17: + return "Analog video lock status, "; + case 18: + return "Automatic contrast, "; + default: + return "Unknown, "; + } +} + + +void +DumpVideoCSInterfaceDescriptorProcessingUnit( + const usb_video_processing_unit_descriptor* descriptor) +{ + printf(" Type .............. 0x%02x\n", + descriptor->descriptor_type); + printf(" Subtype ........... 0x%02x (Processing unit)\n", + descriptor->descriptor_subtype); + printf(" Unit ID ........... %u\n", + descriptor->unit_id); + printf(" Source ID ......... %u\n", + descriptor->source_id); + printf(" Max Multiplier .... %f\n", + descriptor->max_multiplier / 100.f); + printf(" Controls .......... "); + uint32_t controls = (descriptor->controls[0] << 16) + | (descriptor->controls[1] << 8) + | descriptor->controls[2]; + for (int i = 0; i < 19; i++) + { + if (controls & (1 << (23 - i))) { + printf(ProcessingControlString(i)); + } + } + printf("\n"); + printf(" Processing ........ %u\n", + descriptor->processing); + printf(" Video Standards ... 0x%02x\n", + descriptor->video_standards); +} + + +void +DumpVideoCSInterfaceDescriptorExtensionUnit( + const usb_generic_descriptor* descriptor) +{ + uint8 i = 0; + + printf(" Type .............. 0x%02x\n", + descriptor->descriptor_type); + printf(" Subtype ........... 0x%02x (Extension unit)\n", + (uint8)descriptor->data[i++]); + printf(" Unit ID ........... %u\n", + (uint8)descriptor->data[i++]); + + printf(" GUID .............. "); + for (i = 2; i < 16 + 2; i++) + printf("%02x ", descriptor->data[i]); + printf("\n"); + + printf(" Control count ..... %u\n", + (uint8)descriptor->data[i++]); + + printf(" Input pins ........ "); + i = 20; // Skip the input pin count + for (; i - 20 < descriptor->data[19]; i++) + printf("%u, ", descriptor->data[i]); + printf("\n"); + + printf(" Controls .......... "); + uint8_t end = descriptor->data[i++]; + uint8_t start = i; + for (; i - start < end; i++) + printf("%02x", (uint8)descriptor->data[i]); + printf("\n"); + + printf(" Extension ......... %u\n", + (uint8)descriptor->data[i++]); +} + + +void +DumpVideoControlCSInterfaceDescriptor(const usb_generic_descriptor* descriptor) +{ + uint8 descriptorSubtype = descriptor->data[0]; + switch (descriptorSubtype) { + case USB_VIDEO_VC_HEADER: + DumpVideoCSInterfaceDescriptorHeader( + (usb_videocontrol_header_descriptor*)descriptor); + break; + case USB_VIDEO_VC_INPUT_TERMINAL: + DumpVideoCSInterfaceDescriptorInputTerminal( + (usb_video_input_terminal_descriptor*)descriptor); + break; + case USB_VIDEO_VC_OUTPUT_TERMINAL: + DumpVideoCSInterfaceDescriptorOutputTerminal( + (usb_video_output_terminal_descriptor*)descriptor); + break; + case USB_VIDEO_VC_PROCESSING_UNIT: + DumpVideoCSInterfaceDescriptorProcessingUnit( + (usb_video_processing_unit_descriptor*)descriptor); + break; + case USB_VIDEO_VC_EXTENSION_UNIT: + DumpVideoCSInterfaceDescriptorExtensionUnit(descriptor); + break; + default: + DumpDescriptorData(descriptor); + } +} + + +void +DumpAudioStreamCSInterfaceDescriptor(const usb_generic_descriptor* descriptor); + +void +DumpVideoDescriptor(const usb_generic_descriptor* descriptor, int subclass) +{ + switch (subclass) { + case USB_VIDEO_INTERFACE_VIDEOCONTROL_SUBCLASS: + switch (descriptor->descriptor_type) { + case USB_VIDEO_CS_INTERFACE: + DumpVideoControlCSInterfaceDescriptor(descriptor); + break; + default: + DumpDescriptorData(descriptor); + break; + } + break; + case USB_VIDEO_INTERFACE_VIDEOSTREAMING_SUBCLASS: + switch (descriptor->descriptor_type) { + case USB_VIDEO_CS_INTERFACE: + DumpAudioStreamCSInterfaceDescriptor(descriptor); + break; + default: + DumpDescriptorData(descriptor); + break; + } + break; + case USB_VIDEO_INTERFACE_COLLECTION_SUBCLASS: + switch (descriptor->descriptor_type) { + case USB_VIDEO_CS_INTERFACE: + // TODO + DumpDescriptorData(descriptor); + break; + default: + DumpDescriptorData(descriptor); + break; + } + break; + default: + DumpDescriptorData(descriptor); + break; + } +} +