免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1636 | 回复: 0
打印 上一主题 下一主题

LINUX设备驱动之输入子系统(一) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-02-03 10:35 |只看该作者 |倒序浏览
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 > (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 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
0695                            if ((id->bit & dev->bit) != id->bit) \
0696                                   break; \
0697                     if (i != BITS_TO_LONGS(max)) \
0698                            continue;
可以看出如果id->bit有设值,要匹配成功dev->bit也必须设置相应的值;如果id->bit没设值,则该项不需要匹配。
接着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设备的注册就分析到这里。

接下一篇文章。


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/92745/showart_2169770.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP