2005-02-05 19:53:55

by Dmitry Torokhov

[permalink] [raw]
Subject: [RFC/RFT] Better handling of bad xfers/interrupt delays in psmouse

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.

Additionally, psmouse will also request resend if KBC indicates parity or
timeout errors.

The patch should apply to 2.6.11-rc2+. A version of this patch for 2.6.10
is available here:

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

--
Dmitry


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


[email protected], 2005-02-05 14:33:05-05:00, [email protected]
Input: psmouse - better handle bad transfers and interrupt delays
by requesting resend of the last packet so we don't need to
guess if received byte is remainder of last packet or start
of a new one.

Signed-off-by: Dmitry Torokhov <[email protected]>


psmouse-base.c | 48 +++++++++++++++++++++++++++++++++++++++++++-----
psmouse.h | 2 ++
2 files changed, 45 insertions(+), 5 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-05 14:37:51 -05:00
+++ b/drivers/input/mouse/psmouse-base.c 2005-02-05 14:37:51 -05:00
@@ -134,6 +134,42 @@
return PSMOUSE_FULL_PACKET;
}

+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
+ * timeout and we are in initialize phase - there most likely no
+ * mouse at all.
+ */
+ if (psmouse->state > PSMOUSE_INITIALIZING || (~flags & SERIO_TIMEOUT)) {
+ if (serio_write(psmouse->ps2dev.serio, PSMOUSE_CMD_RESEND) == 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->state = PSMOUSE_IGNORE;
+ printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n");
+ serio_reconnect(psmouse->ps2dev.serio);
+ }
+ }
+
+ 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 +185,7 @@
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;
}

@@ -168,11 +200,17 @@
if (psmouse->state == PSMOUSE_INITIALIZING)
goto out;

+ psmouse->resend = 0;
+
if (psmouse->state == PSMOUSE_ACTIVATED &&
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_RESEND) == 0) {
+ psmouse->resend = 1;
+ goto out;
+ }
}

psmouse->last = jiffies;
diff -Nru a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
--- a/drivers/input/mouse/psmouse.h 2005-02-05 14:37:51 -05:00
+++ b/drivers/input/mouse/psmouse.h 2005-02-05 14:37:51 -05:00
@@ -13,6 +13,7 @@
#define PSMOUSE_CMD_ENABLE 0x00f4
#define PSMOUSE_CMD_DISABLE 0x00f5
#define PSMOUSE_CMD_RESET_DIS 0x00f6
+#define PSMOUSE_CMD_RESEND 0x00fe
#define PSMOUSE_CMD_RESET_BAT 0x02ff

#define PSMOUSE_RET_BAT 0xaa
@@ -48,6 +49,7 @@
unsigned long last;
unsigned long out_of_sync;
enum psmouse_state state;
+ unsigned int resend;
char devname[64];
char phys[32];




2005-02-05 21:12:00

by Vojtech Pavlik

[permalink] [raw]
Subject: Re: [RFC/RFT] Better handling of bad xfers/interrupt delays in psmouse

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
GET_PACKET command would be more useful in this case.

Also, we could use GET_PACKET to check the mode of the mouse, when we
get several successive lost bytes.

> Additionally, psmouse will also request resend if KBC indicates parity or
> timeout errors.
>
> The patch should apply to 2.6.11-rc2+. A version of this patch for 2.6.10
> is available here:
>
> http://www.geocities.com/dt_or/input/2_6_10/
>
> --
> Dmitry
>
>
> ===================================================================
>
>
> [email protected], 2005-02-05 14:33:05-05:00, [email protected]
> Input: psmouse - better handle bad transfers and interrupt delays
> by requesting resend of the last packet so we don't need to
> guess if received byte is remainder of last packet or start
> of a new one.
>
> Signed-off-by: Dmitry Torokhov <[email protected]>
>
>
> psmouse-base.c | 48 +++++++++++++++++++++++++++++++++++++++++++-----
> psmouse.h | 2 ++
> 2 files changed, 45 insertions(+), 5 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-05 14:37:51 -05:00
> +++ b/drivers/input/mouse/psmouse-base.c 2005-02-05 14:37:51 -05:00
> @@ -134,6 +134,42 @@
> return PSMOUSE_FULL_PACKET;
> }
>
> +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
> + * timeout and we are in initialize phase - there most likely no
> + * mouse at all.
> + */
> + if (psmouse->state > PSMOUSE_INITIALIZING || (~flags & SERIO_TIMEOUT)) {
> + if (serio_write(psmouse->ps2dev.serio, PSMOUSE_CMD_RESEND) == 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->state = PSMOUSE_IGNORE;
> + printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n");
> + serio_reconnect(psmouse->ps2dev.serio);
> + }
> + }
> +
> + 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 +185,7 @@
> 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;
> }
>
> @@ -168,11 +200,17 @@
> if (psmouse->state == PSMOUSE_INITIALIZING)
> goto out;
>
> + psmouse->resend = 0;
> +
> if (psmouse->state == PSMOUSE_ACTIVATED &&
> 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_RESEND) == 0) {
> + psmouse->resend = 1;
> + goto out;
> + }
> }
>
> psmouse->last = jiffies;
> diff -Nru a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
> --- a/drivers/input/mouse/psmouse.h 2005-02-05 14:37:51 -05:00
> +++ b/drivers/input/mouse/psmouse.h 2005-02-05 14:37:51 -05:00
> @@ -13,6 +13,7 @@
> #define PSMOUSE_CMD_ENABLE 0x00f4
> #define PSMOUSE_CMD_DISABLE 0x00f5
> #define PSMOUSE_CMD_RESET_DIS 0x00f6
> +#define PSMOUSE_CMD_RESEND 0x00fe
> #define PSMOUSE_CMD_RESET_BAT 0x02ff
>
> #define PSMOUSE_RET_BAT 0xaa
> @@ -48,6 +49,7 @@
> unsigned long last;
> unsigned long out_of_sync;
> enum psmouse_state state;
> + unsigned int resend;
> char devname[64];
> char phys[32];
>
>
>

--
Vojtech Pavlik
SuSE Labs, SuSE CR

2005-02-06 05:29:27

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [RFC/RFT] Better handling of bad xfers/interrupt delays in psmouse

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...

--
Dmitry

2005-02-06 07:24:59

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [RFC/RFT] Better handling of bad xfers/interrupt delays in psmouse

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


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


[email protected], 2005-02-06 01:58:47-05:00, [email protected]
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 <[email protected]>


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];

2005-02-06 08:29:09

by Vojtech Pavlik

[permalink] [raw]
Subject: Re: [RFC/RFT] Better handling of bad xfers/interrupt delays in psmouse

On Sun, Feb 06, 2005 at 12:29:20AM -0500, 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?

Yes, sorry for the wrong name, it should've been "CMD_POLL".

> We could also try sending "set stream" mode as a sync marker...

That's an interesting idea, too. But I suspect we'll also have to turn
the stream mode off first (CMD_DISABLE).

--
Vojtech Pavlik
SuSE Labs, SuSE CR

2005-02-06 08:37:32

by Vojtech Pavlik

[permalink] [raw]
Subject: Re: [RFC/RFT] Better handling of bad xfers/interrupt delays in psmouse

On Sun, Feb 06, 2005 at 02:23:48AM -0500, Dmitry Torokhov wrote:

> 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.

Did you check that issuing the POLL command in the middle of a mouse
packet does indeed reset the counter of the streaming mode? I'd expect
them to be separate, at least on some mice, if POLL is handled as a
normal mouse command, and after the three bytes from POLL are sent, the
mouse could just continue sending the packet like with any other
command.

--
Vojtech Pavlik
SuSE Labs, SuSE CR

2005-02-06 09:36:48

by Pavel Machek

[permalink] [raw]
Subject: Re: [RFC/RFT] Better handling of bad xfers/interrupt delays in psmouse

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.

+ * This is second error in a row. If mouse was itialized - attempt
+ * to rconnect, otherwise just signal failure.

Tooo many typso in on coment?
Pavel
--
People were complaining that M$ turns users into beta-testers...
...jr ghea gurz vagb qrirybcref, naq gurl frrz gb yvxr vg gung jnl!

2005-02-06 17:52:49

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [RFC/RFT] Better handling of bad xfers/interrupt delays in psmouse

On Sunday 06 February 2005 03:37, Vojtech Pavlik wrote:
> On Sun, Feb 06, 2005 at 02:23:48AM -0500, Dmitry Torokhov wrote:
>
> > 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.
>
> Did you check that issuing the POLL command in the middle of a mouse
> packet does indeed reset the counter of the streaming mode? I'd expect
> them to be separate, at least on some mice, if POLL is handled as a
> normal mouse command, and after the three bytes from POLL are sent, the
> mouse could just continue sending the packet like with any other
> command.
>

I have tested with Synaptics touchpad, a noname explorer mouse and a Belkin
USB with USB-PS/2 converted, all of them resumed streaming with the full
packet. I used the following patch to force polling:

===== drivers/input/mouse/psmouse-base.c 1.88 vs edited =====
--- 1.88/drivers/input/mouse/psmouse-base.c 2005-02-06 03:01:36 -05:00
+++ edited/drivers/input/mouse/psmouse-base.c 2005-02-06 12:46:47 -05:00
@@ -185,6 +185,7 @@
static irqreturn_t psmouse_interrupt(struct serio *serio,
unsigned char data, unsigned int flags, struct pt_regs *regs)
{
+ static int bcnt;
struct psmouse *psmouse = serio_get_drvdata(serio);
psmouse_ret_t rc;

@@ -237,6 +238,20 @@
goto out;
}
}
+
+ if (psmouse->state == PSMOUSE_ACTIVATED &&
+ psmouse->type != PSMOUSE_SYNAPTICS &&
+ !serio->parent &&
+ (++bcnt % 502) == 0) {
+ printk(KERN_WARNING "psmouse.c: %s at %s - repolling, 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;
psmouse->packet[psmouse->pktcnt++] = data;



We of course need more testing, I am particularly interested in ALPS reaction
to poll command.

--
Dmitry

2005-02-06 17:55:19

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [RFC/RFT] Better handling of bad xfers/interrupt delays in psmouse

On Sunday 06 February 2005 04:27, Pavel Machek 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.
>
> + * This is second error in a row. If mouse was itialized - attempt
> + * to rconnect, otherwise just signal failure.
>
> Tooo many typso in on coment?
> Pavel

Sorry about that. If the patch turns out to be working fine I'll fix the
comments before resubmitting.

Hmm, wouldn't it be nice if they put spell checker in GCC? ;)

--
Dmitry

2005-02-07 05:31:48

by Ryan Anderson

[permalink] [raw]
Subject: Re: [RFC/RFT] Better handling of bad xfers/interrupt delays in psmouse

On Sun, Feb 06, 2005 at 12:55:00PM -0500, Dmitry Torokhov wrote:
>
> Hmm, wouldn't it be nice if they put spell checker in GCC? ;)

Isn't the resulting beast called "emacs"?

--

Ryan Anderson
sometimes Pug Majere