看到这里,有的哥们要生气了,怎么我们美丽的input设备被嫁出去,居然一下就忽悠过去了,都不详细描述一下她的具体被嫁过程,她到底嫁给哪个handler了?又是怎么相中的?相中后他们两又一起做了些什么?好了,为了满足这位兄弟的欲望,我们来详细阅读一下前面那个input_attach_handler(dev, handler)函数。就是在这个函数中,发生了所有该发生的事情。
static int input_attach_handler(struct input_dev *dev, struct input_handler *handler)
{
1 const struct input_device_id *id;
2 int error;
3 if (handler->blacklist && input_match_device(handler->blacklist, dev))
4 return -ENODEV;
5 id = input_match_device(handler->id_table, dev);
6 if (!id)
7 return -ENODEV;
8 error = handler->connect(handler, dev, id);
9 if (error && error != -ENODEV)
10 printk(KERN_ERR
11 "input: failed to attach handler %s to device %s, "
12 "error: %d/n",
13 handler->name, kobject_name(&dev->dev.kobj), error);
14 return error;
}
1行,定义一个结构体struct input_device_id的变量id。该结构体是属于handler的,它为我们的handler提供了一套择偶标准。不在标准以内了,一律拒之门外,不管你是何方妖女。
2行,定义一个整形变量 error,后面要用得到。
3行,我们的handler应该来头不小,不是富一代,也至少是个富二代。不仅有前面那一堆择偶标准,还来一个黑名单列表,对于那些在黑名单以内的设备,比如说好不容易打听到一女的,电话一通,那头突然冒出凤姐的声音。别说handler兄,对于平凡的我估计也接受不了,所以直接枪毙。如果不是凤姐,证明你不是在黑名单以内,哪怕你身高只有1米48,哪怕你有一张大嘴,哪怕你还外加一口龅牙,咱好歹给个面子先见个面聊聊,然后找理由说你不符合我的择偶标准。
4行,好了,我们的input设备美少女开始和handler兄首次见面,然后互相匹配双方信息,深入input_match_device中你会发现,最终的主动权还是在我们的handler兄这里。
static const struct input_device_id *input_match_device(const struct input_device_id *id,
struct input_dev *dev)
{
int i;
for (; id->flags || id->driver_info; id++) {
if (id->flags & INPUT_DEVICE_ID_MATCH_BUS)
if (id->bustype != dev->id.bustype)
continue;
if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR)
if (id->vendor != dev->id.vendor)
continue;
if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT)
if (id->product != dev->id.product)
continue;
if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION)
if (id->version != dev->id.version)
continue;
MATCH_BIT(evbit, EV_MAX);
MATCH_BIT(keybit, KEY_MAX);
MATCH_BIT(relbit, REL_MAX);
MATCH_BIT(absbit, ABS_MAX);
MATCH_BIT(mscbit, MSC_MAX);
MATCH_BIT(ledbit, LED_MAX);
MATCH_BIT(sndbit, SND_MAX);
MATCH_BIT(ffbit, FF_MAX);
MATCH_BIT(swbit, SW_MAX);
return id;
}
return NULL;
}
看到没,只要我们的handler兄有某一个flag设置了,你的input设备对应的条件必须具备,否则,咱俩玩完了。深入MATCH_BIT宏:
#define MATCH_BIT(bit, max) /
for (i = 0; i < BITS_TO_LONGS(max); i++) /
if ((id->bit[i] & dev->bit[i]) != id->bit[i]) /
break; /
if (i != BITS_TO_LONGS(max)) /
continue;
还是这样,只要我们的handler兄的的id中evbit、keybit等等中的某一位设置了,input设备美眉也得具备这个条件(还记不记得我们在第二节中用set_bit(EV_ABS, akm->input_dev->evbit);为我们这个input 设备美眉制造了一个条件),否则,还是枪毙。于是乎,我开始怀疑:写linux代码的这些兄弟们原来比春哥还纯爷们,所有的想来和他相亲的女的必须要服从我这些苛刻的条件,哪怕有一个不符合,你别想和他好。不过人家确实有那个资本,能够在linux内核的世界里驰骋的人一般不简单,像国内这方面的人估计还找不上几个。还好的是,我们的input设备美眉可以遍历input_handler_list上所有的handler兄,就不相信没有一个条件稍微要求低点的。那么请问条件要求很低的这样的handler现在哪里有呢?哎!这位美眉你运气真好,这里正好有一个。
看看这位仁兄的择偶标准:
static const struct input_device_id evdev_ids[] = {
{ .driver_info = 1 }, /* Matches all devices */
{ }, /* Terminating zero entry */
};
他就一个条件,而且还是一个可以说不是条件的条件,为什么会这么说呢,请继续回到我们的input_match_device函数中,看到了吗?某些兄弟可能会惊奇的大呼一声,我的妈呀!他确实是没有要求,一没设置flag,而没设置evbit、keybit等等。所以…所以…这哥们其实最有福了,就是那些所有找不到男朋友的input设备美眉,都会和他好上,(当然凤姐是看不上他的,因为他不是北大清华的经济学硕士,他长得没有金城武帅,他身高也没有1米8……)所以就出现了传说中的一夫多妻制。
这里我们这个input设备美眉因为某些条件不够,(这里申明一下,不是我们的这个input设备条件不好,是那些其他的handler针对性实在太强了,比如说,他只要嘴角下方有颗美人痣,笑起来像张曼玉,并且还得有着像张馨予一样身材的,或者是年纪20岁左右、巨蟹座的、没谈过恋爱、还长着一张张柏芝的脸的)所以也和我们这个evdev_handler结合了。evdev_handler兄偷偷地笑了,骂其他的哥们真傻,又轻松搞定一妞。
6、7行,没找到,则返回。
8行,既然找到了,就发生上关系了,马上调用我们evdev handler中的connect函数进行联姻。在此函数中,又发生什么了呢,这个我们留到下节中讲。
9-13行,如果匹配不成功,显示打印出来。
14行,打道回府。