Re: Sticky keyboard keys [Debug Patch]

Fagerburg, Eric D (eric.d.fagerburg@intel.com)
Fri, 30 Jul 1999 14:16:52 -0700


Attached is a patch (against 2.2.10) that could help debugging the scenario
when a shift-like key is acting stuck down. I was corresponding with a
fellow who was experiencing this but I seem to have lost the e-mails. :(

The patch verifies that k_down[] and shift_state are consistent with
key_down[] at the end of handle_scancode. If something is inconsistent then
it prints out something like the following:

INCONSISTENT keyboard state
shift_state=00000008
computed =00000000
k_down[0-8]=0,0,0,1,0,0,0,0,0
computed =0,0,0,0,0,0,0,0,0
last 40 scan codes (most recent last)
d4 1c 9c 1c 9c 26 1f a6
9f 1c 9c 16 96 19 99 14
94 17 32 97 12 b2 92 1c
9c 26 a6 1f 9f 1c 9c 38
38 38 54 54 54 39 b9 b8

I got the above by pressing Alt, SysRq, space and then releasing Alt before
SysRq. The Left-Alt key is acting like it's still down even though it
isn't. Magic-SysRq support must be compiled in to reproduce what I've done
above but not for the patch in general. BTW, kernels >= 2.3.4 don't have
this same bug.

Decifering the output requires a bit of knowledge which can be obtained by
looking at include/linux/keyboard.h, drivers/char/defkeymap.*,
drivers/char/keyboard.c. Also, I don't mind helping decifer and track down
inconsistencies that might be found.

Eric

--begin patch

--- drivers/char/keyboard.c.orig Mon Apr 26 14:21:42 1999
+++ drivers/char/keyboard.c Mon Jul 26 14:24:22 1999
@@ -226,7 +226,7 @@
* Convert scancode to keycode
*/
if (!kbd_translate(scancode, &keycode, raw_mode))
- return;
+ goto HANDLE_SCANCODE_RETURN;

/*
* At this point the variable `keycode' contains the keycode.
@@ -245,11 +245,11 @@
#ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */
if (keycode == SYSRQ_KEY) {
sysrq_pressed = !up_flag;
- return;
+ goto HANDLE_SCANCODE_RETURN;
} else if (sysrq_pressed) {
if (!up_flag)
handle_sysrq(kbd_sysrq_xlate[keycode], kbd_pt_regs,
kbd, tty);
- return;
+ goto HANDLE_SCANCODE_RETURN;
}
#endif

@@ -289,7 +289,7 @@
if (type >= 0xf0) {
type -= 0xf0;
if (raw_mode && ! (TYPES_ALLOWED_IN_RAW_MODE &
(1 << type)))
- return;
+ goto HANDLE_SCANCODE_RETURN;
if (type == KT_LETTER) {
type = KT_LATIN;
if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
@@ -317,6 +317,58 @@
if (type == KT_SHIFT)
(*key_handler[type])(keysym & 0xff, up_flag);
#endif
+ }
+ }
+ // this code checks that the state of k_down[] and shift_state is
consistent
+ // with key_down[] and logs an error if not
+HANDLE_SCANCODE_RETURN:
+ {
+ #define SCANCODES_TO_REMEMBER 40
+ static unsigned char sc[SCANCODES_TO_REMEMBER];
+ static int lsc = -1; //
pos of last scancode added
+ unsigned char k_down_save[NR_SHIFT];
+ int shift_state_save;
+ int i;
+
+ // init sc if this is the first time through
+ if (lsc == -1) {
+ memset (sc, 0, sizeof (sc));
+ }
+
+ // remember the scancode
+ lsc = (lsc + 1) % SCANCODES_TO_REMEMBER;
+ sc[lsc] = scancode;
+
+ // save shift_state and k_down[]
+ shift_state_save = shift_state;
+ memcpy (k_down_save, k_down, sizeof (k_down));
+
+ // recompute shift_state and k_down[]
+ compute_shiftstate ();
+
+ if (shift_state != shift_state_save ||
+ memcmp (k_down_save, k_down, sizeof (k_down))) {
+ printk (KERN_WARNING "INCONSISTENT keyboard
state\n");
+ printk (KERN_WARNING "shift_state=%08x\n",
shift_state_save);
+ printk (KERN_WARNING "computed =%08x\n",
shift_state);
+ printk (KERN_WARNING "k_down[0-%d]", sizeof (k_down)
- 1);
+ for (i = 0; i < sizeof (k_down); i++) {
+ printk ("%c%d", i ? ',' : '=',
k_down_save[i]);
+ }
+ printk ("\n");
+ printk (KERN_WARNING "computed ");
+ for (i = 0; i < sizeof (k_down); i++) {
+ printk ("%c%d", i ? ',' : '=', k_down[i]);
+ }
+ printk ("\n");
+ printk (KERN_WARNING "last %d scan codes (most
recent last)", SCANCODES_TO_REMEMBER);
+ for (i = 0; i < SCANCODES_TO_REMEMBER; i++) {
+ if ((i % 8) == 0) {
+ printk ("\n" KERN_WARNING);
+ }
+ printk ("%02x ", sc[(i + lsc + 1) %
SCANCODES_TO_REMEMBER]);
+ }
+ printk ("\n");
}
}
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/