From: Andries.Brouwer@cwi.nl

I just checked my old keyboard code, looking at pc_keyb.c here,
and the resend variable is used only to react to keyboard controller
requests for resend. There is no reaction to a timeout or parity
error from the keyboard controller, other than to throw the data
byte out as invalid.

In the new code we do
   serio_write(serio, ATKBD_CMD_RESEND);
when an error occurs.

I think that is bad for several reasons.
(i) It crashes the kernel with interrupt within interrupt :-)
(ii) Retrying is almost always bad.
Retrying is meaningful at the very lowest level.
With usb-storage devices I have seen the kernel retrying for
a quarter of an hour because all layers did a dozen or so retries
on error, and the total number of retries grew exponentially with
the number of layers involved.
(iii) My docs on the PS/2 keyboard controller say:
"the 0xfe resend command to the keyboard is meant for use by
the keyboard controller; it is not used by the BIOS".
(iv) You send the same commands to any connected device.
But sending 0xfe to a non-keyboard, e.g. a (multiplexed) mouse,
may provoke undefined behaviour, even hangs.

So, I would propose to remove the resend field from struct atkbd,
and to replace

    if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) \
         && !atkbd->resend && atkbd->write) {
            printk("atkbd.c: frame/parity error: %02x\n", flags);
            serio_write(serio, ATKBD_CMD_RESEND);
            atkbd->resend = 1;
            goto out;
    }

    if (!flags)
            atkbd->resend = 0;

by something like

    if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT)) {
	    printk("atkbd.c: frame/parity error: %02x\n", flags);
	    goto out;
    }

I seem to recall that I had to #ifdef out the printk in the end,
because too many people had bad keyboards, or switches that produced
some garbage at a switchover.
We can leave it for the moment, for debugging purposes, or give the
message at most five times or so.



 drivers/input/keyboard/atkbd.c |    8 +++-----
 1 files changed, 3 insertions(+), 5 deletions(-)

diff -puN drivers/input/keyboard/atkbd.c~keyboard-resend-fix drivers/input/keyboard/atkbd.c
--- 25/drivers/input/keyboard/atkbd.c~keyboard-resend-fix	2003-09-20 19:36:20.000000000 -0700
+++ 25-akpm/drivers/input/keyboard/atkbd.c	2003-09-20 19:37:22.000000000 -0700
@@ -35,7 +35,7 @@ static int atkbd_reset = 1;
 
 /*
  * Scancode to keycode tables. These are just the default setting, and
- * are loadable via an userland utility.
+ * are loadable via a userland utility.
  */
 
 static unsigned char atkbd_set2_keycode[512] = {
@@ -127,7 +127,6 @@ struct atkbd {
 	unsigned char emul;
 	unsigned short id;
 	unsigned char write;
-	unsigned char resend;
 };
 
 /*
@@ -147,10 +146,9 @@ static irqreturn_t atkbd_interrupt(struc
 #endif
 
 #if !defined(__i386__) && !defined (__x86_64__)
-	if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && !atkbd->resend && atkbd->write) {
+	if ((flags & (SERIO_FRAME | SERIO_PARITY)) &&
+	    (~flags & SERIO_TIMEOUT)) {
 		printk("atkbd.c: frame/parity error: %02x\n", flags);
-		serio_write(serio, ATKBD_CMD_RESEND);
-		atkbd->resend = 1;
 		goto out;
 	}
 	

_