linux输入子系统(5)

<!--[if !supportLists]-->第2章 <!--[endif]-->输入子系统的事件驱动

上一章已经说过输入子系统分为三层,最上面的一层是事件处理层,我们暂时称它为事件驱动,这是相对于上一章的设备驱动来讲的。

上一章介绍了设备驱动注册时要与匹配的handler连接,报告的事件也会分发给连接的handler,这一章介绍handler的相关操作。

2.1 <!--[endif]-->重要的数据结构

首先介绍input_handle,这个结构体用来连接input_devinput_handler。它的代码如程序清单 2.1<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F005200650066003200380032003000380038003100310030000000</w:data> </xml><![endif]-->所示。

程序清单 <!--[if supportFields]><span style='mso-bookmark:_Ref282088110'></span><span style='mso-element:field-begin'></span><span style='mso-bookmark:_Ref282088110'><span lang=EN-US><span style='mso-spacerun:yes'>&nbsp;</span>STYLEREF 1 \s <span style='mso-element:field-separator'></span></span></span><![endif]-->2<!--[if supportFields]><span style='mso-bookmark: _Ref282088110'></span><span style='mso-element:field-end'></span><![endif]-->.<!--[if supportFields]><span style='mso-bookmark:_Ref282088110'></span><span style='mso-element:field-begin'></span><span style='mso-bookmark:_Ref282088110'><span lang=EN-US> SEQ </span></span><span style='mso-bookmark:_Ref282088110'><span style='font-family:黑体;mso-ascii-font-family: Arial'>程序清单</span><span lang=EN-US> \* ARABIC \s 1 <span style='mso-element: field-separator'></span></span></span><![endif]-->1<!--[if supportFields]><span style='mso-bookmark:_Ref282088110'></span><span style='mso-element:field-end'></span><![endif]--> input_handle

/* include/linux/input.h */

struct input_handle {

void *private; <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 1 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑴<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

int open; <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 2 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑵<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

const char *name; <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 3 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑶<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

struct input_dev *dev; <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 4 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑷<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

struct input_handler *handler; <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 5 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑸<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

struct list_head d_node; <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 6 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑹<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

struct list_head h_node; <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 7 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑺<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

};

各个成员的含义如下:

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 1 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑴<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->私有数据指针。

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 2 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑵<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->记录本设备被打开的次数。

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 3 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑶<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->创建此handlehandler所赋予的名字。

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 4 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑷<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->指向附着的input_dev

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 5 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑸<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->指向创建此handlehandler

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 6 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑹<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->链表节点,用来加入附着的input_dev

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 7 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑺<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->链表节点,用来加入附着的input_handler

程序清单 1.11<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F005200650066003200380032003000320030003800360038000000</w:data> </xml><![endif]-->中,我们看到input_devinput_handler匹配过程中用到了input_device_id。它的代码如程序清单 2.2<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F005200650066003200380032003000380039003600380030000000</w:data> </xml><![endif]-->所示。

程序清单 <!--[if supportFields]><span style='mso-bookmark:_Ref282089680'></span><span style='mso-element:field-begin'></span><span style='mso-bookmark:_Ref282089680'><span lang=EN-US><span style='mso-spacerun:yes'>&nbsp;</span>STYLEREF 1 \s <span style='mso-element:field-separator'></span></span></span><![endif]-->2<!--[if supportFields]><span style='mso-bookmark: _Ref282089680'></span><span style='mso-element:field-end'></span><![endif]-->.<!--[if supportFields]><span style='mso-bookmark:_Ref282089680'></span><span style='mso-element:field-begin'></span><span style='mso-bookmark:_Ref282089680'><span lang=EN-US> SEQ </span></span><span style='mso-bookmark:_Ref282089680'><span style='font-family:黑体;mso-ascii-font-family: Arial'>程序清单</span><span lang=EN-US> \* ARABIC \s 1 <span style='mso-element: field-separator'></span></span></span><![endif]-->2<!--[if supportFields]><span style='mso-bookmark:_Ref282089680'></span><span style='mso-element:field-end'></span><![endif]--> input_device_id

/* include/linux/mod_devicetable.h */

struct input_device_id {

kernel_ulong_t flags; <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 1 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑴<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

__u16 bustype; <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 2 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑵<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

__u16 vendor;

__u16 product;

__u16 version;

kernel_ulong_t evbit[INPUT_DEVICE_ID_EV_MAX / BITS_PER_LONG + 1]; <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 3 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑶<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

kernel_ulong_t keybit[INPUT_DEVICE_ID_KEY_MAX / BITS_PER_LONG + 1];

kernel_ulong_t relbit[INPUT_DEVICE_ID_REL_MAX / BITS_PER_LONG + 1];

kernel_ulong_t absbit[INPUT_DEVICE_ID_ABS_MAX / BITS_PER_LONG + 1];

kernel_ulong_t mscbit[INPUT_DEVICE_ID_MSC_MAX / BITS_PER_LONG + 1];

kernel_ulong_t ledbit[INPUT_DEVICE_ID_LED_MAX / BITS_PER_LONG + 1];

kernel_ulong_t sndbit[INPUT_DEVICE_ID_SND_MAX / BITS_PER_LONG + 1];

kernel_ulong_t ffbit[INPUT_DEVICE_ID_FF_MAX / BITS_PER_LONG + 1];

kernel_ulong_t swbit[INPUT_DEVICE_ID_SW_MAX / BITS_PER_LONG + 1];

kernel_ulong_t driver_info; <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 4 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑷<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

};

