Как разыменовать device_private в struct device

Я работаю над драйвером в Linux. Я работаю над получением некоторых атрибутов файла /sys, которые сделают вещи лучше. При предоставлении того, что должны сказать эти атрибуты, функции атрибутов должны иметь доступ к некоторым данным, которые хранятся драйвером. Из-за того, как вещи, кажется, сделаны и сохранены, я думал, что мог бы использовать device_private *p член struct device, который происходит от device_create(). По сути, это так:

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 member Я получаю разыменовывающий указатель неполного типа из gcc. Я решил, что это struct device_private член struct device это неполно, но почему? Есть ли другая структура, которую я должен использовать? Кажется, это что-то действительно внутреннее для ядра.

1 ответ

Решение

Для назначения личных данных для устройства, вы должны использовать void *drvdata параметр для device_create(), После создания, данные могут быть доступны через dev_get_drvdata(pdev),

struct device_private является внутренним для реализации устройства. Из описания этой структуры (drivers/base/base.h):

Ничто за пределами ядра драйвера не должно касаться этих полей.

Другие вопросы по тегам