How do I read the output of the `usb-devices` command?

I’m trying to debug a USB issue on an Ubuntu 22.04. I’ve come across the usb-devices command. However I do not understand the output. I’ve read the man page, and it says:

The output of the script is similar to the usb/devices file available either under /proc/bus (if usbfs is mounted), or under /sys/kernel/debug (if debugfs is mounted there). The script is primarily intended to be used if the file is not available.
In contrast to the usb/devices file, this script only lists active interfaces (those marked with a "*" in the usb/devices file) and their endpoints.
Be advised that there can be differences in the way information is sorted, as well as in the format of the output.

However I am not able to find a clear guide on how to read the output of those files either.
What follows is example output from a different machine:

T:  Bus=01 Lev=01 Prnt=01 Port=03 Cnt=01 Dev#=  3 Spd=1.5 MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=045e ProdID=082c Rev=01.00
S:  Manufacturer=Microsoft
S:  Product=Microsoft Ergonomic Keyboard
S:  SerialNumber=601135501321
C:  #Ifs= 2 Cfg#= 1 Atr=a0 MxPwr=100mA
I:  If#= 0 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=01 Prot=01 Driver=usbhid
E:  Ad=81(I) Atr=03(Int.) MxPS=   8 Ivl=10ms
I:  If#= 1 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=00 Prot=00 Driver=usbhid
E:  Ad=82(I) Atr=03(Int.) MxPS=   8 Ivl=10ms

How do I read this? What do the initials mean?
I can read the script itself, from vim $(which usb-devices), and that helps a little. For example, in the 1st line, It outputs:

T: Bus=01 Lev=01 Prnt=01 Port=03 Cnt=01 Dev#= 3 Spd=1.5 MxCh= 0

And in the code I can see that it refers comes from the line:

printf "nT: Bus=%02i Lev=%02i Prnt=%02i Port=%02i Cnt=%02i Dev#=%3i Spd=%-3s MxCh=%2in"
$busnum $level $parent $port $count $devnum $speed $maxchild

So from that I can see where $busnum and such come, but even then I don’t see that the T in the beginning stands for.

Asked By: Uberhumus


After a bit of digging, the answer was found here.
The interesting bits are quoted below:

The line that starts with T: is the topology.Bus indicates which bus the device is on. Lev indicates the level of the device, starting at level 00 for the root hub, level 01 for any device attached to the root hub, level 02 for devices attached to hubs at level 01, and so on. Prnt is the parent device for this device (always 00 for the root hub, and 01 for the devices attached to the root hub). Port is the port on the parent device, starting at 00 for the first port on each device. Prnt/Port is unique per bus. Cnt indicates what number device this is, at this level, based on the enumeration order within that level of the topology, starting at 01 for the first device. Dev# indicates what number device this is, irrespective of level, based on the bus enumeration order. This is unique per bus. Spd indicates what speed this device is running at, in Mbps (either 1.5 or 12 with the current version of USB). MxCh indicates how many devices can be connected to this device, and is 00 for anything except a hub. Driver indicates which device driver is being used for this device – an entry of (none) indicates that no driver is being used.

The line that starts with D: is information from the device descriptor. Ver indicates which USB specification version the device claims to meet. Cls indicates which device class the device is claiming to meet, in both hexadecimal and as a string. A Cls entry of 00(>ifc) indicates that the device class specification compliance is interface dependent, and the interface descriptor should be read for device class information. Sub indicates which sub-class (within the Cls entry), the device meets. Prot indicates which protocol within a class or sub-class the device claims to meet. MxPS indicates how big the packets from Endpoint 0 are. #Cfgs indicates how many configurations this device has.

Much like D:, the line that starts with P: is information from the device descriptor, and is seperated mainly because it wouldn’t all fit on one line. Vendor indicates the Vendor Identification code for the device, and ProdID indicates the Product Identification code for the device. Rev indicates the product revision number.

The lines that start with S:, if any, are the vendor and product strings that the device returned.

The line that starts with C: is information from the configuration descriptor – the number of C:lines per device is given by #Cfgs, and the entry followed by an asterisk is the current configuration. #If indicates how many interfaces the device has. Cfg# indicates which configuration is being described. Atr is a hexadecimal indication of the device attributes (0x80 for bus-powered, 0x40 for self-powered, 0x20 for remote wake-up capable). MxPwr is the maximum power draw for this device configuration, in milliamps. Refer to USB specification clause 9.7.2 for further information on configuration descriptors.

The line that starts with I: is information from the interface descriptor – the number of I: lines per C: line is given by the #Ifs entry. If# indicates which interface is being described within a given device configuration. Alt indicates which alternate setting of this interface is being described. #EPs indicates how many endpoints there are within the alternate setting for this endpoint. Cls indicates which class the alternate setting of the interface corresponds to, in both hexadecimal and as a character string. Sub indicates which sub-class the alternate setting of the interface belongs to. Prot indicates which interface protocol (within a class and sub-class tuple) the alternate setting of the interface conforms to. Driver indicates which of the various USB drivers has claimed this interface. See USB specification clause 9.7.3 for further information.

The line that starts with E: is information from the endpoint descriptor – the number of E: lines per I: line is given by the #EPs entry. Endpoint 0 is not displayed. Ad indicates the endpoint address, with a letter to indicate whether the endpoint is an In or Out endpoint. Atr indicate the attribute (transfer type) associated with the endpoint, followed by a string translating the transfer type. MxPS indicates the maximum packet size this endpoint is capable of sending or receiving, as appropriate. Ivl indicates the interval, in milliseconds, between polling of interrupt endpoints. Ivl is ignored for bulk and control transfers, and is set to 1 for isochronous transfers. See USB specification clause 9.7.4 for further information on endpoint descriptors.

Answered By: Uberhumus
Categories: Answers Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.