linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
To: Benjamin Tissoires <benjamin.tissoires@redhat.com>,
	Hans de Goede <hdegoede@redhat.com>,
	Lyude Paul <lyude@redhat.com>
Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 7/7] Input: libps2 - relax command byte ACK handling
Date: Fri, 19 Jan 2018 11:41:11 -0800	[thread overview]
Message-ID: <20180119194111.185590-8-dmitry.torokhov@gmail.com> (raw)
In-Reply-To: <20180119194111.185590-1-dmitry.torokhov@gmail.com>

When we probe PS/2 devices we first issue "Get ID" command and only if we
receive what we consider a valid keyboard or mouse ID we disable the device
and continue with protocol detection. That means that the device may be
transmitting motion or keystroke data, while we expect ACK response.

Instead of signaling failure if we see anything but ACK/NAK let's ignore
"garbage" response until we see ACK for the command byte (first byte). The
checks for subsequent ACKs of command parameters will continue be strict.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/serio/libps2.c | 25 ++++++++++++++++++++++---
 include/linux/libps2.h       |  1 +
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c
index f05c407b31f3d..e6a07e68d1ff6 100644
--- a/drivers/input/serio/libps2.c
+++ b/drivers/input/serio/libps2.c
@@ -256,16 +256,23 @@ int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command)
 		for (i = 0; i < receive; i++)
 			ps2dev->cmdbuf[(receive - 1) - i] = param[i];
 
+	/* Signal that we are sending the command byte */
+	ps2dev->flags |= PS2_FLAG_ACK_CMD;
+
 	/*
 	 * Some devices (Synaptics) peform the reset before
 	 * ACKing the reset command, and so it can take a long
 	 * time before the ACK arrives.
 	 */
-	rc = ps2_do_sendbyte(ps2dev, command & 0xff,
-			     command == PS2_CMD_RESET_BAT ? 1000 : 200, 2);
+	timeout = command == PS2_CMD_RESET_BAT ? 1000 : 200;
+
+	rc = ps2_do_sendbyte(ps2dev, command & 0xff, timeout, 2);
 	if (rc)
 		goto out_reset_flags;
 
+	/* Now we are sending command parameters, if any */
+	ps2dev->flags &= ~PS2_FLAG_ACK_CMD;
+
 	for (i = 0; i < send; i++) {
 		rc = ps2_do_sendbyte(ps2dev, param[i], 200, 2);
 		if (rc)
@@ -416,7 +423,19 @@ bool ps2_handle_ack(struct ps2dev *ps2dev, u8 data)
 		}
 		/* Fall through */
 	default:
-		return false;
+		/*
+		 * 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.
+		 * 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;
+		return ps2dev->flags & PS2_FLAG_ACK_CMD;
 	}
 
 	if (!ps2dev->nak) {
diff --git a/include/linux/libps2.h b/include/linux/libps2.h
index cd4454502a042..8b8139337e552 100644
--- a/include/linux/libps2.h
+++ b/include/linux/libps2.h
@@ -27,6 +27,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_ACK_CMD	BIT(5)	/* Waiting to ACK the command (first) byte */
 
 struct ps2dev {
 	struct serio *serio;
-- 
2.16.0.rc1.238.g530d649a79-goog

      parent reply	other threads:[~2018-01-19 19:42 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-19 19:41 [PATCH 0/7] libps2 facelift Dmitry Torokhov
2018-01-19 19:41 ` [PATCH 1/7] Input: libps2 - fix switch statement formatting Dmitry Torokhov
2018-01-19 19:41 ` [PATCH 2/7] Input: libps2 - use u8 for byte data Dmitry Torokhov
2018-01-19 19:41 ` [PATCH 3/7] Input: libps2 - use BIT() for bitmask constants Dmitry Torokhov
2018-01-19 22:26   ` Randy Dunlap
2018-01-19 22:39     ` Dmitry Torokhov
2018-01-19 19:41 ` [PATCH 4/7] Input: psmouse - move sliced command implementation to libps2 Dmitry Torokhov
2018-01-19 19:41 ` [PATCH 5/7] Input: libps2 - add debugging statements Dmitry Torokhov
2018-01-21 20:22   ` ulrik.debie-os
2018-01-22 18:33     ` Dmitry Torokhov
2018-01-19 19:41 ` [PATCH 6/7] Input: libps2 - support retransmission of command data Dmitry Torokhov
2018-01-19 19:41 ` Dmitry Torokhov [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=20180119194111.185590-8-dmitry.torokhov@gmail.com \
    --to=dmitry.torokhov@gmail.com \
    --cc=benjamin.tissoires@redhat.com \
    --cc=hdegoede@redhat.com \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lyude@redhat.com \
    /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 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).