4.事件处理层
4.1 概述
事件处理层负责和应用层接口,创建设备节点和相关的文件系统文件,把事件信息上报给应用层。每种事件处理层驱动程序都是实现了一个file_operations,当应用调用open,write,read等系统调用访问输入设备文件时,就会调用到file_operations中的方法。
4.2 数据结构和函数
l Input_handler,用来描述一个输入设备处理器,
struct input_handler {
void*private;
void (*event)(structinput_handle *handle, unsigned int type, unsigned int code, int value);
bool(*filter)(struct input_handle *handle, unsigned int type, unsigned int code,int value);
bool(*match)(struct input_handler *handler, struct input_dev *dev);
int (*connect)(structinput_handler *handler, struct input_dev *dev, const struct input_device_id*id);
void (*disconnect)(structinput_handle *handle);
void(*start)(struct input_handle *handle);
conststruct file_operations *fops; /* 这个不用说了吧 */
intminor;
constchar *name;
conststruct input_device_id *id_table; /* 用于input_dev和input_handler匹配 */
struct list_head h_list;
struct list_head node;
};
Event:用来向上报告事件信息
Connect:Input_dev和input_handler匹配成功后调用来完成相应的工作
Disconnect:与connect函数作用相反
H_list:关联handler的Input_handle链表
Node:用于把input_handler链接到全局的Input_handler_list链表
l Input_register_handler函数,用于注册一个新的input_handler
int input_register_handler(structinput_handler *handler)
{
INIT_LIST_HEAD(&handler->h_list);
if(handler->fops != NULL) {
if(input_table[handler->minor >> 5]) {
retval= -EBUSY;
gotoout;
}
input_table[handler->minor>> 5] = handler;
}
list_add_tail(&handler->node,&input_handler_list);
list_for_each_entry(dev,&input_dev_list, node)
input_attach_handler(dev,handler);
}
1.List_add_tail 将input_handler加入到全局链表input_handler_list;
2.List_for_each_entry 遍历input_dev_list上的Input_dev,调用Input_attach_handler函数
l Input_handle,用于连接input_device和input_handler
struct input_handle {
void*private;
intopen;
constchar *name;
struct input_dev *dev;
struct input_handler *handler;
struct list_head d_node;
struct list_head h_node;
};
Dev:连接到输入设备
Handler:输入设备对应的处理方法
d_node: 将handle放到设备相关的链表中,也就是放到input_dev->h_list表示的链表中
h_node:将handle放到input_handler相关的链表中,也就是放到input_handler->h_list表示的链表中
l input_register_handle函数,注册一个新的Input_handle
int input_register_handle(structinput_handle *handle)
{
if(handler->filter)
list_add_rcu(&handle->d_node,&dev->h_list);
else
list_add_tail_rcu(&handle->d_node,&dev->h_list);
/*
* Since we are supposed to be called from->connect()
* which is mutually exclusive with->disconnect()
* we can't be racing withinput_unregister_handle()
* and so separate lock is not needed here.
*/
list_add_tail_rcu(&handle->h_node,&handler->h_list);
}
主要负责把handle链入到input_dev和input_handler的h_list链表,从而通过handle可以把两者关联起来。