Eric Fang2010-02-03
--------------------------------------------------------------
本站分析linux内核源码,版本号为2.6.32.3
--------------------------------------------------------------
接上一篇文章继续分析。
二.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:
1403int __init kbd_init(void)
1404{
1405int i;
1406int error;
1407
1408for (i = 0; i < MAX_NR_CONSOLES; i++) {
1409kbd_table[i].ledflagstate = KBD_DEFLEDS;
1410kbd_table[i].default_ledflagstate = KBD_DEFLEDS;
1411kbd_table[i].ledmode = LED_SHOW_FLAGS;
1412kbd_table[i].lockstate = KBD_DEFLOCK;
1413kbd_table[i].slockstate = 0;
1414kbd_table[i].modeflags = KBD_DEFMODE;
1415kbd_table[i].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
1416}
1417
1418error = input_register_handler(&kbd_handler);
1419if (error)
1420return error;
1421
1422tasklet_enable(&keyboard_tasklet);
1423tasklet_schedule(&keyboard_tasklet);
1424
1425return 0;
1426}
第1408~1416行初始化kbd_table数组,这部分与tty内容相关,以后再分析。
1418行,这里我们终于看到调用input_register_handler函数注册kbd_handler,kbd_handler定义如下:
1394static 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定义如下:
1378static 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函数:
1600int input_register_handler(struct input_handler *handler)
1601{
1602struct input_dev *dev;
1603int retval;
1604
1605retval = mutex_lock_interruptible(&input_mutex);
1606if (retval)
1607return retval;
1608
1609INIT_LIST_HEAD(&handler->h_list);
1610
1611if (handler->fops != NULL) {
1612if (input_table[handler->minor >> 5]) {
1613retval = -EBUSY;
1614goto out;
1615}
1616input_table[handler->minor >> 5] = handler;
1617}
1618
1619list_add_tail(&handler->node, &input_handler_list);
1620
1621list_for_each_entry(dev, &input_dev_list, node)
1622input_attach_handler(dev, handler);
1623
1624input_wakeup_procfs_readers();
1625
1626out:
1627mutex_unlock(&input_mutex);
1628return 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,看一下这个函数:
1314static int kbd_connect(struct input_handler *handler, struct input_dev *dev,
1315const struct input_device_id *id)
1316{
1317struct input_handle *handle;
1318int error;
1319int i;
1320
1321for (i = KEY_RESERVED; i < BTN_MISC; i++)
1322if (test_bit(i, dev->keybit))
1323break;
1324
1325if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit))
1326return -ENODEV;
1327
1328handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
1329if (!handle)
1330return -ENOMEM;
1331
1332handle->dev = dev;
1333handle->handler = handler;
1334handle->name = "kbd";
1335
1336error = input_register_handle(handle);
1337if (error)
1338goto err_free_handle;
1339
1340error = input_open_device(handle);
1341if (error)
1342goto err_unregister_handle;
1343
1344return 0;
1345
1346err_unregister_handle:
1347input_unregister_handle(handle);
1348err_free_handle:
1349kfree(handle);
1350return error;
1351}
第1321~1326行判断dev->keybit,如果属于例外的情况,则不再往下走,返回-ENODEV。
第1328行,为handle分配内存空间,1332~1334行初始化handle的部分字段。
第1336行调用input_register_handle注册handle,看一下这个函数:
1671int input_register_handle(struct input_handle *handle)
1672{
1673struct input_handler *handler = handle->handler;
1674struct input_dev *dev = handle->dev;
1675int error;
1676
1677/*
1678* We take dev->mutex here to prevent race with
1679* input_release_device().
1680*/
1681error = mutex_lock_interruptible(&dev->mutex);
1682if (error)
1683return error;
1684list_add_tail_rcu(&handle->d_node, &dev->h_list);
1685mutex_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*/
1693list_add_tail(&handle->h_node, &handler->h_list);
1694
1695if (handler->start)
1696handler->start(handle);
1697
1698return 0;
1699}
第1684、1693将handle分别链接到dev->h_list和handler->h_list。
第1695~1696行,如果handler的start函数存在,则调用它。对于这个kbd_handler相应的函数为kbd_start,看一下这个函数:
1364static void kbd_start(struct input_handle *handle)
1365{
1366unsigned char leds = ledstate;
1367
1368tasklet_disable(&keyboard_tasklet);
1369if (leds != 0xff) {
1370input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
1371input_inject_event(handle, EV_LED, LED_NUML,!!(leds & 0x02));
1372input_inject_event(handle, EV_LED, LED_CAPSL,!!(leds & 0x04));
1373input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
1374}
1375tasklet_enable(&keyboard_tasklet);
1376}
禁止keyboard_tasklet,初始化键盘的三个led灯及SYN_REPORT,然后启用keyboard_tasklet,这个keyboard_tasklet也是对led灯进行操作的,函数如下
1032DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);
1014static void kbd_bh(unsigned long dummy)
1015{
1016struct list_head *node;
1017unsigned char leds = getleds();
1018
1019if (leds != ledstate) {
1020list_for_each(node, &kbd_handler.h_list) {
1021struct input_handle *handle = to_handle_h(node);
1022input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
1023input_inject_event(handle, EV_LED, LED_NUML,!!(leds & 0x02));
1024input_inject_event(handle, EV_LED, LED_CAPSL,!!(leds & 0x04));
1025input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
1026}
1027}
1028
1029ledstate = leds;
1030}
input_register_handle函数返回后,第1340行调用input_open_device函数,这个函数执行后相应的handle就能接受设备上报的事件。函数如下:
0421int input_open_device(struct input_handle *handle)
0422{
0423struct input_dev *dev = handle->dev;
0424int retval;
0425
0426retval = mutex_lock_interruptible(&dev->mutex);
0427if (retval)
0428return retval;
0429
0430if (dev->going_away) {
0431retval = -ENODEV;
0432goto out;
0433}
0434
0435handle->open++;
0436
0437if (!dev->users++ && dev->open)
0438retval = dev->open(dev);
0439
0440if (retval) {
0441dev->users--;
0442if (!--handle->open) {
0443/*
0444* Make sure we are not delivering any more events
0445* through this handle
0446*/
0447synchronize_rcu();
0448}
0449}
0450
0451out:
0452mutex_unlock(&dev->mutex);
0453return retval;
0454}
增加handle的open计数,如果handle->dev->users不为0,则自增1,如果为0并且handle->dev的open函数存在则会调用它,对于前面分析的atkbd,相应的handle->dev的open函数不存在。
至此,input handler和input handler的注册都分析完了,接着将分析事件处理部分内容。
接下一篇文章。