3

我为 Linux 开发了一个外围驱动程序。.probe 函数执行常见的错误检查,如内存分配失败,并尝试与硬件通信,并在任何类型的错误中解除分配任何内存并返回错误代码,如 -ENOMEM 或 -EIO。

问题是,虽然模块探测函数在硬件不可达时返回 -EIO,但我仍然看到模块在lsmod输出中列出。当初始化过程中出现问题时,是否可以确保insmod完全失败?

这是我当前的探测功能。所有特定于设备的函数在失败时都会返回适当的错误代码,通常是 -EIO。

static int mlx90399_probe(struct i2c_client *client,
        const struct i2c_device_id *id)
{
    int err;
    struct mlx90399_data *data;

    data = kzalloc(sizeof(*data), GFP_KERNEL);
    if (!data) {
        dev_err(&client->dev, "Memory allocation fails\n");
        err = -ENOMEM;
        goto exit;
    }
    i2c_set_clientdata(client, data);
    data->client = client;
    mutex_init(&data->lock);
    data->mode = MLX90399_MODE_OFF;

    err = mlx90399_reset(client);
    if (err < 0)
        goto exit;

    msleep(1); /* nominal 0.6ms from reset */
    err = mlx90399_write_register_defaults(client);
    if (err < 0)
        goto exit;

    err = mlx90399_update_scale(client);
    if (err < 0)
        goto exit;

    data->indio_dev = iio_allocate_device(0);
    if (data->indio_dev == NULL) {
        err = -ENOMEM;
        goto exit;
    }

    data->indio_dev->dev.parent = &client->dev;
    data->indio_dev->info = &mlx90399_info;
    data->indio_dev->dev_data = (void *)(data);
    data->indio_dev->modes = INDIO_DIRECT_MODE;

    mlx90399_setup_irq(client);

    err = iio_device_register(data->indio_dev);
    if(err < 0)
        goto exit;

    return 0;

exit:
    kfree(data);
    return err;
}
4

2 回答 2

2

请参阅中的评论__driver_attach()

/*
 * Lock device and try to bind to it. We drop the error
 * here and always return 0, because we need to keep trying
 * to bind to devices and some drivers will return an error
 * simply if it didn't support the device.
 *
 * driver_probe_device() will spit a warning if there
 * is an error.
 */

要使模块初始化失败,请取消注册驱动程序并从您的 init 函数中返回错误代码。

于 2014-02-27T17:07:46.783 回答
2

请注意,模块和设备之间不一定存在 1:1 的关系。一个模块可以用于多个设备。例如,通过使用设备树,设备树可以声明多个板载 UART,所有这些都使用一个串行设备内核模块。模块的probe函数会被调用多次,每个设备调用一次。仅仅因为一次probe调用失败,这并不一定意味着应该卸载模块。

于 2016-07-07T04:55:34.467 回答