Как разыменовать 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
):
Ничто за пределами ядра драйвера не должно касаться этих полей.