Готовый перевод Linux Device Drivers 3 / Драйверы устройств Линукс (третье издание): 17.12. Custom ioctl Commands
17.12. Пользовательские команды ioctl
Мы видели, что системный вызов ioctl реализован для сокетов.
SIOCSIFADDR и SIOCSIFMAP являются примерами сокетной функции
ioctl. Теперь рассмотрим, как третий аргумент системного вызова
используется сетевым кодом.
При выполнении системного вызова ioctl для сокета, управление
передается в функцию sock_ioctl, специфичную для протокола (где
"протокол" означает основной используемый сетевой протокол, например,
IP или AppleTalk). Номера команд определенны в "linux/sockios.h".
Любая команда, не опознанная на уровне протокола, передается на
уровень устройства. Эта, специфичная для устройства, команда
передается третьим аргументом из пользовательского пространства, как
struct ifreq * (структура определена в "linux/if.h"). Команды
SIOCSIFADDR И SIOCSIFMAP воздействуют на структуру ifreq.
Дополнительный аргумент SIOCSIFMAP, хоть определен как ifmap, но
является полем ifreq.
Дополнительно к стандартным вызовам, каждый интерфейс может
определять собственные команды ioctl. Интерфейс plip, например,
позволяет интерфейсу изменять его внутренние значения таймаута,
через ioctl. Реализация ioctl для сокетов поддерживает 16 приватных
команд интерфейса: с SIOCDEVPRIVATE по SIOCDEVPRIVATE+15
(обратите
внимание, что, согласно <"linux/sockios.h">, команды SIOCDEVPRIVATE
не желательны; не ясно чем заменить их, и многие драйверы все еще
используют их).
При обнаружении одной из этих команд, вызывается dev->do_ioctl
для соответствующего интерфейса. Функция получает тот же указатель
struct ifreq *, что и универсальная функция ioctl:
int (*do_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd);
Указатель ifr содержит адрес копии структуры пользователя в
пространстве ядра. После вызова do_ioctl, структура копируется обратно
в пространство пользователя. Поэтому драйвер может использовать
приватные команды, как для отправки, так и для принятия данных.
Команды, специфичные устройству, могут использовать поля struct
ifreq. Но поля хранят стандартизированные значения, и маловероятно,
что драйвер cможет приспособить структуру для своих нужд. Поле
ifr_data является указателем caddr_t, который используется в
зависимости от специфики устройства. Драйвер и программа, вызвавшая
ioctl, должна иметь соглашения об использовании ifr_data. Например,
ppp-stats использует специфичные устройству команды, чтобы передать,
информацию от драйвера интерфейса ppp.
Здесь не показана реализация функции do_ioctl, но приведенная
информация и примеры из ядра позволят вам написать ее при
необходимости. Имейте ввиду, что реализация plip не корректно
использует ifr_data, и не может служить примером реализации ioctl.
Внимание! Этот перевод, возможно, ещё не готов.
Его статус: перевод редактируется
Переведено на Нотабеноиде
http://notabenoid.org/book/11832/38393
Переводчики: hardorsoft
Настройки
Готово:
