/* 向上层上报一个scancode */ input_event(dev, EV_MSC, MSC_SCAN, code);
将事件上报给事件处理句柄意味这事件将真正到达事件处理层,对于PC keyboard的event handle就是sysrq,kbd,eventX,这些handle对应的handler分别是sysrq_handler,kbd_handler,evdev_handler。每次上报一个事件,都会由input_pass_event函数去遍历这些event handle再有这些event handle 找到对应的handler,最后调用handler->event()函数对事件进行最终的处理。 回看atkbd_interrupt的三次input_event调用: 第一次type为EV_MSC,code为MSC_RAW,但有/sys/class/input/input0/capabilities/msc 为0x10可知(第4位为0),一般PC keyboard都不支持上报RAW类型事件。也就是说对于那些对event设备感兴趣的应用程序而言是无法从这里获得RAW scancode的。 第二次type为EV_MSC,code为MSC_SCAN 正好是PC keyboard唯一支持的EV_MSC事件类型,所以可以在此上报scancode 事件。其实从代码里可以看到RAW scancode和scancode 区别在于前者可以多几种scancode。 第三次type为EV_KEY,code为scancode,这才算是上报一次普通的按键事件。 最后一路跟踪到了kbd_handler,里面将调用kbd_event进行最终的处理。另外两个,sysrq_event和evdev_event不再讲了,前者处理sysrq特殊按键组合的事件,后者涉及evdev client和用户层挂接的问题
对于一个常规按键,kbd_event会在整个流程中被调用两次,第一次是event_type=EV_MSC ,event_code=MSC_SCAN ,这次其实是会被忽略。另外HW_RAW(handle->dev) 这个宏对于PC keyboard恒为0,所以再次重复一遍,PC keyboard永远也不会将raw scancode上报处理。 第二次是event_type=EV_KEY,event_code=keycode,这才是需要关心的。