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:
Jérôme Duval 2022-10-10 20:00:59 +02:00 committed by waddlesplash
parent e6ce95c5ab
commit edeaa9c0c7
3 changed files with 127 additions and 180 deletions

View File

@ -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)
{

View File

@ -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)
}

View File

@ -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);