二.Input handler的註冊
在Input device的註冊中存在下列疑問:
1, 匹配dev和handler時,input_handler_list上的handler是什麼時候掛上去的呢?
2, 匹配成功後會調用相應handler的connect函數,此函數做了什麼事?
帶着這兩個疑問,我們以鍵盤爲例進行分析。
在系統啓動初始化vty(vty_init函數,tty、vty部分內容將在以後分析)時會調用kbd_init()進行鍵盤初始化,kbd_init函數定義於drivers/char/keyboard.c:
1403 int __init kbd_init(void)
1404 {
1405 int i;
1406 int error;
1407
1408 for (i = 0; i < MAX_NR_CONSOLES; i++) {
1409 kbd_table[i].ledflagstate = KBD_DEFLEDS;
1410 kbd_table[i].default_ledflagstate = KBD_DEFLEDS;
1411 kbd_table[i].ledmode = LED_SHOW_FLAGS;
1412 kbd_table[i].lockstate = KBD_DEFLOCK;
1413 kbd_table[i].slockstate = 0;
1414 kbd_table[i].modeflags = KBD_DEFMODE;
1415 kbd_table[i].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
1416 }
1417
1418 error = input_register_handler(&kbd_handler);
1419 if (error)
1420 return error;
1421
1422 tasklet_enable(&keyboard_tasklet);
1423 tasklet_schedule(&keyboard_tasklet);
1424
1425 return 0;
1426 }
第1408~1416行初始化kbd_table數組,這部分與tty內容相關,以後再分析。
1418行,這裏我們終於看到調用input_register_handler函數註冊kbd_handler,kbd_handler定義如下:
1394 static struct input_handler kbd_handler = {
1395 .event = kbd_event,
1396 .connect = kbd_connect,
1397 .disconnect = kbd_disconnect,
1398 .start = kbd_start,
1399 .name = "kbd",
1400 .id_table = kbd_ids,
1401 };
我們看到id_table指向kbd_ids數組,kbd_ids定義如下:
1378 static const struct input_device_id kbd_ids[] = {
1379 {
1380 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
1381 .evbit = { BIT_MASK(EV_KEY) },
1382 },
1383
1384 {
1385 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
1386 .evbit = { BIT_MASK(EV_SND) },
1387 },
1388
1389 { }, /* Terminating entry */
1390 };
從這個id_table看到,只要input_dev設置了其evbit字段支持EV_KEY或EV_SND都會匹配到hnadler,回想一下在鍵盤驅動中創建input_dev後調用的atkbd_set_device_attrs設置input_dev的函數中有下列語句:
input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) |
BIT_MASK(EV_MSC);
說明at鍵盤的input_dev會匹配到這個hnadler。
我們接着看input_register_handler函數:
1600 int input_register_handler(struct input_handler *handler)
1601 {
1602 struct input_dev *dev;
1603 int retval;
1604
1605 retval = mutex_lock_interruptible(&input_mutex);
1606 if (retval)
1607 return retval;
1608
1609 INIT_LIST_HEAD(&handler->h_list);
1610
1611 if (handler->fops != NULL) {
1612 if (input_table[handler->minor >> 5]) {
1613 retval = -EBUSY;
1614 goto out;
1615 }
1616 input_table[handler->minor >> 5] = handler;
1617 }
1618
1619 list_add_tail(&handler->node, &input_handler_list);
1620
1621 list_for_each_entry(dev, &input_dev_list, node)
1622 input_attach_handler(dev, handler);
1623
1624 input_wakeup_procfs_readers();
1625
1626 out:
1627 mutex_unlock(&input_mutex);
1628 return retval;
1629 }
第1605行獲得互斥信號量,1609行初始化handler 的h_list字段,這個h_list指向的鏈表用於存放input_handle。
第1611~1617行,我們的kbd_handler沒有定義fops函數,所以這段代碼不會執行,不過我們還是看一下,這裏的input_table數組是一個struct input_handler結構數組,根據設備的次設備號除以32的值爲下標的元素爲input_handler爲什麼是32?輸入子系統最多支持256個設備,而input_handler結構的數組最多處理8類事件,所以分給每一類的次設備號段分配32個。
第1619行把handler鏈接到input_handler_list尾部。
第1621~1622用handler去匹配input_dev_list上的input_dev,input_attach_handler函數在上面已經分析過,再最後如果匹配成功會調用handler的connect函數,對於這個kbd_handler相應的函數爲kbd_connect,看一下這個函數:
1314 static int kbd_connect(struct input_handler *handler, struct input_dev *dev,
1315 const struct input_device_id *id)
1316 {
1317 struct input_handle *handle;
1318 int error;
1319 int i;
1320
1321 for (i = KEY_RESERVED; i < BTN_MISC; i++)
1322 if (test_bit(i, dev->keybit))
1323 break;
1324
1325 if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit))
1326 return -ENODEV;
1327
1328 handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
1329 if (!handle)
1330 return -ENOMEM;
1331
1332 handle->dev = dev;
1333 handle->handler = handler;
1334 handle->name = "kbd";
1335
1336 error = input_register_handle(handle);
1337 if (error)
1338 goto err_free_handle;
1339
1340 error = input_open_device(handle);
1341 if (error)
1342 goto err_unregister_handle;
1343
1344 return 0;
1345
1346 err_unregister_handle:
1347 input_unregister_handle(handle);
1348 err_free_handle:
1349 kfree(handle);
1350 return error;
1351 }
第1321~1326行判斷dev->keybit,如果屬於例外的情況,則不再往下走,返回-ENODEV。
第1328行,爲handle分配內存空間,1332~1334行初始化handle的部分字段。
第1336行調用input_register_handle註冊handle,看一下這個函數:
1671 int input_register_handle(struct input_handle *handle)
1672 {
1673 struct input_handler *handler = handle->handler;
1674 struct input_dev *dev = handle->dev;
1675 int error;
1676
1677 /*
1678 * We take dev->mutex here to prevent race with
1679 * input_release_device().
1680 */
1681 error = mutex_lock_interruptible(&dev->mutex);
1682 if (error)
1683 return error;
1684 list_add_tail_rcu(&handle->d_node, &dev->h_list);
1685 mutex_unlock(&dev->mutex);
1686
1687 /*
1688 * Since we are supposed to be called from ->connect()
1689 * which is mutually exclusive with ->disconnect()
1690 * we can't be racing with input_unregister_handle()
1691 * and so separate lock is not needed here.
1692 */
1693 list_add_tail(&handle->h_node, &handler->h_list);
1694
1695 if (handler->start)
1696 handler->start(handle);
1697
1698 return 0;
1699 }
第1684、1693將handle分別鏈接到dev->h_list和handler->h_list。
第1695~1696行,如果handler的start函數存在,則調用它。對於這個kbd_handler相應的函數爲kbd_start,看一下這個函數:
1364 static void kbd_start(struct input_handle *handle)
1365 {
1366 unsigned char leds = ledstate;
1367
1368 tasklet_disable(&keyboard_tasklet);
1369 if (leds != 0xff) {
1370 input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
1371 input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02));
1372 input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04));
1373 input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
1374 }
1375 tasklet_enable(&keyboard_tasklet);
1376 }
禁止keyboard_tasklet,初始化鍵盤的三個led燈及SYN_REPORT,然後啓用keyboard_tasklet,這個keyboard_tasklet也是對led燈進行操作的,函數如下
1032 DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);
1014 static void kbd_bh(unsigned long dummy)
1015 {
1016 struct list_head *node;
1017 unsigned char leds = getleds();
1018
1019 if (leds != ledstate) {
1020 list_for_each(node, &kbd_handler.h_list) {
1021 struct input_handle *handle = to_handle_h(node);
1022 input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
1023 input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02));
1024 input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04));
1025 input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
1026 }
1027 }
1028
1029 ledstate = leds;
1030 }
input_register_handle函數返回後,第1340行調用input_open_device函數,這個函數執行後相應的handle就能接受設備上報的事件。函數如下:
0421 int input_open_device(struct input_handle *handle)
0422 {
0423 struct input_dev *dev = handle->dev;
0424 int retval;
0425
0426 retval = mutex_lock_interruptible(&dev->mutex);
0427 if (retval)
0428 return retval;
0429
0430 if (dev->going_away) {
0431 retval = -ENODEV;
0432 goto out;
0433 }
0434
0435 handle->open++;
0436
0437 if (!dev->users++ && dev->open)
0438 retval = dev->open(dev);
0439
0440 if (retval) {
0441 dev->users--;
0442 if (!--handle->open) {
0443 /*
0444 * Make sure we are not delivering any more events
0445 * through this handle
0446 */
0447 synchronize_rcu();
0448 }
0449 }
0450
0451 out:
0452 mutex_unlock(&dev->mutex);
0453 return retval;
0454 }
增加handle的open計數,如果handle->dev->users不爲0,則自增1,如果爲0並且handle->dev的open函數存在則會調用它,對於前面分析的atkbd,相應的handle->dev的open函數不存在。
至此,input handler和input handler的註冊都分析完了,接着將分析事件處理部分內容。