内核版本:3.9.5
本节将以even handler来分析设备的注册和打开的过程,分析之前不妨回顾一下上节介绍的数据结构.
结合前两节分析可知,input子系统分为3层,最上一层是event handler,中间层是input core,底层是input driver.input driver把event report到input core层,input core对event进行分发,传到 event handler,相应的event handler层把event 放到event buffer中,等待应用程序读取!这就是input的基本思想.
那么我我们来看,Linux模块机制告诉我们在设备注册之前必须先初始化INPUT子系统,这个工作由input_init()函数来完成.在drivers/input.c中:
1 static int __init input_init(void) 2 { 3 int err; 4 5 err = class_register(&input_class);//注册input类 6 if (err) { 7 pr_err("unable to register input_dev class\n"); 8 return err; 9 } 10 11 err = input_proc_init();//创建/proc中的项 12 if (err) 13 goto fail1; 14 15 err = register_chrdev_region(MKDEV(INPUT_MAJOR, 0), 16 INPUT_MAX_CHAR_DEVICES, "input");/*注册设备,主设备号为INPUT_MAJOR,就是13,后面注册的输入设备都使用该主设备号*/ 17 if (err) { 18 pr_err("unable to register char major %d", INPUT_MAJOR); 19 goto fail2; 20 } 21 22 return 0; 23 24 fail2: input_proc_exit(); 25 fail1: class_unregister(&input_class); 26 return err; 27 } 28 29 static void __exit input_exit(void) 30 { 31 input_proc_exit(); 32 unregister_chrdev_region(MKDEV(INPUT_MAJOR, 0), 33 INPUT_MAX_CHAR_DEVICES); 34 class_unregister(&input_class); 35 } 36 37 subsys_initcall(input_init); 38 module_exit(input_exit);
subsys_initcall和module_exit宏相信大家都很熟悉,这俩函数也很简单,没什么看的.
在入口函数里面创建了一个input_class类,其实就在/sys/class下创建了一个目录input.当然对于一个新设备,可以注册进一个class也可以不注册进去,如果存在对应class的话注册进去更好.另外在/proc创建了入口项,这样就可以/proc目录看到input的信息,然后就注册设备,可以看出输入子系统的主设备号是13,在这里并没有生成设备文件.只是在/dev/目录下创建了input目录,以后所有注册进系统的输入设备文件都放在这个目录下.
那么接下来看看怎么注册input设备的.我们需要在设备驱动层中完成输入设备的注册,通过调用input_register_device()函数来完成,该函数的一个重要任务就是完成设备与事件驱动的匹配.
1 int input_register_device(struct input_dev *dev) 2 { 3 static atomic_t input_no = ATOMIC_INIT(0); 4 struct input_devres *devres = NULL; 5 struct input_handler *handler; 6 unsigned int packet_size; 7 const char *path; 8 int error; 9 10 if (dev->devres_managed) { 11 devres = devres_alloc(devm_input_device_unregister, 12 sizeof(struct input_devres), GFP_KERNEL); 13 if (!devres) 14 return -ENOMEM; 15 16 devres->input = dev; 17 } 18 19 /* Every input device generates EV_SYN/SYN_REPORT events. */ 20 __set_bit(EV_SYN, dev->evbit); 21 22 /* KEY_RESERVED is not supposed to be transmitted to userspace. */ 23 __clear_bit(KEY_RESERVED, dev->keybit); 24 25 /* Make sure that bitmasks not mentioned in dev->evbit are clean. */ 26 input_cleanse_bitmasks(dev); 27 28 packet_size = input_estimate_events_per_packet(dev); 29 if (dev->hint_events_per_packet < packet_size) 30 dev->hint_events_per_packet = packet_size; 31 32 dev->max_vals = max(dev->hint_events_per_packet, packet_size) + 2; 33 dev->vals = kcalloc(dev->max_vals, sizeof(*dev->vals), GFP_KERNEL); 34 if (!dev->vals) { 35 error = -ENOMEM; 36 goto err_devres_free; 37 } 38 39 /* 40 * If delay and period are pre-set by the driver, then autorepeating 41 * is handled by the driver itself and we don't do it in input.c. 42 */ 43 init_timer(&dev->timer); 44 if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) { 45 dev->timer.data = (long) dev; 46 dev->timer.function = input_repeat_key; 47 dev->rep[REP_DELAY] = 250; 48 dev->rep[REP_PERIOD] = 33; 49 } 50 51 if (!dev->getkeycode)/*没有定义设备的getkeycode函数,则使用默认的获取键值函数*/ 52 dev->getkeycode = input_default_getkeycode; 53 54 if (!dev->setkeycode)/*没有定义设备的setkeycode函数,则使用默认的设定键值函数*/ 55 dev->setkeycode = input_default_setkeycode; 56 57 dev_set_name(&dev->dev, "input%ld", 58 (unsigned long) atomic_inc_return(&input_no) - 1);/*设定dev的名字*/ 59 60 error = device_add(&dev->dev);/*添加设备*/ 61 if (error) 62 goto err_free_vals; 63 64 path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL); 65 pr_info("%s as %s\n", 66 dev->name ? dev->name : "Unspecified device", 67 path ? path : "N/A"); 68 kfree(path); 69 70 error = mutex_lock_interruptible(&input_mutex); 71 if (error) 72 goto err_device_del; 73 74 list_add_tail(&dev->node, &input_dev_list);/*将设备添加到input_dev_list设备链表*/ 75 76 list_for_each_entry(handler, &input_handler_list, node) 77 input_attach_handler(dev, handler);/*遍历input_handler_list,试图与每一个handler进行匹配*/ 78 79 input_wakeup_procfs_readers(); 80 81 mutex_unlock(&input_mutex); 82 83 if (dev->devres_managed) { 84 dev_dbg(dev->dev.parent, "%s: registering %s with devres.\n", 85 __func__, dev_name(&dev->dev)); 86 devres_add(dev->dev.parent, devres); 87 } 88 return 0; 89 90 err_device_del: 91 device_del(&dev->dev); 92 err_free_vals: 93 kfree(dev->vals); 94 dev->vals = NULL; 95 err_devres_free: 96 devres_free(devres); 97 return error; 98 }
第76,77行对于每个input_dev,遍历input_handler_list,调用input_attach_handler,根据input_handler的id_table判断能否支持这个input_dev.
1 static int input_attach_handler(struct input_dev *dev, struct input_handler *handler) 2 { 3 const struct input_device_id *id; 4 int error; 5 6 id = input_match_device(handler, dev); 7 if (!id) 8 return -ENODEV; 9 10 error = handler->connect(handler, dev, id);/*执行handler的connect,建立handler与设备之间的联系*/ 11 if (error && error != -ENODEV) 12 pr_err("failed to attach handler %s to device %s, error: %d\n", 13 handler->name, kobject_name(&dev->dev.kobj), error); 14 15 return error; 16 }
匹配的具体过程如下:
1 static const struct input_device_id *input_match_device(struct input_handler *handler, 2 struct input_dev *dev) 3 { 4 const struct input_device_id *id; 5 6 /*遍历handler的id_table与device进行匹配*/ 7 for (id = handler->id_table; id->flags || id->driver_info; id++) { 8 9 /*根据flags的标志位,按需要匹配相应的字段*/ 10 if (id->flags & INPUT_DEVICE_ID_MATCH_BUS) 11 if (id->bustype != dev->id.bustype)//总线类型不匹配 12 continue; 13 14 if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR) 15 if (id->vendor != dev->id.vendor)//生产厂商不匹配 16 continue; 17 18 if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT) 19 if (id->product != dev->id.product)//产品不匹配 20 continue; 21 22 if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION) 23 if (id->version != dev->id.version)//版本不匹配 24 continue; 25 26 if (!bitmap_subset(id->evbit, dev->evbit, EV_MAX))//匹配所有的事件类型 27 continue; 28 29 /*匹配所有事件的子事件*/ 30 if (!bitmap_subset(id->keybit, dev->keybit, KEY_MAX)) 31 continue; 32 33 if (!bitmap_subset(id->relbit, dev->relbit, REL_MAX)) 34 continue; 35 36 if (!bitmap_subset(id->absbit, dev->absbit, ABS_MAX)) 37 continue; 38 39 if (!bitmap_subset(id->mscbit, dev->mscbit, MSC_MAX)) 40 continue; 41 42 if (!bitmap_subset(id->ledbit, dev->ledbit, LED_MAX)) 43 continue; 44 45 if (!bitmap_subset(id->sndbit, dev->sndbit, SND_MAX)) 46 continue; 47 48 if (!bitmap_subset(id->ffbit, dev->ffbit, FF_MAX)) 49 continue; 50 51 if (!bitmap_subset(id->swbit, dev->swbit, SW_MAX)) 52 continue; 53 54 if (!handler->match || handler->match(handler, dev)) 55 return id;//匹配成功,返回id 56 } 57 58 return NULL; 59 }
这里接下来就到input_handler的connect了,看来注册input_handler是一道绕不过去的坎儿.那么我们来看具体的event handler的注册,在drivers/input/evdev.c中:
1 static const struct input_device_id evdev_ids[] = { 2 { .driver_info = 1 }, /* Matches all devices */ 3 { }, /* Terminating zero entry */ 4 }; 5 6 MODULE_DEVICE_TABLE(input, evdev_ids); 7 8 static struct input_handler evdev_handler = { 9 .event = evdev_event, 10 .events = evdev_events, 11 .connect = evdev_connect, 12 .disconnect = evdev_disconnect, 13 .legacy_minors = true, 14 .minor = EVDEV_MINOR_BASE, 15 .name = "evdev", 16 .id_table = evdev_ids, 17 }; 18 19 static int __init evdev_init(void) 20 { 21 return input_register_handler(&evdev_handler); 22 } 23 24 static void __exit evdev_exit(void) 25 { 26 input_unregister_handler(&evdev_handler); 27 } 28 29 module_init(evdev_init); 30 module_exit(evdev_exit);
这里一些相关的代码我也顺便贴出来了,再来一个:
1 int input_register_handler(struct input_handler *handler) 2 { 3 struct input_dev *dev; 4 int error; 5 6 error = mutex_lock_interruptible(&input_mutex); 7 if (error) 8 return error; 9 10 INIT_LIST_HEAD(&handler->h_list); 11 12 list_add_tail(&handler->node, &input_handler_list); 13 14 list_for_each_entry(dev, &input_dev_list, node) 15 input_attach_handler(dev, handler); 16 17 input_wakeup_procfs_readers(); 18 19 mutex_unlock(&input_mutex); 20 return 0; 21 }
这个函数不用多说了,注册event handler这个input_haner的实例,并且在注册之后迅速遍历了一下input_dev_list链表,查找所有的input_dev设备,看这个input_handler是否支持它.那么回到我们上面的遗留问题看看input_handler的connect函数.对于event handler来说,这个函数就是evdev_connect.在drivers/input/evdev.c中:
1 static int evdev_connect(struct input_handler *handler, struct input_dev *dev, 2 const struct input_device_id *id) 3 { 4 struct evdev *evdev; 5 int minor; 6 int dev_no; 7 int error; 8 9 minor = input_get_new_minor(EVDEV_MINOR_BASE, EVDEV_MINORS, true); 10 if (minor < 0) { 11 error = minor; 12 pr_err("failed to reserve new minor: %d\n", error); 13 return error; 14 } 15 16 evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL); 17 if (!evdev) { 18 error = -ENOMEM; 19 goto err_free_minor; 20 } 21 22 INIT_LIST_HEAD(&evdev->client_list); 23 spin_lock_init(&evdev->client_lock); 24 mutex_init(&evdev->mutex); 25 init_waitqueue_head(&evdev->wait); 26 evdev->exist = true; 27 28 dev_no = minor; 29 /* Normalize device number if it falls into legacy range */ 30 if (dev_no < EVDEV_MINOR_BASE + EVDEV_MINORS) 31 dev_no -= EVDEV_MINOR_BASE; 32 dev_set_name(&evdev->dev, "event%d", dev_no); 33 34 /*初始化handle,每个evdev中都有一个handle*/ 35 evdev->handle.dev = input_get_device(dev);/*这里就将handle的dev指针指向了input_dev*/ 36 evdev->handle.name = dev_name(&evdev->dev); 37 evdev->handle.handler = handler;/*这里将handle的handler指向了当前的input_handler.注意本函数evdev_connect,可能是在在输入设备注册的时候 38 在input_register_device函数中调用input_attach_handler的时候调用;也可能是在输入设备的处理方法input_handler时在input_register_handler 39 函数中也会用到input_attach_handler函数,就会调用本函数.这里就很明显了,本函数就将input_handler和input_dev都放在input_handle中统一管理*/ 40 evdev->handle.private = evdev; 41 42 /*初始化evdev中的内嵌device*/ 43 evdev->dev.devt = MKDEV(INPUT_MAJOR, minor); 44 evdev->dev.class = &input_class; 45 evdev->dev.parent = &dev->dev; 46 evdev->dev.release = evdev_free; 47 device_initialize(&evdev->dev); 48 49 /*注册handle,主要将handle链接到input_dev和handler的h_list链表中去*/ 50 error = input_register_handle(&evdev->handle); 51 if (error) 52 goto err_free_evdev; 53 54 cdev_init(&evdev->cdev, &evdev_fops); 55 evdev->cdev.kobj.parent = &evdev->dev.kobj; 56 error = cdev_add(&evdev->cdev, evdev->dev.devt, 1); 57 if (error) 58 goto err_unregister_handle; 59 60 error = device_add(&evdev->dev); 61 if (error) 62 goto err_cleanup_evdev; 63 64 return 0; 65 66 err_cleanup_evdev: 67 evdev_cleanup(evdev); 68 err_unregister_handle: 69 input_unregister_handle(&evdev->handle); 70 err_free_evdev: 71 put_device(&evdev->dev); 72 err_free_minor: 73 input_free_minor(minor); 74 return error; 75 }
至此设备的注册完成!对应event handler,在/dev/input中将多出一个event(x)设备文件,对应一个evdev实例,应用程序打开它的话也就意味着通过event handler来和设备驱动层传递事件.
第54~60行这几行字符设备初始化,这里之后再将字符设备注册,然后我们打开event(x)设备文件的时候实际上就调用evdev_fops里定义的open回调函数.相应的操作函数也在evdev_fops中定义了.我们来看看evdev_fops.同样在drivers/input/evdev.c中:
1 static const struct file_operations evdev_fops = { 2 .owner = THIS_MODULE, 3 .read = evdev_read, 4 .write = evdev_write, 5 .poll = evdev_poll, 6 .open = evdev_open, 7 .release = evdev_release, 8 .unlocked_ioctl = evdev_ioctl, 9 #ifdef CONFIG_COMPAT 10 .compat_ioctl = evdev_ioctl_compat, 11 #endif 12 .fasync = evdev_fasync, 13 .flush = evdev_flush, 14 .llseek = no_llseek, 15 };
首先来看打开event(x)设备文件,evdev_open函数.
1 static int evdev_open(struct inode *inode, struct file *file) 2 { 3 struct evdev *evdev = container_of(inode->i_cdev, struct evdev, cdev); 4 unsigned int bufsize = evdev_compute_buffer_size(evdev->handle.dev); 5 struct evdev_client *client; 6 int error; 7 8 /*每当一个应用程序打开该文件都会生成一个client*/ 9 client = kzalloc(sizeof(struct evdev_client) + 10 bufsize * sizeof(struct input_event), 11 GFP_KERNEL); 12 if (!client) 13 return -ENOMEM; 14 15 client->bufsize = bufsize; 16 spin_lock_init(&client->buffer_lock); 17 client->evdev = evdev; 18 evdev_attach_client(evdev, client);/*将client链入evdev的client_list中*/ 19 20 error = evdev_open_device(evdev); 21 if (error) 22 goto err_free_client; 23 24 file->private_data = client; 25 nonseekable_open(inode, file); 26 27 return 0; 28 29 err_free_client: 30 evdev_detach_client(evdev, client); 31 kfree(client); 32 return error; 33 }
第20行调用evdev_open_device来打开evdev(如果将inpit_dev抽象为一个父对象,这其实就是一个子对象,或者说这个结构封装了一个具体的实例化的input_dev).
1 static int evdev_open_device(struct evdev *evdev) 2 { 3 int retval; 4 5 retval = mutex_lock_interruptible(&evdev->mutex); 6 if (retval) 7 return retval; 8 9 if (!evdev->exist) 10 retval = -ENODEV; 11 else if (!evdev->open++) {/*如果是第一次打开该设备,则要执行输入设备的open*/ 12 retval = input_open_device(&evdev->handle); 13 if (retval) 14 evdev->open--; 15 } 16 17 mutex_unlock(&evdev->mutex); 18 return retval; 19 }
这里终于看到了输入子系统核心层的接口input_open_device,此函数就是内核为我们做好的初始化input_dev的函数接口.
1 int input_open_device(struct input_handle *handle) 2 { 3 struct input_dev *dev = handle->dev; 4 int retval; 5 6 retval = mutex_lock_interruptible(&dev->mutex); 7 if (retval) 8 return retval; 9 10 if (dev->going_away) { 11 retval = -ENODEV; 12 goto out; 13 } 14 15 handle->open++; 16 17 if (!dev->users++ && dev->open)/*如果是第一次打开此设备(当前input_dev的使用者数为0),并且input_dev中定义的open函数不为空*/ 18 retval = dev->open(dev);//执行input_dev中定义的open,完成设备的初始化 19 20 if (retval) { 21 dev->users--; 22 if (!--handle->open) { 23 /* 24 * Make sure we are not delivering any more events 25 * through this handle 26 */ 27 synchronize_rcu(); 28 } 29 } 30 31 out: 32 mutex_unlock(&dev->mutex); 33 return retval; 34 }
至于具体的如何初始化input_dev,这个是具体的输入设备去实现的.我们这里不分析了.现在来看看,对于一个event(x)设备文件的.
1 static ssize_t evdev_read(struct file *file, char __user *buffer, 2 size_t count, loff_t *ppos) 3 { 4 struct evdev_client *client = file->private_data; 5 struct evdev *evdev = client->evdev; 6 struct input_event event; 7 size_t read = 0; 8 int error; 9 10 if (count != 0 && count < input_event_size()) 11 return -EINVAL; 12 13 for (;;) { 14 if (!evdev->exist)/*evdev没有定义返回函数,直接返回吧,因为我们下面必须要用到这个函数*/ 15 return -ENODEV; 16 17 if (client->packet_head == client->tail && 18 (file->f_flags & O_NONBLOCK))/*无数据并且是非阻塞状态,则直接返回,说明没什么要处理的*/ 19 return -EAGAIN; 20 21 /* 22 * count == 0 is special - no IO is done but we check 23 * for error conditions (see above). 24 */ 25 if (count == 0) 26 break; 27 28 while (read + input_event_size() <= count && 29 evdev_fetch_next_event(client, &event)) { 30 31 if (input_event_to_user(buffer + read, &event)) 32 return -EFAULT; 33 34 read += input_event_size(); 35 } 36 37 if (read) 38 break; 39 40 if (!(file->f_flags & O_NONBLOCK)) {/*如果是可阻塞状态的话,则等待在wait队列上.直到有数据要被处理,当前进程才被唤醒.这很好理解,既然是 41 输入设备,读的话比如读按键,那么必须要有硬件设备有按键按下才会返回按键值,这里还是处于事件处理层,应用程序在这里休眠,那么谁来唤醒? 42 当然是有按键按下才去唤醒,因此这个工作就交给了设备驱动层,那么找到这个唤醒呢,直接去找不好找,那么可以直接搜索evdev->wait,搜索结果 43 可知evdev->wait在evdev_event()函数中被唤醒*/ 44 error = wait_event_interruptible(evdev->wait, 45 client->packet_head != client->tail || 46 !evdev->exist); 47 if (error) 48 return error; 49 } 50 } 51 52 return read; 53 }
注释中说的很清楚,evdev_event()会唤醒此处的读按键进程.那么evdev_event()又是被谁调用?显然是设备驱动层,现在看一个设备层例子,内核中有个按键的例子,gpiokey.c,这只是个例子不针对任何设备,在gpiokey.c终端处理函数里面.
1 static void evdev_pass_values(struct evdev_client *client, 2 const struct input_value *vals, unsigned int count, 3 ktime_t mono, ktime_t real) 4 { 5 struct evdev *evdev = client->evdev; 6 const struct input_value *v; 7 struct input_event event; 8 bool wakeup = false; 9 10 event.time = ktime_to_timeval(client->clkid == CLOCK_MONOTONIC ? 11 mono : real); 12 13 /* Interrupts are disabled, just acquire the lock. */ 14 spin_lock(&client->buffer_lock); 15 16 for (v = vals; v != vals + count; v++) { 17 event.type = v->type; 18 event.code = v->code; 19 event.value = v->value; 20 __pass_event(client, &event); 21 if (v->type == EV_SYN && v->code == SYN_REPORT) 22 wakeup = true; 23 } 24 25 spin_unlock(&client->buffer_lock); 26 27 if (wakeup) 28 wake_up_interruptible(&evdev->wait); 29 } 30 31 /* 32 * Pass incoming events to all connected clients. 33 */ 34 static void evdev_events(struct input_handle *handle, 35 const struct input_value *vals, unsigned int count) 36 { 37 struct evdev *evdev = handle->private; 38 struct evdev_client *client; 39 ktime_t time_mono, time_real; 40 41 time_mono = ktime_get(); 42 time_real = ktime_sub(time_mono, ktime_get_monotonic_offset()); 43 44 rcu_read_lock(); 45 46 client = rcu_dereference(evdev->grab); 47 48 if (client) 49 evdev_pass_values(client, vals, count, time_mono, time_real); 50 else 51 list_for_each_entry_rcu(client, &evdev->client_list, node) 52 evdev_pass_values(client, vals, count, 53 time_mono, time_real); 54 55 rcu_read_unlock(); 56 } 57 58 /* 59 * Pass incoming event to all connected clients. 60 */ 61 static void evdev_event(struct input_handle *handle, 62 unsigned int type, unsigned int code, int value) 63 { 64 struct input_value vals[] = { { type, code, value } }; 65 66 evdev_events(handle, vals, 1); 67 }
好了,就贴到这里,input子系统的大体脉络以及比较清楚了.