USB HID 传输与错误恢复
1. 枚举
drivers/hid/usbhid/hid-core.c 注册 USB interface driver:
1 | USB interface probe |
HID device 通常按 interface,而不是整台 USB device 创建;复合设备可产生多个 HID 节点。
2. Descriptor
usbhid_parse():
- 获取 HID descriptor;
- 找 report descriptor 长度;
- control GET_DESCRIPTOR;
hid_parse_report()。
HID_QUIRK_NOGET、broken descriptor 等 quirk 会改变初始化。
3. 启动
usbhid_start():
- 计算最大 report 大小;
- 分配 input/control/output buffer;
- 分配 interrupt IN URB;
- 可选 interrupt OUT URB;
- 初始化 queue、timer、work;
- 获取初始 report(除 quirk 禁止)。
4. Input
1 | interrupt IN URB complete |
Input endpoint 通常周期轮询。高速/全速 interval 处理错误会影响 CPU 和延迟,部分设备有 interval quirk。
5. Output 与 Feature
- interrupt OUT:低延迟 output report;
- control endpoint:GET_REPORT/SET_REPORT;
usbhid_request()排入 control/output queue;usbhid_raw_request()同步等待;usbhid_output_report()发送原始输出。
同一 endpoint 的请求必须串行,queue 完成后唤醒等待者。
6. Open/close
usbhid_open() 第一个消费者启动 input URB 并取得 runtime PM;usbhid_close() 最后一个消费者停止或允许 autosuspend。HID_QUIRK_ALWAYS_POLL 使设备即使无人打开也持续轮询。
7. 错误恢复
USB 错误包括:
-EPIPEstall:clear halt/reset;- protocol/timeout;
- unplug/shutdown;
- repeated I/O errors。
usbhid 使用 timer/work 和 reset 标志恢复 input/output/control queue。永久断开时必须停止 URB,防止 completion 访问已释放对象。
8. PM
- autosuspend;
- suspend/resume;
- reset_resume;
- remote wakeup;
hid_driver_suspend/resume/reset_resume。
键盘/鼠标作为唤醒源时需 USB host、hub 和设备均支持 wakeup。
9. HIDDEV
usbhid/hiddev.c 是 USB 专属旧接口 /dev/usb/hiddevN,提供解析后的 usage/report ioctl。它不等同于 hidraw,且非 USB transport 不支持。
10. Boot Protocol
usbkbd.c、usbmouse.c 只支持简化 Boot Protocol。Kconfig 要求在不使用完整 USB HID 时由 EXPERT 选择,功能有限,正常 RK3588 产品应使用 usbhid。
11. 观测
1 | lsusb -t |
正在加载留言…