HID Core 设备驱动模型与生命周期

HID Core 设备驱动模型与生命周期

1. HID bus

hid_bus_type 定义:

  • .match = hid_bus_match
  • .probe = hid_device_probe
  • .remove = hid_device_remove
  • .uevent = hid_uevent

sysfs modalias:

1
hid:bBUSgGROUPvVENDORpPRODUCT

2. 传输创建设备

1
2
3
4
5
6
7
8
9
10
hid_allocate_device()
-> device_initialize()
-> dev.bus = hid_bus_type
-> init driver_input_lock / ll_open_lock / kref

transport fills:
bus/group/vendor/product/version/country
name/phys/uniq/parent/ll_driver

hid_add_device()

销毁必须用 hid_destroy_device(),最终由 device release 释放。

3. add_device

  1. hid_lookup_quirk()
  2. hid_ignore() 过滤;
  3. 检查 transport 必须实现 raw_request
  4. ll_driver->parse() 读取原始 report descriptor;
  5. hid_scan_report() 初步确定 group;
  6. 设置 HID device 名;
  7. debugfs 注册;
  8. device_add() 触发 driver core 匹配。

4. 匹配

hid_match_one_id() 比较:

  • bus;
  • group;
  • vendor;
  • product。

专用驱动与 generic 驱动通过 match() 和 reprobe 机制协调。专用驱动后加载时,Core 可重新探测原 generic 设备。

5. Probe

1
2
3
4
5
6
hid_device_probe()
-> driver_input_lock
-> hid_match_device()
-> reload quirks
-> hdev->driver = hdrv
-> hdrv->probe()

没有自定义 probe 时:

1
2
3
4
hid_open_report()
-> hid_hw_start(HID_CONNECT_DEFAULT)
-> ll_driver->start()
-> hid_connect()

6. Connect mask

hid_connect() 可建立:

  • HID_CLAIMED_INPUT
  • HID_CLAIMED_HIDRAW
  • HID_CLAIMED_HIDDEV
  • HID_CLAIMED_DRIVER

非 USB 设备会屏蔽 HIDDEV。只有 raw_event 的专用驱动也可不连接其它 listener。

7. Open/close

多个上层消费者共享底层 open:

1
2
3
4
5
6
hid_hw_open()
-> ll_open_lock
-> if first: ll_driver->open()

hid_hw_close()
-> if last: ll_driver->close()

ll_open_count 避免 input 与 hidraw 分别打开时重复启停 transport。

8. Remove

1
2
3
4
5
6
7
8
9
hid_device_remove()
-> driver_input_lock
-> hdrv->remove() or hid_hw_stop()
-> hid_close_report()
-> hdev->driver = NULL

transport disconnect
-> hid_destroy_device()
-> device_del + put_device

hid_hw_stop() 先断开 input/hidraw/hiddev,再调用 transport stop()

9. 并发

锁/引用 作用
driver_input_lock semaphore 输入上报与 probe/remove 串行
ll_open_lock mutex 底层 open count
device refcount sysfs/driver core 生命周期
hid_device::kref HID 专用引用
driver dyn_lock 动态 ID 列表
debug list spinlock debugfs reader

中断上报若无法获得 driver_input_lockhid_input_report() 返回 -EBUSY,避免 remove 与 event 并发访问已解绑驱动。

文章互动

阅读 --

留言

0 条留言

正在加载留言…