LINUX.ORG.RU

Доступ к двум одинаковым платам из user-space


0

0

Здравствуйте. Написал драйвер для pci устройства(передача данных) в ядре 2.6.26.

Функция инициализации включает в себя инициализацию pci и иниц-ю character device:

rval = register_chrdev(0, "tester", &tester_fops);

...

return pci_register_driver(&pci_driver);

Если в компьютер вставлены два таких устройства, при загрузке драйвера каждому устройству выделяется свои прерывания и область памяти. Для этого устройства я создаю файл устройства в папке /dev.

Получить доступ к первому из двух устройств проблем нет - достаточно открыть файл устройства

fd=open("/dev/tester", O_RDWR);

Как из user-space достучаться к каждому из этих двух устройств?
Перемещено Dimez из Linux-hardware


На каждое устройство создавай свой файл в /dev. Для примера, com-порты - /dev/ttyS0, /dev/ttyS1,...

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

В консоли ручками я могу создать два и более устройств, это просто. Но в драйвере идет регистрация одного устройства -

rval = register_chrdev(0, "tester", &tester_fops);

Поэтому при загрузке драйвера под одним именем получаются сразу два устройства - оба в /proc/interrupts называются tester.

Если в драйвере регистрировать несколько устройств - все эти устройства будут относиться к первой из двух плат.

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

> Но в драйвере идет регистрация одного устройства

У тебя претензии к своему-же драйверу? Надо доработать чтобы все устройства инициализировались. Посмотри как это сделано, например, у сетевых карточек. Какой-нить rtl8129.

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

Как раз поэтому я на форум и зашел, чтобы узнать, как доработать.

У меня на одном компе есть две сетевые карты, так там для них используются разные драйверы. А вот каким образом, непонятно.

В драйверах сетевых карт та же функция, как и у меня:

pci_register_driver(&xxx_driver);

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

Посмотри в книге Linux Device Drivers.  А так я вижу у rtl8139:

static struct pci_driver rtl8139_pci_driver = {
    .name       = DRV_NAME,
    .id_table   = rtl8139_pci_tbl,
    .probe      = rtl8139_init_one,
    [...]
};


Вот rtl8139_pci_tbl это список pci id для которых ядро будет
использовать этот драйвер. А дальше оно для каждого найденного
адаптера будет вызывать инициализирующую функцию(rtl8139_init_one).
И вот в этой функции и аллоцируется всё что нужно.

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

В Linux device drivers я ответа не нашел, смотрел там в первую очередь. Этой строчкой .id_table = rtl8139_pci_tbl указывается список, но карты у меня одинаковые - VendorID и DeviceID у них тот же, поэтому в списке всего один элемент.

Соответственно и функция инициализации не отличает платы друг от друга. Как сделать так, чтобы отличала, непонятно.

jencha
() автор топика

а слабо одно устройство назвать как tester0, второе - tester1 (и т.д.)?
между прочим eth интерфейсы нумеруются банальным счетчиком.

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

>Соответственно и функция инициализации не отличает платы друг от друга.
ну здрасте! а ничего, что они как бы на разных pci-адресах сидят?

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

То, что они сидят на разных адресах для драйвера pci параллельно. PCI устройство инициалзируется командой:

pci_register_driver(&pci_driver);

Где pci_driver - структура, имеющая 4 поля:

static struct pci_driver pci_driver = {

.name = "xxx",

.id_table = ids,

.probe = probe,

.remove = remove,

}; Имя, таблица сочетаний Vendor и Device, функция probe и remove.

Данных о шине нигде не указывается :( По поводу уrазать разные имена: не понимаю, где это надо делать.

То есть указать как alias, можно, для сетевых карт так и сделано.

А дальше? Пользователь в программе обращается непосредственно к файлу устройства из /dev.

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

Думаю, что разобрался. Во время загрузки драйвера функция probe запускается 2 раза, так как в системе два устройства.

Только потом запускается функция инициализации драйвера.

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

Единственная проблема - обработчиков прерываний поставить два не удалось, все равно прерывания от обоих устройств сыпятся в один обработчик. И со стороны пользователя можно поставить только один обработчик асинхронных уведомлений.

Остальное вроде все работает :) Спасибо за подсказки!

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