简体   繁体   English

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

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

I am reasonably new to sysfs with respect to driver development and I seem to be observing some rather odd behavior. 对于驱动程序开发,我对sysfs相当陌生,而且我似乎观察到一些相当奇怪的行为。 To make a long story short, it seems that the kernel is not passing back complete structs to my callback. 简而言之,内核似乎没有将完整的结构传递回我的回调中。 This driver is a rather simple SPI-ADC driver that is being used to read analog thermal / voltage data. 该驱动器是一个相当简单的SPI-ADC驱动器,用于读取模拟热/电压数据。

Now, I have a hard time believing that I just found a bug in the Linux kernel in such a widely-used subsystem. 现在,我很难相信我只是在这样一个广泛使用的子系统中的Linux内核中发现了一个错误。 I have scoured the internet for anything that might help, but all signs indicate that this should work as is. 我在互联网上搜索了可能有帮助的任何内容,但是所有迹象表明这应该照常进行。 Other passed structures seem to be populated correctly, it is only the attr->attr member that appears to be NULL . 其他传递的结构似乎已正确填充,只有attr->attr成员似乎为NULL

I should also mention that this is against the 3.2 kernel. 我还应该提到,这是针对3.2内核的。

So, in short, what would causes sysfs callbacks to not receive a fully populated kobj_attribute struct? 简而言之,是什么导致sysfs回调无法接收完整填充的kobj_attribute结构?

Sample Code: 样例代码:

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 ...

Output Produced: 产生的输出:

[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

References 参考

http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/samples/kobject/kobject-example.c http://kroah.com/log/blog/2013/06/26/how-to-create-a-sysfs-file-correctly/ 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的文件,正确/


Edit 1: 编辑1:

To summarize the comments below, I manually called sysfs_create_group from my _init and the kobj_attribute struct passed to the callback appeared to be correctly populated. 总结下面的评论,我从_init手动调用了sysfs_create_group ,并且传递给回调的kobj_attribute结构似乎已正确填充。 The callback now works without issue (or modification, for that matter). 回调现在可以正常工作(或修改)。 As was stated below, spi_register_driver just calls sysfs_create_group . 如下所述, spi_register_driver仅调用sysfs_create_group So, why would one invoke the callback properly while the other does not? 那么,为什么一个人正确地调用回调而另一个人不正确呢?

Per comments below, below is the complete _init function and spi_driver structure. 根据下面的注释,下面是完整的_init函数和spi_driver结构。 The test that I did to manually create the paths myself was based off the _init code in the first reference with almost no modification. 我自己手动创建路径的测试是基于第一个引用中的_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);

The .groups member of struct device_driver must point to a NULL-terminated list of pointers to attribute groups, not to a single pointer to an attribute group. struct device_driver .groups成员必须指向以NULL结尾的指向属性组的指针列表,而不是指向属性组的单个指针。 So, instead of attr_group_ptr , you need: 因此,您需要代替attr_group_ptr

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

...and then ...接着

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

However, there's a helper macro to declare both the attribute group and list of attribute groups that you can use instead: 但是,有一个帮助程序宏可以声明属性组和属性组列表,您可以改为使用它们:

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