日期:2014-05-16  浏览次数:20606 次

我对linux理解之input一
我们先看下input的注册过程:
input_register_device(input_dev):
int input_register_device(struct input_dev *dev)
{
    static atomic_t input_no = ATOMIC_INIT(0);
    struct input_handler *handler;
    const char *path;
    int error;

    __set_bit(EV_SYN, dev->evbit);//支持同步事件

    /*
     * If delay and period are pre-set by the driver, then autorepeating
     * is handled by the driver itself and we don't do it in input.c.
     */

    init_timer(&dev->timer);//为重复按键做准备
    if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) {
        dev->timer.data = (long) dev;
        dev->timer.function = input_repeat_key;
        dev->rep[REP_DELAY] = 250;
        dev->rep[REP_PERIOD] = 33;
    }

    if (!dev->getkeycode)//如果没设置,则设置成默认的
        dev->getkeycode = input_default_getkeycode;

    if (!dev->setkeycode)
        dev->setkeycode = input_default_setkeycode;

    dev_set_name(&dev->dev, "input%ld",
                 (unsigned long) atomic_inc_return(&input_no) - 1);//按顺序地去定义input序号

    error = device_add(&dev->dev);//将input dev添加到sys系统中,包括创建一些input的属性文件
    if (error)
        return error;

    path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);//这里路径是上面device_add产生的
    printk(KERN_INFO "input: %s as %s\n",
        dev->name ? dev->name : "Unspecified device", path ? path : "N/A");
    kfree(path);

    error = mutex_lock_interruptible(&input_mutex);
    if (error) {
        device_del(&dev->dev);
        return error;
    }

    list_add_tail(&dev->node, &input_dev_list);//添加到input设备列表里面

    list_for_each_entry(handler, &input_handler_list, node)//对input handler列表中的每个handler都进行匹配,这里input_handler_list怎么来的呢?我们在 input_register_handler找到它的形成过程
        input_attach_handler(dev, handler);//匹配dev和handler

    input_wakeup_procfs_readers();

    mutex_unlock(&input_mutex);

    return 0;
}
我们看下input_attach_handler(dev, handler):
static int input_attach_handler(struct input_dev *dev, struct input_handler *handler)
{
    const struct input_device_id *id;
    int error;

    if (handler->blacklist && input_match_device(handler->blacklist, dev))//如果在黑名单里面就返回
        return -ENODEV;

    id = input_match_device(handler->id_table, dev);//匹配handler->id_table和dev
    if (!id)
        return -ENODEV;

    error = handler->connect(handler, dev, id);//调用handler的connect连接handler、 dev,这个函数很重要,起到了承上启下的作用。
    if (error && error != -ENODEV)
        printk(KERN_ERR
            "input: failed to attach handler %s to device %s, "
            "error: %d\n",
            handler->nam