Драйвер получает доступ к портам с помощью inb() и outb()
Я делаю драйвер устройства, который включает и выключает светодиоды клавиатуры, получая любую комбинацию из трех, двух, одной или ни одной цифры, которая должна быть 1, 2 или 3, если я сделаю:
echo 12 > /dev/ledDevice
Программа должна включить Num Lock, Caps Lock и отключить блокировку прокрутки, если я напишу:
echo "" > /dev/ledDevice
Каждый светодиод должен быть выключен или включен, если это будет echo 123
но этого не происходит, они всегда выключаются. Они используются (в Debian 6) в порту, представленном целым числом, в позициях o, 1 и 2. Кроме того, но я не знаю, связано ли это, 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;
}
1 ответ
Это может быть вызвано множеством ситуаций. Многие ключевые переключатели и другие инструменты запускают 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 .