listusb: generate class code table from usb.ids, and use it
Change-Id: I43b79c5abc74306aba9a69991aeb5e110b2d790b Reviewed-on: https://review.haiku-os.org/c/haiku/+/5737 Reviewed-by: Fredrik Holmqvist <fredrik.holmqvist@gmail.com>
This commit is contained in:
parent
e6ce95c5ab
commit
edeaa9c0c7
@ -12,6 +12,30 @@
|
||||
#include "usbhdr.h"
|
||||
|
||||
|
||||
static void
|
||||
usb_get_class_info(uint8 usb_class_base_id, uint8 usb_class_sub_id, uint8 usb_class_proto_id,
|
||||
char *classInfo, size_t size)
|
||||
{
|
||||
USB_CLASSCODETABLE *foundItem = NULL;
|
||||
int i;
|
||||
for (i = 0; i < (int)USB_CLASSCODETABLE_LEN; i++) {
|
||||
if ((usb_class_base_id == UsbClassCodeTable[i].BaseClass)
|
||||
&& (usb_class_sub_id == UsbClassCodeTable[i].SubClass)) {
|
||||
foundItem = &UsbClassCodeTable[i];
|
||||
if (usb_class_proto_id == UsbClassCodeTable[i].Protocol)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (foundItem) {
|
||||
snprintf(classInfo, size, "%s (%s%s%s)", foundItem->BaseDesc, foundItem->SubDesc,
|
||||
(foundItem->ProtocolDesc && strcmp("", foundItem->ProtocolDesc)) ? ", " : "",
|
||||
foundItem->ProtocolDesc);
|
||||
} else
|
||||
snprintf(classInfo, size, "%s (%u:%u:%u)", "(Unknown)",
|
||||
usb_class_base_id, usb_class_sub_id, usb_class_proto_id);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
usb_get_vendor_info(uint16 vendorID, const char **vendorName)
|
||||
{
|
||||
|
@ -22,6 +22,8 @@ BEGIN {
|
||||
cleanvalues = "[^A-Za-z0-9{}\"'&@?!*.,:;+<> \\t\\/_\\[\\]=#()-]"
|
||||
# ToDo: currently IDs aren't checked, we dumbly assume the source is clean
|
||||
|
||||
inClassesDefinition = 0
|
||||
|
||||
# descriptive output header
|
||||
print "#if 0" > ofile
|
||||
print "#\tUSBHDR.H: USB Vendors, Devices\n#" > ofile
|
||||
@ -67,6 +69,61 @@ BEGIN {
|
||||
devices[devicecount, 3] = device
|
||||
}
|
||||
|
||||
# match device class - store data for later
|
||||
/^C [[:xdigit:]][[:xdigit:]] / {
|
||||
|
||||
class = $2
|
||||
classname = substr($0, 7)
|
||||
gsub( /\"/, "\\\"", classname )
|
||||
|
||||
inClassesDefinition = 1
|
||||
|
||||
classcount++
|
||||
classes[classcount, 1] = class
|
||||
classes[classcount, 2] = "00"
|
||||
classes[classcount, 3] = "00"
|
||||
classes[classcount, 4] = classname
|
||||
classes[classcount, 5] = ""
|
||||
classes[classcount, 6] = ""
|
||||
}
|
||||
|
||||
# match subclass, use device class data captured earlier, and output
|
||||
inClassesDefinition && (/^\t[[:xdigit:]][[:xdigit:]] /) {
|
||||
subclass = $1
|
||||
subclassname = substr($0, 6)
|
||||
gsub( /\"/, "\\\"", subclassname )
|
||||
|
||||
classcount++
|
||||
classes[classcount, 1] = class
|
||||
classes[classcount, 2] = subclass
|
||||
classes[classcount, 3] = "00"
|
||||
classes[classcount, 4] = classname
|
||||
classes[classcount, 5] = subclassname
|
||||
classes[classcount, 6] = ""
|
||||
}
|
||||
|
||||
# match protocol
|
||||
inClassesDefinition && (/^\t\t[[:xdigit:]][[:xdigit:]] /) {
|
||||
|
||||
protocol = $1
|
||||
protocolname = substr($0, 7)
|
||||
gsub( /\"/, "\\\"", protocolname )
|
||||
|
||||
classcount++
|
||||
classes[classcount, 1] = class
|
||||
classes[classcount, 2] = subclass
|
||||
classes[classcount, 3] = protocol
|
||||
classes[classcount, 4] = classname
|
||||
classes[classcount, 5] = subclassname
|
||||
classes[classcount, 6] = protocolname
|
||||
}
|
||||
|
||||
#match comments
|
||||
/^#/ {
|
||||
inClassesDefinition = false
|
||||
}
|
||||
|
||||
|
||||
# We've processed the file, now output.
|
||||
END {
|
||||
|
||||
@ -89,6 +146,36 @@ END {
|
||||
|
||||
}
|
||||
|
||||
if ( classcount > 0 ) {
|
||||
print "typedef struct _USB_CLASSCODETABLE\n{\n\tunsigned char BaseClass ;\n\tunsigned char SubClass ;\n\tunsigned char Protocol ;" > ofile
|
||||
print "\tconst char *\t\tBaseDesc ;\n\tconst char *\t\tSubDesc ;\n\tconst char *\t\tProtocolDesc ;\n} USB_CLASSCODETABLE, *PUSB_CLASSCODETABLE ;\n" > ofile
|
||||
print "USB_CLASSCODETABLE UsbClassCodeTable [] =\n{" > ofile
|
||||
currentclass = classes[1, 1]
|
||||
for (i = 1; i <= classcount; i++) {
|
||||
|
||||
if (i != 1) {
|
||||
formatting = ",\n"
|
||||
} else {
|
||||
formatting = ""
|
||||
}
|
||||
|
||||
# pretty print separate classes
|
||||
if ( currentclass != classes[i, 1] ) {
|
||||
formatting = formatting "\n"
|
||||
currentclass = classes[i, 1]
|
||||
}
|
||||
|
||||
# if the next item has the same details, we know we're to skip ourselves
|
||||
# this is because the programming interface name needs to be used, and we dont have it ourselves
|
||||
if ( ( classes[i, 1] != classes[i+1, 1] ) || ( classes[i, 2] != classes[i+1, 2] ) || ( classes[i, 3] != classes[i+1, 3] ) ) {
|
||||
printf formatting "\t{ 0x" classes[i, 1] ", 0x" classes[i, 2] ", 0x" classes[i, 3] ", \"" classes[i, 4] "\", \"" classes[i, 5] "\", \"" classes[i, 6] "\" }" > ofile
|
||||
}
|
||||
}
|
||||
print "\n} ;\n\n// Use this value for loop control during searching:\n#define USB_CLASSCODETABLE_LEN (sizeof(UsbClassCodeTable)/sizeof(USB_CLASSCODETABLE))\n" > ofile
|
||||
|
||||
}
|
||||
|
||||
|
||||
close(ofile)
|
||||
}
|
||||
|
||||
|
@ -21,175 +21,6 @@
|
||||
#include "listusb.h"
|
||||
|
||||
|
||||
const char*
|
||||
ClassName(int classNumber) {
|
||||
switch (classNumber) {
|
||||
case 0:
|
||||
return "Per-interface classes";
|
||||
case USB_AUDIO_DEVICE_CLASS:
|
||||
return "Audio";
|
||||
case 2:
|
||||
return "Communication";
|
||||
case 3:
|
||||
return "HID";
|
||||
case 5:
|
||||
return "Physical";
|
||||
case 6:
|
||||
return "Image";
|
||||
case 7:
|
||||
return "Printer";
|
||||
case 8:
|
||||
return "Mass storage";
|
||||
case 9:
|
||||
return "Hub";
|
||||
case 10:
|
||||
return "CDC-Data";
|
||||
case 11:
|
||||
return "Smart card";
|
||||
case 13:
|
||||
return "Content security";
|
||||
case USB_VIDEO_DEVICE_CLASS:
|
||||
return "Video";
|
||||
case 15:
|
||||
return "Personal Healthcare";
|
||||
case 0xDC:
|
||||
return "Diagnostic device";
|
||||
case 0xE0:
|
||||
return "Wireless controller";
|
||||
case 0xEF:
|
||||
return "Miscellaneous";
|
||||
case 0xFE:
|
||||
return "Application specific";
|
||||
case 0xFF:
|
||||
return "Vendor specific";
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
SubclassName(int classNumber, int subclass)
|
||||
{
|
||||
if (classNumber == 0xEF) {
|
||||
if (subclass == 0x02)
|
||||
return " (Common)";
|
||||
if (subclass == 0x04)
|
||||
return " (RNDIS)";
|
||||
if (subclass == 0x05)
|
||||
return " (USB3 Vision)";
|
||||
if (subclass == 0x06)
|
||||
return " (STEP)";
|
||||
if (subclass == 0x07)
|
||||
return " (DVB Command Interface)";
|
||||
}
|
||||
|
||||
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)";
|
||||
}
|
||||
}
|
||||
|
||||
if (classNumber == 0xFE) {
|
||||
if (subclass == 0x01)
|
||||
return " (Firmware Upgrade)";
|
||||
if (subclass == 0x02)
|
||||
return " (IrDA)";
|
||||
if (subclass == 0x03)
|
||||
return " (Test and measurement)";
|
||||
}
|
||||
|
||||
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 control)";
|
||||
if (subclass == 0x01 && protocol == 0x02)
|
||||
return " (UWB Radio)";
|
||||
if (subclass == 0x01 && protocol == 0x03)
|
||||
return " (RNDIS control)";
|
||||
if (subclass == 0x01 && protocol == 0x04)
|
||||
return " (Bluetooth AMP)";
|
||||
if (subclass == 0x02 && protocol == 0x01)
|
||||
return " (Host wire adapter)";
|
||||
if (subclass == 0x02 && protocol == 0x02)
|
||||
return " (Device wire adapter)";
|
||||
if (subclass == 0x02 && protocol == 0x03)
|
||||
return " (Device wire isochronous)";
|
||||
case 0xEF:
|
||||
if (subclass == 0x01 && protocol == 0x01)
|
||||
return " (Microsoft Active Sync)";
|
||||
if (subclass == 0x01 && protocol == 0x02)
|
||||
return " (Palm Sync)";
|
||||
if (subclass == 0x02 && protocol == 0x01)
|
||||
return " (Interface Association)";
|
||||
if (subclass == 0x02 && protocol == 0x02)
|
||||
return " (Wire adapter multifunction peripheral)";
|
||||
if (subclass == 0x03 && protocol == 0x01)
|
||||
return " (Cable based association framework)";
|
||||
if (subclass == 0x04 && protocol == 0x01)
|
||||
return " (RNDIS Ethernet)";
|
||||
if (subclass == 0x04 && protocol == 0x02)
|
||||
return " (RNDIS Wifi)";
|
||||
if (subclass == 0x04 && protocol == 0x03)
|
||||
return " (RNDIS WiMAX)";
|
||||
if (subclass == 0x04 && protocol == 0x04)
|
||||
return " (RNDIS WWAN)";
|
||||
if (subclass == 0x04 && protocol == 0x05)
|
||||
return " (RNDIS raw IPv4)";
|
||||
if (subclass == 0x04 && protocol == 0x06)
|
||||
return " (RNDIS raw IPv6)";
|
||||
if (subclass == 0x04 && protocol == 0x07)
|
||||
return " (RNDIS GPRS)";
|
||||
if (subclass == 0x05 && protocol == 0x00)
|
||||
return " (USB3 vision control)";
|
||||
if (subclass == 0x05 && protocol == 0x01)
|
||||
return " (USB3 vision event)";
|
||||
if (subclass == 0x05 && protocol == 0x02)
|
||||
return " (USB3 vision streaming)";
|
||||
if (subclass == 0x06 && protocol == 0x01)
|
||||
return " (STEP)";
|
||||
if (subclass == 0x06 && protocol == 0x02)
|
||||
return " (STEP RAW)";
|
||||
if (subclass == 0x07 && protocol == 0x01)
|
||||
return " (DVB Command Interface in IAD)";
|
||||
if (subclass == 0x07 && protocol == 0x02)
|
||||
return " (DVB Command Interface in interface descriptor)";
|
||||
if (subclass == 0x07 && protocol == 0x03)
|
||||
return " (Media interface in interface descriptor)";
|
||||
break;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DumpCDCDescriptor(const usb_generic_descriptor* descriptor, int subclass)
|
||||
{
|
||||
@ -400,14 +231,17 @@ DumpInterface(const BUSBInterface* interface)
|
||||
if (!interface)
|
||||
return;
|
||||
|
||||
char classInfo[128];
|
||||
usb_get_class_info(interface->Class(), 0, 0, classInfo, sizeof(classInfo));
|
||||
printf(" Class .............. 0x%02x (%s)\n",
|
||||
interface->Class(), ClassName(interface->Class()));
|
||||
interface->Class(), classInfo);
|
||||
usb_get_class_info(interface->Class(), interface->Subclass(), 0, classInfo, sizeof(classInfo));
|
||||
printf(" Subclass ........... 0x%02x%s\n",
|
||||
interface->Subclass(),
|
||||
SubclassName(interface->Class(), interface->Subclass()));
|
||||
interface->Subclass(), classInfo);
|
||||
usb_get_class_info(interface->Class(), interface->Subclass(), interface->Protocol(), classInfo,
|
||||
sizeof(classInfo));
|
||||
printf(" Protocol ........... 0x%02x%s\n",
|
||||
interface->Protocol(), ProtocolName(interface->Class(),
|
||||
interface->Subclass(), interface->Protocol()));
|
||||
interface->Protocol(), classInfo);
|
||||
printf(" Interface String ... \"%s\"\n",
|
||||
interface->InterfaceString());
|
||||
|
||||
@ -486,13 +320,15 @@ DumpInfo(BUSBDevice& device, bool verbose)
|
||||
return;
|
||||
}
|
||||
|
||||
char classInfo[128];
|
||||
printf("[Device /dev/bus/usb%s]\n", device.Location());
|
||||
printf(" Class .................. 0x%02x (%s)\n", device.Class(),
|
||||
ClassName(device.Class()));
|
||||
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()));
|
||||
usb_get_class_info(device.Class(), 0, 0, classInfo, sizeof(classInfo));
|
||||
printf(" Class .................. 0x%02x (%s)\n", device.Class(), classInfo);
|
||||
usb_get_class_info(device.Class(), device.Subclass(), 0, classInfo, sizeof(classInfo));
|
||||
printf(" Subclass ............... 0x%02x%s\n", device.Subclass(), classInfo);
|
||||
usb_get_class_info(device.Class(), device.Subclass(), device.Protocol(), classInfo,
|
||||
sizeof(classInfo));
|
||||
printf(" Protocol ............... 0x%02x%s\n", device.Protocol(), classInfo);
|
||||
printf(" Max Endpoint 0 Packet .. %d\n", device.MaxEndpoint0PacketSize());
|
||||
uint32_t version = device.USBVersion();
|
||||
printf(" USB Version ............ %d.%d\n", version >> 8, version & 0xFF);
|
||||
|
Loading…
Reference in New Issue
Block a user