acpi event

来源:互联网 发布:php 随机红包算法 编辑:程序博客网 时间:2024/05/21 15:42
在使用netlink时,我们一般会使用genl_register_family 和 genl_register_ops,或者直接使用genl_register_family_with_ops,但是genl_register_ops的作用仅仅是是用户空间收到消息是实际处理的回调函数,如果我们只是向用户空间发送一个字符串的话,只调用genl_register_family 就可以了。
例如在acpi button的中就调用acpi_bus_generate_netlink_event 来向用户空间发送event
static void acpi_button_notify(struct acpi_device *device, u32 event)
{
    
            keycode = test_bit(KEY_SLEEP, input->keybit) ?
                        KEY_SLEEP : KEY_POWER;
            input_report_key(input, keycode, 1);
            input_sync(input);
            input_report_key(input, keycode, 0);
            input_sync(input);

            acpi_bus_generate_netlink_event(
                    device->pnp.device_class,
                    dev_name(&device->dev),
                    event, ++button->pushed);
        
}
而这里用的netlink其实是在acpi_event_init 中注册的。
static int __init acpi_event_init(void)
{
    /* create genetlink for acpi event */
    error = acpi_event_genetlink_init();
    if (error)
        printk(KERN_WARNING PREFIX
               "Failed to create genetlink family for ACPI event\n");
    return 0;
}

fs_initcall(acpi_event_init);
通过fs_initcall 可知是开机自动运行
static int acpi_event_genetlink_init(void)
{
    return genl_register_family(&acpi_event_genl_family);
}
直接调用genl_register_family,因为我们不需要user space收到消息后回调所以没有必要使用genl_register_ops。
在调用__genl_register_family的时候会检查ops是否合法
int __genl_register_family(struct genl_family *family)
361 {
362         int err = -EINVAL, i;
363
364         if (family->id && family->id < GENL_MIN_ID)
365                 goto errout;
366
367         if (family->id > GENL_MAX_ID)
368                 goto errout;
369
370         err = genl_validate_ops(family);
371         if (err)
372                 return err;
    }
从genl_validate_ops 函数中可以看出,因为n_ops ==0 和 ops == NULL,这组条件也是合法的。所以在这种情况下就没有必要调用genl_register_ops
static int genl_validate_ops(const struct genl_family *family)
324 {
325         const struct genl_ops *ops = family->ops;
326         unsigned int n_ops = family->n_ops;
327         int i, j;
328
329         if (WARN_ON(n_ops && !ops))
330                 return -EINVAL;
331
332         if (!n_ops)
333                 return 0;
334
335         for (i = 0; i < n_ops; i++) {
336                 if (ops[i].dumpit == NULL && ops[i].doit == NULL)
337                         return -EINVAL;
338                 for (j = i + 1; j < n_ops; j++)
339                         if (ops[i].cmd == ops[j].cmd)
340                                 return -EINVAL;
341         }
342
343         return 0;
344 }
0 0
原创粉丝点击