您的位置:首页 > 运维架构 > Linux

【转】LINUX设备驱动之输入子系统(一)

2011-08-24 15:55 309 查看
Eric Fang 2010-02-03

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

本站分析linux内核源码,版本号为2.6.32.3

转载请注明出处:http://ericfang.cublog.cn/

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

在前面键盘驱动的分析中已经接触到了输入子系统,本文将结合键盘驱动,系统分析输入子系统。

回想一下,在设备驱动匹配成功时,创建了一个input_dev并注册到输入子系统;在键盘中断处理例程中向输入子系统上报事件。

输入子系统是所有I/O设备驱动的中间层,如何为下层众多各式各样的输入设备提供接口以及为上层提供了一个统一的界面?

根据内核代码,输入子系统中存在两个链表:input_dev_list、input_handler_list,当注册一个input_dev时就会把它挂到input_dev_list上,然后去匹配input_handler_list上的input_handler,相反,当注册一个input_handler时就会把它挂到input_handler_list上,然后去匹配input_dev_list上的input_dev,匹配成功时就会调用该handler的connect函数,该函数一般会创建和注册一个input_handle,这个input_handle中包含了input_dev和input_handler相关的信息,这样当下层向输入子系统上报事件时就可以通过input_handle找到相应的input_handler并调用相关函数,进一步为上次提供服务。

下面将一步一步详细的分析这个过程。

一.Input设备的注册

Input设备注册的接口函数为:input_register_device,不过在注册Input设备,前必须先创建一个Input设备,可以静态定义一个Input设备然后自行初始化它,也可以调用input_allocate_device来创建一个Input设备(回想一下,在键盘驱动分析的代码中就是调用这个函数的),看一下这个函数:

1389 struct input_dev *input_allocate_device(void)

1390 {

1391 struct input_dev *dev;

1392

1393 dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);

1394 if (dev) {

1395 dev->dev.type = &input_dev_type;

1396 dev->dev.class = &input_class;

1397 device_initialize(&dev->dev);

1398 mutex_init(&dev->mutex);

1399 spin_lock_init(&dev->event_lock);

1400 INIT_LIST_HEAD(&dev->h_list);

1401 INIT_LIST_HEAD(&dev->node);

1402

1403 __module_get(THIS_MODULE);

1404 }

1405

1406 return dev;

1407 }

input_dev结构如下:

1072 struct input_dev {

1073 const char *name;

1074 const char *phys;

1075 const char *uniq;

1076 struct input_id id;

1077

1078 unsigned long evbit[BITS_TO_LONGS(EV_CNT)];

1079 unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];

1080 unsigned long relbit[BITS_TO_LONGS(REL_CNT)];

1081 unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];

1082 unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];

1083 unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];

1084 unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];

1085 unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];

1086 unsigned long swbit[BITS_TO_LONGS(SW_CNT)];

1087

1088 unsigned int keycodemax;

1089 unsigned int keycodesize;

1090 void *keycode;

1091 int (*setkeycode)(struct input_dev *dev, int scancode, int keycode);

1092 int (*getkeycode)(struct input_dev *dev, int scancode, int *keycode);

1093

1094 struct ff_device *ff;

1095

1096 unsigned int repeat_key;

1097 struct timer_list timer;

1098

1099 int sync;

1100

1101 int abs[ABS_MAX + 1];

1102 int rep[REP_MAX + 1];

1103

1104 unsigned long key[BITS_TO_LONGS(KEY_CNT)];

1105 unsigned long led[BITS_TO_LONGS(LED_CNT)];

1106 unsigned long snd[BITS_TO_LONGS(SND_CNT)];

1107 unsigned long sw[BITS_TO_LONGS(SW_CNT)];

1108

1109 int absmax[ABS_MAX + 1];

1110 int absmin[ABS_MAX + 1];

1111 int absfuzz[ABS_MAX + 1];

1112 int absflat[ABS_MAX + 1];

1113 int absres[ABS_MAX + 1];

1114

1115 int (*open)(struct input_dev *dev);

1116 void (*close)(struct input_dev *dev);

1117 int (*flush)(struct input_dev *dev, struct file *file);

1118 int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);

1119

1120 struct input_handle *grab;

1121

1122 spinlock_t event_lock;

1123 struct mutex mutex;

1124

1125 unsigned int users;

1126 bool going_away;

1127

1128 struct device dev;

1129

1130 struct list_head h_list;

1131 struct list_head node;

1132 };

和前面分析的其他设备的创建一样,input_allocate_device函数为input_dev分配内存空间,初始化其内嵌的device,这里还初始化了input_dev结构中的h_list和node链表头,node是用于将该input_dev挂到input_dev_list上,而h_list指向的量表用于存放input_handle,在后面分析将会看到这点。

input_dev结构里边众多的其他字段先不理会,等用到时再做分析。

创建了input_dev后,根据具体的驱动程序情况对input_dev进行相应的设置(如在键盘驱动的分析中,调用了atkbd_set_device_attrs函数等)后,就可以调用input_register_device函数向输入子系统注册input_dev了,函数如下:

