我正在制作一个设备驱动程序,通过接收三个,两个,一个或任何数字的组合来打开和关闭键盘LED,如果我做的话,应该是1,2或3:
echo 12 > /dev/ledDevice
如果我写了:
,程序应该打开Num lock,Caps lock并关闭滚动锁定 echo "" > /dev/ledDevice
每个LED应该关闭,或者如果它是echo 123
则打开但是这不会发生,它们总是关闭。它们在一个用整数表示的端口中,在位置o,1和2中被ubicated(在debian 6中)。另外但我不知道它是否相关,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;
}
答案 0 :(得分:2)
这可以在无数种情况下触发。相当多的键切换器和其他工具会触发ATKBD_RET_NAK
,在某些情况下我们肯定会无能为力。
考虑到您的代码是公正的,让我们尝试打破错误代码。从它的外观来看,错误似乎来自atkbd_interrupt
调用。
atkbd_interrupt()
处理从键盘接收到的事件数据。
static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char
data, unsigned int flags)
{----}
由于触发与ATKBD_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。