LINUX.ORG.RU

netdrivers ?


0

0

Здрастуйте не подскажите может у кого есть опыт
связанный с сетевыми драйверами у меня вопросики 
1. в какой функции драйвера правильно захватывать ресурсы: портов, памяти, прерывания
в функции инициализации модуля  (***_init()) или в функции открытия устройства ( ***_open() ) ?
2. В какой момент открывается устройство,
 в момент вызова: ifconfig ?
3. В разных сетевых модулях используется 
разный набор функций инициализации например pci_module_init() используется не везде.
Не подскажите от чего это может зависеть ?  

Если не сложно может кто может подсказать ?

anonymous

> 3. В разных сетевых модулях используется
> разный набор функций инициализации например pci_module_init()
> используется не везде.

pci_module_init() устарела, пользуйтесь pci_register_driver()

> 2. В какой момент открывается устройство,
> в момент вызова: ifconfig ?

ifconfig up/down приводит к вызову ->open/->stop из struct
net_device, если вы это имели в виду. смотрите

net/core/dev.c:dev_change_flags()

        ret = ((old_flags & IFF_UP) ? dev_close : dev_open)(dev);

и далее dev_close/dev_open.

> 1. в какой функции драйвера правильно захватывать ресурсы: портов,
> памяти, прерывания
> в функции инициализации модуля  (***_init()) или в функции открытия
> устройства ( ***_open() ) ?


мне кажется, логичнее всего сделать это в методе pci_driver->probe(), будет вызван вызван во время pci_register_driver().

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

Спасибо что ответили.

> если вы это имели в виду.
Да, косноязычно выразился.

Есть драйвера например smc9194.c там не используется
ни pci_module_init() ни pci_register_driver().
И не описывается структура: 
static struct pci_driver 

Соответственно нет  указателя на функцию
pci_driver->probe()

Там делается примерно так:
В функции module_init()
заполняется некоторые поля "struct net_device"
в том числе 
 devSMC9194.init = smc_init;

Дальще инициализируется 
  register_netdev(&devSMC9194);
Как я понимаю ядро при регистрации вызывает
мою функцию smc_init(), 
из которой явно(в теле прописан вызов) вызывается некая функция smc_probe(),
в которой происходит окончательная
инициализация структуры  "struct net_device"
указываются:
  dev->open            = smc_open;         
  dev->stop            = smc_close_release;
  dev->set_config      = smc_set_config;               
  ...  
  dev->do_ioctl        = sms_do_ioctl;
  ...
и всевозможные захваты: прерывания, портов(базовых
адресов)

Кроме того вроде инициализируются разные структуры, 
я смотрел scm9194.c и e100.c - используются вызовы
 pci_module_init(), ...
У Rubini описан способ без использования  pci_module_init(). 

Получается, драйвера пишутся по разному ?
Не могу понять как правильнее и почему по разному.
От чего это может зависеть, от аппаратуры(микросхемы)?
И как выбрать способ, если действительно по разному ?

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

>  Дальще инициализируется
>    register_netdev(&devSMC9194);
>  Как я понимаю ядро при регистрации вызывает

да, register_netdev() вызовет netdev->init()

> Получается, драйвера пишутся по разному ?

ну а вы думали :)

> От чего это может зависеть,

от времени написания, от квалификации/предпочтений
разработчика

> ни pci_module_init() ни pci_register_driver().
> И не описывается структура:
> static struct pci_driver

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

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

Спасибо.
Буду пробовать стремиться к тому коду,
который использует pci_driver, pci_register_driver().
Во всяком случае попробую разобраться.

Спасибо за Вашу помошь, составляя вопросы у меня иногда получается немного продвинуться в понимании.
Но все-же есть что мне не совсем понятно.
Такой вопрос наверное нельзя задавать, но
я не могу понять как происходит чтение пакетов и ожидание данных. 
Вернее функцию request_irq(), **_interrupt()
вроде знакомо, но вот не совсем ясно:
к сетевому драйверу нет доступа из пользовательского
контекста, вернее на прямую ? Т.е. нет скажем чтения, поэтому не нужно усыплять,когда нет данных/будить.
Есть такая функция: netif_wake_queue(dev), она при определенных условиях вызывается в обработчике.
Эта функция ставит в очередь на обработку или 
пробуждает очередь или просто пробуждает - аналог
wake_up_interruptible() ?
Есть еще похожие: netif_start_queue(),netif_stop_queue()
Я попробую сам разобраться о чем эти функции,
но может немного намекнете, если не сложно.

Еще вопрос по приему пакетов.
Выделяется память в функции чтения или в функции
обработчика: 
skb = dev_alloc_skb();

Но не удаляется, во всяком случае явно.
Если и удаляется то есть такая строчка
в драйвере e100_main.c: e100_alloc_skb()
err:
        dev_kfree_skb_irq(new_skb);
Но это в случае ошибки,
а если нет ошибки, выделенная память
 не освобождается?

Я наверное не очень понимаю
что это за буфер skb ?

Еще не понял пока в драйвере реализован буфер приема пакетов или это в самом ядре ?

Если сможите напишите пожалуйста пару строчек. 

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

я не очень понял ваши вопросы, кроме того я мало
знаю про net/ и drivers/net.

> Выделяется память в функции чтения или в функции
> обработчика:
> skb = dev_alloc_skb();
> Но не удаляется, во всяком случае явно.

все правильно, зачем удалять, если skb передается
"наверх"?

netif_wake_queue() НЕ аналог wake_up_interruptible(),
она "включает" NET_TX_SOFTIRQ.

netif_start_queue()/netif_stop_queue() просто переключают
__LINK_STATE_XOFF bit.

смотрите также http://www.linux.org.ru/view-message.jsp?msgid=736384

судя по вопросам вам стоит почитать Rubini, там что-то
есть про net drivers.

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

Вопросы действительно корявые. :(
Но я понял, что они лишние так как в сетевых
драйверах чтение осушествляется по прерыванию
и данные передаются наверх, а не в функцию чтения.
Rubini стараюсь смотреть.
Спасибо за ссылку.
Я искал, но или пропустил или читал плохо, спасибо. 
Буду разбираться.

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

> в сетевых драйверах чтение осушествляется по прерыванию

вообще-то вы можете этим обойтись, но смотрите также метод ->poll(), он работает не по прерыванию (NAPI).

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