本文主要讲述在Linux中配置打开或关闭USB HUB功能。
支持特定的USB HUB
在<kernel_dir>/drivers/usb/core/hub.c
中的hub_probe()
函数添加以下代码:
主要是通过pid和vid来进行过滤判断。
1 | if (hdev->parent) { |
插入特定的USB HUB,打印的log如下:
1 | [ 13.913019] usb 2-1: new high-speed USB device number 2 using xxx-ehci |
插入其他的USB HUB,打印log如下:
1 | [ 326.481019] usb 2-1: new high-speed USB device number 3 using xxx-ehci |
这里的hdev
变量用struct usb_device
来表示,说明USB HUB本身也是属于USB设备。
hdev->parent
:该成员用来判断这个USB设备不是ROOT HUB;hdev->bus->busnum
:表示当前处于哪个USB总线,更一般的说是哪个控制器控制的USB口;hdev->level
:表示当前的设备处于哪一层。ROOT HUB为第0层;hdev->descriptor.idVendor
:设备的VID;hdev->descriptor.idProduct
:设备的PID;
采用上面的方式是已正确完全枚举了一个USB HUB的USB设备,然后hub_probe()中将其他的USB HUB给过滤掉,使之不加载hub驱动。
我们接下来采用另外一种方式过滤USB HUB。
在枚举阶段过滤USB HUB
在枚举阶段中获取到设备描述符之后,我们就已经知道该USB设备的pid和vid了,此时就可以进行过滤。
在<kernel_dir>/drivers/usb/core/hub.c
中的usb_enumerate_device()
函数调用usb_get_configuration()
之后添加以下代码:
1 | printk("in %s, line = %d, level =%d, vid = 0x%x, pid = 0x%x, DeviceClass = 0x%x\n", |
这个方法是当枚举到特定的USB设备,那么就返回出错,表示该设备不能正常枚举。因此,得到的log如下:
1 | [ 57.233188] usb 2-1: new high-speed USB device number 3 using xxx-ehci |
插入其他的USB HUB设备,得到的log如下,表示可以正常被枚举:
1 | [ 270.948984] usb 2-1: new high-speed USB device number 4 using xxx-ehci |
完全不开放USB HUB功能
目前想到有两种方法实现:
(1)、
在defconfig
文件中打开宏CONFIG_USB_OTG_BLACKLIST_HUB
。因为在hub_probe()
中有这么一句判断:
1 |
|
通过hdev->parent
来判断这是一个外接的USB HUB还是ROOT HUB
,如果是外接的USB HUB,那么直接返回出错,不加载hub驱动。以此达到完全不开发USB HUB的功能,但是这个USB设备还是能正常被枚举上。
(2)、
通过struct usb_device
中的level成员来判断当前的USB设备处于USB总线拓扑的哪个层级。USB ROOT HUB(level=0)
,第一个外接的USB设备的level=1,以此类推。
因此我们可以确定,当外接一个USB HUB,其level=1,在这个外接的USB HUB再接上USB设备,那么该USB设备的level=2。
此时可以在usb_enumerate_device()
将连接在外接的USB HUB上的USB设备给屏蔽掉。
可以枚举到USB HUB,也正常加载了hub驱动,但是过滤掉这个USB HUB上的其他port口,不支持它的下一层级。