patch-2.0.9 linux/drivers/char/keyboard.c
Next file: linux/drivers/char/mem.c
Previous file: linux/drivers/cdrom/mcdx.c
Back to the patch index
Back to the overall index
- Lines: 203
- Date:
Thu Jul 25 20:24:49 1996
- Orig file:
v2.0.8/linux/drivers/char/keyboard.c
- Orig date:
Mon May 13 23:02:48 1996
diff -u --recursive --new-file v2.0.8/linux/drivers/char/keyboard.c linux/drivers/char/keyboard.c
@@ -18,6 +18,7 @@
*/
#define KEYBOARD_IRQ 1
+#define DISABLE_KBD_DURING_INTERRUPTS 0
#include <linux/sched.h>
#include <linux/interrupt.h>
@@ -69,14 +70,6 @@
#define KBD_DEFLOCK 0
#endif
-/*
- * The default IO slowdown is doing 'inb()'s from 0x61, which should be
- * safe. But as that is the keyboard controller chip address, we do our
- * slowdowns here by doing short jumps: the keyboard controller should
- * be able to keep up
- */
-#define REALLY_SLOW_IO
-#define SLOW_IO_BY_JUMPING
#include <asm/io.h>
#include <asm/system.h>
@@ -337,48 +330,31 @@
e0_keys[scancode - 128];
}
-static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+#if DISABLE_KBD_DURING_INTERRUPTS
+#define disable_keyboard() do { send_cmd(0xAD); kb_wait(); } while (0)
+#define enable_keyboard() send_cmd(0xAE)
+#else
+#define disable_keyboard() /* nothing */
+#define enable_keyboard() /* nothing */
+#endif
+
+static void handle_scancode(unsigned char scancode)
{
- unsigned char scancode, keycode;
+ unsigned char keycode;
static unsigned int prev_scancode = 0; /* remember E0, E1 */
char up_flag; /* 0 or 0200 */
char raw_mode;
- int status;
- pt_regs = regs;
- send_cmd(0xAD); /* disable keyboard */
- kb_wait();
- status = inb_p(0x64);
- if ((status & kbd_read_mask) != 0x01) {
- /*
- * On some platforms (Alpha XL for one), the init code may leave
- * an interrupt hanging, yet with status indicating no data.
- * After making sure that there's no data indicated and its not a
- * mouse interrupt, we will read the data register to clear it.
- * If we don't do this, the data reg stays full and will not
- * allow new data or interrupt from the keyboard. Sigh...
- */
- if (!(status & 0x21)) { /* neither ODS nor OBF */
- scancode = inb(0x60); /* read data anyway */
-#if 0
- printk(KERN_DEBUG "keyboard: status 0x%x mask 0x%x data 0x%x\n",
- status, kbd_read_mask, scancode);
-#endif
- }
- goto end_kbd_intr;
- }
- scancode = inb(0x60);
- mark_bh(KEYBOARD_BH);
if (reply_expected) {
/* 0xfa, 0xfe only mean "acknowledge", "resend" for most keyboards */
/* but they are the key-up scancodes for PF6, PF10 on a FOCUS 9000 */
reply_expected = 0;
if (scancode == 0xfa) {
acknowledge = 1;
- goto end_kbd_intr;
+ return;
} else if (scancode == 0xfe) {
resend = 1;
- goto end_kbd_intr;
+ return;
}
/* strange ... */
reply_expected = 1;
@@ -392,7 +368,7 @@
printk(KERN_INFO "keyboard buffer overflow\n");
#endif
prev_scancode = 0;
- goto end_kbd_intr;
+ return;
}
do_poke_blanked_console = 1;
mark_bh(CONSOLE_BH);
@@ -417,12 +393,12 @@
#endif
#endif
prev_scancode = 0;
- goto end_kbd_intr;
+ return;
}
if (scancode == 0xe0 || scancode == 0xe1) {
prev_scancode = scancode;
- goto end_kbd_intr;
+ return;
}
/*
@@ -439,7 +415,7 @@
if (prev_scancode != 0xe0) {
if (prev_scancode == 0xe1 && scancode == 0x1d) {
prev_scancode = 0x100;
- goto end_kbd_intr;
+ return;
} else if (prev_scancode == 0x100 && scancode == 0x45) {
keycode = E1_PAUSE;
prev_scancode = 0;
@@ -449,7 +425,7 @@
printk(KERN_INFO "keyboard: unknown e1 escape sequence\n");
#endif
prev_scancode = 0;
- goto end_kbd_intr;
+ return;
}
} else {
prev_scancode = 0;
@@ -467,7 +443,7 @@
* So, we should also ignore the latter. - aeb@cwi.nl
*/
if (scancode == 0x2a || scancode == 0x36)
- goto end_kbd_intr;
+ return;
if (e0_keys[scancode])
keycode = e0_keys[scancode];
@@ -477,7 +453,7 @@
printk(KERN_INFO "keyboard: unknown scancode e0 %02x\n",
scancode);
#endif
- goto end_kbd_intr;
+ return;
}
}
} else if (scancode >= SC_LIM) {
@@ -500,7 +476,7 @@
" - ignored\n", scancode);
#endif
}
- goto end_kbd_intr;
+ return;
}
} else
keycode = scancode;
@@ -526,12 +502,12 @@
rep = set_bit(keycode, key_down);
if (raw_mode)
- goto end_kbd_intr;
+ return;
if (kbd->kbdmode == VC_MEDIUMRAW) {
/* soon keycodes will require more than one byte */
put_queue(keycode + up_flag);
- goto end_kbd_intr;
+ return;
}
/*
@@ -592,9 +568,32 @@
#endif
}
}
+}
+
+static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ unsigned char status;
-end_kbd_intr:
- send_cmd(0xAE); /* enable keyboard */
+ pt_regs = regs;
+ disable_keyboard();
+
+ status = inb_p(0x64);
+ do {
+ unsigned char scancode;
+
+ /* mouse data? */
+ if (status & kbd_read_mask & 0x20)
+ break;
+
+ scancode = inb(0x60);
+ if (status & 0x01)
+ handle_scancode(scancode);
+
+ status = inb(0x64);
+ } while (status & 0x01);
+
+ mark_bh(KEYBOARD_BH);
+ enable_keyboard();
}
static void put_queue(int ch)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov