Re: 2.6.0-test1-ac2 issues / Toshiba Laptop keyboard

From: Chris Heath (chris@heathens.co.nz)
Date: Sat Jul 19 2003 - 08:18:28 EST


> The patch that fixed the issue with the key release events was this -
> I submitted it to Alan who then put it into ac and then it went into
> 2.4.x...
>
> Details: http://www.informatik.uni-freiburg.de/~leibl/lol/
>
> Patch excerpt:
>
> + /* The following 'if' is a workaround for hardware
> + * which sometimes send the key release event twice */
> + unsigned char next_scancode = scancode|up_flag;
> + if (up_flag && next_scancode==prev_scancode) {
> + /* unexpected 2nd release event */
> + } else {
> + prev_scancode=next_scancode;
> + put_queue(next_scancode);
> + }
>
> I haven't checked if 2.6.0 already has this!

This patch went into 2.4.21, and we immediately got a bug report!
See http://www.ussg.iu.edu/hypermail/linux/kernel/0306.1/1871.html

I wrote another patch (better, I hope), which is now in 2.4.22-pre6-ac1.
It is included below. I would appreciate it if it got some testing on
both Toshiba laptops and other machines.

I am also interested in helping fix it in 2.6, but let's see if the fix
for 2.4 works first.

Chris

--- a/drivers/char/keyboard.c 2003-07-07 21:03:44.000000000 -0400
+++ b/drivers/char/keyboard.c 2003-07-08 23:07:47.000000000 -0400
@@ -198,6 +198,7 @@
         unsigned char keycode;
         char up_flag = down ? 0 : 0200;
         char raw_mode;
+ char have_keycode;
 
         pm_access(pm_kbd);
         add_keyboard_randomness(scancode | up_flag);
@@ -214,16 +215,30 @@
                 tty = NULL;
         }
         kbd = kbd_table + fg_console;
- if ((raw_mode = (kbd->kbdmode == VC_RAW))) {
+ /*
+ * Convert scancode to keycode
+ */
+ raw_mode = (kbd->kbdmode == VC_RAW);
+ have_keycode = kbd_translate(scancode, &keycode, raw_mode);
+ if (raw_mode) {
                 /*
                  * The following is a workaround for hardware
                  * which sometimes send the key release event twice
                  */
                 unsigned char next_scancode = scancode|up_flag;
- if (up_flag && next_scancode==prev_scancode) {
+ if (have_keycode && up_flag && next_scancode==prev_scancode) {
                         /* unexpected 2nd release event */
                 } else {
- prev_scancode=next_scancode;
+ /*
+ * Only save previous scancode if it was a key-up
+ * and had a single-byte scancode.
+ */
+ if (!have_keycode)
+ prev_scancode = 1;
+ else if (!up_flag || prev_scancode == 1)
+ prev_scancode = 0;
+ else
+ prev_scancode = next_scancode;
                         put_queue(next_scancode);
                 }
                 /* we do not return yet, because we want to maintain
@@ -231,10 +246,7 @@
                    values when finishing RAW mode or when changing VT's */
         }
 
- /*
- * Convert scancode to keycode
- */
- if (!kbd_translate(scancode, &keycode, raw_mode))
+ if (!have_keycode)
                 goto out;
 
         /*

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



This archive was generated by hypermail 2b29 : Wed Jul 23 2003 - 22:00:37 EST