1
我正在製作一個設備驅動程序,它通過接收三個,兩個,一個或非數字(應該是1,2或3)的任意組合來打開和關閉鍵盤LED,如果我做:使用inb()和outb()訪問端口的驅動程序
echo 12 > /dev/ledDevice
程序應該打開數字鎖定,大寫鎖定和關閉滾動鎖定,如果我寫:
echo "" > /dev/ledDevice
每個LED都應該關閉,或者如果它打開將是echo 123
但這不會發生,他們總是關閉。他們是在一個整數代表的端口ubicated(在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;
}
IIRC,這樣的程序已經存在:'setleds'和'xkbvleds';所以研究他們的源代碼(你可能不需要任何內核代碼)。 –
Esa UCM !! Prueba haciendo una xor en vez de una或。 El operador es^ – Jesus
我已經解決了它,(是,UCM),問題在於用戶使用字節數而不是鏈長度複製,因此您必須使用strlen();如果您直接接入端口,則ACK是正常警告 – Kaostias