All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dmitry Torokhov <dtor_core@ameritech.net>
To: Vojtech Pavlik <vojtech@suse.de>
Cc: linux-input@atrey.karlin.mff.cuni.cz,
	linux-kernel@vger.kernel.org, zhilla <zhilla@spymac.com>,
	Victor Hahn <victorhahn@web.de>
Subject: Re: [RFC/RFT] Better handling of bad xfers/interrupt delays in psmouse
Date: Sun, 6 Feb 2005 02:23:48 -0500	[thread overview]
Message-ID: <200502060223.55090.dtor_core@ameritech.net> (raw)
In-Reply-To: <200502060029.21068.dtor_core@ameritech.net>

On Sunday 06 February 2005 00:29, Dmitry Torokhov wrote:
> On Saturday 05 February 2005 16:11, Vojtech Pavlik wrote:
> > On Sat, Feb 05, 2005 at 02:48:56PM -0500, Dmitry Torokhov wrote:
> > > Hi,
> > > 
> > > The patch below attempts to better handle situation when psmouse interrupt
> > > is delayed for more than 0.5 sec by requesting a resend. This will allow
> > > properly synchronize with the beginning of the packet as mouse is supposed
> > > to resend entire package.
> > 
> > Have you actually tested the mouse is really sending the whole packet?
> > I'd suspect it could just resend the last byte. :I Maybe using the
> 
> Well, I did test and my touchpad behaved properly. But then I tried 2 external
> mice and they are both sending ACK (and they should not) and then the last byte
> only. So I guess we'll have to scrap using 0xfe idea...
> 
> > GET_PACKET command would be more useful in this case.
> >
> 
> Are you talking about 0xeb? We could also try sending "set stream" mode as a
> sync marker...
> 

Ok, here is the patch using PSMOUSE_CMD_POLL. Seems to work fine with 2
external mice that I have and my touchpad in PS/2 compatibility mode.

Unfortunately POLL command kicks Synaptics out of absolute mode so I
disabled all time-based sync checks for Synaptics altogether. This should
be OK since Synaptics have pretty strict protocol rules and usually
can resync on their own. I wonder what POLL does to ALPS?

Again, 2.6.10 version can be found here:

	http://www.geocities.com/dt_or/input/2_6_10/

Comments/testing is appreciated.

-- 
Dmitry


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


ChangeSet@1.2006, 2005-02-06 01:58:47-05:00, dtor_core@ameritech.net
  Input: psmouse - better handle bad transfers and interrupt delays
         by using POLL command to synchtonize on beginning of a
         packet so we don't need to guess whether received byte is
         remainder of the last packet or beginning of a new one.
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 psmouse-base.c |   83 +++++++++++++++++++++++++++++++++++++++++++++++++--------
 psmouse.h      |    1 
 2 files changed, 73 insertions(+), 11 deletions(-)


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



diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c	2005-02-06 02:15:18 -05:00
+++ b/drivers/input/mouse/psmouse-base.c	2005-02-06 02:15:18 -05:00
@@ -134,6 +134,49 @@
 	return PSMOUSE_FULL_PACKET;
 }
 
