我正在尝试根据捕获的 USB 通信为现有 USB 设备编写 Linux 驱动程序。
该设备有多种配置。不幸的是,该设备似乎不遵循 USB 规范:只有第一个设置配置请求有效。设备在发出第二个设置配置请求时锁定并最终崩溃。 USB 重置或重置配置(将其设置为 0)也没有任何帮助。
现在,似乎 Linux USB 核心出于某种原因决定将设备的配置设置为错误的值(它只选择第一个),而我没有任何机会在它这样做之前介入。我已经从内核模块和用户空间 libusb 驱动程序尝试过。
从阅读内核源代码来看,选择配置的函数似乎位于usb_choose_configuration()
通用驱动程序中/drivers/usb/core/generic.c。我可以看到,如果返回 true,则可以跳过该函数usb_device_is_owned()
,但我不知道如何影响该函数的结果。
我希望我不必为了添加 USB 驱动程序而重新编译整个内核。
因此,这是我的问题:
- 在将控制权交给我的驱动程序之前,如何防止系统设置配置?
- 看来在最近的内核版本中,usbcore是一个内置模块,无法替换。有没有其他方法可以覆盖
usb_choose_configuration
通用驱动程序中的函数(这似乎是 usbcore 的一部分)? - 我怎样才能拥有该设备,以便
usb_device_is_owned()
在连接设备时返回 true?
答案1
似乎有一种方法可以阻止系统尝试设置设备的配置,它甚至可以在用户空间中工作。我偶然发现了将此功能添加到内核的提交,幸运的是它还包含一些示例代码。
用户空间程序可以通过设备文件系统声明 USB 集线器特定端口的所有权,从而usb_device_is_owned()
返回 true。
诀窍似乎是:
unsigned int port = 2; // Just as an example
// Send request 24 of type 'U' (USB), which returns an unsigned int
unsigned int ioctl_id = _IOR('U', 24, unsigned int);
// fd is a file descriptor to the hub's file in the devfs
ioctl(fd, ioctl_id, &port);
有关 USB 子系统的一些 ioctl 请求的信息在内核文档。完整列表可以在内核源代码。 #define 是这里。
有趣的是,系统仍然发送配置 0(重置配置)的设置配置请求。