2014-01-11 90 views
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; 
} 
+2

IIRC,這樣的程序已經存在:'setleds'和'xkbvleds';所以研究他們的源代碼(你可能不需要任何內核代碼)。 –

+0

Esa UCM !! Prueba haciendo una xor en vez de una或。 El operador es^ – Jesus

+0

我已經解決了它,(是,UCM),問題在於用戶使用字節數而不是鏈長度複製,因此您必須使用strlen();如果您直接接入端口,則ACK是正常警告 – Kaostias

回答

2

這可以觸發在無數的情況。不少關鍵切換器和其他工具都會觸發ATKBD_RET_NAK,在某些情況下,我們確實無能爲力。

考慮到您的代碼只是我們試圖打破錯誤代碼。從外觀來看,這個錯誤似乎是由atkbd_interrupt調用引起的。

atkbd_interrupt()涉及處理從鍵盤接收的數據到事件。

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

特定錯誤消息的發生是由於耦合到unsigned char data參數殼體ATKBD_RET_NAK的觸發。

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。

相關問題