[PATCH] fix magic sysrq on strange keyboards
authorFredrik Roubert <roubert@df.lth.se>
Mon, 26 Jun 2006 07:24:35 +0000 (00:24 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Mon, 26 Jun 2006 16:58:17 +0000 (09:58 -0700)
Magic sysrq fails to work on many keyboards, particulary most of notebook
keyboards.  This patch fixes it.

The idea is quite simple: Discard the SysRq break code if Alt is still being
held down.  This way the broken keyboard can send the break code (or the user
with a normal keyboard can release the SysRq key) and the kernel waits until
the next key is pressed or the Alt key is released.

Signed-off-by: Pavel Machek <pavel@suse.cz>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
drivers/char/keyboard.c

index edd996f..13e3126 100644 (file)
@@ -151,6 +151,7 @@ unsigned char kbd_sysrq_xlate[KEY_MAX + 1] =
         "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
         "\r\000/";                                      /* 0x60 - 0x6f */
 static int sysrq_down;
+static int sysrq_alt_use;
 #endif
 static int sysrq_alt;
 
@@ -1143,7 +1144,7 @@ static void kbd_keycode(unsigned int keycode, int down,
        kbd = kbd_table + fg_console;
 
        if (keycode == KEY_LEFTALT || keycode == KEY_RIGHTALT)
-               sysrq_alt = down;
+               sysrq_alt = down ? keycode : 0;
 #ifdef CONFIG_SPARC
        if (keycode == KEY_STOP)
                sparc_l1_a_state = down;
@@ -1163,9 +1164,14 @@ static void kbd_keycode(unsigned int keycode, int down,
 
 #ifdef CONFIG_MAGIC_SYSRQ             /* Handle the SysRq Hack */
        if (keycode == KEY_SYSRQ && (sysrq_down || (down == 1 && sysrq_alt))) {
-               sysrq_down = down;
+               if (!sysrq_down) {
+                       sysrq_down = down;
+                       sysrq_alt_use = sysrq_alt;
+               }
                return;
        }
+       if (sysrq_down && !down && keycode == sysrq_alt_use)
+               sysrq_down = 0;
        if (sysrq_down && down && !rep) {
                handle_sysrq(kbd_sysrq_xlate[keycode], regs, tty);
                return;