Linux输入子系统分析 -- 输入子系统初始化

Linux输入子系统分析 (1) -- 输入子系统初始化

[linux-3.0 http://lxr.linux.no/#linux+v3.0]


输入子系统:

2173subsys_initcall(input_init);

其源代码如下:

2133static const struct file_operations input_fops = {
2134 .owner = THIS_MODULE,
2135 .open = input_open_file,
2136 .llseek = noop_llseek,
2137};
2138
2139static int __init input_init(void)
2140{
2141 int err;
2142
2143 err = class_register(&input_class);
2144 if (err) {
2145 pr_err("unable to register input_dev class\n");
2146 return err;
2147 }
2148
2149 err = input_proc_init();
2150 if (err)
2151 goto fail1;
2152
2153 err = register_chrdev(INPUT_MAJOR, "input", &input_fops);
2154 if (err) {
2155 pr_err("unable to register char major %d", INPUT_MAJOR);
2156 goto fail2;
2157 }
2158
2159 return 0;
2160
2161 fail2: input_proc_exit();
2162 fail1: class_unregister(&input_class);
2163 return err;
2164}

input_init的主要作用:

2143行,创建“input"类,即在/sys/classs/下面建一个input的子目录。

    input_class的定义如下:

1632struct class input_class = {
1633 .name = "input",
1634 .devnode = input_devnode,
1635};
1636EXPORT_SYMBOL_GPL(input_class);

2149行,创建proc文件系统中创建input目录,存放于/proc/bus/下面(/proc/bus/input),而后在此目录下创建devices和handlers文件

    通过读取devices,可以知道系统中的输入设备。

-------------------------------------------------------------------------------------------

# cat /proc/bus/input/devices

I: Bus=0018 Vendor=0000 Product=0000 Version=0000
N: Name="AT42QT1070 QTouch Sensor"
P: Phys=
S: Sysfs=/devices/platform/i2c-gpio.0/i2c-0/0-001b/input/input0
U: Uniq=
H: Handlers=kbd event0
B: PROP=0
B: EV=3
B: KEY=8fc

I: Bus=0018 Vendor=0000 Product=0000 Version=0000
N: Name="Atmel maXTouch Touchscreen"
P: Phys=
S: Sysfs=/devices/platform/i2c-gpio.0/i2c-0/0-004a/input/input1
U: Uniq=
H: Handlers=mouse0 event1
B: PROP=0
B: EV=b
B: KEY=400 0 0 0 0 0 0 0 0 0 0
B: ABS=610000 1000003

-------------------------------------------------------------------------------------------

    通过读取handlers,可以知道系统中注册了那些处理函数。

-------------------------------------------------------------------------------------------

# cat /proc/bus/input/handlers

N: Number=0 Name=kbd
N: Number=1 Name=mousedev Minor=32
N: Number=2 Name=evdev Minor=64

-------------------------------------------------------------------------------------------

2153行,注册一个字符类型设备及其操作函数。

2159行,如果上面操作没有错误,完美退出。


Linux输入子系统分析 (2) -- evdev handler初始化

[Linux 3.0 http://lxr.linux.no/#linux+v3.0]

前面介绍了输入子系统的初始化,前面提及到/proc/bus/input/handlers,当读取此文件时,其中有一行是

N: Number=2 Name=evdev Minor=64

这一行是如何来的呢?


下面来解开这个迷底,介绍handler ------ evdev的注册过程

988static struct input_handler evdev_handler = {
989 .event = evdev_event,
990 .connect = evdev_connect,
991 .disconnect = evdev_disconnect,
992 .fops = &evdev_fops,
993 .minor = EVDEV_MINOR_BASE,
994 .name = "evdev",
995 .id_table = evdev_ids,
996};
997
998static int __init evdev_init(void)
999{
1000 return input_register_handler(&evdev_handler);
1001}

988 ~ 996行, 定义了一个evdev handler.

1000行,调用input_register_handler去注册这个evdev handler


下面具体看看,input_register_handler是如果去注册evdev这个hanlder的。

/**
* input_register_handler - register a new input handler
* @handler: handler to be registered
*
* This function registers a new input handler (interface) for input
* devices in the system and attaches it to all input devices that
* are compatible with the handler.
 */

1923int input_register_handler(struct input_handler *handler)
1924{
1925 struct input_dev *dev;
1926 int retval;
1927
1928 retval = mutex_lock_interruptible(&input_mutex);
1929 if (retval)
1930 return retval;
1931
1932 INIT_LIST_HEAD(&handler->h_list);
1933
1934 if (handler->fops != NULL) {
1935 if (input_table[handler->minor >> 5]) {
1936 retval = -EBUSY;
1937 goto out;
1938 }
1939 input_table[handler->minor >> 5] = handler;
1940 }
1941
1942 list_add_tail(&handler->node, &input_handler_list);
1943
1944 list_for_each_entry(dev, &input_dev_list, node)
1945 input_attach_handler(dev, handler);
1946
1947 input_wakeup_procfs_readers();
1948
1949 out:
1950 mutex_unlock(&input_mutex);
1951 return retval;
1952}
1953EXPORT_SYMBOL(input_register_handler);

1928行,此处加一个可被中断的锁。

1932行,初始化handler的h_list链表(h_list的定义:list of input handles associated with the handler)

1934 ~1940行,判断此handler的操作函数是否为空,非空,通过其minor值,判断此handler是否已经存在(注册过),如果否,将其加入input_table中。

input_table定义:static struct input_handler *input_table[8]; 说明在linux系统中,最多只能有8个输入handler。

1942行,将此handler加入到input_handler_list的链表中。其定义:static LIST_HEAD(input_handler_list); (lin38 in input.c)

1944行,扫描input_dev_list链表,看是否输入设备需要此handler的支持。 其定义:static LIST_HEAD(input_dev_list); (lin37 in input.c)

          input_attach_handler(line 895, in input.c)--> input_match_device(line 854, in input.c) ,此过程没有找到match的设备, 返回NULL。

1947行,proc文件系统操作。此处需要进一步研究

1950行,释放锁并返回



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值