linux驱动子系统之输入子系统(4)

来源:互联网 发布:淘宝店铺托管公司排名 编辑:程序博客网 时间:2024/05/17 06:08

linux驱动子系统之输入子系统(4)

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可以把两者关联起来。



原创粉丝点击