input子系统学习笔记七 handler处理器注册分析

input_handler 是输入子系统的主要数据结构,一般将其称为handler处理器,表示对输入事件的具体处理。input_handler 为输入设备的功能实现了一个接口,输入事件最终传递到handler 处理器,handler 处理器根据一定的规则,然后对事件进行处理,具体的规则将在下面详细介绍。
关键数据结构

        struct input_dev 物理输入设备的基本数据结构,包含设备相关的一些信息

        struct input_handler 事件处理结构体,定义怎么处理事件的逻辑

        struct input_handle 用来创建 input_dev 和 input_handler 之间关系的结构体

input_handler 结构体

        input_handler 是输入设备的事件处理接口,为处理事件提供一个统一的函数模板,程序员应该根据具体的需要实现其中的一些函数,并将其注册到输入子系统中。该结构体的定义如下:

C/C++代码
  1. struct input_handler { 
  2.         void *private;/*定义了一个 private 指针,表示驱动特定的数据。这里的驱动指的就是 handler 处理器。*/ 
  3.         void (*event)(struct input_handle *handle, unsigned int type, 
  4.         unsigned int code, int value);/*定义了一个 event()处理函数,这个函数将被输入子系统调用去处理发送给设备的事件。例如将发送一个事件命令 LED 灯点亮,实际控制硬件的点亮操作就可以放在 event()函数中实现。*/ 
  5.         int (*connect)(struct input_handler *handler, struct input_dev 
  6.                 *dev,const struct input_device_id *id);/* 定 义 了 一 个 connect() 函 数 , 该 函 数 用 来 连 接 handler 和 input_dev 。 在input_attach_handler()函数的第 10 行,就是回调的这个自定义函数。*/ 
  7.         void (*disconnect)(struct input_handle *handle); 
  8.         void (*start)(struct input_handle *handle); 
  9.         const struct file_operations *fops;/*表示 handler 实现的文件操作集,这里不是很重要。*/ 
  10.         int minor;//表示设备的次设备号。 
  11.         const char *name;/* 表示handler 的名字,显示在/proc/bus/input/handlers 目录中。*/ 
  12.         const struct input_device_id *id_table;/*定义了一个 id_table 表,表示驱动能够处理的表。*/ 
  13.         const struct input_device_id *blacklist;/*指向一个 input_device_id 表,这个表包含 handler 应该忽略的设备。*/ 
  14.         struct list_head h_list;/*定义了一个链表 h_list,表示与这个 input_handler 相联系的下一个 handler。*/ 
  15.         struct list_head node;/*定义了一个链表 node,将其连接到全局的 input_handler_list 链表中,所有的input_handler 都连接在其上。*/ 
  16. }; 
input_handle 结构体

        input_register_handle()函数用来注册一个新的 handle 到输入子系统中。input_handle 的主要功能是用来连接 input_dev 和 input_handler。其结构如下:

C/C++代码
  1. struct input_handle { 
  2.         void *private;/*定义了 private 表示 handler 特定的数据。*/ 
  3.         int open;/*定义了一个 open 变量,表示 handle 是否正在被使用,当使用时,会将事件分发给设备处理。*/ 
  4.         const char *name;/*定义了一个 name 变量,表示 handle 的名字。*/ 
  5.         struct input_dev *dev;/*定义了 dev 变量指针,表示该 handle 依附的 input_dev 设备。*/ 
  6.         struct input_handler *handler;/*定义了一个 handler 变量指针,指向 input_handler,该 handler 处理器就是与设备相关的处理器。*/ 
  7.         struct list_head d_node;/*定义了一个 d_node 变量,使用这个变量将 handle 放到设备相关的链表中,也就是放到 input_dev->h_list 表示的链表中。*/ 
  8.         struct list_head h_node;/*定义了一个 h_node 变量,使用这个变量将 handle 放到 input_handler 相关的链表中,也就是放到 handler->h_list 表示的链表中。*/ 
  9. }; 
注册input_handler

        input_register_handler()函数注册一个新的 input handler 处理器。这个 handler 将为输入设备使用,一个 handler 可以添加到多个支持它的设备中,也就是一个 handler 可以处理多个输入设备的事件。函数的参数传入简要注册的 input_handler 指针,该函数的代码如下:

C/C++代码
  1. int input_register_handler(struct input_handler *handler) 
  2.         struct input_dev *dev; 
  3.         int retval; 
  4.  
  5.         retval = mutex_lock_interruptible(&input_mutex);/*对 input_mutex 进行了加锁。当加锁失败后,则返回。*/ 
  6.         if (retval) 
  7.                 return retval; 
  8.  
  9.         INIT_LIST_HEAD(&handler->h_list);/*初始化 h_hlist 链表,该链表连接与这个 input_handler 相联系的下一个 handler。*/ 
  10.  
  11.         if (handler->fops != NULL) {/*其中的 handler->minor 表示对应 input 设备结点的次设备号。 handler->minor以右移 5 位作为索引值插入到 input_table[ ]中,*/ 
  12.                 if (input_table[handler->minor >> 5]) { 
  13.                         retval = -EBUSY; 
  14.                         goto out; 
  15.                 } 
  16.                 input_table[handler->minor >> 5] = handler; 
  17.         } 
  18.  
  19.         list_add_tail(&handler->node, &input_handler_list);/*调用 list_add_tail()函数,将 handler 加入全局的 input_handler_list 链表中, 该链表包含了系统中所有的 input_handler。*/ 
  20.  
  21.         list_for_each_entry(dev, &input_dev_list, node) 
  22.         input_attach_handler(dev, handler);/*input_attach_handler()函数的作用是匹配 input_dev_list 链表中的 input_dev 与 handler。如果成功会将 input_dev 与 handler 联系起来。*/ 
  23.         input_wakeup_procfs_readers(); 
  24.         out: 
  25.                 mutex_unlock(&input_mutex);/*解互斥锁并退出。*/ 
  26.         return retval; 
注册input_handle

        input_handle 是用来连接input_dev和input_handler的一个中间结构体。事件通过input_handle 从 input_dev 发送到 input_handler,或者从 input_handler 发送到 input_dev 进行处理。在使用 input_handle 之前,需要对其进行注册,注册函数是 input_register_handle()。

注册函数 input_register_handle()

        input_register_handle()函数用来注册一个新的 handle 到输入子系统中。该函数接收一个input_handle 类型的指针,该变量要在注册前对其成员初始化。input_register_handle()函数的代码如下:

C/C++代码
  1. int input_register_handle(struct input_handle *handle) 
  2.         struct input_handler *handler = handle->handler;/*从 handle 中取出一个指向 input_handler 的指针,为下面的操作使用。 */ 
  3.         struct input_dev *dev = handle->dev;/*从 handle 中取出一个指向 input_dev 的指针,为下面的操作使用。 */ 
  4.         int error; 
  5.  
  6.         /*
  7.         * We take dev->mutex here to prevent race with
  8.         * input_release_device().
  9.         */ 
  10.         error = mutex_lock_interruptible(&dev->mutex);/*给竞争区域加一个互斥锁。*/ 
  11.         if (error) 
  12.                 return error; 
  13.  
  14.         /*
  15.         * Filters go to the head of the list, normal handlers
  16.         * to the tail.
  17.         */ 
  18.         if (handler->filter) 
  19.                 list_add_rcu(&handle->d_node, &dev->h_list); 
  20.         else 
  21.                 list_add_tail_rcu(&handle->d_node, &dev->h_list);/*调用 list_add_tail_rcu()函数将 handle 加入输入设备的 dev->h_list 链表中。*/ 
  22.  
  23.         mutex_unlock(&dev->mutex); 
  24.  
  25.         /*
  26.         * Since we are supposed to be called from ->connect()
  27.         * which is mutually exclusive with ->disconnect()
  28.         * we can't be racing with input_unregister_handle()
  29.         * and so separate lock is not needed here.
  30.         */ 
  31.         list_add_tail_rcu(&handle->h_node, &handler->h_list); 
  32.  
  33.         if (handler->start)/*如果定义了 start()函数,则调用它。*/ 
  34.                 handler->start(handle); 
  35.  
  36.         return 0; 
三者之间的关系


        结点 1、2、3 表示input_dev设备,其通过input_dev->node变量连接到全局输入设备链input_dev_list中.结点4、5、6表示input_handler处理器,其通过input_handler->node连接到全局handler处理器链表input_handler_list中。结点7是一个input_handle的结构体,其用来连接input_dev和input_handler。input_handle的dev成员指向了对应的input_dev设备,input_handle的handler成员指向了对应的 input_handler。外结点7的input_handle另设备,通过d_node连接到了结点2的input_dev上的h_list链表上。另一方面,结点7的input_handle通过h_node连接到了结点5的input_handler的h_list链表上。通过这种关系,input_dev将和input_handler联系了起来。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值