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

    技术2025-09-16  70

    Eric Fang  2010-02-03

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

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

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

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

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

     

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

     

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

     

    根据内核代码,输入子系统中存在两个链表:input_dev_listinput_handler_list,当注册一个input_dev时就会把它挂到input_dev_list上,然后去匹配input_handler_list上的input_handler,相反,当注册一个input_handler时就会把它挂到input_handler_list上,然后去匹配input_dev_list上的input_dev,匹配成功时就会调用该handlerconnect函数,该函数一般会创建和注册一个input_handle,这个input_handle中包含了input_devinput_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_listnode链表头,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_devgetkeycodesetkeycode函数指针设值,则用input_default_getkeycodeinput_default_setkeycode赋给他们,getkeycodesetkeycode是在上报事件的处理中用于获得和设置相应的键值,看下这两个函数:

    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索引在键值表中查到相应的值并赋给*keycodeinput_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函数进行devhandler的匹配,这里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行先匹配blacklistdev,如果匹配成功则返回-ENODEV,这里明显屏蔽掉了blacklist列表上的设备,即使其在handler->id_table中能匹配成功。

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

    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~0731MATCH_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 函数第1554input_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是用于更新相应文件filef_version

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

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

     

    接下一篇文章。

    最新回复(0)