Subject: Re: mouse interface resets
To: Martin Husemann <martin@netbsd.org>
From: Jaromir Dolecek <jdolecek@netbsd.org>
List: tech-kern
Date: 05/08/2002 15:19:59
--ELM723983441-5910-0_
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset=US-ASCII

Can you try this patch? It contains two changes:

1. block tty interrupts during the reset, and do the reset with polled commands
2. eliminate the kthread and use callout

I've not changed the timeout yet, so you'd still get the occasional
reset. This change might fix the X freezes tho.
I did not test it, since I don't have machine with the reset
problem happening handy ATM.

Let me know if it helped any.

Jaromir

Martin Husemann wrote:
> I bet I'm not the only one that (still) gets tons of this messages:
> 
> May  7 10:52:55 beasty /netbsd: pms: resetting mouse interface
> 
> There is no KVA switch or strange mouse or unplugging or (proprietary)
> notebook hardware involved.
> 
> This is annoying at least, and will cause a high amount of support queries
> once 1.6 is out.
> 
> So I propose to make the new timeout mechanism optional, defaulting to off.
> 
> What do you think?
> 
> Martin
> 


-- 
Jaromir Dolecek <jdolecek@NetBSD.org> http://www.NetBSD.org/Ports/i386/ps2.html
-=- We should be mindful of the potential goal, but as the tantric    -=-
-=- Buddhist masters say, ``You may notice during meditation that you -=-
-=- sometimes levitate or glow.   Do not let this distract you.''     -=-

--ELM723983441-5910-0_
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset=ISO-8859-2
Content-Disposition: attachment; filename=qq

Index: pms.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/pckbc/pms.c,v
retrieving revision 1.2
diff -u -p -r1.2 pms.c
--- pms.c	2002/04/22 15:16:56	1.2
+++ pms.c	2002/05/08 13:24:53
@@ -31,6 +31,7 @@ __KERNEL_RCSID(0, "$NetBSD: pms.c,v 1.2 
 #include <sys/device.h>
 #include <sys/ioctl.h>
 #include <sys/kthread.h>
+#include <sys/callout.h>
 
 #include <machine/bus.h>
 
@@ -82,8 +83,7 @@ struct pms_softc {		/* driver status inf
 	struct timeval last, current;
 
 	struct device *sc_wsmousedev;
-	struct proc *sc_event_thread;
-	int sc_reset_flag;
+	struct callout sc_rst;
 };
 
 int pmsprobe __P((struct device *, struct cfdata *, void *));
@@ -95,10 +95,9 @@ struct cfattach pms_ca = {
 };
 
 static int	pms_protocol __P((pckbc_tag_t, pckbc_slot_t));
-static void	do_enable __P((struct pms_softc *));
-static void	do_disable __P((struct pms_softc *));
-static void	pms_reset_thread __P((void*));
-static void	pms_spawn_reset_thread __P((void*));
+static void	do_enable __P((struct pms_softc *, int));
+static void	do_disable __P((struct pms_softc *, int));
+static void	pms_reset __P((void*));
 int	pms_enable __P((void *));
 int	pms_ioctl __P((void *, u_long, caddr_t, int, struct proc *));
 void	pms_disable __P((void *));
@@ -233,6 +232,9 @@ pmsattach(parent, self, aux)
 	 */
 	sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
 
+	/* Reset callout */
+	callout_init(&sc->sc_rst);
+
 	/* no interrupts until enabled */
 	cmd[0] = PMS_DEV_DISABLE;
 	res = pckbc_poll_cmd(pa->pa_tag, pa->pa_slot, cmd, 1, 0, 0, 0);
@@ -240,18 +242,15 @@ pmsattach(parent, self, aux)
 		printf("pmsattach: disable error\n");
 	pckbc_slot_enable(sc->sc_kbctag, sc->sc_kbcslot, 0);
 
-	sc->sc_reset_flag = 0;
-
-	kthread_create(pms_spawn_reset_thread, sc);
-
 #ifndef PMS_DISABLE_POWERHOOK
 	sc->sc_powerhook = powerhook_establish(pms_power, sc);
 #endif /* !PMS_DISABLE_POWERHOOK */
 }
 
 static void
-do_enable(sc)
+do_enable(sc, poll)
 	struct pms_softc *sc;
+	int poll;
 {
 	u_char cmd[1];
 	int res;
@@ -265,7 +264,13 @@ do_enable(sc)
 	pckbc_slot_enable(sc->sc_kbctag, sc->sc_kbcslot, 1);
 
 	cmd[0] = PMS_DEV_ENABLE;
-	res = pckbc_enqueue_cmd(sc->sc_kbctag, sc->sc_kbcslot, cmd, 1, 0, 1, 0);
+	if (poll) {
+		res = pckbc_poll_cmd(sc->sc_kbctag, sc->sc_kbcslot,
+			cmd, 1, 0, 0, 1);
+	} else {
+		res = pckbc_enqueue_cmd(sc->sc_kbctag, sc->sc_kbcslot,
+			cmd, 1, 0, 1, 0);
+	}
 	if (res)
 		printf("pms_enable: command error %d\n", res);
 
@@ -300,14 +305,21 @@ do_enable(sc)
 }
 
 static void
-do_disable(sc)
+do_disable(sc, poll)
 	struct pms_softc *sc;
+	int poll;
 {
 	u_char cmd[1];
 	int res;
 
 	cmd[0] = PMS_DEV_DISABLE;
-	res = pckbc_enqueue_cmd(sc->sc_kbctag, sc->sc_kbcslot, cmd, 1, 0, 1, 0);
+	if (poll) {
+		res = pckbc_poll_cmd(sc->sc_kbctag, sc->sc_kbcslot, cmd,
+			1, 0, 0, 1);
+	} else {
+		res = pckbc_enqueue_cmd(sc->sc_kbctag, sc->sc_kbcslot, cmd,
+			1, 0, 1, 0);
+	}
 	if (res)
 		printf("pms_disable: command error\n");
 
@@ -325,7 +337,7 @@ pms_enable(v)
 
 	sc->sc_enabled = 1;
 
-	do_enable(sc);
+	do_enable(sc, 0);
 
 	return 0;
 }
@@ -336,7 +348,7 @@ pms_disable(v)
 {
 	struct pms_softc *sc = v;
 
-	do_disable(sc);
+	do_disable(sc, 0);
 
 	sc->sc_enabled = 0;
 }
@@ -353,11 +365,11 @@ pms_power(why, v)
 	case PWR_SUSPEND:
 	case PWR_STANDBY:
 		if (sc->sc_enabled)
-			do_disable(sc);
+			do_disable(sc, 0);
 		break;
 	case PWR_RESUME:
 		if (sc->sc_enabled)
-			do_enable(sc);
+			do_enable(sc, 0);
 	case PWR_SOFTSUSPEND:
 	case PWR_SOFTSTANDBY:
 	case PWR_SOFTRESUME:
@@ -408,25 +420,20 @@ pms_ioctl(v, cmd, data, flag, p)
 }
 
 static void