各个成员的含义如下:

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 1 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑴<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->定义需要匹配input_id的哪些域(使用方法参考程序清单 1.11<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F005200650066003200380032003000320030003800360038000000</w:data> </xml><![endif]-->)。

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 2 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑵<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->对应input_id的四个数据域。

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 3 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑶<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->存储支持事件的位图,与input_dev中的同名数据成员功能一致。

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 4 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑷<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->指示结构体中是否含有驱动信息。

input_handler这个结构体是事件驱动的主体,每一种处理方式对应一个handler结构体。它的定义如程序清单 2.3<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F005200650066003200380032003000380036003200340036000000</w:data> </xml><![endif]-->所示。

程序清单 <!--[if supportFields]><span style='mso-bookmark:_Ref282086246'></span><span style='mso-element:field-begin'></span><span style='mso-bookmark:_Ref282086246'><span lang=EN-US><span style='mso-spacerun:yes'>&nbsp;</span>STYLEREF 1 \s <span style='mso-element:field-separator'></span></span></span><![endif]-->2<!--[if supportFields]><span style='mso-bookmark: _Ref282086246'></span><span style='mso-element:field-end'></span><![endif]-->.<!--[if supportFields]><span style='mso-bookmark:_Ref282086246'></span><span style='mso-element:field-begin'></span><span style='mso-bookmark:_Ref282086246'><span lang=EN-US> SEQ </span></span><span style='mso-bookmark:_Ref282086246'><span style='font-family:黑体;mso-ascii-font-family: Arial'>程序清单</span><span lang=EN-US> \* ARABIC \s 1 <span style='mso-element: field-separator'></span></span></span><![endif]-->3<!--[if supportFields]><span style='mso-bookmark:_Ref282086246'></span><span style='mso-element:field-end'></span><![endif]--> input_handler

/* include/linux/input.h */

struct input_handler {

void *private; <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 1 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑴<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value); <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 2 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑵<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id); <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 3 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑶<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

void (*disconnect)(struct input_handle *handle); <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 4 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑷<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

void (*start)(struct input_handle *handle); <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 5 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑸<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

const struct file_operations *fops; <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 6 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑹<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

int minor; <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 7 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑺<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

const char *name; <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 8 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑻<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

const struct input_device_id *id_table; <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 9 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑼<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

const struct input_device_id *blacklist; <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 10 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑽<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

struct list_head h_list; <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 11 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑾<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

struct list_head node; <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 12 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑿<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

};

每个成员的具体解释如下:

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 1 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑴<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->私有数据指针。

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 2 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑵<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->事件处理函数指针。设备驱动报告的事件最终由这个函数来处理(参考程序清单 1.14<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F005200650066003200380032003000370035003600380032000000</w:data> </xml><![endif]-->)

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 3 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑶<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->连接handlerinput_dev的函数指针。

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 4 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑷<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->断开连接函数指针。

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 5 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑸<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->为给定的handle启动handler函数指针。

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 6 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑹<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->文件操作结构体。

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 7 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑺<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->这个handler可以使用的32个次设备号的最小值。

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 8 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑻<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->此handler的名字。

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 9 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑼<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->可以处理的input_device_ids列表(用法参考程序清单 1.11<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F005200650066003200380032003000320030003800360038000000</w:data> </xml><![endif]-->)。

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 10 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑽<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->需要被忽略的input_device_ids列表。

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 11 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑾<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->用来连接handle的链表链表节点。每个与此handler相关的handle都放入此链表。

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 12 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑿<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->用来放入全局handler链表的节点。

2.2 <!--[endif]-->input_handler的注册

首先介绍存放注册的input_handler所用的数据结构。如所程序清单 2.4<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F005200650066003200380032003000390031003900340039000000</w:data> </xml><![endif]-->示。

程序清单 <!--[if supportFields]><span style='mso-bookmark:_Ref282091949'></span><span style='mso-element:field-begin'></span><span style='mso-bookmark:_Ref282091949'><span lang=EN-US><span style='mso-spacerun:yes'>&nbsp;</span>STYLEREF 1 \s <span style='mso-element:field-separator'></span></span></span><![endif]-->2<!--[if supportFields]><span style='mso-bookmark: _Ref282091949'></span><span style='mso-element:field-end'></span><![endif]-->.<!--[if supportFields]><span style='mso-bookmark:_Ref282091949'></span><span style='mso-element:field-begin'></span><span style='mso-bookmark:_Ref282091949'><span lang=EN-US> SEQ </span></span><span style='mso-bookmark:_Ref282091949'><span style='font-family:黑体;mso-ascii-font-family: Arial'>程序清单</span><span lang=EN-US> \* ARABIC \s 1 <span style='mso-element: field-separator'></span></span></span><![endif]-->4<!--[if supportFields]><span style='mso-bookmark:_Ref282091949'></span><span style='mso-element:field-end'></span><![endif]--> input core全局数据

