Linux设备驱动剖析之Input(三)

时间:2023-03-09 15:16:18
Linux设备驱动剖析之Input(三)
     /* get current state of buttons */
for (i = ; i < pdata->nbuttons; i++)
gpio_keys_report_event(&ddata->data[i]);
input_sync(input); device_init_wakeup(&pdev->dev, wakeup); return ; fail3:
sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group);
fail2:
while (--i >= ) {
free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]);
if (ddata->data[i].timer_debounce)
del_timer_sync(&ddata->data[i].timer);
cancel_work_sync(&ddata->data[i].work);
gpio_free(pdata->buttons[i].gpio);
} platform_set_drvdata(pdev, NULL);
fail1:
input_free_device(input);
kfree(ddata); return error;
}

520、521行,为了避免与后面的内容重复,为了讲解的连贯性,把它们放到讲完事件驱动程序之后再讲。现在Input设备已经注册进input core了,剩下就是将handler也注册进input core,这样Input事件就能够通过input core到达事件驱动程序,最后到达用户空间,这也是我们的最终目的。

好了,下面开始讲事件驱动程序,以drivers/input/evdev.c为例,这是一个通用的事件驱动程序,可以支持所有的Input设备。好了,“态度决定一切,从初始化函数开始。”

 static int __init evdev_init(void)
{
return input_register_handler(&evdev_handler);
}

先看916行input_register_handler函数参数evdev_handler的定义:

 static struct input_handler evdev_handler = {
.event = evdev_event,
.connect = evdev_connect,
.disconnect = evdev_disconnect,
.fops = &evdev_fops,
.minor = EVDEV_MINOR_BASE,
.name = "evdev",
.id_table = evdev_ids,
};

先有个印象,后面用到的时候再细讲。

916行,调用input_register_handler函数注册handler,这是input core里的函数,定义如下:

 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 (handler->fops != NULL) {
if (input_table[handler->minor >> ]) {
retval = -EBUSY;
goto out;
}
input_table[handler->minor >> ] = handler;
} list_add_tail(&handler->node, &input_handler_list); list_for_each_entry(dev, &input_dev_list, node)
input_attach_handler(dev, handler); input_wakeup_procfs_readers(); out:
mutex_unlock(&input_mutex);
return retval;
}

1846行,初始化用来连接handle的链表。

1848行,if条件成立,1849行,handler->minor的值为EVDEV_MINOR_BASE,即64。input_table是一个struct input_handler类型的指针数组,定义如下:

00000047 static struct input_handler *input_table[8];

handler->minor右移5位后的值为2,因此这里判断input_table[2]的值是否以0,因为是第一次进来,显然是为0的。

1853行,将input_table[2]指向此handler。

1856行,将handler加入到input_handler_list链表的尾部。

1858、1859行,很眼熟是吧,没错,之前说过的,只不过这里是遍历的是input_dev_list这条链表,而在input_register_device函数中遍历的是input_handler_list这条链表。这表明一个Input设备可以有多个handler,一个handler也可以依附多个Input设备。这里有必要把input_attach_handler函数的代码再贴一遍:

 static int input_attach_handler(struct input_dev *dev, struct input_handler *handler)
{
const struct input_device_id *id;
int error; id = input_match_device(handler, dev);
if (!id)
return -ENODEV; error = handler->connect(handler, dev, id);
if (error && error != -ENODEV)
printk(KERN_ERR
"input: failed to attach handler %s to device %s, "
"error: %d\n",
handler->name, kobject_name(&dev->dev.kobj), error); return error;
}

因为evdev.c能够匹配使有的Input设备,至于为什么可以,在讲input_match_device函数时已经讲过了,忘记了的话可以回去看看,所以会执行849行的connect函数,实质上就是evdev.c里的evdev_connect函数,下面看它的定义:

 static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
const struct input_device_id *id)
{
struct evdev *evdev;
int minor;
int error; for (minor = ; minor < EVDEV_MINORS; minor++)
if (!evdev_table[minor])
break; if (minor == EVDEV_MINORS) {
printk(KERN_ERR "evdev: no more free evdev devices\n");
return -ENFILE;
} evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL);
if (!evdev)
return -ENOMEM; INIT_LIST_HEAD(&evdev->client_list);
spin_lock_init(&evdev->client_lock);
mutex_init(&evdev->mutex);
init_waitqueue_head(&evdev->wait); dev_set_name(&evdev->dev, "event%d", minor);
evdev->exist = true;
evdev->minor = minor; evdev->handle.dev = input_get_device(dev);
evdev->handle.name = dev_name(&evdev->dev);
evdev->handle.handler = handler;
evdev->handle.private = evdev; evdev->dev.devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor);
evdev->dev.class = &input_class;
evdev->dev.parent = &dev->dev;
evdev->dev.release = evdev_free;
device_initialize(&evdev->dev); error = input_register_handle(&evdev->handle);
if (error)
goto err_free_evdev; error = evdev_install_chrdev(evdev);
if (error)
goto err_unregister_handle; error = device_add(&evdev->dev);
if (error)
goto err_cleanup_evdev; return ; err_cleanup_evdev:
evdev_cleanup(evdev);
err_unregister_handle:
input_unregister_handle(&evdev->handle);
err_free_evdev:
put_device(&evdev->dev);
return error;
} 827行,struct evdev的定义: struct evdev {
int open;
int minor;
struct input_handle handle;
wait_queue_head_t wait;
struct evdev_client *grab;
struct list_head client_list;
spinlock_t client_lock; /* protects client_list */
struct mutex mutex;
struct device dev;
bool exist;
};

27行,open,当用户open此设备时,open的值加1。

28行,minor,次设备号,主设备都一样,用次设备号来区别不同的设备。

29行,handle,很熟悉了。

30行,wait,等待队列。

31行,grab,可以为evdev实例指定一个struct evdev_client实例,这样在传递Input消息时就只会传递给这一个struct evdev_client实例,而不会传递给所有的struct evdev_client实例。每open一次就会生成一个struct evdev_client实例。

32行,client_list,用来把所有的struct client_list实例连接在一起。

33、34行,同步相关的锁。

35行,dev,用来嵌入到设备模型中。

36行,exist,struct evdev被成功实例化后,exist的值就为true。

下面看struct evdev_client的定义:

 struct evdev_client {
int head;
int tail;
spinlock_t buffer_lock; /* protects access to buffer, head and tail */
struct fasync_struct *fasync;
struct evdev *evdev;
struct list_head node;
int bufsize;
struct input_event buffer[];
};

40、41行,作为环形缓冲区的索引值,环形缓冲区就是用来存储Input事件消息的。

42行,buffer_lock,缓冲区的锁。

43行,fasync,异步通知相关的。

44行,evdev,所属的struct evdev实例。

45行,node,作为节点链入struct evdev实例所形成的链表中。

46行,bufsize,环形缓冲区的长度。

47行,buffer,struct input_event类型的数组,也就是环形缓冲区,数组长度可变。

下面看struct input_event,在include/linux/input.h中定义的:

 struct input_event {
struct timeval time;
__u16 type;
__u16 code;
__s32 value;
};

27行,time,消息产生的时间。

28行,type,消息的类型。

29行,code,消息的值,对于按键事件的话,就对应键盘上的按键。

30行,value,对于本文来说,表示IO电平的取反值。

回到evdev_connect函数,831至833行,evdev_table是一个struct evdev类型的数组,定义如下:

 static struct evdev *evdev_table[EVDEV_MINORS];

其中EVDEV_MINORS的值为32。

那么831至833行的意思就很明显了,就是从evdev_table数组中找到第一个值为0的元素,这样minor就表示这个元素在evdev_table数组中的索引值,或者说下标值。

835至838行,如果minor等于EVDEV_MINORS,就表示evdev_table数组溢出了,不能往下走了,返回出错吧。

840至842行,为struct evdev实例分配内存。

844至847行,一些初始化。

850行,evdev->exist = true,和之前说的一致。

851行,记录下次设备号。

853至862行,注意一下858行,生成设备号,主设备号为INPUT_MAJOR,即13,次设备号为EVDEV_MINOR_BASE + minor,EVDEV_MINOR_BASE的值为64,就是说次设备号是从64开始往上递增的。

864行,注册handle,input_register_handle函数的定义为:

 int input_register_handle(struct input_handle *handle)
{
struct input_handler *handler = handle->handler;
struct input_dev *dev = handle->dev;
int error; /*
00001947 * We take dev->mutex here to prevent race with
00001948 * input_release_device().
00001949 */
error = mutex_lock_interruptible(&dev->mutex);
if (error)
return error; /*
00001955 * Filters go to the head of the list, normal handlers
00001956 * to the tail.
00001957 */
if (handler->filter)
list_add_rcu(&handle->d_node, &dev->h_list);
else
list_add_tail_rcu(&handle->d_node, &dev->h_list); mutex_unlock(&dev->mutex); /*
00001966 * Since we are supposed to be called from ->connect()
00001967 * which is mutually exclusive with ->disconnect()
00001968 * we can't be racing with input_unregister_handle()
00001969 * and so separate lock is not needed here.
00001970 */
list_add_tail_rcu(&handle->h_node, &handler->h_list); if (handler->start)
handler->start(handle); return ;
}

1958行,if条件不成立,所以执行1961行,将handle加入到Input设备的h_list链表的尾部。

1971行,将handle加入到handler的h_list链表的尾部。

1973行,如果handler有定义start函数,那么就调用之,显然,对于evdev.c这个handler是没有定义start函数的。

回到evdev_connect函数,868至870行,调用evdev_install_chrdev函数,定义如下:

 static int evdev_install_chrdev(struct evdev *evdev)
{
/*
00000776 * No need to do any locking here as calls to connect and
00000777 * disconnect are serialized by the input core
00000778 */
evdev_table[evdev->minor] = evdev;
return ;
}

很简单,就是将evdev_table数组对应的元素指向该struct evdev实例。

872行,将dev加入到设备模型中。

至此evdev.c的初始化过程完毕。现在系统里已经具备Input设备和Input事件驱动程序,Input消息产生后应该就能到达事件驱动程序的缓冲区,等着用户程序将Input消息读取出来。下面就分析这一个过程。

首先应该知道Input消息产生的源头是按键的按下,按键按下后会触发中断,然后进入中断处理程序,所以应该从按键的中断处理程序看起,就是drivers/input/keyboard/gpio_keys.c里的gpio_keys_isr函数,它的定义如下:

 static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
{
struct gpio_button_data *bdata = dev_id;
struct gpio_keys_button *button = bdata->button; BUG_ON(irq != gpio_to_irq(button->gpio)); if (bdata->timer_debounce)
mod_timer(&bdata->timer,
jiffies + msecs_to_jiffies(bdata->timer_debounce));
else
schedule_work(&bdata->work); return IRQ_HANDLED;
}

353行,如果按键需要延时消抖的话,那么就启动定时器,否则调用357行的schedule_work函数,将work投入到工作队列里,这样,在一段时间过后work指定的函数将会被执行,这里假设是第一种情况,那么下面看定时器的超时处理函数gpio_keys_timer的定义:

 static void gpio_keys_timer(unsigned long _data)
{
struct gpio_button_data *data = (struct gpio_button_data *)_data; schedule_work(&data->work);
}

同样是调用schedule_work函数。接下来要看的是work指定的函数gpio_keys_work_func。

 static void gpio_keys_work_func(struct work_struct *work)
{
struct gpio_button_data *bdata =
container_of(work, struct gpio_button_data, work); gpio_keys_report_event(bdata);
}

336行,gpio_keys_report_event函数,前面说这个函数放到后面再说,现在就放到这里说,看内核代码需要保持一颗清醒的头脑哈。下面看它的定义:

 static void gpio_keys_report_event(struct gpio_button_data *bdata)
{
struct gpio_keys_button *button = bdata->button;
struct input_dev *input = bdata->input;
unsigned int type = button->type ?: EV_KEY;
int state = (gpio_get_value(button->gpio) ? : ) ^ button->active_low; input_event(input, type, button->code, !!state);
input_sync(input);
}

325行,调用gpio_get_value函数获取IO口的电平并将它异或上active_low,假设active_low的值为1,按键按下时IO的电平一般来说是低电平,即0,那么此时state的值就为1(异或:同为0,异为1)。

327行,调用input_event函数,向input core报告按键事件,在drivers/input/input.c中定义,如下:

 void input_event(struct input_dev *dev,
unsigned int type, unsigned int code, int value)
{
unsigned long flags; if (is_event_supported(type, dev->evbit, EV_MAX)) { spin_lock_irqsave(&dev->event_lock, flags);
add_input_randomness(type, code, value);
input_handle_event(dev, type, code, value);
spin_unlock_irqrestore(&dev->event_lock, flags);
}
}

351行,is_event_supported函数的定义:

 static inline int is_event_supported(unsigned int code,
unsigned long *bm, unsigned int max)
{
return code <= max && test_bit(code, bm);
}

函数返回1的条件是:事件类型的值不能大于input core支持的最大值并且Input设备的事件位图中相应的位已经置1。

回到input_event函数,假设if的条件成立,354行,随机数相关,没怎么了解并且对后面的分析没有影响,因此飘过。

355行,input_handle_event,这函数比较重要,看它的定义:

 static void input_handle_event(struct input_dev *dev,
unsigned int type, unsigned int code, int value)
{
int disposition = INPUT_IGNORE_EVENT; switch (type) { case EV_SYN:
switch (code) {
case SYN_CONFIG:
disposition = INPUT_PASS_TO_ALL;
break; case SYN_REPORT:
if (!dev->sync) {
dev->sync = true;
disposition = INPUT_PASS_TO_HANDLERS;
}
break;
case SYN_MT_REPORT:
dev->sync = false;
disposition = INPUT_PASS_TO_HANDLERS;
break;
}
break; case EV_KEY:
if (is_event_supported(code, dev->keybit, KEY_MAX) &&
!!test_bit(code, dev->key) != value) { if (value != ) {
__change_bit(code, dev->key);
if (value)
input_start_autorepeat(dev, code);
else
input_stop_autorepeat(dev);
} disposition = INPUT_PASS_TO_HANDLERS;
}
break; case EV_SW:
if (is_event_supported(code, dev->swbit, SW_MAX) &&
!!test_bit(code, dev->sw) != value) { __change_bit(code, dev->sw);
disposition = INPUT_PASS_TO_HANDLERS;
}
break; case EV_ABS:
if (is_event_supported(code, dev->absbit, ABS_MAX))
disposition = input_handle_abs_event(dev, code, &value); break; case EV_REL:
if (is_event_supported(code, dev->relbit, REL_MAX) && value)
disposition = INPUT_PASS_TO_HANDLERS; break; case EV_MSC:
if (is_event_supported(code, dev->mscbit, MSC_MAX))
disposition = INPUT_PASS_TO_ALL; break; case EV_LED:
if (is_event_supported(code, dev->ledbit, LED_MAX) &&
!!test_bit(code, dev->led) != value) { __change_bit(code, dev->led);
disposition = INPUT_PASS_TO_ALL;
}
break; case EV_SND:
if (is_event_supported(code, dev->sndbit, SND_MAX)) { if (!!test_bit(code, dev->snd) != !!value)
__change_bit(code, dev->snd);
disposition = INPUT_PASS_TO_ALL;
}
break; case EV_REP:
if (code <= REP_MAX && value >= && dev->rep[code] != value) {
dev->rep[code] = value;
disposition = INPUT_PASS_TO_ALL;
}
break; case EV_FF:
if (value >= )
disposition = INPUT_PASS_TO_ALL;
break; case EV_PWR:
disposition = INPUT_PASS_TO_ALL;
break;
} if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)
dev->sync = false; if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)
dev->event(dev, type, code, value); if (disposition & INPUT_PASS_TO_HANDLERS)
input_pass_event(dev, type, code, value);
}

220至317行,又是一个排比句,根据不同的事件类型执行相应的处理。这里由于type的值为EV_KEY,所以会执行242至255行之间的代码。

242行,if的第一个条件肯定是满足的。

243行,test_bit就是检查dev->key这个数组里的某一位的值,因为在初始化Input设备时这个数组全部被清0,所以test_bit的返回值为0,而value的值为1,因此第二个条件也满足,执行245行,if条件也满足,246行,__change_bit改变dev->key数组里对应位的值,即原来为1的话现在就为0,原来为0的话现在就为1。

247至250行,autorepeat相关的,这里没有用到这个功能,略过。

253行,disposition = INPUT_PASS_TO_HANDLERS,然后就跳出switch,到达319行,很明显,319、322行的if条件都不满足,而325行的if条件满足,所以执行326行的input_pass_event函数。