1

我需要编写一个使用 acpi 方法与硬件设备通信的内核模块。

此时我只想加载驱动程序并枚举总线上的设备。

我在网上找到了一个相当古老但合理的例子,下面是基本大纲。我几乎逐字逐句地更改名称的示例,我使用 acpidump 查找 dsdt 表获取正确的设备 ID 等。

驱动程序加载正常,但没有调用我的添加函数。我怀疑我在注册后错过了刺激扫描总线的步骤。该示例假定驱动程序在引导时加载。有没有办法在注册总线后请求对其进行扫描,以便添加任何连接到已注册总线的设备?理解我的怀疑可能是错误的,所以如果我的假设是错误的,请纠正我。

以下是来源:

static int viking_acpi_add(struct acpi_device *device);
static int viking_acpi_remove(struct acpi_device *device);
static void viking_acpi_notify(struct acpi_device *adev, u32 event);

static const struct acpi_device_id nv_device_ids[] = {
    { "ACPI0012", 0},
    { "", 0},
};
MODULE_DEVICE_TABLE(acpi, nv_device_ids);

static struct acpi_driver nv_acpi_driver = {
    .name =         "NV NVDR",
    .class =        "NV",
    .ids =          nv_device_ids,
    .ops =          {
                            .add =          nv_acpi_add,
                            .remove =       nv_acpi_remove,
                            .notify =       nv_acpi_notify,
                    },
.owner =    THIS_MODULE,
};

//static struct acpi_device acpi_dev;

static int nv_acpi_add(struct acpi_device *device)
{
    printk("NV: acpi bus add\n");
    return 0;
}

static int nv_remove(struct acpi_device *device)
{
    printk("NV: acpi bus remove\n");
    return 0;
}

static void nv_acpi_notify(struct acpi_device *adev, u32 event)
{
    device_lock(&adev->dev);
    printk("notification detected\n");
    device_unlock(&adev->dev);
}

static int __init nv_init(void)
{
    int result = 0;

    result = acpi_bus_register_driver(&nvt_driver);
    if (result < 0) {
        printk("Error registering driver\n");
        return -ENODEV;
    }

    return 0;
}

static void __exit nv_exit(void)
{
    acpi_bus_unregister_driver(&nv_driver);
}

module_init(nv_init);
module_exit(nv_exit);
4

1 回答 1

0

事实证明,我正在使用的 acpi 设备 ID 注册了另一个 acpi 总线驱动程序,因此内核没有调用我的 add 例程。当我使用不同的内核运行它时,我的 add 例程被按预期调用。

于 2018-03-08T22:09:52.303 回答