[PATCH] Make SysRq work with odd keyboards

From: Fredrik Roubert
Date: Wed May 10 2006 - 06:18:56 EST


Hi!

My keyboard is quite old, but I'm very fond of it so I wouldn't like to
replace it, even though it behaves quite odd when the SysRq key is
pressed: It sends the make and break codes immediately after another,
even when the key is beeing held down. After searching the list archives
I found that Mike A. Harris used to have a keyboard that be behaved in
the same way:

http://www.ussg.iu.edu/hypermail/linux/kernel/0001.2/1515.html
http://www.ussg.iu.edu/hypermail/linux/kernel/0001.3/0099.html

He also wrote a patch for the 2.2.14 kernel with a work-around for the
troublesome keyboard:

http://www.ussg.iu.edu/hypermail/linux/kernel/0002.3/0518.html
http://www.ussg.iu.edu/hypermail/linux/kernel/0002.3/0683.html

Using the same work-around as in Mike's patch, I've now written a new
patch (see attachment) for the 2.6.15 kernel.

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.

Would this work-around be acceptable for inclusion in the kernel?

(I don't know how common these kinds of keyboards are, but we at least
know that they are common enough to get two people to write patches to
support them.)

In the patch, I've used the constant sysrq_fix to show where the
work-around is being invoked. If the code with the work-around is used
with a normal keyboard, SysRq will work as expected with the addition
that one can release SysRq after initially pressed. This behaviour might
not be desireable, and in Mike's original patch /proc/sys/kernel/sysrq
was used to control activation of the work-around.

The method he used to get the value from /proc/sys/kernel/sysrq doesn't
work with current kernels, so before I write a new way to configure it,
I'd like to ask you kernel developers if you think that this should be
configurable and if it should be, if it's best to use /proc or to make
it a compile-time option?

Cheers // Fredrik Roubert

--
Sörbyplan 5 | +46 8 7609169 / +46 708 776974
SE-163 71 Spånga | http://www.df.lth.se/~roubert/
--- linux-2.6.15/drivers/char/keyboard.c 2006-01-03 04:21:10.000000000 +0100
+++ linux-2.6.15-sysrq/drivers/char/keyboard.c 2006-03-14 00:05:48.000000000 +0100
@@ -141,6 +141,7 @@
/* Simple translation table for the SysRq keys */

#ifdef CONFIG_MAGIC_SYSRQ
+static const int sysrq_fix = 1;
unsigned char kbd_sysrq_xlate[KEY_MAX + 1] =
"\000\0331234567890-=\177\t" /* 0x00 - 0x0f */
"qwertyuiop[]\r\000as" /* 0x10 - 0x1f */
@@ -150,6 +151,7 @@
"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;

@@ -1044,7 +1046,7 @@
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;
@@ -1064,9 +1066,14 @@

#ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */
if (keycode == KEY_SYSRQ && (sysrq_down || (down == 1 && sysrq_alt))) {
- sysrq_down = down;
+ if (!sysrq_fix || !sysrq_down) {
+ sysrq_down = down;
+ sysrq_alt_use = sysrq_alt;
+ }
return;
}
+ if (sysrq_fix && sysrq_down && !down && keycode == sysrq_alt_use)
+ sysrq_down = 0;
if (sysrq_down && down && !rep) {
handle_sysrq(kbd_sysrq_xlate[keycode], regs, tty);
return;

Attachment: pgp00000.pgp
Description: PGP signature