LINUX.ORG.RU

[ядро] device_create & file_operation struct


0

2

Есть несколько подключённых одинаковых pci устройств. Для каждого устройства надо сделать chardev. Всё это дело хочу сделать через class_create и потом для каждого нового устройсва в probe его инициализировать, и создавать char dev в вышеупомянутом классе, вызывая device_create и соответвенно заполняя private_data для struct file (хочу туда struct pci_dev* засунуть). Но как получить доступ к полям private_data для struct file через struct device я не понял.

Если кто в курсе, тыкните пожалуйста пальцем. А то я что-то смотрю на на определение struct device и никак немогу найти решение. Спасибо.

Создаешь глобальный список устройств my_dev_head

static int my_open (struct inode *inode, struct file *filp)
{
        unsigned int minor = MINOR(inode->i_rdev);
        struct my_dev *dev_file;

        list_for_each_entry(dev_file, &my_dev_head, list)
                 if (dev_file->minor == minor) {
                          ...
                          filp->private_data = dev_file;
                 }
}
ttnl ★★★★★ ()
Ответ на: комментарий от ttnl

Да, но а где мне взять эту самую struct my_dev *dev_file? Лично я её надеюсь найти как раз в private_data.
Я так понял вы предлагаете реализовать linked list с информацией какому устройству какой файл соответсвует и потом в open находить устройство в списке и указатель вставлять в private_data?
В общем-то да, это решение.
Но я надеялся, что у меня будет доступ к private_data ещё в probe, где я создаю chardev. Так бы было проще.

nanoo_linux ()
Ответ на: комментарий от nanoo_linux

Одному устройству может соответствовать несколько экземпляров file. Так что в обратную сторону сделать нельзя.

Структура file создается при открытии файла. Во время .probe о ней ничего не известно.

ttnl ★★★★★ ()
Ответ на: комментарий от nanoo_linux

P.S. Хотя ты можешь попробовать запихать в inode. Как конкретно это делать не скажу, скорее всего это зависит от того, как ты регистрируешь устройство

ttnl ★★★★★ ()
Ответ на: комментарий от ttnl

в i_private? было бы здорово.
регистрирую устройство так: делаю alloc_chrdev_region для штук 16ти (пока ещё не знаю сколько надо), а потом для каждого cdev_add.
Но опять таки, я это планировал делать в .probe, а теперь не знаю даже, придётся многое менять.

nanoo_linux ()
Ответ на: комментарий от nanoo_linux

в struct device есть dev_t устройства. Как-нибудь можно получить от ядра inode зная minor major номера?

nanoo_linux ()
Ответ на: комментарий от nanoo_linux

Пример заполнения inode: drivers/usb/gadget/inode.c

Но я думаю, тебе это не нужно, легче заполнить private_data в .open :)

ttnl ★★★★★ ()
Ответ на: комментарий от nanoo_linux

> что-бы в i_private вписать указатель на pci_dev

i_private

Тебе оно точно надо именно в inode? Обычно такие вещи записываются в file.

tailgunner ★★★★★ ()
Ответ на: комментарий от tailgunner

не нужен

/Documentation/driver-model/binding.txt

Device Class
~~~~~~~~~~~~

Upon the successful completion of probe, the device is registered with the class to which it belongs. Device drivers belong to one and only one class, and that is set in the driver's devclass field. devclass_add_device is called to enumerate the device within the class and actually register it with the class, which happens with the class's register_dev callback.

для чего он тогда нужен?

nanoo_linux ()
Ответ на: комментарий от tailgunner

Совершенно верно. Но как подсказали выше struct file создаётся когда его открывают. А мне бы желательно такой вот «контейнер» иметь когда .probe работает.

nanoo_linux ()
Ответ на: комментарий от nanoo_linux

> /Documentation/driver-model/binding.txt

Обычно драйвер устройства не участвует в реализации device model. Более того, этого не следует делать по чисто практическим соображениям - API кода, реализующего driver model, меняется, так что кроме обычных сломов драйверного API добавляются еще и сломы driver model.

Короче, если твоя цель - просто написать драйвер, то лучше не лезть в такие дебри.

для чего он тогда нужен?

Те, кому он нужен, не задают таких вопросов :) Я, например, полез туда, чтобы реализовать по нескольку спецфайлов на устройство, но до сих пор не уверен, что поступил правильно.

tailgunner ★★★★★ ()
Ответ на: комментарий от nanoo_linux

> А мне бы желательно такой вот «контейнер» иметь когда .probe работает.

Зачем? Используй глобальный (для драйвера) список устройств, чем плохо?

tailgunner ★★★★★ ()
Ответ на: комментарий от tailgunner

чем плохо

Да ни чем не плохо, я уже више писал, что это одно из решений. Так наверное и придётся делать.
Тогда встречный вопрос: а чем плохо использовать inode->i_private для pci_dev? Это имеет какой-то негативный эффект или какие-то часли ядра его тоже используют?
Спасибо.

nanoo_linux ()
Ответ на: комментарий от nanoo_linux

Да и это, я раньше miscdevice использовал. С ним для udev ничего делать не надо, файлы сами появляются. device_class тоже ивенты udev посылает, а cdev нет. Тогда надо будет в udev конфиг добавить.

nanoo_linux ()
Ответ на: комментарий от nanoo_linux

> Тогда встречный вопрос: а чем плохо использовать inode->i_private для pci_dev?

Строго говоря, inode - это объект ФС. Твой драйвер не реализует ФС, поэтому не следует пользоваться inode. И вообще, IIRC, inode драйверу даже передается не всегда.

tailgunner ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.