linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] atkbd: Fix multi-char scancode handling on reconnect.
@ 2012-12-15  0:17 Shawn Nematbakhsh
  2012-12-18 21:24 ` Jesper Juhl
  0 siblings, 1 reply; 2+ messages in thread
From: Shawn Nematbakhsh @ 2012-12-15  0:17 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: Shawn Nematbakhsh, Jesper Juhl, linux-input, linux-kernel

On resume from suspend there is a possibility for multi-byte scancodes
to be handled incorrectly. atkbd_reconnect disables the processing of
scancodes in software by calling atkbd_disable, but the keyboard may
still be active because no disconnect command was sent. Later, software
handling is re-enabled. If a multi-byte scancode sent from the keyboard
straddles the re-enable, only the latter byte(s) will be handled.

In practice, this leads to cases where multi-byte break codes (ex. "e0
4d" - break code for right-arrow) are misread as make codes ("4d" - make
code for numeric 6), leading to one or more unwanted, untyped characters
being interpreted.

The solution implemented here involves sending command f5 (reset
disable) to the keyboard prior to disabling software handling of codes.
Later, the command to re-enable the keyboard is sent only after we are
prepared to handle scancodes.

Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
---
 drivers/input/keyboard/atkbd.c |   26 ++++++++++++++++++++++++--
 1 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index add5ffd..da49e8b 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -844,6 +844,24 @@ static int atkbd_activate(struct atkbd *atkbd)
 }
 
 /*
+ * atkbd_deactivate() resets and disables the keyboard from sending
+ * keystrokes.
+ */
+static int atkbd_deactivate(struct atkbd *atkbd)
+{
+	struct ps2dev *ps2dev = &atkbd->ps2dev;
+
+	if (ps2_command(ps2dev, NULL, ATKBD_CMD_RESET_DIS)) {
+		dev_err(&ps2dev->serio->dev,
+			"Failed to deactivate keyboard on %s\n",
+			ps2dev->serio->phys);
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
  * atkbd_cleanup() restores the keyboard state so that BIOS is happy after a
  * reboot.
  */
@@ -1199,6 +1217,9 @@ static int atkbd_reconnect(struct serio *serio)
 
 	mutex_lock(&atkbd->mutex);
 
+	if (atkbd->write)
+		atkbd_deactivate(atkbd);
+
 	atkbd_disable(atkbd);
 
 	if (atkbd->write) {
@@ -1208,8 +1229,6 @@ static int atkbd_reconnect(struct serio *serio)
 		if (atkbd->set != atkbd_select_set(atkbd, atkbd->set, atkbd->extra))
 			goto out;
 
-		atkbd_activate(atkbd);
-
 		/*
 		 * Restore LED state and repeat rate. While input core
 		 * will do this for us at resume time reconnect may happen
@@ -1224,6 +1243,9 @@ static int atkbd_reconnect(struct serio *serio)
 	}
 
 	atkbd_enable(atkbd);
+	if (atkbd->write)
+		atkbd_activate(atkbd);
+
 	retval = 0;
 
  out:
-- 
1.7.8.6


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] atkbd: Fix multi-char scancode handling on reconnect.
  2012-12-15  0:17 [PATCH] atkbd: Fix multi-char scancode handling on reconnect Shawn Nematbakhsh
@ 2012-12-18 21:24 ` Jesper Juhl
  0 siblings, 0 replies; 2+ messages in thread
From: Jesper Juhl @ 2012-12-18 21:24 UTC (permalink / raw)
  To: Shawn Nematbakhsh; +Cc: Dmitry Torokhov, linux-input, linux-kernel

On Fri, 14 Dec 2012, Shawn Nematbakhsh wrote:

> On resume from suspend there is a possibility for multi-byte scancodes
> to be handled incorrectly. atkbd_reconnect disables the processing of
> scancodes in software by calling atkbd_disable, but the keyboard may
> still be active because no disconnect command was sent. Later, software
> handling is re-enabled. If a multi-byte scancode sent from the keyboard
> straddles the re-enable, only the latter byte(s) will be handled.
> 
> In practice, this leads to cases where multi-byte break codes (ex. "e0
> 4d" - break code for right-arrow) are misread as make codes ("4d" - make
> code for numeric 6), leading to one or more unwanted, untyped characters
> being interpreted.
> 
> The solution implemented here involves sending command f5 (reset
> disable) to the keyboard prior to disabling software handling of codes.
> Later, the command to re-enable the keyboard is sent only after we are
> prepared to handle scancodes.
> 
> Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
> ---
>  drivers/input/keyboard/atkbd.c |   26 ++++++++++++++++++++++++--
>  1 files changed, 24 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
> index add5ffd..da49e8b 100644
> --- a/drivers/input/keyboard/atkbd.c
> +++ b/drivers/input/keyboard/atkbd.c
> @@ -844,6 +844,24 @@ static int atkbd_activate(struct atkbd *atkbd)
>  }
>  
>  /*
> + * atkbd_deactivate() resets and disables the keyboard from sending
> + * keystrokes.
> + */
> +static int atkbd_deactivate(struct atkbd *atkbd)

Why bother with a return type when you never check it anyway?
I'd say, either check for the 0/-1 you return and do something sensible or 
just let it return void.

> +{
> +	struct ps2dev *ps2dev = &atkbd->ps2dev;
> +
> +	if (ps2_command(ps2dev, NULL, ATKBD_CMD_RESET_DIS)) {
> +		dev_err(&ps2dev->serio->dev,
> +			"Failed to deactivate keyboard on %s\n",
> +			ps2dev->serio->phys);
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +/*
>   * atkbd_cleanup() restores the keyboard state so that BIOS is happy after a
>   * reboot.
>   */
> @@ -1199,6 +1217,9 @@ static int atkbd_reconnect(struct serio *serio)
>  
>  	mutex_lock(&atkbd->mutex);
>  
> +	if (atkbd->write)
> +		atkbd_deactivate(atkbd);
> +
>  	atkbd_disable(atkbd);
>  
>  	if (atkbd->write) {
> @@ -1208,8 +1229,6 @@ static int atkbd_reconnect(struct serio *serio)
>  		if (atkbd->set != atkbd_select_set(atkbd, atkbd->set, atkbd->extra))
>  			goto out;
>  
> -		atkbd_activate(atkbd);
> -
>  		/*
>  		 * Restore LED state and repeat rate. While input core
>  		 * will do this for us at resume time reconnect may happen
> @@ -1224,6 +1243,9 @@ static int atkbd_reconnect(struct serio *serio)
>  	}
>  
>  	atkbd_enable(atkbd);
> +	if (atkbd->write)
> +		atkbd_activate(atkbd);
> +
>  	retval = 0;
>  
>   out:
> 

-- 
Jesper Juhl <jj@chaosbits.net>       http://www.chaosbits.net/
Don't top-post http://www.catb.org/jargon/html/T/top-post.html
Plain text mails only, please.


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2012-12-18 21:24 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-12-15  0:17 [PATCH] atkbd: Fix multi-char scancode handling on reconnect Shawn Nematbakhsh
2012-12-18 21:24 ` Jesper Juhl

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).