1.概述
Linux内核中USB设备信息及拓扑结构可以从/sys/kernel/debug/usb/devices和/sys/bus/usb/devices中获取,下面介绍这些信息如何解读。
2./sys/kernel/debug/usb/devices
这些信息由usb_device_dump
函数打印,信息格式如下所示,意义见注释。
[drivers/usb/core/devices.c]
#define ALLOW_SERIAL_NUMBER
/*
Bus: 总线编号
Lev: USB总线拓扑层级,最大7层,Lev=0为Root hub
Prnt: 父设备的设备号
Port: 设备接入端口的端口编号,从0开始,Root hub默认为0,其他Hub的下行端口从0开始编号。
Cnt: 相同拓扑层级上设备的数量
Dev: 设备编号
Spd: 速度
MxCH: Hub的Port数量
*/
static const char format_topo[] =
"\nT: Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%-4s MxCh=%2d\n";
/*
Manufacturer: 厂商字符串
Product: 产品字符串
SerialNumber: 序列号
*/
static const char format_string_manufacturer[] =
"S: Manufacturer=%.100s\n";
static const char format_string_product[] =
"S: Product=%.100s\n";
#ifdef ALLOW_SERIAL_NUMBER
static const char format_string_serialnumber[] =
"S: SerialNumber=%.100s\n";
#endif
/*
Alloc: bFirstInterface
Int: bInterfaceCount
Iso: bFunctionClass, 同时会输出类的名称
*/
static const char format_bandwidth[] =
"B: Alloc=%3d/%3d us (%2d%%), #Int=%3d, #Iso=%3d\n";
/*
Ver: bcdUSB
Cls: bDeviceClass,同时会输出类的名称
Sub: bDeviceSubClass
Prot: bDeviceProtocol
MxPS: bMaxPacketSize0
Cfgs: bNumConfigurations
*/
static const char format_device1[] =
"D: Ver=%2x.%02x Cls=%02x(%-5s) Sub=%02x Prot=%02x MxPS=%2d #Cfgs=%3d\n";
/*
Vendor: idVendor
ProdID: idProduct
Rev: bcdUSB
*/
static const char format_device2[] =
"P: Vendor=%04x ProdID=%04x Rev=%2x.%02x\n";
/*
Ifs: bNumInterfaces
Cfg: bConfigurationValue
Atr: bmAttributes
MxPwr: bMaxPower * mul, USB_SPEED_SUPER: mul=8, 其他mul=2
*/
static const char format_config[] =
"C:%c #Ifs=%2d Cfg#=%2d Atr=%02x MxPwr=%3dmA\n";
/*
FirstIf: bFirstInterface
IfCount: bInterfaceCount
Cls: bFunctionClass, 同时会输出类的名称
Sub: bFunctionSubClass
Prot: bFunctionProtocol
*/
static const char format_iad[] =
"A: FirstIf#=%2d IfCount=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x\n";
/*
If: bInterfaceNumber
Alt: bAlternateSetting
EPs: bNumEndpoints
Cls: bInterfaceClass, 同时会输出类的名称
Sub: bInterfaceSubClass
Prot: bInterfaceProtocol
Driver: 使用的驱动名称
*/
static const char format_iface[] =
"I:%c If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n";
/*
Ad: bEndpointAddress, I: 输入, O: 输出
Atr: bmAttributes, 同时输出传输类型
MxPS: 一次传输最大包长度
Ivl: interval
*/
static const char format_endpt[] =
"E: Ad=%02x(%c) Atr=%02x(%-4s) MxPS=%4d Ivl=%d%cs\n";
static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,
loff_t *skip_bytes, loff_t *file_offset,
struct usb_device *usbdev, struct usb_bus *bus,
int level, int index, int count);
下图是一个示例,可以按照上面的信息分析一下USB总线的拓扑结构。USB1总线速度为USB2.0,总共有3级。第0级为Root Hub,只有一个port,设备号为1。第1级的USB设备也为Hub,接在Root Hub下面,有4个port,设备号为2。第2级有两个USB设备,接在第1级的USB Hub下面。第1个设备的设备号为8,接在第1级Hub的第0个下行port,是USB转网口设备,有1个配置、1个接口、3个端点(0x81为输入端点,传输类型为中断传输;0x82为输入端点,传输类型为批量传输,0x3为输出端点,传输类型为批量传输)。第2个设备的设备号为6,是存储设备,有1个配置、1个接口、2个端点(0x81为输入端点,传输类型为批量传输;0x2为输入端点,传输类型为批量传输)。
3./sys/bus/usb/devices
该文件下面的设备信息的命名规则遵循下面2条原则,内核中的USB设备命名规则也遵循下面2条原则。
- usbn: 表示USB总线,如果是USB3.0控制器,则会有2条总线,分别是usbn和usbn+1。
- bus-port.port…:configuration:interface(总线-端口.端口…:配置:接口): Root Hub的端口号为0,其他Hub的下行端口从1开始编号。
下图是一个示例,设备信息可进入文件查看。
- usb1表示USB1总线。
- 1-0:1.0表示usb1总线的Root Hub,使用配置1和接口0。
- 1-1表示USB1总线Root Hub下面接的设备,端口编号为1,属于第1级Hub。
- 1-1:1.0表示第1级Hub使用配置1和接口0。
- 1-1.1表示第1级Hub的端口1。
- 1-1.1:1.0表示第1级Hub的端口1下面的设备使用配置1和接口0。
- 1-1.3表示第1级Hub的端口3。
- 1-1.3:1.0表示第1级Hub的端口3下面的设备使用配置1和接口0。