LINUX.ORG.RU

Драйвер, обработчик прервания не вызывается

 


0

2

Кажется, сделал все, что нужно. При инициализации модуля

enable_irq(dev.irq_line);
if (0 != request_irq(dev.irq_line, irq_hndl, IRQF_SHARED, DRV_NAME, dev.dev_id)) {
     /* printk error code */
}
ошибки не выдает. Железка устроена так, что когда в нее пишут, после операции чтения/записи она должна выставить прерывание. Соответственно,
iowrite32(some_command, BAR0+8);
wait_event_interruptible_timeout(my_queue,
                                 dev.irq_flag != 0,
                                 500);
А вот обработчик прерывания у меня почему-то не вызывается. Железка показывает, что операция выполнена (соответствующий бит взводится). Что порекомендуете проверить?

★★

Судя по /proc/interrupts, прерывание не генерируется.

enable_irq(dev.irq_line);

if (0 != request_irq(dev.irq_line, irq_hndl, IRQF_SHARED, DRV_NAME, dev.dev_id)) {

Такое трогательное защищенное программирование, а обработчик устанавливается при уже разрешенном прерывании.

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

прерывание должно быть разрешено после установки обработчика?

Да. Иначе прерывание может быть сгенерировано между enable_irq и request_irq, когда обработчика еще нет. Правда, я не думаю, что у тебя загвоздка в этом :)

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner
    get_user_pages(current
                          , current->mm
                          , (long int)(cmd_p->buffer)
                          , cmd_p->pages // кол-во страниц
                          , 0
                          , 0
                          , &pages[0] // ранее выделено
                          , vmas);
    for (i = 0; i < pinned_pages_amount; i++) {
        data_desc[i] = (int*)__pa(kmap(pages[i]));
    }

а смещение чего и/или от чего ты имеешь ввиду?

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

после записи бит WR_Exec взведен.

А до записи? %) Чтение с неправильно замапленного адреса возвращает «все единицы».

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

Это уже проверено, вроде все ОК

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

Error: could not insert module ./sgdma.ko: Unknown symbol in module

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

Да. Во-первых, MSI нужно включать; во-вторых, бывают случаи, когда втыкаешь PCIe устройство в одну машину - оно не работает (как раз прерывания не генерируются), а в другой - всё нормально.

sgdma.ko

И дай модулю какое-нибудь приличное имя.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от braboar

shEEt подойдет?

О да. Прекрасное имя, серьезно - абсолютно уникальное.

tailgunner ★★★★★
()

ananas, tailgunner спасибо!

Заработало, обработчик ловит прерывание, жизнь удалась.

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

Не-а

Я пытался установить обработчик на прерывание, полученное из конфигурационного пространства, а система перекидывала на другое прерывание. При инициализации модуля передается *pci_dev, вот из этой структуры надо вытаскивать прерывание.

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