/* driver/input/input.c */

static LIST_HEAD(input_dev_list); /* 设备链表头 */

static LIST_HEAD(input_handler_list); /* handler链表头 */

static DEFINE_MUTEX(input_mutex); /* 保护以上两个链表 */

static struct input_handler *input_table[8]; /*存放注册的input_handler的指针数组*/

程序清单 1.9<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F005200650066003200380032003000310038003400390031000000</w:data> </xml><![endif]-->中<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span> = 4 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑷<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->处注册的input_dev结构体加入到上面的input_dev_list当中,下面将要介绍的注册input_handler,其实就是将input_hangler加入到input_handler_list当中。input_table中存放进行文件操作的handler,使用它们次设备号的最高三比特在input_table中寻址,因此每个handler最多支持32个设备节点。由上面的代码可以看出输入子系统最多允许8个进行文件操作的input_handler同时存在。

input_register_handler的代码如程序清单 2.5<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F005200650066003200380032003000390036003400340034000000</w:data> </xml><![endif]-->所示。

程序清单 <!--[if supportFields]><span style='mso-bookmark:_Ref282096444'></span><span style='mso-element:field-begin'></span><span style='mso-bookmark:_Ref282096444'><span lang=EN-US><span style='mso-spacerun:yes'>&nbsp;</span>STYLEREF 1 \s <span style='mso-element:field-separator'></span></span></span><![endif]-->2<!--[if supportFields]><span style='mso-bookmark: _Ref282096444'></span><span style='mso-element:field-end'></span><![endif]-->.<!--[if supportFields]><span style='mso-bookmark:_Ref282096444'></span><span style='mso-element:field-begin'></span><span style='mso-bookmark:_Ref282096444'><span lang=EN-US> SEQ </span></span><span style='mso-bookmark:_Ref282096444'><span style='font-family:黑体;mso-ascii-font-family: Arial'>程序清单</span><span lang=EN-US> \* ARABIC \s 1 <span style='mso-element: field-separator'></span></span></span><![endif]-->5<!--[if supportFields]><span style='mso-bookmark:_Ref282096444'></span><span style='mso-element:field-end'></span><![endif]--> input_register_handler

int input_register_handler(struct input_handler *handler)

{

struct input_dev *dev;

int retval;

retval = mutex_lock_interruptible(&input_mutex);

if (retval)

return retval;

INIT_LIST_HEAD(&handler->h_list); <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 1 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑴<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

if (handler->fops != NULL) { <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 2 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑵<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

if (input_table[handler->minor >> 5]) { <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 3 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑶<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

retval = -EBUSY;

goto out;

}

input_table[handler->minor >> 5] = handler; <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 4 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑷<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

}

list_add_tail(&handler->node, &input_handler_list); <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 5 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑸<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

list_for_each_entry(dev, &input_dev_list, node) <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 6 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑹<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

input_attach_handler(dev, handler); <!--[if supportFields]><span lang=DE><span style='mso-element:field-begin'></span> = 7 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑺<!--[if supportFields]><span lang=DE><span style='mso-element:field-end'></span></span><![endif]-->

input_wakeup_procfs_readers();

out:

mutex_unlock(&input_mutex);

return retval;

}

EXPORT_SYMBOL(input_register_handler);

程序含义如下:

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 1 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑴<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->初始化handler中的链表节点,为加入input_handler_list做准备。

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 2 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑵<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->如果此handler需要进行文件操作。

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 3 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑶<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->如果相应的次设备号段被占用。

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 4 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑷<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->将handler注册进input_table

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 5 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑸<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->将handler加入input_handler_list链表。

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 6 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑹<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->遍历input_dev_list链表中的每一个input_dev结构体。

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'>&nbsp;</span>= 7 \* GB2 <span style='mso-element:field-separator'></span></span><![endif]-->⑺<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->将handler与每一个input_dev进行匹配。

input_attach_handler的代码如程序清单 1.10<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F005200650066003200380032003000320030003000390031000000</w:data> </xml><![endif]-->所示,这里不再赘述。

总结一下input_handler的注册过程:见自己加入input_handler_listinput_table,然后与input_dev_list中的input_dev比较并与匹配的建立连接。

参考<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span> REF _Ref282153330 \r \h <span style='mso-element:field-separator'></span></span><![endif]-->1.4<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F005200650066003200380032003100350033003300330030000000</w:data> </xml><![endif]--><!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]--><!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span> REF _Ref282153346 \h <span style='mso-element:field-separator'></span></span><![endif]-->input_dev的注册<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F005200650066003200380032003100350033003300340036000000</w:data> </xml><![endif]--><!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->这一节,我们发现input_devinput_handler都是将自己加入各自的链表,然后再和对方链表中匹配的进行连接。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值