看到這裡,有的哥們要生氣了,怎麼我們美麗的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行,打道回府。