1503 int input_register_device(struct input_dev *dev)

1504 {

1505 static atomic_t input_no = ATOMIC_INIT(0);

1506 struct input_handler *handler;

1507 const char *path;

1508 int error;

1509

1510 __set_bit(EV_SYN, dev->evbit);

1511

1512 /*

1513 * If delay and period are pre-set by the driver, then autorepeating

1514 * is handled by the driver itself and we don't do it in input.c.

1515 */

1516

1517 init_timer(&dev->timer);

1518 if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) {

1519 dev->timer.data = (long) dev;

1520 dev->timer.function = input_repeat_key;

1521 dev->rep[REP_DELAY] = 250;

1522 dev->rep[REP_PERIOD] = 33;

1523 }

1524

1525 if (!dev->getkeycode)

1526 dev->getkeycode = input_default_getkeycode;

1527

1528 if (!dev->setkeycode)

1529 dev->setkeycode = input_default_setkeycode;

1530

1531 dev_set_name(&dev->dev, "input%ld",

1532 (unsigned long) atomic_inc_return(&input_no) - 1);

1533

1534 error = device_add(&dev->dev);

1535 if (error)

1536 return error;

1537

1538 path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);

1539 printk(KERN_INFO "input: %s as %s\n",

1540 dev->name ? dev->name : "Unspecified device", path ? path : "N/A");

1541 kfree(path);

1542

1543 error = mutex_lock_interruptible(&input_mutex);

1544 if (error) {

1545 device_del(&dev->dev);

1546 return error;

1547 }

1548

1549 list_add_tail(&dev->node, &input_dev_list);

1550

1551 list_for_each_entry(handler, &input_handler_list, node)

1552 input_attach_handler(dev, handler);

1553

1554 input_wakeup_procfs_readers();

1555

1556 mutex_unlock(&input_mutex);

1557

1558 return 0;

1559 }

1525~1529行,如果调用input_register_device前没有为input_dev的getkeycode和setkeycode函数指针设值,则用input_default_getkeycode和input_default_setkeycode赋给他们,getkeycode和setkeycode是在上报事件的处理中用于获得和设置相应的键值,看下这两个函数:

0560 static int input_default_getkeycode(struct input_dev *dev,

0561 int scancode, int *keycode)

0562 {

0563 if (!dev->keycodesize)

0564 return -EINVAL;

0565

0566 if (scancode >= dev->keycodemax)

0567 return -EINVAL;

0568

0569 *keycode = input_fetch_keycode(dev, scancode);

0570

0571 return 0;

0572 }

0546 static int input_fetch_keycode(struct input_dev *dev, int scancode)

0547 {

0548 switch (dev->keycodesize) {

0549 case 1:

0550 return ((u8 *)dev->keycode)[scancode];

0551

0552 case 2:

0553 return ((u16 *)dev->keycode)[scancode];

0554

0555 default:

0556 return ((u32 *)dev->keycode)[scancode];

0557 }

0558 }

0574 static int input_default_setkeycode(struct input_dev *dev,

0575 int scancode, int keycode)

0576 {

0577 int old_keycode;

0578 int i;

0579

0580 if (scancode >= dev->keycodemax)

0581 return -EINVAL;

0582

0583 if (!dev->keycodesize)

0584 return -EINVAL;

0585

0586 if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8)))

0587 return -EINVAL;

0588

0589 switch (dev->keycodesize) {

0590 case 1: {

0591 u8 *k = (u8 *)dev->keycode;

0592 old_keycode = k[scancode];

0593 k[scancode] = keycode;

0594 break;

0595 }

0596 case 2: {

0597 u16 *k = (u16 *)dev->keycode;

0598 old_keycode = k[scancode];

0599 k[scancode] = keycode;

0600 break;

0601 }

0602 default: {

0603 u32 *k = (u32 *)dev->keycode;

0604 old_keycode = k[scancode];

0605 k[scancode] = keycode;

0606 break;

0607 }

0608 }

0609

0610 clear_bit(old_keycode, dev->keybit);

0611 set_bit(keycode, dev->keybit);

0612

0613 for (i = 0; i < dev->keycodemax; i++) {

0614 if (input_fetch_keycode(dev, i) == old_keycode) {

0615 set_bit(old_keycode, dev->keybit);

0616 break; /* Setting the bit twice is useless, so break */

0617 }

0618 }

0619

0620 return 0;

0621 }

不难看出,如上面分析一样input_default_getkeycode通过scancode索引在键值表中查到相应的值并赋给*keycode;input_default_setkeycode函数则重新设置输入索引的键值表的值。

接着看input_register_device函数,第1534行调用device_add函数注册input_dev内嵌的device,获得互斥锁后,1549行调用list_add_tail(&dev->node, &input_dev_list)将该input_dev挂到input_dev_list链表上。

接着1551~1552行扫面input_handler_list上的每个handler,用input_attach_handler函数进行dev和handler的匹配,这里input_handler_list上的handler是什么时候挂上去的,我们在后面再分析,继续分析input_attach_handler函数:

