I am making a device driver that turns on and off the keyboard leds by receiving any combination of three, two, one or none digit which should be 1, 2 or 3, if I make:
echo 12 > /dev/ledDevice
The program should turn on Num lock, Caps lock and turn off scroll lock, if I write:
echo "" > /dev/ledDevice
Every led should be turned off, or turn on if it would be echo 123
but this does not happen, they always turn off. They are ubicated (in debian 6) in a port represented with an integer, in the positions o, 1 and 2. Additionally but I don't know if it's related, outb
produce this exit on system log
atkbd.c: Spurious ACK on isa0060/serio0. Some program might be trying access hardware directly.
This is my source
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;
}
This can be triggered in a myriad of situations. Quite a few key switchers and other tools trigger the
ATKBD_RET_NAK
and in some cases we sure are helpless.Considering your code to be just, let us try to break the error code. From the looks of it, the error seems to arise from the
atkbd_interrupt
call.atkbd_interrupt()
deals with the processing of data received from the keyboard to events.The specific error message occurs due to the triggering of case
ATKBD_RET_NAK
coupled tounsigned char data
argument.The atkbd provides access to AT enhanced keyboard connected to the AT keyboard controller. Try bypassing KVM .