作者:Sam(甄峰) sam_code@hotmail.com
在drivers/hid/usbhid/hid-core.c中,有如下语句:
module_init(hid_init);
表明当hid-usb.o(hid-core.o等三个组成)添加入kernel core时,会调用hid_init.
1. hid_init分析:
hid_init首先调用usbhid_quirks_init();
1.1. usbhid_quirks_init() 解析:
其实就是查找insmod 时给的pid,vid参数在quirks列表中是否有,如果有,就替换。没有就创建。
1.2. hiddev_init();
此function只有在选中CONFIG_USB_HIDDEV才会真正做事。
也就是说:只有在配置kernel时选中下面条目才有效.
config USB_HIDDEV
bool "/dev/hiddev raw HID device support"
它只是简单的注册一个USB设备。但这个设备在USB 硬件插入时什么都不作。
1.3 usb_register(&hid_driver);
注册一个USB driver.
从这个driver的id_table来看:
.match_flags = USB_DEVICE_ID_MATCH_INT_CLASS
表明匹配的是:Interface class
.bInterfaceClass = USB_INTERFACE_CLASS_HID
表明Interface Class为HID设备,则会被唤醒。
2. HIDUSB设备被插入时的状况:
分析hid_driver->probe
第一个参数为USB Core传过来的USB设备Interface。第二个参数为本driver的id_table.
2.1 usb_hid_configure(intf);
首先查看quirks.使用usbhid_lookup_quirk()从静态和动态quirkslist中查是否此device包含在其中。
Sam看HID driver是以mouse为线索,
interface->desc.bInterfaceSubClass=USB_CLASS_HID
interface->desc.bInterfaceSubClass ==USB_INTERFACE_SUBCLASS_BOOT
interface->desc.bInterfaceProtocol ==USB_INTERFACE_PROTOCOL_MOUSE
所以:quirks |= HID_QUIRK_NOGET;
背景知识一:模块参数:
当使用insmod或modprobe安装模块时,可以通过模块参数给模块传递一些数值。这增加了模块的灵活性。但在使用模块参数之前,必须要让这些参数对insmod可见,则可以使用如下方式,让insmod知道参数名:
module_param_named(name, value, type, perm)
name是参数的名称(insmod时使用)
value是参数在模块中对应的变量
type是参数的类型
perm是参数的权限(其实就是/sys/module/[module_name]/parameters的权限)
例如:
int disk_size = 1024;
module_param_named(size, disk_size, int, S_IRUGO);
则给模块加上名称为"size"的参数,如果在加载模块是使用
insmod thismodule size=100,
那么在模块代码中disk_size的值就是100。相反,如果加载模块时没有指定参数,那么模块代码中disk_size的值仍是默认的1024。
注意,所有模块参数,都应该给定一个默认值。
MODULE_PARM_DESC(),对模块参数的描述。
背景知识二:模块宏:
MODULE_AUTHOR();标明模块拥有者
MODULE_DESCRIPTION(); module描述
MODULE_LICENSE(); module license.如果没有,insmod时会警告