0739 static int input_attach_handler(struct input_dev *dev, struct input_handler *handler)

0740 {

0741 const struct input_device_id *id;

0742 int error;

0743

0744 if (handler->blacklist && input_match_device(handler->blacklist, dev))

0745 return -ENODEV;

0746

0747 id = input_match_device(handler->id_table, dev);

0748 if (!id)

0749 return -ENODEV;

0750

0751 error = handler->connect(handler, dev, id);

0752 if (error && error != -ENODEV)

0753 printk(KERN_ERR

0754 "input: failed to attach handler %s to device %s, "

0755 "error: %d\n",

0756 handler->name, kobject_name(&dev->dev.kobj), error);

0757

0758 return error;

0759 }

第0744行先匹配blacklist和dev,如果匹配成功则返回-ENODEV,这里明显屏蔽掉了blacklist列表上的设备,即使其在handler->id_table中能匹配成功。

第0747行匹配handler->id_table 和dev,如果匹配成功则调用handler的connect函数。

input_device_id结构定义如下:

0312 struct input_device_id {

0313

0314 kernel_ulong_t flags;

0315

0316 __u16 bustype;

0317 __u16 vendor;

0318 __u16 product;

0319 __u16 version;

0320

0321 kernel_ulong_t evbit[INPUT_DEVICE_ID_EV_MAX / BITS_PER_LONG + 1];

0322 kernel_ulong_t keybit[INPUT_DEVICE_ID_KEY_MAX / BITS_PER_LONG + 1];

0323 kernel_ulong_t relbit[INPUT_DEVICE_ID_REL_MAX / BITS_PER_LONG + 1];

0324 kernel_ulong_t absbit[INPUT_DEVICE_ID_ABS_MAX / BITS_PER_LONG + 1];

0325 kernel_ulong_t mscbit[INPUT_DEVICE_ID_MSC_MAX / BITS_PER_LONG + 1];

0326 kernel_ulong_t ledbit[INPUT_DEVICE_ID_LED_MAX / BITS_PER_LONG + 1];

0327 kernel_ulong_t sndbit[INPUT_DEVICE_ID_SND_MAX / BITS_PER_LONG + 1];

0328 kernel_ulong_t ffbit[INPUT_DEVICE_ID_FF_MAX / BITS_PER_LONG + 1];

0329 kernel_ulong_t swbit[INPUT_DEVICE_ID_SW_MAX / BITS_PER_LONG + 1];

0330

0331 kernel_ulong_t driver_info;

0332 };

接着看这个匹配过程:

0700 static const struct input_device_id *input_match_device(const struct input_device_id *id,

0701 struct input_dev *dev)

0702 {

0703 int i;

0704

0705 for (; id->flags || id->driver_info; id++) {

0706

0707 if (id->flags & INPUT_DEVICE_ID_MATCH_BUS)

0708 if (id->bustype != dev->id.bustype)

0709 continue;

0710

0711 if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR)

0712 if (id->vendor != dev->id.vendor)

0713 continue;

0714

0715 if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT)

0716 if (id->product != dev->id.product)

0717 continue;

0718

0719 if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION)

0720 if (id->version != dev->id.version)

0721 continue;

0722

0723 MATCH_BIT(evbit, EV_MAX);

0724 MATCH_BIT(keybit, KEY_MAX);

0725 MATCH_BIT(relbit, REL_MAX);

0726 MATCH_BIT(absbit, ABS_MAX);

0727 MATCH_BIT(mscbit, MSC_MAX);

0728 MATCH_BIT(ledbit, LED_MAX);

0729 MATCH_BIT(sndbit, SND_MAX);

0730 MATCH_BIT(ffbit, FF_MAX);

0731 MATCH_BIT(swbit, SW_MAX);

0732

0733 return id;

0734 }

0735

0736 return NULL;

0737 }

只要设置了id->driver_info ,for循环就会执行,id->flags标示按需要匹配的字段,0723~0731行MATCH_BIT部分是必须匹配部分,看看这个宏定义:

0693 #define MATCH_BIT(bit, max) \

0694 for (i = 0; i < BITS_TO_LONGS(max); i++) \

0695 if ((id->bit[i] & dev->bit[i]) != id->bit[i]) \

0696 break; \

0697 if (i != BITS_TO_LONGS(max)) \

0698 continue;

可以看出如果id->bit[i]有设值,要匹配成功dev->bit[i]也必须设置相应的值;如果id->bit[i]没设值,则该项不需要匹配。

接着input_register_device 函数第1554行input_wakeup_procfs_readers()函数:

0768 static inline void input_wakeup_procfs_readers(void)

0769 {

0770 input_devices_state++;

0771 wake_up(&input_devices_poll_wait);

0772 }

自增input_devices_state并唤醒在文件操作poll上阻塞的进程,input_devices_state是用于更新相应文件file的f_version。

input_register_device 函数接着释放信号后返回。

Input设备的注册就分析到这里。

接下一篇文章。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: