Разработка ядра Linux | страница 95



— значение параметра >dev_id. В случае ошибки код печатает сообщение, что произошла ошибка, и возвращается из выполняющейся функции. Если функция регистрации возвращает нулевое значение, то обработчик прерывания инсталлирован успешно. С этого момента обработчик прерывания будет вызываться в ответ на приходящие прерывания. Важно произвести инициализацию оборудования и регистрацию обработчика прерывания в правильной последовательности, чтобы предотвратить возможность вызова обработчика до того момента, пока оборудование не инициализировано.

Освобождение обработчика прерывания

Для освобождения линии прерывания необходимо вызвать функцию

>void free_irq(unsigned int irq, void *dev_id);

Если указанная линия не является совместно используемой, то эта функция удаляет обработчик и запрещает линию прерывания. Если линия запроса на прерывание является совместно используемой, то удаляется обработчик, соответствующий параметру >dev_id. Линия запроса на прерывание также запрещается, когда удаляется последний обработчик. Теперь понятно, почему важно передавать уникальное значение параметра >dev_id. При использовании совместно используемых прерываний требуется уникальный идентификатор для того, чтобы отличать друг от друга различные обработчики, связанные с одним номером прерывания, и позволить функции >free_irq() удалять правильный обработчик. В любом случае, если параметр >dev_id не равен значению >NULL, то он должен соответствовать тому обработчику, который удаляется.

Вызов функции >free_irq() должен производиться из контекста процесса.


Таблица 6.1. Список функций управления регистрацией прерываний

ФункцияОписание
>request_irq()Зарегистрировать заданный обработчик прерывания для заданной линии прерывания
>free_irq()Освободить указанный обработчик прерывания. Если с линией прерывания больше не связан ни один обработчик, то запретить указанную линию прерывания

Написание обработчика прерывания

Следующее описание является типичным для обработчика прерывания.

>static irqreturn_t intr_handler(int irq, void *dev_id,

> struct pt_regs *regs);

Заметим, что оно должно соответствовать аргументу, который передается в функцию >request_irq(). Первый параметр, >irq, — это численное значение номера прерывания, которое обслуживается обработчиком. Сейчас этот параметр практически не используется, кроме разве что при печати сообщений. Для версий ядра, меньших 2.0, не было параметра >dev_id, поэтому параметр >irq использовался, чтобы различать устройства, которые обслуживаются одним драйвером, и поэтому используют один и тот же обработчик прерываний (как пример можно рассмотреть компьютер с несколькими контроллерами жесткого диска одного типа).