用“dev_groups”替换已弃用的“dev_attrs”属性

时间:2014-02-18 19:33:45

标签: c linux linux-kernel linux-device-driver kernel-module

我正在尝试编译一个Linux设备驱动程序(内核模块),但该模块最后一次更新于2013年4月,当然它不再编译在最近的(3.13)内核上,这里是错误:

als_sys.c:99:2: error: unknown field ‘dev_attrs’ specified in initializer

我已经搜索了但是我发现的所有内容都是补丁,没有关于更新旧模块的明确“教程”,我唯一理解的是我需要使用dev_groups代替,但它没有不接受与dev_attrs相同的值,我不知道如何调整现有代码。

代码(其中一部分,整个代码可以找到here):

# als_sys.c

static ssize_t
illuminance_show(struct device *dev, struct device_attribute *attr, char *buf)
{
    struct als_device *als = to_als_device(dev);
    int illuminance;
    int result;

    result = als->ops->get_illuminance(als, &illuminance);
    if (result)
        return result;

    if (!illuminance)
        return sprintf(buf, "0\n");
    else if (illuminance == -1)
        return sprintf(buf, "-1\n");
    else if (illuminance < -1)
        return -ERANGE;
    else
        return sprintf(buf, "%d\n", illuminance);
}

# truncated - also "adjustment_show" is similar to this function so
# I didn't copy/paste it to save some space in the question

static struct device_attribute als_attrs[] = { # that's what I need to modify, but
    __ATTR(illuminance, 0444, illuminance_show, NULL), # I have no clue what to
    __ATTR(display_adjustment, 0444, adjustment_show, NULL), # put here instead
    __ATTR_NULL,
};

# truncated

static struct class als_class = {
    .name = "als",
    .dev_release = als_release,
    .dev_attrs = als_attrs, # line 99, that's where it fails
};

修改

如下面的答案所述,我改变了这样的代码:

static struct device_attribute als_attrs[] = {
    __ATTR(illuminance, 0444, illuminance_show, NULL),
    __ATTR(display_adjustment, 0444, adjustment_show, NULL),
    __ATTR_NULL,
};

static const struct attribute_group als_attr_group = {
    .attrs = als_attrs,
};

static struct class als_class = {
    .name = "als",
    .dev_release = als_release,
    .dev_groups = als_attr_group, # line 103 - it fails here again
};

但我还是得到了另一个错误:

als_sys.c:103:2: error: initializer element is not constant

我发现this question大概有同样的错误,但它的答案是关于单个属性的,我不知道如何让它适应多个属性。

感谢您的帮助,祝您度过愉快的一天。

1 个答案:

答案 0 :(得分:5)

确实,{3.1}中的dev_attrs被替换为dev_groups。在3.12中,它们都以结构形式呈现。查看3.12 version3.13 version

无论如何,应该没有问题,因为简单的search for attribute_group会给你很多例子。

简而言之,您必须将dev_attrs嵌入dev_group:

static const struct attribute_group als_attr_group = {
        .attrs = als_attrs,
};

然后在struct class中使用该属性组。

还有一个方便的宏ATTRIBUTE_GROUPS。请参阅示例用法https://lkml.org/lkml/2013/10/23/218

修改

从属性组中删除const声明,如下所示:

static struct attribute_group als_attr_group = {
        .attrs = als_attrs,
};

因为你不能用不像0xff'c'这样的文字来初始化const struct。查看更多详细信息here