+static void psmouse_schedule_reconnect(struct psmouse *psmouse)
+{
+	psmouse->state = PSMOUSE_IGNORE;
+	printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n");
+	serio_reconnect(psmouse->ps2dev.serio);
+}
+
+static void psmouse_handle_bad_xfer(struct psmouse *psmouse, unsigned int flags)
+{
+	if (psmouse->state == PSMOUSE_ACTIVATED)
+		printk(KERN_WARNING "psmouse.c: bad data from KBC -%s%s\n",
+			flags & SERIO_TIMEOUT ? " timeout" : "",
+			flags & SERIO_PARITY ? " bad parity" : "");
+
+	if (!psmouse->resend) {
+		/*
+		 * This is first error. Try to request resend but not if we
+		 * got a timeout and we in initialize phase - there most
+		 * likely no mouse at all. Also skip Synaptics as they don't
+		 * like POLL command and pass-through ports since we can't
+		 * use their serio_write in interrupt context.
+		 */
+		if ((psmouse->state > PSMOUSE_INITIALIZING || (~flags & SERIO_TIMEOUT)) &&
+		    psmouse->type != PSMOUSE_SYNAPTICS && !psmouse->ps2dev.serio->parent) {
+			if (serio_write(psmouse->ps2dev.serio, PSMOUSE_CMD_POLL & 0xff) == 0) {
+				psmouse->resend = 1;
+				psmouse->pktcnt = 0;
+			}
+		}
+	} else {
+		/*
+		 * This is second error in a row. If mouse was itialized - attempt
+		 * to rconnect, otherwise just signal failure.
+		 */
+		psmouse->resend = 0;
+		if (psmouse->state > PSMOUSE_INITIALIZING)
+			psmouse_schedule_reconnect(psmouse);
+	}
+
+	if (!psmouse->resend)
+		ps2_cmd_aborted(&psmouse->ps2dev);
+}
+
 /*
  * psmouse_interrupt() handles incoming characters, either gathering them into
  * packets or passing them to the command routine as command output.
@@ -149,11 +192,14 @@
 		goto out;
 
 	if (flags & (SERIO_PARITY|SERIO_TIMEOUT)) {
-		if (psmouse->state == PSMOUSE_ACTIVATED)
-			printk(KERN_WARNING "psmouse.c: bad data from KBC -%s%s\n",
-				flags & SERIO_TIMEOUT ? " timeout" : "",
-				flags & SERIO_PARITY ? " bad parity" : "");
-		ps2_cmd_aborted(&psmouse->ps2dev);
+		psmouse_handle_bad_xfer(psmouse, flags);
+		goto out;
+	}
+
+	if (unlikely(psmouse->resend)) {
+		psmouse->resend = 0;
+		if (data != PSMOUSE_RET_ACK)
+			psmouse_schedule_reconnect(psmouse);
 		goto out;
 	}
 
@@ -168,11 +214,28 @@
 	if (psmouse->state == PSMOUSE_INITIALIZING)
 		goto out;
 
+	/*
+	 * If there is a long delay between bytes in a packet we suspect
+	 * that we lost synchronization and will try to restore it by
+	 * requesting transmission of a full packet from th? mouse.
+	 * Unfortunately POLL command kicks Synaptics touchpads out of
+	 * absolute mode, so we skip them (but they have good protocol
+	 * checks and usually can re-sync without problems). We also don't
+	 * try to re-sync devices on pass-through ports as their serio_write
+	 * can't be used in interrupt context and they usually in sync as
+	 * long as their parent is.
+	 */
 	if (psmouse->state == PSMOUSE_ACTIVATED &&
+	    psmouse->type != PSMOUSE_SYNAPTICS &&
+	    !serio->parent &&
 	    psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) {
 		printk(KERN_WARNING "psmouse.c: %s at %s lost synchronization, throwing %d bytes away.\n",
 		       psmouse->name, psmouse->phys, psmouse->pktcnt);
 		psmouse->pktcnt = 0;
+		if (serio_write(serio, PSMOUSE_CMD_POLL & 0xff) == 0) {
+			psmouse->resend = 1;
+			goto out;
+		}
 	}
 
 	psmouse->last = jiffies;
@@ -206,11 +269,9 @@
 				psmouse->name, psmouse->phys, psmouse->pktcnt);
 			psmouse->pktcnt = 0;
 
-			if (++psmouse->out_of_sync == psmouse->resetafter) {
-				psmouse->state = PSMOUSE_IGNORE;
-				printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n");
-				serio_reconnect(psmouse->ps2dev.serio);
-			}
+			if (++psmouse->out_of_sync == psmouse->resetafter)
+				psmouse_schedule_reconnect(psmouse);
+
 			break;
 
 		case PSMOUSE_FULL_PACKET:
@@ -594,7 +655,7 @@
 {
 	serio_pause_rx(psmouse->ps2dev.serio);
 	psmouse->state = new_state;
-	psmouse->pktcnt = psmouse->out_of_sync = 0;
+	psmouse->pktcnt = psmouse->out_of_sync = psmouse->resend = 0;
 	psmouse->ps2dev.flags = 0;
 	serio_continue_rx(psmouse->ps2dev.serio);
 }
diff -Nru a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
--- a/drivers/input/mouse/psmouse.h	2005-02-06 02:15:18 -05:00
+++ b/drivers/input/mouse/psmouse.h	2005-02-06 02:15:18 -05:00
@@ -48,6 +48,7 @@
 	unsigned long last;
 	unsigned long out_of_sync;
 	enum psmouse_state state;
+	unsigned int resend;
 	char devname[64];
 	char phys[32];
 

  reply	other threads:[~2005-02-06  7:24 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-02-05 19:48 [RFC/RFT] Better handling of bad xfers/interrupt delays in psmouse Dmitry Torokhov
2005-02-05 21:11 ` Vojtech Pavlik
2005-02-06  5:29   ` Dmitry Torokhov
2005-02-06  7:23     ` Dmitry Torokhov [this message]
2005-02-06  8:37       ` Vojtech Pavlik
2005-02-06 17:52         ` Dmitry Torokhov
2005-02-06  8:29     ` Vojtech Pavlik
2005-02-06  9:27 ` Pavel Machek
2005-02-06 17:55   ` Dmitry Torokhov
2005-02-07  5:31     ` Ryan Anderson

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=200502060223.55090.dtor_core@ameritech.net \
    --to=dtor_core@ameritech.net \
    --cc=linux-input@atrey.karlin.mff.cuni.cz \
    --cc=linux-kernel@vger.kernel.org \
    --cc=victorhahn@web.de \
    --cc=vojtech@suse.de \
    --cc=zhilla@spymac.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 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.