All of lore.kernel.org
 help / color / mirror / Atom feed
From: Raul E Rangel <rrangel@chromium.org>
To: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 7/7] Input: libps2 - do not discard non-ack bytes when controlling LEDs
Date: Thu, 18 May 2023 11:24:44 -0600	[thread overview]
Message-ID: <ZGZfXOwnEi8hYKlv@google.com> (raw)
In-Reply-To: <20230511185252.386941-8-dmitry.torokhov@gmail.com>

On Thu, May 11, 2023 at 11:52:47AM -0700, Dmitry Torokhov wrote:
> Upon receiving a PS/2 command the device and controller are supposed to
> stop sending normal data (scancodes or movement packets) and instead
> immediately start delivering ACK/NAK and command response. Unfortunately
> often EC has an output buffer which may contain latched data by the time
> the EC receives a command from the host. The kernel used to ignore such
> data, but that may cause "stuck" keys if the data dropped happens to be a
> break code or a part of a break code. This occasionally happens, for
> example, on Chromebooks when the kernel tries to toggle CapsLock LED on
> a keyboard while user releases Alt+Search keyboard shortcut.
> 
> Fix this by passing the first non-ACK byte to the normal handler for a
> handful of PS/2 commands that are expected to be used during normal device
> operation (as opposed to probe/configuration time).
> 
> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> ---
>  drivers/input/serio/libps2.c | 36 ++++++++++++++++++++++++++++++++----
>  1 file changed, 32 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c
> index 7c5fc853072a..6d78a1fe00c1 100644
> --- a/drivers/input/serio/libps2.c
> +++ b/drivers/input/serio/libps2.c
> @@ -21,7 +21,10 @@
>  
>  #define PS2_CMD_SETSCALE11	0x00e6
>  #define PS2_CMD_SETRES		0x10e8
> +#define PS2_CMD_EX_SETLEDS	0x20eb
> +#define PS2_CMD_SETLEDS		0x10ed
>  #define PS2_CMD_GETID		0x02f2
> +#define PS2_CMD_SETREP		0x10f3 /* Set repeat rate/set report rate */
>  #define PS2_CMD_RESET_BAT	0x02ff
>  
>  #define PS2_RET_BAT		0xaa
> @@ -35,6 +38,7 @@
>  #define PS2_FLAG_CMD1		BIT(2)	/* Waiting for the first byte of command response */
>  #define PS2_FLAG_WAITID		BIT(3)	/* Command executing is GET ID */
>  #define PS2_FLAG_NAK		BIT(4)	/* Last transmission was NAKed */
> +#define PS2_FLAG_PASS_NOACK	BIT(5)	/* Pass non-ACK byte to receive handler */
>  
>  static int ps2_do_sendbyte(struct ps2dev *ps2dev, u8 byte,
>  			   unsigned int timeout, unsigned int max_attempts)
> @@ -281,9 +285,28 @@ int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command)
>  
>  	serio_pause_rx(ps2dev->serio);
>  
> -	/* Some mice do not ACK the "get ID" command, prepare to handle this. */
> -	ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0;
>  	ps2dev->cmdcnt = receive;
> +
> +	switch (command) {
> +	case PS2_CMD_GETID:
> +		/*
> +		 * Some mice do not ACK the "get ID" command, prepare to
> +		 * handle this.
> +		 */
> +		ps2dev->flags = PS2_FLAG_WAITID;
> +		break;
> +
> +	case PS2_CMD_SETLEDS:
> +	case PS2_CMD_EX_SETLEDS:
> +	case PS2_CMD_SETREP:
> +		ps2dev->flags = PS2_FLAG_PASS_NOACK;
> +		break;
> +
> +	default:
> +		ps2dev->flags = 0;
> +		break;
> +	}
> +
>  	if (receive) {
>  		/* Indicate that we expect response to the command. */
>  		ps2dev->flags |= PS2_FLAG_CMD | PS2_FLAG_CMD1;
> @@ -512,14 +535,19 @@ static void ps2_handle_ack(struct ps2dev *ps2dev, u8 data)
>  		 * Do not signal errors if we get unexpected reply while
>  		 * waiting for an ACK to the initial (first) command byte:
>  		 * the device might not be quiesced yet and continue
> -		 * delivering data.
> +		 * delivering data. For certain commands (such as set leds and
> +		 * set repeat rate) that can be used during normal device
> +		 * operation, we even pass this data byte to the normal receive
> +		 * handler.
>  		 * Note that we reset PS2_FLAG_WAITID flag, so the workaround
>  		 * for mice not acknowledging the Get ID command only triggers
>  		 * on the 1st byte; if device spews data we really want to see
>  		 * a real ACK from it.
>  		 */
>  		dev_dbg(&ps2dev->serio->dev, "unexpected %#02x\n", data);
> -		ps2dev->flags &= ~PS2_FLAG_WAITID;
> +		if (ps2dev->flags & PS2_FLAG_PASS_NOACK)
> +			ps2dev->receive_handler(ps2dev, data);
> +		ps2dev->flags &= ~(PS2_FLAG_WAITID | PS2_FLAG_PASS_NOACK);
>  		return;
>  	}
>  

Great refactoring. It made this final patch super simple!

Reviewed-by: Raul E Rangel <rrangel@chromium.org>

      reply	other threads:[~2023-05-18 17:24 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-11 18:52 [PATCH 0/7] libps2: be more tolerant when processing commands Dmitry Torokhov
2023-05-11 18:52 ` [PATCH 1/7] Input: libps2 - attach ps2dev instances as serio port's drvdata Dmitry Torokhov
2023-05-18 17:20   ` Raul E Rangel
2023-05-11 18:52 ` [PATCH 2/7] Input: libps2 - remove special handling of ACK for command byte Dmitry Torokhov
2023-05-18 17:21   ` Raul E Rangel
2023-05-11 18:52 ` [PATCH 3/7] Input: libps2 - rework handling of command response Dmitry Torokhov
2023-05-18 17:21   ` Raul E Rangel
2023-05-11 18:52 ` [PATCH 4/7] Input: libps2 - fix NAK handling Dmitry Torokhov
2023-05-18 17:22   ` Raul E Rangel
2023-05-11 18:52 ` [PATCH 5/7] Input: libps2 - fix aborting PS/2 commands Dmitry Torokhov
2023-05-18 17:22   ` Raul E Rangel
2023-05-11 18:52 ` [PATCH 6/7] Input: libps2 - introduce common interrupt handler Dmitry Torokhov
2023-05-12  1:01   ` kernel test robot
2023-05-15  1:52   ` kernel test robot
2023-05-15 23:14   ` [PATCH v2 " Dmitry Torokhov
2023-05-18 17:22   ` [PATCH " Raul E Rangel
2023-05-11 18:52 ` [PATCH 7/7] Input: libps2 - do not discard non-ack bytes when controlling LEDs Dmitry Torokhov
2023-05-18 17:24   ` Raul E Rangel [this message]

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=ZGZfXOwnEi8hYKlv@google.com \
    --to=rrangel@chromium.org \
    --cc=dmitry.torokhov@gmail.com \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /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.