Changeset cea12e9 in mainline for kernel/genarch/src/kbd/i8042.c


Ignore:
Timestamp:
2006-10-27T11:13:13Z (18 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
16d71f41
Parents:
8c84448
Message:

ia32: adopt new IRQ interface, mouse not tested yet

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/genarch/src/kbd/i8042.c

    r8c84448 rcea12e9  
    4242#include <genarch/kbd/scanc_pc.h>
    4343#include <arch/drivers/i8042.h>
    44 #include <arch/interrupt.h>
    4544#include <cpu.h>
    4645#include <arch/asm.h>
     
    5049#include <console/console.h>
    5150#include <interrupt.h>
     51#include <sysinfo/sysinfo.h>
     52#include <ddi/irq.h>
    5253
    5354/* Keyboard commands. */
     
    8788};
    8889
    89 static void i8042_interrupt(int n, istate_t *istate);
    90 static void i8042_wait(void);
    91 
    92 static iroutine oldvector;
    93 /** Initialize keyboard and service interrupts using kernel routine */
     90/** Structure for i8042's IRQ. */
     91static irq_t i8042_irq;
     92
     93/** Wait until the controller reads its data. */
     94static void i8042_wait(void) {
     95        while (i8042_status_read() & i8042_WAIT_MASK) {
     96                /* wait */
     97        }
     98}
     99
    94100void i8042_grab(void)
    95101{
    96         oldvector = exc_register(VECTOR_KBD, "i8042_interrupt", (iroutine) i8042_interrupt);
     102        ipl_t ipl = interrupts_disable();
     103       
    97104        i8042_wait();
    98105        i8042_command_write(i8042_SET_COMMAND);
     
    100107        i8042_data_write(i8042_COMMAND);
    101108        i8042_wait();
    102 }
    103 /** Resume the former interrupt vector */
     109
     110        spinlock_lock(&i8042_irq.lock);
     111        i8042_irq.notif_cfg.notify = false;
     112        spinlock_unlock(&i8042_irq.lock);
     113        interrupts_restore(ipl);
     114}
     115
    104116void i8042_release(void)
    105117{
    106         if (oldvector)
    107                 exc_register(VECTOR_KBD, "user_interrupt", oldvector);
     118        ipl_t ipl = interrupts_disable();
     119        spinlock_lock(&i8042_irq.lock);
     120        if (i8042_irq.notif_cfg.answerbox)
     121                i8042_irq.notif_cfg.notify = true;
     122        spinlock_unlock(&i8042_irq.lock);
     123        interrupts_restore(ipl);
     124}
     125
     126static irq_ownership_t i8042_claim(void)
     127{
     128        return IRQ_ACCEPT;
     129}
     130
     131static void i8042_irq_handler(irq_t *irq, void *arg, ...)
     132{
     133        if (irq->notif_cfg.notify && irq->notif_cfg.answerbox)
     134                ipc_irq_send_notif(irq);
     135        else {
     136                uint8_t x;
     137                uint8_t status;
     138               
     139                while (((status = i8042_status_read()) & i8042_BUFFER_FULL_MASK)) {
     140                        x = i8042_data_read();
     141                       
     142                        if ((status & i8042_MOUSE_DATA))
     143                                continue;
     144                       
     145                        if (x & KEY_RELEASE)
     146                                key_released(x ^ KEY_RELEASE);
     147                        else
     148                                key_pressed(x);
     149                }
     150        }
    108151}
    109152
    110153/** Initialize i8042. */
    111 void i8042_init(void)
    112 {
    113         int i;
    114 
    115         i8042_grab();
    116         /* Prevent user from accidentaly releasing calling i8042_resume
    117          * and disabling keyboard
    118          */
    119         oldvector = NULL;
    120 
    121         trap_virtual_enable_irqs(1<<IRQ_KBD);
     154void i8042_init(devno_t devno, inr_t inr)
     155{
    122156        chardev_initialize("i8042_kbd", &kbrd, &ops);
    123157        stdin = &kbrd;
    124 
     158       
     159        irq_initialize(&i8042_irq);
     160        i8042_irq.devno = devno;
     161        i8042_irq.inr = inr;
     162        i8042_irq.claim = i8042_claim;
     163        i8042_irq.handler = i8042_irq_handler;
     164        irq_register(&i8042_irq);
     165       
     166        trap_virtual_enable_irqs(1 << inr);
     167       
    125168        /*
    126169         * Clear input buffer.
    127170         * Number of iterations is limited to prevent infinite looping.
    128171         */
     172        int i;
    129173        for (i = 0; (i8042_status_read() & i8042_BUFFER_FULL_MASK) && i < 100; i++) {
    130174                i8042_data_read();
    131         } 
    132 }
    133 
    134 /** Process i8042 interrupt.
    135  *
    136  * @param n Interrupt vector.
    137  * @param istate Interrupted state.
    138  */
    139 void i8042_interrupt(int n, istate_t *istate)
    140 {
    141         uint8_t x;
    142         uint8_t status;
    143 
    144         while (((status=i8042_status_read()) & i8042_BUFFER_FULL_MASK)) {
    145                 x = i8042_data_read();
    146 
    147                 if ((status & i8042_MOUSE_DATA))
    148                         continue;
    149 
    150                 if (x & KEY_RELEASE)
    151                         key_released(x ^ KEY_RELEASE);
    152                 else
    153                         key_pressed(x);
    154         }
    155         trap_virtual_eoi();
    156 }
    157 
    158 /** Wait until the controller reads its data. */
    159 void i8042_wait(void) {
    160         while (i8042_status_read() & i8042_WAIT_MASK) {
    161                 /* wait */
    162         }
     175        }
     176       
     177        sysinfo_set_item_val("kbd", NULL, true);
     178        sysinfo_set_item_val("kbd.devno", NULL, devno);
     179        sysinfo_set_item_val("kbd.inr", NULL, inr);
     180       
     181        i8042_grab();
    163182}
    164183
Note: See TracChangeset for help on using the changeset viewer.