如何在struct device

时间:2015-07-21 17:30:08

标签: linux linux-kernel linux-device-driver sysfs

我正在研究Linux中的驱动程序。我正在努力获得一些/ sys文件属性,这将使事情变得更好。在提供这些属性要告知的内容时,属性函数必须能够访问驱动程序存储的某些数据。由于事物的制作和存储方式,我想我可以使用来自device_create()的struct device的device_private *p成员。基本上,就像这样:

for (i = 0; i < total; i++) {
    pDevice = device_create(ahcip_class, NULL, /*no parent*/
            MKDEV(AHCIP_MAJOR, AHCIP_MINOR + i), NULL, /*no additional info*/
            DRIVER_NAME "%d", AHCIP_MINOR + i);
    if (IS_ERR(pDevice)) {
        ret = PTR_ERR(pDevice);
        printk(KERN_ERR "%s:%d device_create failed AHCIP_MINOR %d\n",
                __func__, __LINE__, (AHCIP_MINOR + i));
        break;
    }

    mydevs[i].psysfs_dev = pDevice;

    ret = sysfs_create_group(&pDevice->kobj, &attr_group);
    if (!ret) {
        pr_err("%s:%d failed in making the device attributes\n",
                __func__, __LINE__);
        goto build_udev_quick_out;
    }
}

这还没有显示device_private指针的分配,但这就是我要去的地方。在此类下创建的每个新设备都需要相同的属性,因此该组。这是我从“概念证明”

开始的我的单一属性
static ahcip_dev *get_ahcip_dev(struct kobject *ko)
{
    ahcip_dev *adev = NULL;
    struct device *pdev = container_of(ko, struct device, kobj);
    if (!pdev) {
        pr_err("%s:%d unable to find device struct in kobject\n",
                __func__, __LINE__);
        return NULL;
    }

    /* **** problem dereferencing p **** */
    adev = (ahcip_dev*)pdev->p->driver_data;
    /* return the pointer anyway, but if it's null, print to klog */
    if (!adev)
        pr_err("%s:%d no ahcip_dev, private driver data is NULL\n",
                __func__, __LINE__);

    /* **** again problem dereferencing p **** */
    return pdev->p->(ahcip_dev*)driver_data; // <--- problem here
}

static ssize_t pxis_show(struct kobject *kobj, struct kobj_attribute *attr,
        char *buff)
{
    u32 pi = 0;
    ahcip_dev *adev = get_ahcip_dev(kobj);

    /* get_ahcip_dev() will print what happened, this needs to return
     * error code
     */
    if (!adev)
        return -EIO;

    pi = adev->port_index;

    return sprintf(buff, "%08x\n", get_port_reg(adev->hba->ports[pi], 0x10));
}

我认为,由于device_create()返回struct device*并且我正在使用它来创建设备组,因此struct kobject*成为pxis_show的成员由device_create制作的设备结构。如果这是真的,那么我应该能够将一些私有数据填充到该对象中,并在访问/ sys文件时使用它。但是,当上面标记的代码行取消引用p成员时,我得到从gcc中取消引用不完整类型的指针。我已经确定struct device_private成员struct device的成员不完整,但为什么?我应该使用不同的结构吗?这似乎是内核真正的内部事情。

1 个答案:

答案 0 :(得分:0)

要为设备分配私人数据,您需要使用void *drvdata参数device_create()。创建后,可以通过dev_get_drvdata(pdev)访问数据。

struct device_private是设备实施的内部信息。从此结构的描述(drivers/base/base.h):

  

驱动程序核心之外的任何内容都不应触及这些字段。