繁体   English   中英

Linux内核未将完整结构传递给sysfs回调

[英]Linux Kernel Not Passing Complete Structure to sysfs Callback

对于驱动程序开发,我对sysfs相当陌生,而且我似乎观察到一些相当奇怪的行为。 简而言之,内核似乎没有将完整的结构传递回我的回调中。 该驱动器是一个相当简单的SPI-ADC驱动器,用于读取模拟热/电压数据。

现在,我很难相信我只是在这样一个广泛使用的子系统中的Linux内核中发现了一个错误。 我在互联网上搜索了可能有帮助的任何内容,但是所有迹象表明这应该照常进行。 其他传递的结构似乎已正确填充,只有attr->attr成员似乎为NULL

我还应该提到,这是针对3.2内核的。

简而言之,是什么导致sysfs回调无法接收完整填充的kobj_attribute结构?

样例代码:

static ssize_t ads7960_sysfs_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
int var, rc, i = 0, j = 0;
long channel = 0;

//DEBUG
printk("%s: kobj->name = %s\n", __func__, kobj->name);
printk("%s: attr = %p\n", __func__, attr);
printk("%s: attr->attr = %p\n", __func__, attr->attr);
printk("%s: attr->attr.name = %s\n", __func__, attr->attr.name);
printk("%s: attr->attr.mode = %o\n", __func__, attr->attr.mode);

/* check for silly things */
if ((attr->attr.name == NULL) || (strlen(attr->attr.name) < 1)) {
    printk("%s: invalid channel number. = %s\n", __func__, attr->attr.name);
    return -EINVAL;
}

... snip (We never get past here) ...

static struct kobj_attribute ads7960_ch0  = __ATTR(0,  0444, ads7960_sysfs_show, NULL);
static struct kobj_attribute ads7960_ch1  = __ATTR(1,  0444, ads7960_sysfs_show, NULL);
static struct kobj_attribute ads7960_ch2  = __ATTR(2,  0444, ads7960_sysfs_show, NULL);

... snip (there are 12 total ADC channels in the same format) ...

static struct attribute *ch_attrs[] = {
    &ads7960_ch0.attr,
    &ads7960_ch1.attr,
    &ads7960_ch2.attr,

    ... snip (same 12 channels as above)...

    NULL,
};

static struct attribute_group attr_group = {
    .attrs = ch_attrs,
};

static struct attribute_group *attr_group_ptr = &attr_group;

... snip ...

static struct spi_driver ads7960_driver = {
    .driver = {
        .name   = "ads7960",
        .bus    = &spi_bus_type,
        .owner  = THIS_MODULE,
        .groups = &attr_group_ptr,
    },
    .probe          = ads7960_probe,
    .remove         = __devexit_p(ads7960_remove),
    .id_table       = ads7960_id,
};

... snip ...

产生的输出:

[root@172.17.152.42: ]# cat /sys/bus/spi/drivers/ads7960/4
[   65.344789] ads7960_sysfs_show: kobj->name = ads7960
[   65.350026] ads7960_sysfs_show: attr = dc934000
[   65.354859] ads7960_sysfs_show: attr->attr =   (null)
[   65.360155] ads7960_sysfs_show: attr->attr.name = (null)
[   65.365746] ads7960_sysfs_show: attr->attr.mode = 0
[   65.370861] ads7960_sysfs_show: invalid channel number. = (null)
cat: read error: Invalid argument

参考

http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/samples/kobject/kobject-example.c http://kroah.com/log/blog/2013/06/ 26 /如何到创建-A-sysfs的文件,正确/


编辑1:

总结下面的评论,我从_init手动调用了sysfs_create_group ,并且传递给回调的kobj_attribute结构似乎已正确填充。 回调现在可以正常工作(或修改)。 如下所述, spi_register_driver仅调用sysfs_create_group 那么,为什么一个人正确地调用回调而另一个人不正确呢?

根据下面的注释,下面是完整的_init函数和spi_driver结构。 我自己手动创建路径的测试是基于第一个引用中的_init代码,几乎没有修改。

static struct spi_driver ads7960_driver = {
    .driver = {
        .name   = "ads7960",
        .bus    = &spi_bus_type,
        .owner  = THIS_MODULE,
        .groups = attr_groups,
    },
    .probe          = ads7960_probe,
    .remove         = __devexit_p(ads7960_remove),
    .id_table       = ads7960_id,
};

static int __init ads7960_init(void)
{  
    return spi_register_driver(&ads7960_driver);
}
module_init(ads7960_init);

struct device_driver .groups成员必须指向以NULL结尾的指向属性组的指针列表,而不是指向属性组的单个指针。 因此,您需要代替attr_group_ptr

static struct attribute_group *attr_groups[] = { &attr_group, NULL };

...接着

static struct spi_driver ads7960_driver = {
    .driver = {
        .name   = "ads7960",
        .bus    = &spi_bus_type,
        .owner  = THIS_MODULE,
        .groups = attr_groups,
    },

但是,有一个帮助程序宏可以声明属性组和属性组列表,您可以改为使用它们:

static struct attribute *ch_attrs[] = {
    &ads7960_ch0.attr,
    &ads7960_ch1.attr,
    &ads7960_ch2.attr,

    /* ... */

    NULL,
};

ATTRIBUTE_GROUPS(ch);  /* declares ch_group and ch_groups */

static struct spi_driver ads7960_driver = {
    .driver = {
        .name   = "ads7960",
        .bus    = &spi_bus_type,
        .owner  = THIS_MODULE,
        .groups = ch_groups,
    },

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM