All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vojtech Pavlik <vojtech@suse.cz>
To: Neil Brown <neilb@cse.unsw.edu.au>
Cc: Vojtech Pavlik <vojtech@suse.cz>,
	Andries Brouwer <aebr@win.tue.nl>,
	linux-kernel@vger.kernel.org
Subject: Re: Input issues - key down with no key up
Date: Mon, 18 Aug 2003 18:01:38 +0200	[thread overview]
Message-ID: <20030818160138.GA31760@ucw.cz> (raw)
In-Reply-To: <16189.58357.516036.664166@gargle.gargle.HOWL>

[-- Attachment #1: Type: text/plain, Size: 1249 bytes --]

On Sat, Aug 16, 2003 at 05:57:41PM +1000, Neil Brown wrote:
> On Friday August 15, vojtech@suse.cz wrote:
> > On Fri, Aug 15, 2003 at 03:52:48PM +0200, Andries Brouwer wrote:
> > > On Fri, Aug 15, 2003 at 10:46:07PM +1000, Neil Brown wrote:
> > > 
> > > > It seems to work (though some of the keys actually generate 'down'
> > > > events for both the down and up transitions, so it seems that the key
> > > > is pressed twice.
> > > 
> > > Maybe it really is as you say. But your description sounds fishy.
> > > It would be nice to know what really happens.
> > > (And it would be nice to know which scancodes are involved.)
> > 
> > Indeed. Neil, please enable DEBUG in i8042.c ... both with and without the
> > i8042_direct=1 and atkbd_set=3 options from my previous e-mail.
> > 
> > And for Andries, if you can, do the showkey -s test on 2.4, too ...
> 
> Well...
> 
> For my purposes, I need to use an "ioctl" to set a keycode for each
> scancode, so adding an ioctl to set the no-keyup status is no hassle
> for me.  However the suggest approach of auto-detecting keys which
> have no up event would probably a good idea.

How about this patch? It tries to be a bit clever, but hopefully not too
much ...

-- 
Vojtech Pavlik
SuSE Labs, SuSE CR

[-- Attachment #2: norelease.diff --]
[-- Type: text/plain, Size: 8169 bytes --]

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

===================================================================

ChangeSet@1.1386, 2003-08-18 18:00:19+02:00, vojtech@suse.cz
  input: atkbd.c - First take on keys which systematically or randomly
  don't generate release.


 atkbd.c |  156 ++++++++++++++++++++++++++++++++++++----------------------------
 1 files changed, 90 insertions(+), 66 deletions(-)

===================================================================

diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c	Mon Aug 18 18:00:46 2003
+++ b/drivers/input/keyboard/atkbd.c	Mon Aug 18 18:00:46 2003
@@ -18,6 +18,7 @@
 #include <linux/input.h>
 #include <linux/serio.h>
 #include <linux/workqueue.h>
+#include <linux/timer.h>
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
 MODULE_DESCRIPTION("AT and PS/2 keyboard driver");
@@ -87,10 +88,10 @@
 #define ATKBD_CMD_GSCANSET	0x11f0
 #define ATKBD_CMD_SSCANSET	0x10f0
 #define ATKBD_CMD_GETID		0x02f2
+#define ATKBD_CMD_SETREP	0x10f3
 #define ATKBD_CMD_ENABLE	0x00f4
 #define ATKBD_CMD_RESET_DIS	0x00f5
 #define ATKBD_CMD_RESET_BAT	0x02ff
-#define ATKBD_CMD_SETALL_MB	0x00f8
 #define ATKBD_CMD_RESEND	0x00fe
 #define ATKBD_CMD_EX_ENABLE	0x10ea
 #define ATKBD_CMD_EX_SETLEDS	0x20eb
@@ -114,12 +115,14 @@
 	unsigned char keycode[512];
 	struct input_dev dev;
 	struct serio *serio;
+	struct timer_list timer;
 	char name[64];
 	char phys[32];
 	unsigned char cmdbuf[4];
 	unsigned char cmdcnt;
 	unsigned char set;
 	unsigned char release;
+	int lastkey;
 	volatile signed char ack;
 	unsigned char emul;
 	unsigned short id;
@@ -142,6 +145,7 @@
 	printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags);
 #endif
 
+#if !defined(__i386__) && !defined (__x86_64__)
 	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);
@@ -151,6 +155,7 @@
 	
 	if (!flags)
 		atkbd->resend = 0;
+#endif
 
 	switch (code) {
 		case ATKBD_RET_ACK:
@@ -195,6 +200,14 @@
 				atkbd->set, code, serio->phys, atkbd->release ? "released" : "pressed");
 			break;
 		default:
+
+			if (!atkbd->release) {
+				mod_timer(&atkbd->timer,
+					(test_bit(atkbd->keycode[code], &atkbd->dev.key)
+						? HZ/30 : HZ/4) + HZ/100);
+				atkbd->lastkey = atkbd->keycode[code];
+			}
+
 			input_regs(&atkbd->dev, regs);
 			input_report_key(&atkbd->dev, atkbd->keycode[code], !atkbd->release);
 			input_sync(&atkbd->dev);
@@ -205,6 +218,13 @@
 	return IRQ_HANDLED;
 }
 
+static void atkbd_force_key_up(unsigned long data)
+{
+	struct atkbd *atkbd = (void *) data;
+	input_report_key(&atkbd->dev, atkbd->lastkey, 0);
+	input_sync(&atkbd->dev);
+}
+
 /*
  * atkbd_sendbyte() sends a byte to the keyboard, and waits for
  * acknowledge. It doesn't handle resends according to the keyboard
@@ -214,7 +234,7 @@
 
 static int atkbd_sendbyte(struct atkbd *atkbd, unsigned char byte)
 {
-	int timeout = 10000; /* 100 msec */
+	int timeout = 20000; /* 200 msec */
 	atkbd->ack = 0;
 
 #ifdef ATKBD_DEBUG
@@ -322,6 +342,53 @@
 }
 
 /*
+ * atkbd_probe() probes for an AT keyboard on a serio port.
+ */
+
+static int atkbd_probe(struct atkbd *atkbd)
+{
+	unsigned char param[2];
+
+/*
+ * Some systems, where the bit-twiddling when testing the io-lines of the
+ * controller may confuse the keyboard need a full reset of the keyboard. On
+ * these systems the BIOS also usually doesn't do it for us.
+ */
+
+	if (atkbd_reset)
+		if (atkbd_command(atkbd, NULL, ATKBD_CMD_RESET_BAT)) 
+			printk(KERN_WARNING "atkbd.c: keyboard reset failed on %s\n", atkbd->serio->phys);
+
+/*
+ * Then we check the keyboard ID. We should get 0xab83 under normal conditions.
+ * Some keyboards report different values, but the first byte is always 0xab or
+ * 0xac. Some old AT keyboards don't report anything. If a mouse is connected, this
+ * should make sure we don't try to set the LEDs on it.
+ */
+
+	if (atkbd_command(atkbd, param, ATKBD_CMD_GETID)) {
+
+/*
+ * If the get ID command failed, we check if we can at least set the LEDs on
+ * the keyboard. This should work on every keyboard out there. It also turns
+ * the LEDs off, which we want anyway.
+ */
+		param[0] = 0;
+		if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS))
+			return -1;
+		atkbd->id = 0xabba;
+		return 0;
+	}
+
+	if (param[0] != 0xab && param[0] != 0xac)
+		return -1;
+	atkbd->id = (param[0] << 8) | param[1];
+
+
+	return 0;
+}
+
+/*
  * atkbd_set_3 checks if a keyboard has a working Set 3 support, and
  * sets it into that. Unfortunately there are keyboards that can be switched
  * to Set 3, but don't work well in that (BTC Multimedia ...)
@@ -355,75 +422,26 @@
 			return 4;
 	}
 
-/*
- * Try to set the set we want.
- */
+	if (atkbd_set != 3) 
+		return 2;
 
-	param[0] = atkbd_set;
+	param[0] = 3;
 	if (atkbd_command(atkbd, param, ATKBD_CMD_SSCANSET))
 		return 2;
 
-/*
- * Read set number. Beware here. Some keyboards always send '2'
- * or some other number regardless into what mode they have been
- * attempted to be set. Other keyboards treat the '0' command as
- * 'set to set 0', and not 'report current set' as they should.
- * In that case we time out, and return 2.
- */
-
 	param[0] = 0;
 	if (atkbd_command(atkbd, param, ATKBD_CMD_GSCANSET))
 		return 2;
 
-/*
- * Here we return the set number the keyboard reports about
- * itself.
- */
+	if (param[0] != 3)
+		return 2;
 
-	return (param[0] == 3) ? 3 : 2;
+	return 3;
 }
 
-/*
- * atkbd_probe() probes for an AT keyboard on a serio port.
- */
-
-static int atkbd_probe(struct atkbd *atkbd)
+static int atkbd_enable(struct atkbd *atkbd)
 {
-	unsigned char param[2];
-
-/*
- * Some systems, where the bit-twiddling when testing the io-lines of the
- * controller may confuse the keyboard need a full reset of the keyboard. On
- * these systems the BIOS also usually doesn't do it for us.
- */
-
-	if (atkbd_reset)
-		if (atkbd_command(atkbd, NULL, ATKBD_CMD_RESET_BAT)) 
-			printk(KERN_WARNING "atkbd.c: keyboard reset failed on %s\n", atkbd->serio->phys);
-
-/*
- * Then we check the keyboard ID. We should get 0xab83 under normal conditions.
- * Some keyboards report different values, but the first byte is always 0xab or
- * 0xac. Some old AT keyboards don't report anything.
- */
-
-	if (atkbd_command(atkbd, param, ATKBD_CMD_GETID)) {
-
-/*
- * If the get ID command failed, we check if we can at least set the LEDs on
- * the keyboard. This should work on every keyboard out there. It also turns
- * the LEDs off, which we want anyway.
- */
-		param[0] = 0;
-		if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS))
-			return -1;
-		atkbd->id = 0xabba;
-		return 0;
-	}
-
-	if (param[0] != 0xab && param[0] != 0xac)
-		return -1;
-	atkbd->id = (param[0] << 8) | param[1];
+	unsigned char param[1];
 
 /*
  * Set the LEDs to a defined state.
@@ -434,21 +452,22 @@
 		return -1;
 
 /*
- * Disable autorepeat. We don't need it, as we do it in software anyway,
- * because that way can get faster repeat, and have less system load (less
- * accesses to the slow ISA hardware). If this fails, we don't care, and will
- * just ignore the repeated keys.
+ * Set autorepeat to fastest possible.
  */
 
-	atkbd_command(atkbd, NULL, ATKBD_CMD_SETALL_MB);
+	param[0] = 0;
+	if (atkbd_command(atkbd, param, ATKBD_CMD_SETREP))
+		return -1;
 
 /*
- * Last, we enable the keyboard to make sure  that we get keypresses from it.
+ * Enable the keyboard to receive keystrokes.
  */
 
-	if (atkbd_command(atkbd, NULL, ATKBD_CMD_ENABLE))
+	if (atkbd_command(atkbd, NULL, ATKBD_CMD_ENABLE)) {
 		printk(KERN_ERR "atkbd.c: Failed to enable keyboard on %s\n",
 			atkbd->serio->phys);
+		return -1;
+	}
 
 	return 0;
 }
@@ -517,6 +536,10 @@
 
 	serio->private = atkbd;
 
+	init_timer(&atkbd->timer);
+	atkbd->timer.data = (long) atkbd;
+	atkbd->timer.function = atkbd_force_key_up;
+
 	if (serio_open(serio, dev)) {
 		kfree(atkbd);
 		return;
@@ -531,6 +554,7 @@
 		}
 		
 		atkbd->set = atkbd_set_3(atkbd);
+		atkbd_enable(atkbd);
 
 	} else {
 		atkbd->set = 2;

  reply	other threads:[~2003-08-18 16:02 UTC|newest]

Thread overview: 75+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-08-15  5:16 Input issues - key down with no key up Neil Brown
2003-08-15  7:46 ` Andries Brouwer
2003-08-15 10:58   ` Vojtech Pavlik
2003-08-15 12:36     ` Andries Brouwer
2003-08-15 12:43       ` Vojtech Pavlik
2003-08-15 13:27         ` Jamie Lokier
2003-08-15 13:52           ` Vojtech Pavlik
2003-08-15 14:02             ` Jamie Lokier
2003-08-15 15:05         ` Jason Lunz
2003-08-15 13:04       ` Jamie Lokier
2003-08-15 13:10         ` Vojtech Pavlik
2003-08-15 13:33           ` Jamie Lokier
2003-08-15 13:53             ` Vojtech Pavlik
2003-08-16 13:02               ` Maciej W. Rozycki
2003-08-16 14:09                 ` Jamie Lokier
2003-08-17 21:54                   ` Vojtech Pavlik
2003-08-18 12:22                     ` Maciej W. Rozycki
2003-08-18 10:29                 ` Andries Brouwer
2003-08-19 13:04                   ` Maciej W. Rozycki
2003-08-19 17:48                     ` Andries Brouwer
2003-08-21 11:37                       ` Maciej W. Rozycki
2003-08-21 12:44                         ` Andries Brouwer
2003-08-21 13:45                           ` Maciej W. Rozycki
2003-08-21 14:28                             ` Andries Brouwer
2003-08-21 14:38                               ` Maciej W. Rozycki
2003-08-21 13:48                         ` Jamie Lokier
2003-08-21 14:08                           ` Maciej W. Rozycki
2003-08-21 14:14                             ` Vojtech Pavlik
2003-08-21 14:33                               ` Maciej W. Rozycki
2003-08-21 14:44                                 ` Andries Brouwer
2003-08-21 15:03                                   ` Maciej W. Rozycki
2003-08-21 15:29                                     ` Vojtech Pavlik
2003-08-16 13:01             ` Maciej W. Rozycki
2003-08-15 12:46     ` Neil Brown
2003-08-15 12:54       ` Vojtech Pavlik
2003-08-15 13:52       ` Andries Brouwer
2003-08-15 14:13         ` Vojtech Pavlik
2003-08-16  7:57           ` Neil Brown
2003-08-18 16:01             ` Vojtech Pavlik [this message]
2003-08-19 11:40               ` Neil Brown
2003-08-19 11:50                 ` Vojtech Pavlik
2003-08-19 23:59                   ` Neil Brown
2003-08-20 22:36             ` Andries Brouwer
2003-08-20 22:58               ` Jamie Lokier
2003-08-20 23:52                 ` Andries Brouwer
2003-08-21  0:03                   ` Jamie Lokier
2003-08-21  0:33                     ` Andries Brouwer
2003-08-21  1:36                       ` Jamie Lokier
2003-08-21  8:08                       ` Vojtech Pavlik
2003-08-21  8:06                     ` Vojtech Pavlik
2003-08-21 11:40                     ` Maciej W. Rozycki
2003-08-21 12:48                       ` Andries Brouwer
2003-08-21 13:22                         ` Jamie Lokier
2003-08-21 13:29                         ` Maciej W. Rozycki
2003-08-21  8:01                   ` Vojtech Pavlik
2003-08-22  0:27                     ` Andries Brouwer
2003-08-22  7:33                       ` Vojtech Pavlik
2003-08-25  4:22                         ` Jamie Lokier
2003-08-25  8:22                           ` Vojtech Pavlik
2003-08-25 19:36                             ` Jamie Lokier
2003-09-03  8:06                               ` Pavel Machek
2003-08-22 13:35                       ` Maciej W. Rozycki
  -- strict thread matches above, loose matches on Subject: below --
2003-08-16 15:15 John Bradford
2003-08-18 11:53 ` Maciej W. Rozycki
2003-08-19 19:37 John Bradford
2003-08-19 23:58 ` Jamie Lokier
2003-08-20  5:59 John Bradford
2003-08-20 15:17 ` Jamie Lokier
2003-08-21 12:11 John Bradford
2003-08-21 12:26 ` Vojtech Pavlik
2003-08-23 12:30 Norman Diamond
2003-08-25  4:24 ` Jamie Lokier
2003-08-25 12:15   ` Norman Diamond
2003-08-25  8:45 John Bradford
2003-08-25 12:47 John Bradford

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20030818160138.GA31760@ucw.cz \
    --to=vojtech@suse.cz \
    --cc=aebr@win.tue.nl \
    --cc=linux-kernel@vger.kernel.org \
    --cc=neilb@cse.unsw.edu.au \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.