Не може да се освободи irq линията на клавиатурата: Устройството или ресурсът са заети

Пишех примерен код request_irq

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/delay.h>

MODULE_LICENSE("GPL");
int irq = 1;
int dev = 0xaa;

static irqreturn_t keyboard_handler(int irq, void *dev)
{
    static int counter = 0;
    pr_info("Keyboard Counter:%d\n", counter++);
    return IRQ_NONE;
}

static int test_interrupt_init(void)
{
    pr_info("%s: In init\n", __func__);
    return request_irq(irq, keyboard_handler, IRQF_SHARED,
            "my_keyboard_handler", &dev);
}

static void test_interrupt_exit(void)
{
    pr_info("%s: In exit\n", __func__);
    synchronize_irq(irq);
    free_irq(irq, &dev);
}

module_init(test_interrupt_init);
module_exit(test_interrupt_exit);

Докато премахвам този модул, получавам грешката:

rmmod: ERROR: ../libkmod/libkmod-module.c:769 kmod_module_remove_module() could not remove 'interrupt': Device or resource busy
rmmod: ERROR: could not remove module interrupt: Device or resource busy

Защо получавам тази грешка, тъй като използвам IRQF_SHARED и подадох параметъра dev в request_irq и free_irq

Актуализация: От dmesg не виждам никакви printk на rmmod Добавени регистрационни файлове на dmesg:

[ 4007.223281] Keyboard Counter:884
[ 4007.560846] Keyboard Counter:885
[ 4007.670339] Keyboard Counter:886
[ 4008.240139] Keyboard Counter:887
[ 4008.275412] Keyboard Counter:888
[ 4008.359338] Keyboard Counter:889
[ 4008.425101] Keyboard Counter:890
[ 4008.433026] Keyboard Counter:891
[ 4008.501763] Keyboard Counter:892
[ 4008.579201] Keyboard Counter:893
[ 4008.653335] Keyboard Counter:894
[ 4008.682862] Keyboard Counter:895
[ 4008.733950] Keyboard Counter:896

$ cat /proc/interrupts 
           CPU0       CPU1       CPU2       CPU3       
  0:          1          0          0          0   IO-APIC   2-edge      timer
  1:        449          0          0        707   IO-APIC   1-edge      i8042, my_keyboard_handler
  6:          0          0          2          0   IO-APIC   6-edge      floppy
  7:          0          0          0          0   IO-APIC   7-edge      parport0
  8:          0          1          0          0   IO-APIC   8-edge      rtc0
  9:          0          0          0          0   IO-APIC   9-fasteoi   acpi

person md.jamal    schedule 30.12.2018    source източник
comment
какво казва cat /proc/modules за interrupt? Трябва да е в състояние Live. Можете ли да ни покажете dmesg регистрационни файлове?   -  person Achal    schedule 30.12.2018
comment
Добавени dmesg регистрационни файлове и изход cat /proc/interrupts   -  person md.jamal    schedule 30.12.2018
comment
Този interrupt модул споменава ли се от някой друг модул? това е вероятната причина за Устройството или ресурсът е зает. Междувременно можете да направите rmmod -f, за да го премахнете, да изчистите dmesg и да стартирате отново.   -  person Achal    schedule 30.12.2018
comment
rmmod -f също дава същата грешка   -  person md.jamal    schedule 30.12.2018
comment
Най-вероятно клавиатурата вече е заявена от конзолата или X не е споделена. Трябва или да сте първи, или да ги деактивирате.   -  person stark    schedule 30.12.2018
comment
Кодът, който публикувахте, изглежда работи според очакванията на ubuntu 16.04, изпълняващ 4.15.0-42-generic   -  person yashC    schedule 01.01.2019
comment
можете ли да публикувате резултата от lsmod | grep <your module>   -  person yashC    schedule 01.01.2019
comment
Как измислихте 1 като параметър за request_irq()? Разбирате ли разликата между хардуерно IRQ и linux IRQ?   -  person 0andriy    schedule 12.01.2019


Отговори (1)


Опитайте тази:

static int irq = 1, dev = 0xaa;

Трябва да дадете разрешение на променлива irq и след това да извикате module_param() както по-долу

module_param(irq, int, S_IRUGO);

примерен код

MODULE_LICENSE("GPL");
static int irq = 1,  dev = 0xaa, counter = 0;
module_param(irq, int, S_IRUGO); /* give the permission to user space variable */

static irqreturn_t keyboard_handler(int irq, void *dev)
{
        pr_info("Keyboard Counter:%d\n", counter++);
        return IRQ_NONE;
}
/* registering irq */
static int test_interrupt_init(void)
{
        pr_info("%s: In init\n", __func__);
        if(request_irq(irq, keyboard_handler, IRQF_SHARED,"my_keyboard_handler", &dev)) {
                return -1;
        }
        else
        {
                pr_info("success \n");
                return 0;
        }
}

static void test_interrupt_exit(void)
{
        pr_info("%s: In exit\n", __func__);
        synchronize_irq(irq); /* synchronize interrupt */
        free_irq(irq, &dev);
}

module_init(test_interrupt_init);
module_exit(test_interrupt_exit);
person Achal    schedule 30.12.2018
comment
Да, работи на моята система. Можете ли да кажете конфигурацията на ядрото на вашата система? - person Achal; 30.12.2018
comment
Linux ubuntu 4.20.0-rc6+ #1 SMP петък, 28 декември 00:44:41 PST 2018 x86_64 x86_64 x86_64 GNU/Linux - person md.jamal; 30.12.2018
comment
Копирах вашия код и все още същият проблем: Устройството или ресурсът са заети - person md.jamal; 30.12.2018
comment
Същият коментар като в публикацията на OP. - person 0andriy; 12.01.2019