Changeset cea12e9 in mainline for kernel/genarch/src/kbd/i8042.c
- Timestamp:
- 2006-10-27T11:13:13Z (18 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 16d71f41
- Parents:
- 8c84448
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/genarch/src/kbd/i8042.c
r8c84448 rcea12e9 42 42 #include <genarch/kbd/scanc_pc.h> 43 43 #include <arch/drivers/i8042.h> 44 #include <arch/interrupt.h>45 44 #include <cpu.h> 46 45 #include <arch/asm.h> … … 50 49 #include <console/console.h> 51 50 #include <interrupt.h> 51 #include <sysinfo/sysinfo.h> 52 #include <ddi/irq.h> 52 53 53 54 /* Keyboard commands. */ … … 87 88 }; 88 89 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. */ 91 static irq_t i8042_irq; 92 93 /** Wait until the controller reads its data. */ 94 static void i8042_wait(void) { 95 while (i8042_status_read() & i8042_WAIT_MASK) { 96 /* wait */ 97 } 98 } 99 94 100 void i8042_grab(void) 95 101 { 96 oldvector = exc_register(VECTOR_KBD, "i8042_interrupt", (iroutine) i8042_interrupt); 102 ipl_t ipl = interrupts_disable(); 103 97 104 i8042_wait(); 98 105 i8042_command_write(i8042_SET_COMMAND); … … 100 107 i8042_data_write(i8042_COMMAND); 101 108 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 104 116 void i8042_release(void) 105 117 { 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 126 static irq_ownership_t i8042_claim(void) 127 { 128 return IRQ_ACCEPT; 129 } 130 131 static 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 } 108 151 } 109 152 110 153 /** 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); 154 void i8042_init(devno_t devno, inr_t inr) 155 { 122 156 chardev_initialize("i8042_kbd", &kbrd, &ops); 123 157 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 125 168 /* 126 169 * Clear input buffer. 127 170 * Number of iterations is limited to prevent infinite looping. 128 171 */ 172 int i; 129 173 for (i = 0; (i8042_status_read() & i8042_BUFFER_FULL_MASK) && i < 100; i++) { 130 174 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(); 163 182 } 164 183
Note:
See TracChangeset
for help on using the changeset viewer.