Получение контейнера пустого указателя - PullRequest
0 голосов
/ 26 апреля 2020

В настоящее время я пытаюсь избавиться от backref, который мне нужен для следующей функции:

/**
 * amd_sfh_hid_poll - Updates the input report for a HID device.
 * @work:   The delayed work
 *
 * Polls input reports from the respective HID devices and submits
 * them by invoking hid_input_report() from hid-core.
 */
static void amd_sfh_hid_poll(struct work_struct *work)
{
    struct amd_sfh_hid_data *hid_data;
    struct hid_device *hid;
    size_t size;
    u8 *buf;

    hid_data = container_of(work, struct amd_sfh_hid_data, work.work);
    hid = hid_data->hid;
    size = get_descriptor_size(hid_data->sensor_idx, AMD_SFH_INPUT_REPORT);

    buf = kzalloc(size, GFP_KERNEL);
    if (!buf) {
        hid_err(hid, "Failed to allocate memory for input report!\n");
        goto reschedule;
    }

    size = get_input_report(hid_data->sensor_idx, 1, buf, size,
                            hid_data->cpu_addr);
    if (size < 0) {
        hid_err(hid, "Failed to get input report!\n");
        goto free_buf;
    }

    hid_input_report(hid, HID_INPUT_REPORT, buf, size, 0);

free_buf:
    kfree(buf);
reschedule:
    schedule_delayed_work(&hid_data->work, hid_data->interval);
}

struct amd_sfh_hid_data - это данные драйвера, сохраненные в hid->driver_data для соответственно struct hid_device. В рабочей очереди мне нужно получить доступ к данным драйвера HID и с этого устройства HID, что я сейчас и делаю, обращаясь к backref hid = hid_data->hid. Теперь я попытался избавиться от backref, используя container_of в данных драйвера:

hid = container_of((void*)hid_data, struct hid_device, driver_data);

Но это приводит к ошибкам страницы, как и

hid = container_of((void**)*hid_data, struct hid_device, driver_data);

Что является правильным способ получить struct hid_device * с учетом его члена void *driver_data, используя container_of?

1 Ответ

2 голосов
/ 27 апреля 2020

Как правильно получить struct hid_device * с учетом его члена void *driver_data, используя container_of?

Ни за что.

Использование container_of подразумевает, что у вас есть указатель на член , а не значение члена, как в вашем случае.

Краткий пример:

struct B;
struct C;

struct A {
   struct B field1;
   struct C* field2;
}

Имея указатель на field1, используя container_of, вы можете получить указатель на весь struct A объект.

Имея значение field2 (даже если он имеет тип struct C*, то есть указатель), вы не можете получить указатель на объект struct A.

...