-pms_spawn_reset_thread(arg)
+pms_reset(arg)
 	void *arg;
 {
 	struct pms_softc *sc = arg;
-	kthread_create1(pms_reset_thread, sc, &sc->sc_event_thread,
-	    sc->sc_dev.dv_xname);
-}
+	int s;
 
-static void
-pms_reset_thread(arg)
-	void *arg;
-{
-	struct pms_softc *sc = arg;
-	for (;;) {
-		tsleep(&sc->sc_reset_flag, PWAIT, "pmsreset", 0);
-		printf("pms: resetting mouse interface\n");
-		pms_disable(sc);
-		pms_enable(sc);
-	}
+	printf("%s: resetting mouse interface\n", sc->sc_dev.dv_xname);
+
+	s = spltty();
+	sc->sc_enabled = 0;
+	do_disable(sc, 1);
+	do_enable(sc, 1);
+	sc->sc_enabled = 1;
+	splx(s);
 }
 
 /* Masks for the first byte of a packet */
@@ -473,7 +480,8 @@ pmsinput(vsc, data)
 			    "spawning reset thread\n"));
 			sc->inputstate = 0;
 			sc->sc_enabled = 0;
-			wakeup(&sc->sc_reset_flag);
+			/* Schedule reset */
+			callout_reset(&sc->sc_rst, 0, pms_reset, sc);
 			return;
 		}
 	}
@@ -490,7 +498,8 @@ pmsinput(vsc, data)
 			    "[0x%02x], resetting\n", sc->packet[0]));
 			sc->inputstate = 0;
 			sc->sc_enabled = 0;
-			wakeup(&sc->sc_reset_flag);
+			/* Schedule reset */
+			callout_reset(&sc->sc_rst, 0, pms_reset, sc);
 			return;
 		}
 		break;
@@ -574,7 +583,8 @@ pmsinput(vsc, data)
 		printf("pmsinput: very confused.  resetting.\n");
 		sc->inputstate = 0;
 		sc->sc_enabled = 0;
-		wakeup(&sc->sc_reset_flag);
+		/* Schedule reset */
+		callout_reset(&sc->sc_rst, 0, pms_reset, sc);
 		return;
 	}
 }

--ELM723983441-5910-0_--