Разработка ядра Linux | страница 94
Этот параметр также передается обработчику прерывания при каждом вызове. Обычная практика — это передача указателя на структуру устройства (контекст устройства), так как этот параметр является уникальным, и, кроме того, в обработчике прерывания может быть полезным иметь указатель на эту структуру.
В случае успеха функция >request_irq()
возвращает нуль. Возврат ненулевого значения указывает на то, что произошла ошибка и указанный обработчик прерывания не был зарегистрирован. Наиболее часто встречающийся код ошибки — это значение >-EBUSY
, что указывает на то, что данная линия запроса на прерывание уже занята (и или при текущем вызове, или при первом вызове не был указан флаг >SA_SHIRQ
).
Следует обратить внимание, что функция >request_irq()
может переходить в состояние ожидания (sleep) и, соответственно, не может вызываться из контекста прерывания, или в других ситуациях, когда код не может блокироваться. Распространенной ошибкой является мнение, что функцию >request_irq()
можно безопасно вызывать в случаях, когда нельзя переходить в состояние ожидания. Это происходит отчасти от того, что действительно сразу непонятно, почему функция >request_irq()
должна чего-то ожидать. Дело в том. что при регистрации происходит добавление информации о линии прерывания в каталоге >/proc/irq
. Функция >proc_mkdir()
используется для создания новых элементов на файловой системе >procfs
. Эта функция вызывает функцию >proc_create()
для создания новых элементов файловой системы >procfs
, которая в свою очередь вызывает функцию >kmalloc()
для выделения памяти. Как будет показано в главе 11, "Управление памятью", функция >kmalloc()
может переходить в состояние ожидания. Вот так вот!
Для регистрации линии прерывания и инсталляции обработчика в коде драйвера можно использовать следующий вызов.
>if (request_irq(irqn, my_interrupt, SA_SHIRQ, "my_device", dev)) {
> printk(KERN_ERR "my_device: cannot register IRQ %d\n", irqn);
> return -EIO;
>}
В этом примере параметр >irqn
— это запрошенный номер линии запроса на прерывание, параметр >my_interrupt
— это обработчик этой линии прерывания, линия запроса на прерывание может быть совместно используемой, имя устройства — >"my_device"
, >dev
— значение параметра