1.概述
USB设备通过debugfs导出/sys/kernel/debug/usb/devices显示内核已知的每个USB设备及其配置描述符。此文件对于用户模式下的状态查看
工具非常方便,可以扫描文本格式并忽略大部分文本。 设备特定文件中提供了更详细的设备状态(包括类和供应商状态)。
此文件与poll()系统调用结合使用,还可用于检测何时添加或删除设备:
int fd; struct pollfd pfd; fd = open("/sys/kernel/debug/usb/devices", O_RDONLY); pfd = { fd, POLLIN, 0 }; for (;;) { /* The first time through, this call will return immediately. */ poll(&pfd, 1, -1); /* To see what's changed, compare the file's previous and current contents or scan the filesystem. (Scanning is more precise.) */ }
请注意,此行为旨在用于信息获取和调试目的。 例如,使用诸如udev或HAL之类的程序来初始化设备或启动用户模式助手程序会更合适。
2.文件格式
每个T:行(拓扑信息:Lev,Prnt,Port,Cnt)的前4列中的数字可用于构建USB拓扑图。
每行标记有该行的单字符ID:
T = Topology (etc.) B = Bandwidth (applies only to USB host controllers, which are virtualized as root hubs) D = Device descriptor info. P = Product ID info. (from Device descriptor, but they won't fit together on one line) S = String descriptors. C = Configuration descriptor info. (* = active configuration) I = Interface descriptor info. E = Endpoint descriptor info.
历史遗留:d = 十进制数(可能有前导空格或0) x = 十六进制数(可能有前导空格或0) s = string
1)拓扑信息:
T: Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=dddd MxCh=dd | | | | | | | | |__MaxChildren | | | | | | | |__Device Speed in Mbps | | | | | | |__DeviceNumber | | | | | |__Count of devices at this level | | | | |__Connector/Port on Parent for this device | | | |__Parent DeviceNumber | | |__Level in topology for this bus | |__Bus number |__Topology info tag
Speed如下, 插入端口4的设备将显示Port = 03。
1.5 Mbit/s for low speed USB 12 Mbit/s for full speed USB 480 Mbit/s for high speed USB (added for USB 2.0); also used for Wireless USB, which has no fixed speed 5000 Mbit/s for SuperSpeed USB (added for USB 3.0)
2)带宽信息:
B: Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd | | | |__Number of isochronous requests | | |__Number of interrupt requests | |__Total Bandwidth allocated to this bus |__Bandwidth info tag
3)设备描述符信息和产品ID信息:
D: Ver=x.xx Cls=xx(s) Sub=xx Prot=xx MxPS=dd #Cfgs=dd
P: Vendor=xxxx ProdID=xxxx Rev=xx.xx
D: Ver=x.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd | | | | | | |__NumberConfigurations | | | | | |__MaxPacketSize of Default Endpoint | | | | |__DeviceProtocol | | | |__DeviceSubClass | | |__DeviceClass | |__Device USB version |__Device info tag #1
P: Vendor=xxxx ProdID=xxxx Rev=xx.xx | | | |__Product revision number | | |__Product ID code | |__Vendor ID code |__Device info tag #2
4)字符串描述符信息:
S: Manufacturer=ssss | |__Manufacturer of this device as read from the device. | For USB host controller drivers (virtual root hubs) this may | be omitted, or (for newer drivers) will identify the kernel | version and the driver which provides this hub emulation. |__String info tag S: Product=ssss | |__Product description of this device as read from the device. | For older USB host controller drivers (virtual root hubs) this | indicates the driver; for newer ones, it's a product (and vendor) | description that often comes from the kernel's PCI ID database. |__String info tag S: SerialNumber=ssss | |__Serial Number of this device as read from the device. | For USB host controller drivers (virtual root hubs) this is | some unique ID, normally a bus ID (address or slot name) that | can't be shared with any other device. |__String info tag
5)配置描述符信息:
C:* #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA | | | | | |__MaxPower in mA | | | | |__Attributes | | | |__ConfiguratioNumber | | |__NumberOfInterfaces | |__ "*" indicates the active configuration (others are " ") |__Config info tag
USB设备可能具有多种配置,每种配置的行为都不同。 例如,总线供电的配置可能比自供电配置的能力低得多。 一次只能激活一个设备配
置; 大多数设备只有一个配置。
每个配置都包含一个或多个接口。 每个接口都提供不同的“功能”,通常绑定到不同的USB设备驱动程序。 一个常见的例子是带有用于回放的
音频接口的USB扬声器,以及用于软件音量控制的HID接口。
:6)接口描述符信息:
I:* If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=ssss | | | | | | | | |__Driver name | | | | | | | | or "(none)" | | | | | | | |__InterfaceProtocol | | | | | | |__InterfaceSubClass | | | | | |__InterfaceClass | | | | |__NumberOfEndpoints | | | |__AlternateSettingNumber | | |__InterfaceNumber | |__ "*" indicates the active altsetting (others are " ") |__Interface info tag
一个给定接口可以具有一个或多个“可选”设置。 例如,默认设置可能不会使用少量的周期性带宽。 要使用大部分总线带宽,驱动程序必须
选择非默认的altsetting。
一次只能有一个接口的设置处于活动状态,并且一次只能有一个驱动程序绑定到接口。 大多数设备每个接口只有一个可用设置。
7)端点描述符信息:
E: Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=dddss | | | | |__Interval (max) between transfers | | | |__EndpointMaxPacketSize | | |__Attributes(EndpointType) | |__EndpointAddress(I=In,O=Out) |__Endpoint info tag
所有周期性(中断或等时)端点的间隔都是非零的。 对于高速端点,传输间隔可以以微秒而不是毫秒来度量。
对于高速周期端点,EndpointMaxPacketSize反映了每微帧数据传输大小。 对于“高带宽”端点,每个端点可以反映两个或三个数据包(每125
个用户最多3个字节)。
使用Linux-USB堆栈,定期带宽保留使用URB提供的传输间隔和大小,这可能小于端点描述符中的传输间隔和大小。
3.此文件的使用例子
例如,如果用户或脚本仅对拓扑信息感兴趣,请使用类似的内容
grep ^T: /sys/kernel/debug/usb/devices 仅用于拓扑行。
grep -i ^[tdp]: /sys/kernel/debug/usb/devices 这样的命令可用于仅列出以方括号中的字符开头的行,其中有效字符为TDPCIE。 使用稍
微更强大的脚本,它可以显示任何选定的行(例如,只显示T,D和P行)并更改其输出格式。 (procusb Perl脚本是这个想法的开始。它将
仅列出从/sys/kernel/debug/usb/devices中选择的行[从TBDPSCIE中选择]或“All”行。)
拓扑行可用于生成系统根集线器上USB设备的图形/图示。
接口行可用于确定每个设备使用的驱动程序,以及被激活的可选设置。
配置行可用于列出系统的USB设备正在使用的最大功率(以毫安为单位)。 例如:/sys/kernel/debug/usb/devices.
eg:
T: Bus=00 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2 B: Alloc= 28/900 us ( 3%), #Int= 2, #Iso= 0 D: Ver= 1.00 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=0000 ProdID=0000 Rev= 0.00 S: Product=USB UHCI Root Hub S: SerialNumber=dce0 C:* #Ifs= 1 Cfg#= 1 Atr=40 MxPwr= 0mA I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl=255ms T: Bus=00 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 4 D: Ver= 1.00 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=0451 ProdID=1446 Rev= 1.00 C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=100mA I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub E: Ad=81(I) Atr=03(Int.) MxPS= 1 Ivl=255ms T: Bus=00 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 3 Spd=1.5 MxCh= 0 D: Ver= 1.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=04b4 ProdID=0001 Rev= 0.00 C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=100mA I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=02 Driver=mouse E: Ad=81(I) Atr=03(Int.) MxPS= 3 Ivl= 10ms T: Bus=00 Lev=02 Prnt=02 Port=02 Cnt=02 Dev#= 4 Spd=12 MxCh= 0 D: Ver= 1.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=0565 ProdID=0001 Rev= 1.08 S: Manufacturer=Peracom Networks, Inc. S: Product=Peracom USB to Serial Converter C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr=100mA I: If#= 0 Alt= 0 #EPs= 3 Cls=00(>ifc ) Sub=00 Prot=00 Driver=serial E: Ad=81(I) Atr=02(Bulk) MxPS= 64 Ivl= 16ms E: Ad=01(O) Atr=02(Bulk) MxPS= 16 Ivl= 16ms E: Ad=82(I) Atr=03(Int.) MxPS= 8 Ivl= 8ms
从中选择仅T:和I:行(例如,使用procusb ti),我们有:
T: Bus=00 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2 T: Bus=00 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 4 接在父设备的0号端口上, 而且自己有4个下行端口 I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub T: Bus=00 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 3 Spd=1.5 MxCh= 0 I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=02 Driver=mouse T: Bus=00 Lev=02 Prnt=02 Port=02 Cnt=02 Dev#= 4 Spd=12 MxCh= 0 接在父设备的2号端口上,自己没有下行端口 I: If#= 0 Alt= 0 #EPs= 3 Cls=00(>ifc ) Sub=00 Prot=00 Driver=serial
得出拓扑:
+------------------+ | PC/root_hub (12)| Dev# = 1 +------------------+ (nn) is Mbps. Level 0 | CN.0 | CN.1 | [CN = connector/port #] +------------------+ / / +-----------------------+ Level 1 | Dev#2: 4-port hub (12)| +-----------------------+ |CN.0 |CN.1 |CN.2 |CN.3 | +-----------------------+ \____________________ \_____ +--------------------+ +--------------------+ Level 2 | Dev# 3: mouse (1.5)| | Dev# 4: serial (12)| +--------------------+ +--------------------+
下面是我这个Renesas开发板的:
# cat /sys/kernel/debug/usb/devices T: Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=480 MxCh= 1 B: Alloc= 0/800 us ( 0%), #Int= 0, #Iso= 0 D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1d6b ProdID=0002 Rev= 4.14 S: Manufacturer=Linux 4.14.35 ehci_hcd S: Product=EHCI Host Controller S: SerialNumber=ee080100.usb C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr= 0mA I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub E: Ad=81(I) Atr=03(Int.) MxPS= 4 Ivl=256ms T: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=480 MxCh= 1 B: Alloc= 0/800 us ( 0%), #Int= 0, #Iso= 0 D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1d6b ProdID=0002 Rev= 4.14 S: Manufacturer=Linux 4.14.35 ehci_hcd S: Product=EHCI Host Controller S: SerialNumber=ee0a0100.usb C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr= 0mA I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub E: Ad=81(I) Atr=03(Int.) MxPS= 4 Ivl=256ms T: Bus=03 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 1 B: Alloc= 0/900 us ( 0%), #Int= 0, #Iso= 0 D: Ver= 1.10 Cls=09(hub ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1d6b ProdID=0001 Rev= 4.14 S: Manufacturer=Linux 4.14.35 ohci_hcd S: Product=Generic Platform OHCI controller S: SerialNumber=ee080000.usb C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr= 0mA I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub E: Ad=81(I) Atr=03(Int.) MxPS= 2 Ivl=255ms T: Bus=04 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 1 B: Alloc= 0/900 us ( 0%), #Int= 0, #Iso= 0 D: Ver= 1.10 Cls=09(hub ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1d6b ProdID=0001 Rev= 4.14 S: Manufacturer=Linux 4.14.35 ohci_hcd S: Product=Generic Platform OHCI controller S: SerialNumber=ee0a0000.usb C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr= 0mA I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub E: Ad=81(I) Atr=03(Int.) MxPS= 2 Ivl=255ms
https://01.org/linuxgraphics/gfx-docs/drm/driver-api/usb/usb.html#dev-bus-usb-bbb-ddd