linux设备驱动(13)input子系统(二)API详解
input子系统分为三层:
事件驱动层input_handler,提供事件注册接口。
输入核心层input_handle,是input子系统实现的核心。
设备驱动层input_dev,提供设备注册接口,输入信息反馈接口。
1 输入核心层
1.1input的初始化
input_init(),属于输入核心层
定义位于:drivers\input\input.c
1 static int __init input_init(void) 2 { 3 int err; 4 5 err = class_register(&input_class);/* 在sysfs中的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文件系统 *就是创建/proc中入口项,在/proc中就可以查看input/ 12 if (err) 13 goto fail1; 14 15 err = register_chrdev_region(MKDEV(INPUT_MAJOR, 0),/* 注册字符设备驱动,主设备号为INPUT_MAJOR,就是13,后面注册的输入设备都使用该主设备号 */ 16 INPUT_MAX_CHAR_DEVICES, "input"); 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 }
在入口函数里面创建了一个input_class类,其实就在/sys/class下创建了一个目录input.当然对于一个新设备,可以注册进一个class也可以不注册进去,如果存在对应class的话注册进去更好.另外在/proc创建了入口项,这样就可以/proc目录看到input的信息,然后就注册设备,可以看出输入子系统的主设备号是13,在这里并没有生成设备文件.只是在/dev/目录下创建了input目录,以后所有注册进系统的输入设备文件都放在这个目录下.
1.2 handle的注册
其实就是把handler和dev的链表加入到handle的数据中。
1 /** 2 * input_register_handle - register a new input handle 3 * @handle: handle to register 4 * 5 * This function puts a new input handle onto device's 6 * and handler's lists so that events can flow through 7 * it once it is opened using input_open_device(). 8 * 9 * This function is supposed to be called from handler's 10 * connect() method. 11 */ 12 int input_register_handle(struct input_handle *handle) 13 { 14 struct input_handler *handler = handle->handler; 15 struct input_dev *dev = handle->dev; 16 int error; 17 18 /* 19 * We take dev->mutex here to prevent race with 20 * input_release_device(). 21 */ 22 error = mutex_lock_interruptible(&dev->mutex); 23 if (error) 24 return error; 25 26 /* 27 * Filters go to the head of the list, normal handlers 28 * to the tail. 29 */ 30 if (handler->filter) 31 list_add_rcu(&handle->d_node, &dev->h_list); 32 else 33 list_add_tail_rcu(&handle->d_node, &dev->h_list);/*把dev加入到handle*/ 34 35 mutex_unlock(&dev->mutex); 36 37 /* 38 * Since we are supposed to be called from ->connect() 39 * which is mutually exclusive with ->disconnect() 40 * we can't be racing with input_unregister_handle() 41 * and so separate lock is not needed here. 42 */ 43 list_add_tail_rcu(&handle->h_node, &handler->h_list);/*把handler加入到handle*/ 44 45 if (handler->start) 46 handler->start(handle); 47 48 return 0; 49 }
RCU形式的锁机制,它允许多个执行单元对它同时对它进行读,但是多个执行单元对它进行写操作时,要求你先复制一个副本,要改要删随你便,反正你改的不是其本身。当所有的写单元都一一改完后,再统一写回,比一般的自旋锁高级些。但是不要轻易用它,因为系统开销较大。
1.3input_open_device()
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 }
2.设备驱动层。
2.1.input_allocate_device()
设备描述结构体变量input_dev分配,同时初始化一些通用性数据。其他数据对于不同设备特有的数据需要自己填充。
1 /** 2 * input_allocate_device - allocate memory for new input device 3 * 4 * Returns prepared struct input_dev or %NULL. 5 * 6 * NOTE: Use input_free_device() to free devices that have not been 7 * registered; input_unregister_device() should be used for already 8 * registered devices. 9 */ 10 struct input_dev *input_allocate_device(void) 11 { 12 struct input_dev *dev; 13 14 dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL); 15 if (dev) { 16 dev->dev.type = &input_dev_type;/* 绑定设备信息 */ 17 dev->dev.class = &input_class;/* 绑定在sysfs所属的类,后面的register里面的add_device后才能出现在sysfs下的input文件夹下 */ 18 device_initialize(&dev->dev);/*初始化设备*/ 19 mutex_init(&dev->mutex); 20 spin_lock_init(&dev->event_lock);/*初始化挂载input_device的input_hander的链表*/ 21 INIT_LIST_HEAD(&dev->h_list);/*初始化挂载input_device的链表*/ 22 INIT_LIST_HEAD(&dev->node); 23 24 __module_get(THIS_MODULE); 25 } 26 27 return dev; 28 }
1 static struct device_type input_dev_type = { 2 .groups = input_dev_attr_groups, 3 .release = input_dev_release, 4 .uevent = input_dev_uevent, 5 #ifdef CONFIG_PM 6 .pm = &input_dev_pm_ops, 7 #endif 8 };
2.2 设置dev设备的能力,只有注册前设置来它拥有的能力,将来该设备注册后,发送的信息才能被上报。
注意:该函数每次只能设置一个能力。
1 /** 2 * input_set_capability - mark device as capable of a certain event 3 * @dev: device that is capable of emitting or accepting event 4 * @type: type of the event (EV_KEY, EV_REL, etc...) 5 * @code: event code 6 * 7 * In addition to setting up corresponding bit in appropriate capability 8 * bitmap the function also adjusts dev->evbit. 9 */ 10 void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code) 11 { 12 switch (type) {/*根据type类型,设置code到相应的typebit*/ 13 case EV_KEY: 14 __set_bit(code, dev->keybit); 15 break; 16 17 case EV_REL: 18 __set_bit(code, dev->relbit); 19 break; 20 21 case EV_ABS: 22 input_alloc_absinfo(dev); 23 if (!dev->absinfo) 24 return; 25 26 __set_bit(code, dev->absbit); 27 break; 28 29 case EV_MSC: 30 __set_bit(code, dev->mscbit); 31 break; 32 33 case EV_SW: 34 __set_bit(code, dev->swbit); 35 break; 36 37 case EV_LED: 38 __set_bit(code, dev->ledbit); 39 break; 40 41 case EV_SND: 42 __set_bit(code, dev->sndbit); 43 break; 44 45 case EV_FF: 46 __set_bit(code, dev->ffbit); 47 break; 48 49 case EV_PWR: 50 /* do nothing */ 51 break; 52 53 default: 54 pr_err("input_set_capability: unknown type %u (code %u)\n", 55 type, code); 56 dump_stack(); 57 return; 58 } 59 60 __set_bit(type, dev->evbit); 61 }
2.3.input设备注册
向核心层注册input设备,需要以上两步申请空间和填充能力完成之后才能call下面的函数进行注册。一个重要任务就是完成设备与事件驱动的匹配。
1 /** 2 * input_register_device - register device with input core 3 * @dev: device to be registered 4 * 5 * This function registers device with input core. The device must be 6 * allocated with input_allocate_device() and all it's capabilities 7 * set up before registering. 8 * If function fails the device must be freed with input_free_device(). 9 * Once device has been successfully registered it can be unregistered 10 * with input_unregister_device(); input_free_device() should not be 11 * called in this case. 12 * 13 * Note that this function is also used to register managed input devices 14 * (ones allocated with devm_input_allocate_device()). Such managed input 15 * devices need not be explicitly unregistered or freed, their tear down 16 * is controlled by the devres infrastructure. It is also worth noting 17 * that tear down of managed input devices is internally a 2-step process: 18 * registered managed input device is first unregistered, but stays in 19 * memory and can still handle input_event() calls (although events will 20 * not be delivered anywhere). The freeing of managed input device will 21 * happen later, when devres stack is unwound to the point where device 22 * allocation was made. 23 */ 24 int input_register_device(struct input_dev *dev) 25 { 26 static atomic_t input_no = ATOMIC_INIT(0); 27 struct input_devres *devres = NULL; 28 struct input_handler *handler; 29 unsigned int packet_size; 30 const char *path; 31 int error; 32 33 if (dev->devres_managed) { 34 devres = devres_alloc(devm_input_device_unregister, 35 sizeof(struct input_devres), GFP_KERNEL); 36 if (!devres) 37 return -ENOMEM; 38 39 devres->input = dev; 40 } 41 42 /* Every input device generates EV_SYN/SYN_REPORT events. */ 43 __set_bit(EV_SYN, dev->evbit);//通用的同步包 44 45 /* KEY_RESERVED is not supposed to be transmitted to userspace. */ 46 __clear_bit(KEY_RESERVED, dev->keybit); 47 48 /* Make sure that bitmasks not mentioned in dev->evbit are clean. */ 49 input_cleanse_bitmasks(dev); 50 51 packet_size = input_estimate_events_per_packet(dev); 52 if (dev->hint_events_per_packet < packet_size) 53 dev->hint_events_per_packet = packet_size; 54 55 dev->max_vals = max(dev->hint_events_per_packet, packet_size) + 2; 56 dev->vals = kcalloc(dev->max_vals, sizeof(*dev->vals), GFP_KERNEL); 57 if (!dev->vals) { 58 error = -ENOMEM; 59 goto err_devres_free; 60 } 61 62 /* 63 * If delay and period are pre-set by the driver, then autorepeating 64 * is handled by the driver itself and we don't do it in input.c. 65 */ 66 init_timer(&dev->timer);//重复上报功能数据填充 67 if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) { 68 dev->timer.data = (long) dev; 69 dev->timer.function = input_repeat_key; 70 dev->rep[REP_DELAY] = 250; 71 dev->rep[REP_PERIOD] = 33; 72 } 73 /*继续初始化结构体*/ 74 if (!dev->getkeycode)/*没有定义设备的getkeycode函数,就是用默认的键值获取函数*/ 75 dev->getkeycode = input_default_getkeycode; 76 77 if (!dev->setkeycode) 78 dev->setkeycode = input_default_setkeycode; 79 /*设置设备名字,从input0开始,依次增大1*/ 80 dev_set_name(&dev->dev, "input%ld", 81 (unsigned long) atomic_inc_return(&input_no) - 1); 82 /*把该inputx设备加入到设备链表中,同时在sysfs的input文件夹系出现inputx以及我们初始化的name,phy等参数*/ 83 error = device_add(&dev->dev); 84 if (error) 85 goto err_free_vals; 86 /*打印调试信息,安装设备会出现*/ 87 path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL); 88 pr_info("%s as %s\n", 89 dev->name ? dev->name : "Unspecified device", 90 path ? path : "N/A"); 91 kfree(path); 92 93 error = mutex_lock_interruptible(&input_mutex); 94 if (error) 95 goto err_device_del; 96 /*把该设备加入到核心层维护的两个重要链表之一的设备链表input_dev_list中去*/ 97 list_add_tail(&dev->node, &input_dev_list); 98 /*依次遍历另一条重要链表input_handler_list,看该设备能不能匹配到那个handler*/ 99 list_for_each_entry(handler, &input_handler_list, node) 100 input_attach_handler(dev, handler);/*匹配,和链接两者*/ 101 102 input_wakeup_procfs_readers();/*匹配到了,则更新proc文件系统*/ 103 104 mutex_unlock(&input_mutex); 105 106 if (dev->devres_managed) { 107 dev_dbg(dev->dev.parent, "%s: registering %s with devres.\n", 108 __func__, dev_name(&dev->dev)); 109 devres_add(dev->dev.parent, devres); 110 } 111 return 0; 112 113 err_device_del: 114 device_del(&dev->dev); 115 err_free_vals: 116 kfree(dev->vals); 117 dev->vals = NULL; 118 err_devres_free: 119 devres_free(devres); 120 return error; 121 }
第99/100行中对于每个input_dev,遍历input_handler_list,调用input_attach_handler,根据input_handler的id_table判断能否支持这个input_dev.
2.4 input_attach_handler()
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 /*匹配hander和dev*/ 6 id = input_match_device(handler, dev); 7 if (!id) 8 return -ENODEV; 9 /*做具体的绑定handler和dev工作,由具体的事驱动层实现*/ 10 error = handler->connect(handler, dev, id); 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 }
2.4.1 每一个事件驱动层在实现的时候都要实现一个struct input_device_id的表(数组),用来表明该事件驱动可以支持的设备。
定义位于:include\linux\mod_devicetable.h
1 struct input_device_id { 2 3 kernel_ulong_t flags;/*flags表明下面的四个要不要匹配,已经用相关宏定义好*/ 4 5 __u16 bustype; 6 __u16 vendor; 7 __u16 product; 8 __u16 version; 9 10 kernel_ulong_t evbit[INPUT_DEVICE_ID_EV_MAX / BITS_PER_LONG + 1]; 11 kernel_ulong_t keybit[INPUT_DEVICE_ID_KEY_MAX / BITS_PER_LONG + 1]; 12 kernel_ulong_t relbit[INPUT_DEVICE_ID_REL_MAX / BITS_PER_LONG + 1]; 13 kernel_ulong_t absbit[INPUT_DEVICE_ID_ABS_MAX / BITS_PER_LONG + 1]; 14 kernel_ulong_t mscbit[INPUT_DEVICE_ID_MSC_MAX / BITS_PER_LONG + 1]; 15 kernel_ulong_t ledbit[INPUT_DEVICE_ID_LED_MAX / BITS_PER_LONG + 1]; 16 kernel_ulong_t sndbit[INPUT_DEVICE_ID_SND_MAX / BITS_PER_LONG + 1]; 17 kernel_ulong_t ffbit[INPUT_DEVICE_ID_FF_MAX / BITS_PER_LONG + 1]; 18 kernel_ulong_t swbit[INPUT_DEVICE_ID_SW_MAX / BITS_PER_LONG + 1]; 19 20 kernel_ulong_t driver_info; 21 }
2.4.2 如果填充时在handler里面的在flags标志里面置位了下面的某一个,则匹配时就会检查响应的(总线类型,厂商,设备号,设备版本)。如果没有置位相应位,则表明匹配时不检查响应的标志位。
#define INPUT_DEVICE_ID_MATCH_BUS 1 #define INPUT_DEVICE_ID_MATCH_VENDOR 2 #define INPUT_DEVICE_ID_MATCH_PRODUCT 4 #define INPUT_DEVICE_ID_MATCH_VERSION 8
2.4.3同时也可以置位需要匹配类型
#define INPUT_DEVICE_ID_MATCH_EVBIT 0x0010 #define INPUT_DEVICE_ID_MATCH_KEYBIT 0x0020 #define INPUT_DEVICE_ID_MATCH_RELBIT 0x0040 #define INPUT_DEVICE_ID_MATCH_ABSBIT 0x0080 #define INPUT_DEVICE_ID_MATCH_MSCIT 0x0100 #define INPUT_DEVICE_ID_MATCH_LEDBIT 0x0200 #define INPUT_DEVICE_ID_MATCH_SNDBIT 0x0400 #define INPUT_DEVICE_ID_MATCH_FFBIT 0x0800 #define INPUT_DEVICE_ID_MATCH_SWBIT 0x1000
2.4.4 input_match_device
接下来真正的通过input_device_id来匹配
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 /*input_device_id是一个数组,从前向后依次遍历id_table中和dev里面的id和xxbit中完全匹配的*/ 6 for (id = handler->id_table; id->flags || id->driver_info; id++) { 7 /*正如前面描述的handler中id_table置位了相应标志位才做匹配检查*/ 8 if (id->flags & INPUT_DEVICE_ID_MATCH_BUS) 9 if (id->bustype != dev->id.bustype) 10 continue; 11 12 if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR) 13 if (id->vendor != dev->id.vendor) 14 continue; 15 16 if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT) 17 if (id->product != dev->id.product) 18 continue; 19 20 if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION) 21 if (id->version != dev->id.version) 22 continue; 23 /*同一id_table里面的flags匹配成功,才能MATCH_BIT匹配*/ 24 if (!bitmap_subset(id->evbit, dev->evbit, EV_MAX)) 25 continue; 26 27 if (!bitmap_subset(id->keybit, dev->keybit, KEY_MAX)) 28 continue; 29 30 if (!bitmap_subset(id->relbit, dev->relbit, REL_MAX)) 31 continue; 32 33 if (!bitmap_subset(id->absbit, dev->absbit, ABS_MAX)) 34 continue; 35 36 if (!bitmap_subset(id->mscbit, dev->mscbit, MSC_MAX)) 37 continue; 38 39 if (!bitmap_subset(id->ledbit, dev->ledbit, LED_MAX)) 40 continue; 41 42 if (!bitmap_subset(id->sndbit, dev->sndbit, SND_MAX)) 43 continue; 44 45 if (!bitmap_subset(id->ffbit, dev->ffbit, FF_MAX)) 46 continue; 47 48 if (!bitmap_subset(id->swbit, dev->swbit, SW_MAX)) 49 continue; 50 /*看handler层有没有再定义macth匹配函数,如果没有,那到这里就是已经找到id了,否则,还要通过handler里面的match才能确定就是该id*/ 51 if (!handler->match || handler->match(handler, dev)) 52 return id; 53 } 54 55 return NULL; 56 }
2.4.5input_handler中connect()函数
最后input_attach_handler调用handler->connect(handler, dev, id)函数。即到事件驱动层handler。
3.事件驱动层input_handler
以evdev事件为例来讲解input_handler,定义:drivers/input/evdev.c中:
3.1evdev_init()
1 static int __init evdev_init(void) 2 { 3 return input_register_handler(&evdev_handler); 4 }
3.2.input_register_handler
input_handler的注册,定义位于:drivers\input\input.c
注册前,先要对input_handler结构体初始化
1 static struct input_handler evdev_handler = { 2 .event = evdev_event, 3 .events = evdev_events, 4 .connect = evdev_connect, 5 .disconnect = evdev_disconnect, 6 .legacy_minors = true, 7 .minor = EVDEV_MINOR_BASE, 8 .name = "evdev", 9 .id_table = evdev_ids, 10 };
给input_device_id 赋值
1 static const struct input_device_id evdev_ids[] = { 2 { .driver_info = 1 }, /* Matches all devices */ 3 { }, /* Terminating zero entry */ 4 };
然后再初始化
1 /** 2 * input_register_handler - register a new input handler 3 * @handler: handler to be registered 4 * 5 * This function registers a new input handler (interface) for input 6 * devices in the system and attaches it to all input devices that 7 * are compatible with the handler. 8 */ 9 int input_register_handler(struct input_handler *handler) 10 { 11 struct input_dev *dev; 12 int error; 13 14 error = mutex_lock_interruptible(&input_mutex); 15 if (error) 16 return error; 17 18 INIT_LIST_HEAD(&handler->h_list);//初始化挂载input_hand的list 19 20 list_add_tail(&handler->node, &input_handler_list);//将handler_node加到input_handler_list中 21 /*用当前的handler遍历核心层维护的两条重要链表之一的dev链表,并尝试匹配*/ 22 list_for_each_entry(dev, &input_dev_list, node) 23 input_attach_handler(dev, handler); 24 25 input_wakeup_procfs_readers();/*更新proce文件*/ 26 27 mutex_unlock(&input_mutex); 28 return 0; 29 }
匹配算法和device那边的完全一样(调用的同一个函数都)。这里要说明的是为什么即在注册handler的时候匹配一遍,又要在注册device的时候匹配一次。
这是因为,通常系统不能确定是handler先注册,还是dev先注册。假设只在注册dev的时候匹配handler(注册handler去掉匹配那几句代码 ),结果,devi先执行的,因为handler还没被注册,所以dev匹配失败。当注册handler的时候,因为没有了再次匹配,所以两者无法再接续到一块了。所以要在handler和dev注册都匹配一次,当然肯定是后面注册的才能匹配成。
3.3 connect函数
然后再回到我们上面2.4.5中的遗留问题看看input_handler的connect函数.对于event handler来说,这个函数就是evdev_connect函数。
定义位于:drivers/input/evdev.c
1 /* 2 * Create new evdev device. Note that input core serializes calls 3 * to connect and disconnect. 4 */ 5 static int evdev_connect(struct input_handler *handler, struct input_dev *dev, 6 const struct input_device_id *id) 7 { 8 struct evdev *evdev; 9 int minor; 10 int dev_no; 11 int error; 12 13 minor = input_get_new_minor(EVDEV_MINOR_BASE, EVDEV_MINORS, true); 14 if (minor < 0) { 15 error = minor; 16 pr_err("failed to reserve new minor: %d\n", error); 17 return error; 18 } 19 20 evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL); 21 if (!evdev) { 22 error = -ENOMEM; 23 goto err_free_minor; 24 } 25 26 INIT_LIST_HEAD(&evdev->client_list); 27 spin_lock_init(&evdev->client_lock); 28 mutex_init(&evdev->mutex); 29 init_waitqueue_head(&evdev->wait); 30 evdev->exist = true; 31 32 dev_no = minor; 33 /* Normalize device number if it falls into legacy range */ 34 if (dev_no < EVDEV_MINOR_BASE + EVDEV_MINORS) 35 dev_no -= EVDEV_MINOR_BASE; 36 dev_set_name(&evdev->dev, "event%d", dev_no); 37 38 /*初始化handle,每个evdev中都有一个handle*/ 39 evdev->handle.dev = input_get_device(dev);/*这里就将handle的dev指针指向了input_dev*/ 40 evdev->handle.name = dev_name(&evdev->dev); 41 evdev->handle.handler = handler;/*这里将handle的handler指向了当前的input_handler.注意本函数evdev_connect,可能是在在输入设备注册的时候 42 在input_register_device函数中调用input_attach_handler的时候调用;也可能是在输入设备的处理方法input_handler时在input_register_handler 43 函数中也会用到input_attach_handler函数,就会调用本函数.这里就很明显了,本函数就将input_handler和input_dev都放在input_handle中统一管理*/ 44 evdev->handle.private = evdev; 45 46 /*初始化evdev中的内嵌device*/ 47 evdev->dev.devt = MKDEV(INPUT_MAJOR, minor); 48 evdev->dev.class = &input_class; 49 evdev->dev.parent = &dev->dev; 50 evdev->dev.release = evdev_free; 51 device_initialize(&evdev->dev); 52 53 /*注册handle,主要将handle链接到input_dev和handler的h_list链表中去*/ 54 error = input_register_handle(&evdev->handle); 55 if (error) 56 goto err_free_evdev; 57 58 cdev_init(&evdev->cdev, &evdev_fops); 59 evdev->cdev.kobj.parent = &evdev->dev.kobj; 60 error = cdev_add(&evdev->cdev, evdev->dev.devt, 1); 61 if (error) 62 goto err_unregister_handle; 63 64 error = device_add(&evdev->dev); 65 if (error) 66 goto err_cleanup_evdev; 67 68 return 0; 69 70 err_cleanup_evdev: 71 evdev_cleanup(evdev); 72 err_unregister_handle: 73 input_unregister_handle(&evdev->handle); 74 err_free_evdev: 75 put_device(&evdev->dev); 76 err_free_minor: 77 input_free_minor(minor); 78 return error; 79 }
1 struct evdev {//evdev结构体再配对成功的时候生成,由handler->connect生成 2 int open;//打开引用计数 3 struct input_handle handle;//关联的input_handle 4 wait_queue_head_t wait;/等待队列 5 struct evdev_client __rcu *grab; 6 struct list_head client_list;//evdev_client链表,说明一个evdev设备可以处理多个evdev_client,可以有多个进程访问 7 spinlock_t client_lock; /* protects client_list */ 8 struct mutex mutex; 9 struct device dev; 10 struct cdev cdev; 11 bool exist; 12 };
至此设备的注册完成!对应event handler,在/dev/input中将多出一个event(x)设备文件,对应一个evdev实例,应用程序打开它的话也就意味着通过event handler来和设备驱动层传递事件.
第58~64行这几行字符设备初始化,这里之后再将字符设备注册,然后我们打开event(x)设备文件的时候实际上就调用evdev_fops里定义的open回调函数.相应的操作函数也在evdev_fops中定义了.
3.4evdev_fops.
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 };
3.4.1evdev_open
首先来看打开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);//打开evdev(如果将inpit_dev抽象为一个父对象,这其实就是一个子对象,或者说这个结构封装了一个具体的实例化的input_dev) 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 }
3.2evdev_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 }
3.3输入子系统核心层的接口input_open_device
这里终于看到了输入子系统核心层的接口input_open_device,此函数就是内核为我们做好的初始化input_dev的函数接口.
见上2.3分析
3.4 怎么读一个event(x)设备文件的,即evdev_read()
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 }
3.4.1 evdev_fetch_next_event
查看有没有数据,有的话返回1,且*event参数会把数据带出来一包
1 static int evdev_fetch_next_event(struct evdev_client *client, 2 struct input_event *event) 3 { 4 int have_event; 5 6 spin_lock_irq(&client->buffer_lock); 7 8 have_event = client->packet_head != client->tail;/*头不等于尾说明有数据*/ 9 if (have_event) { 10 *event = client->buffer[client->tail++];/*读数据到*event,每次只能读一个包*/ 11 client->tail &= client->bufsize - 1;/**读完一个包,指针移到下一个/ 12 } 13 14 spin_unlock_irq(&client->buffer_lock); 15 16 return have_event; 17 }
3.5 evdev_event()
会唤醒此处的读按键进程.那么evdev_event()又是被谁调用?显然是设备驱动层,现在看一个设备层例子,内核中有个按键的例子,gpiokey.c,这只是个例子不针对任何设备,在gpiokey.c终端处理函数里面.
1 /* 2 * Pass incoming event to all connected clients. 3 */ 4 static void evdev_event(struct input_handle *handle, 5 unsigned int type, unsigned int code, int value) 6 { 7 struct input_value vals[] = { { type, code, value } }; 8 9 evdev_events(handle, vals, 1); 10 } 11 12 /* 13 * Pass incoming events to all connected clients. 14 */ 15 static void evdev_events(struct input_handle *handle, 16 const struct input_value *vals, unsigned int count) 17 { 18 struct evdev *evdev = handle->private; 19 struct evdev_client *client; 20 ktime_t time_mono, time_real;/*输入信息打包成标准格式*/ 21 22 time_mono = ktime_get(); 23 time_real = ktime_sub(time_mono, ktime_get_monotonic_offset()); 24 25 rcu_read_lock(); 26 /*如果该evdev有个专用的client,那么就将事件发给它如果该evdev不存在专用的client,那个就把该事件发送给evdev上client_list链表上所有的client*/ 27 client = rcu_dereference(evdev->grab); 28 29 if (client) 30 evdev_pass_values(client, vals, count, time_mono, time_real); 31 else 32 list_for_each_entry_rcu(client, &evdev->client_list, node) 33 evdev_pass_values(client, vals, count, 34 time_mono, time_real); 35 36 rcu_read_unlock(); 37 } 38 39 static void evdev_pass_values(struct evdev_client *client, 40 const struct input_value *vals, unsigned int count, 41 ktime_t mono, ktime_t real) 42 { 43 struct evdev *evdev = client->evdev; 44 const struct input_value *v; 45 struct input_event event; 46 bool wakeup = false; 47 48 event.time = ktime_to_timeval(client->clkid == CLOCK_MONOTONIC ? 49 mono : real); 50 51 /* Interrupts are disabled, just acquire the lock. */ 52 spin_lock(&client->buffer_lock); 53 54 for (v = vals; v != vals + count; v++) { 55 event.type = v->type; 56 event.code = v->code; 57 event.value = v->value; 58 __pass_event(client, &event); 59 if (v->type == EV_SYN && v->code == SYN_REPORT) 60 wakeup = true; 61 } 62 63 spin_unlock(&client->buffer_lock); 64 65 if (wakeup) 66 wake_up_interruptible(&evdev->wait);/*唤醒等到队列上的进程,注意这里是唤醒,connect中有定义,read中让他睡眠*/ 67 }
3.5.1__pass_event
发送数据给client函数
1 static void __pass_event(struct evdev_client *client, 2 const struct input_event *event) 3 { 4 client->buffer[client->head++] = *event; 5 client->head &= client->bufsize - 1; 6 7 if (unlikely(client->head == client->tail)) { 8 /* 9 * This effectively "drops" all unconsumed events, leaving 10 * EV_SYN/SYN_DROPPED plus the newest event in the queue. 11 */ 12 client->tail = (client->head - 2) & (client->bufsize - 1); 13 /*把键值写入client缓冲队列中,方便app层读,app层可能一次读多个输入信息*/ 14 client->buffer[client->tail].time = event->time; 15 client->buffer[client->tail].type = EV_SYN; 16 client->buffer[client->tail].code = SYN_DROPPED; 17 client->buffer[client->tail].value = 0; 18 19 client->packet_head = client->tail; 20 } 21 22 if (event->type == EV_SYN && event->code == SYN_REPORT) { 23 client->packet_head = client->head; 24 kill_fasync(&client->fasync, SIGIO, POLL_IN);/*发送一个异步通知,通知该打开该client的应用程序,执行信号处理函数*/ 25 } 26 }
参考博文:
https://blog.csdn.net/qq_16777851/java/article/details/81229209