Готовый перевод Linux Device Drivers 3 / Драйверы устройств Линукс (третье издание): 17.4. Открытие и закрытие
17.4. Открытие и закрытие
Наш драйвер может быть опробован при загрузке модуля или
загрузке системы. До того как интерфейс сможет доставлять пакеты, ядро
должно произвести открытие драйвера, после чего произойдет
назначение адреса. Ядро открывает или закрывает интерфейс в ответ на
команду ifconfig.
Когда ifconfig используется для назначения адреса интерфейсу, он
выполняет два действия.
Назначает адрес вызовом ioctrl(SIOCSIFADDR) (Socket I/O Control
Set Interface Address). Затем устанавливает бит IFF_UP в dev->flag, через
ioctrl(SIOCSIFFLAGS) (Socket I/O Control Set Interface Flags), активизируя
интерфейс.
Аналогично происходит и выключение интерфейса. ifconfig
использует ioctl(SIOCSIFFLAGS) для очистки флага IFF_UP и вызова
метода stop.
Оба метода возвращают 0 в случае успешной работы, и
отрицательное значение, если возникла ошибка.
Если абстрагироваться от реальной реализации кода, то можно
сказать, что драйвер выполняет одинаковые задачи как символьного так и
блочного устройства. оpen запрашивает необходимые системные ресурсы,
и активизирует интерфейс. stop выключает интерфейс и освобождает
ресурсы. В функции оpen, драйвер должен выполнить еще некоторые
действия.
Аппаратный (MAC) адрес должен копироваться из устройства в поле
dev->dev_addr, до того как интерфейс свяжется с внешним миром.
Программа устройства snull устанавливает адрес в функции оpen.
Имеется хитрость, аппаратный адрес используется в виде ASCII строки
длинной ETH_ALEN – длинна аппаратного адреса Ethernet.
Метод также стартует очередь передачи, что позволяет посылать
пакеты. Для этого ядро предоставляет функцию:
void netif_start_queue(struct net_device *dev);
Код функции оpen для snull выглядит следующим образом:
int snull_open(struct net_device *dev)
{
/* request_region( ), request_irq( ), .... (like fops->open) */
/*
* Назначение аппаратного адреса плате: используется "\0SNULx",
* где x = 0 или 1. первый байт = '\0', для избежания групповой
* адресации. (для групповой адресации первый байт - нечетный)
*/
memcpy(dev->dev_addr, "\0SNUL0", ETH_ALEN);
if (dev = = snull_devs[1])
dev->dev_addr[ETH_ALEN-1]++; /* \0SNUL1 */
netif_start_queue(dev);
return 0;
}
Как видите, в отсутствии реальной аппаратуры, метод оpen
выполняет мало действий. Тоже справедливо в отношении метода stop,
который выполняет действия обратные оpen. Функцию, реализующую
stop, часто называют close или release.
int snull_release(struct net_device *dev)
{
/* освобождение портов, прерываний и т.д. – аналогично fops->close */
netif_stop_queue(dev); /* ничего больше нельзя передавать*/
return 0;
}
Функция:
void netif_stop_queue(struct net_device *dev);
противоположна netif_start_queue. Функция вызывается при
закрытии интерфейса (в методе stop). Так же может использоваться
временная приостановка передачи, как показано в следующем
подразделе.
Внимание! Этот перевод, возможно, ещё не готов.
Его статус: перевод редактируется
Переведено на Нотабеноиде
http://notabenoid.org/book/11832/38384
Переводчики: hardorsoft
Настройки
Готово:
