1

我正在制作一个设备驱动程序,它通过接收三个、两个、一个或无数字的任意组合来打开和关闭键盘 LED,如果我做的话,应该是 1、2 或 3:

 echo 12 > /dev/ledDevice

如果我这样写,程序应该打开 Num lock、Caps lock 并关闭 scroll lock:

 echo "" > /dev/ledDevice

每个 LED 都应该关闭,或者如果会打开,echo 123但不会发生这种情况,它们总是关闭。它们在用整数表示的端口中(在 debian 6 中)在位置 o、1 和 2 中被 ubicated。此外,但我不知道它是否相关,请outb在系统日志中生成此退出

atkbd.c: Spurious ACK on isa0060/serio0. Some program might be trying access hardware directly.

这是我的来源

static ssize_t
device_write(struct file *filp, const char *buff, size_t len, loff_t * off)
{
    char aux[BUF_LEN];
    int state = 0x00;
    int stateInitial = 0x00;
    int i =0;

    int timeout = 0;
    int retries = 7;
    printk(KERN_ALERT "Entering device_write");

    if(copy_from_user(aux,buff,len)){
        printk(KERN_ALERT "Problems in copy from user");
        return -EINVAL;
    }
    if (len  <= 4){
        for (i=0; i<len;i++){
            if(aux[i] == '3'){
                state = state | 0x01; //Scroll lock
            }else if(aux[i] == '1'){
                state = state | 0x02; //Caps lock
            }else if(aux[i]== '2'){
                state= state | 0x04; //Num lock
            }else if (aux[i] != '\n'){
                printk(KERN_ALERT "Error, wrong input.");
                return -EINVAL;
            }
        }
    }else   return -EINVAL;

    if (down_interruptible(&mtx)) /*SEMAPHORE LOCK*/
        return -EINTR;

    stateInitial = inb(0xed);

    stateInitial = stateInitial & 0xF8; //248 mask that deletes the 1, 2 and 3 bits (the led ones)
    state = stateInitial | state;

    /*
     Aquí se modifican los leds
    */
    timeout = 1000;
    outb(0xed,0x60); // Telling the keyboard that we want to modify the leds
    udelay(timeout);

    while (retries!=0 && inb(0x60)!=0xfa) { // Waiting for the controller
        retries--;
        udelay(timeout);
    }
    if (retries!=0) { // prooving the keyboard is ready

        outb(state,0x60);
    }else{  
        up(&mtx);  
        return -EINVAL;
    }
    up(&mtx);

    printk(KERN_ALERT "getting out from device_write, %d bytes read",len);

    return len;
}
4

1 回答 1

2

这可以在无数情况下触发。相当多的按键切换器和其他工具触发ATKBD_RET_NAK,在某些情况下我们肯定是无助的。

考虑到您的代码是公正的,让我们尝试破解错误代码。从外观上看,错误似乎是由atkbd_interrupt调用引起的。

atkbd_interrupt()处理从键盘接收到的数据到事件的处理。

static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char
data, unsigned int flags)
{----}

特定的错误消息是由于触发 caseATKBD_RET_NAK耦合到unsigned char data参数而发生的。

case ATKBD_RET_NAK:
    if (printk_ratelimit())
        dev_warn(&serio->dev,
             "Spurious %s on %s. "
             "Some program might be trying access hardware directly.\n",
             data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys);

atkbd 提供对连接到 AT 键盘控制器的 AT 增强型键盘的访问。尝试绕过 KVM 。

于 2014-01-11T12:53:22.110 回答