关于内核3.4 ——3.14—— 4.16 input_attach_handler ——>input_match_device——>input_match_device_id

3.4以前的版本 是有个黑名单的,

if (handler->blacklist && input_match_device(handler->blacklist,        dev))  
        return -ENODEV;        

具体哪个版本开始删除不清楚 , 但是3.4是直接判断 ,

然后我看到在4.16就又封装了一层input_match_device_id函数进行单独的判断 更便于理解

static int input_attach_handler(struct input_dev *dev, 
struct   input_handler *handler)  
{  
    // input_device_id 这个结构体表示设备的标识,存储了设备信息。
    const struct input_device_id *id;       /*输入设备的指针*/  
    int error;  
    //先判断 handler 的 blacklist 有无赋值,然后判断是否匹配
    //blacklist 是一个 input_device_id *类型,指向了一个表,表中存放的是该驱动程序应该忽略的设备
    if (handler->blacklist && input_match_device(handler->blacklist,        dev))  
        return -ENODEV;                     
    /*** 设备和处理函数之间的匹配 ***/
    //匹配 handler->id_table指向的列表中的设备 和 dev->id 数据
    id = input_match_device(handler->id_table, dev);  
    if (!id)  
        return -ENODEV;  
    //匹配成功则调用 handler->connect,连接 handler 和 input_dev
    error = handler->connect(handler, dev, id);/*连接设备和处理函数*/  
    if (error && error != -ENODEV)  
        printk(KERN_ERR  
            "input: failed to attach handler %s to device %s, "  
            "error: %d\n",  
            handler->name, kobject_name(&dev->dev.kobj), error);  
    return error;  
} 

 

static const struct input_device_id *input_match_device(const struct  
    input_device_id *id,struct input_dev *dev)  
{  
    int i;  
    //匹配 id 和 dev->id 中的信息
    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;  
} 

3.4的linux的输入子系统 

input_attach_handler 
调用 input_match_device (与上面的函数相同,不同的是没有黑名单) 进行匹配,判断 dev 在不在 devices 的屏蔽中,不在就调用 handler->connect 连接设备和处理函数 默认在系统中是匹配所有的 

static int input_attach_handler(struct input_dev *dev, struct input_handler *handler)
{
	const struct input_device_id *id;
	int error;

	id = input_match_device(handler, dev);
	if (!id)
		return -ENODEV;

	error = handler->connect(handler, dev, id);
	if (error && error != -ENODEV)
		pr_err("failed to attach handler %s to device %s, error: %d\n",
		       handler->name, kobject_name(&dev->dev.kobj), error);

	return error;
}

 

3.14的input_attach_handler ——>input_match_device 

static int input_attach_handler(struct input_dev *dev, struct input_handler *handler)
{
	const struct input_device_id *id;
	int error;

	id = input_match_device(handler, dev);
	if (!id)
		return -ENODEV;

	error = handler->connect(handler, dev, id);
	if (error && error != -ENODEV)
		pr_err("failed to attach handler %s to device %s, error: %d\n",
		       handler->name, kobject_name(&dev->dev.kobj), error);

	return error;
}
static const struct input_device_id *input_match_device(struct input_handler *handler,
							struct input_dev *dev)
{
	const struct input_device_id *id;

	for (id = handler->id_table; 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;

		if (!bitmap_subset(id->evbit, dev->evbit, EV_MAX))
			continue;

		if (!bitmap_subset(id->keybit, dev->keybit, KEY_MAX))
			continue;

		if (!bitmap_subset(id->relbit, dev->relbit, REL_MAX))
			continue;

		if (!bitmap_subset(id->absbit, dev->absbit, ABS_MAX))
			continue;

		if (!bitmap_subset(id->mscbit, dev->mscbit, MSC_MAX))
			continue;

		if (!bitmap_subset(id->ledbit, dev->ledbit, LED_MAX))
			continue;

		if (!bitmap_subset(id->sndbit, dev->sndbit, SND_MAX))
			continue;

		if (!bitmap_subset(id->ffbit, dev->ffbit, FF_MAX))
			continue;

		if (!bitmap_subset(id->swbit, dev->swbit, SW_MAX))
			continue;

		if (!handler->match || handler->match(handler, dev))
			return id;
	}

	return NULL;
}

 

4.16的input_attach_handler ——>input_match_device——>input_match_device_id

static int input_attach_handler(struct input_dev *dev, struct input_handler *handler)
{
	const struct input_device_id *id;
	int error;

	id = input_match_device(handler, dev);
	if (!id)
		return -ENODEV;

	error = handler->connect(handler, dev, id);
	if (error && error != -ENODEV)
		pr_err("failed to attach handler %s to device %s, error: %d\n",
		       handler->name, kobject_name(&dev->dev.kobj), error);

	return error;
}

 

static const struct input_device_id *input_match_device(struct input_handler *handler,
							struct input_dev *dev)
{
	const struct input_device_id *id;

	for (id = handler->id_table; id->flags || id->driver_info; id++) {
		if (input_match_device_id(dev, id) &&
		    (!handler->match || handler->match(handler, dev))) {
			return id;
		}
	}

	return NULL;
}
bool input_match_device_id(const struct input_dev *dev,
			   const struct input_device_id *id)
{
	if (id->flags & INPUT_DEVICE_ID_MATCH_BUS)
		if (id->bustype != dev->id.bustype)
			return false;

	if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR)
		if (id->vendor != dev->id.vendor)
			return false;

	if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT)
		if (id->product != dev->id.product)
			return false;

	if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION)
		if (id->version != dev->id.version)
			return false;

	if (!bitmap_subset(id->evbit, dev->evbit, EV_MAX) ||
	    !bitmap_subset(id->keybit, dev->keybit, KEY_MAX) ||
	    !bitmap_subset(id->relbit, dev->relbit, REL_MAX) ||
	    !bitmap_subset(id->absbit, dev->absbit, ABS_MAX) ||
	    !bitmap_subset(id->mscbit, dev->mscbit, MSC_MAX) ||
	    !bitmap_subset(id->ledbit, dev->ledbit, LED_MAX) ||
	    !bitmap_subset(id->sndbit, dev->sndbit, SND_MAX) ||
	    !bitmap_subset(id->ffbit, dev->ffbit, FF_MAX) ||
	    !bitmap_subset(id->swbit, dev->swbit, SW_MAX) ||
	    !bitmap_subset(id->propbit, dev->propbit, INPUT_PROP_MAX)) {
		return false;
	}

	return true;
}

 

你可能感兴趣的:(linux)