Subject: kern/16788: pms mouse driver needs to try harder to reset
To: None <gnats-bugs@gnats.netbsd.org>
From: None <apb@cequrux.com>
List: netbsd-bugs
Date: 05/13/2002 15:54:08
>Number: 16788
>Category: kern
>Synopsis: pms mouse driver needs to try harder to reset
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon May 13 09:33:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator: Alan Barrett
>Release: NetBSD 1.5ZC
>Organization:
not much
>Environment:
Architecture: i386
Machine: i386
src/sys/dev/pckbc/psm.c revision 1.20
>Description:
I have an old NEC VERSA 4080H laptop with a trackpad mouse.
The pms mouse driver attaches like this:
pms0 at pckbc0 (aux slot)
wsmouse0 at pms0 mux 0
pms_protocol: standard PS/2 protocol (no scroll wheel)
pms_enable: using no scroll wheel (3 buttons) protocol
It works fine for a while, but after a suspend/resume cycle the
mouse no longer works. A kernel built with options PMSDEBUG
reports errors like this:
pmsinput: 0x8 not set in first byte [0x00], resetting
pms: resetting mouse interface
I suspect that the trackpad's native protocol is not PS/2 compatible,
that something done by pmsprobe() puts it into PS/2 mode, and that
a suspend/resume cycle puts it back into its native mode.
The appended patch seems to work for me, but is probably not the right
thing. (I am running with sources from before the psm.c to pms.c
rename.)
>How-To-Repeat:
>Fix:
--- psm.c.orig Mon May 13 11:27:56 2002
+++ psm.c Mon May 13 15:30:01 2002
@@ -97,6 +97,7 @@
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 do_really_reset __P((struct pms_softc *));
static void pms_reset_thread __P((void*));
static void pms_spawn_reset_thread __P((void*));
int pms_enable __P((void *));
@@ -314,6 +315,33 @@
pckbc_slot_enable(sc->sc_kbctag, sc->sc_kbcslot, 0);
}
+static void
+do_really_reset(sc)
+ struct pms_softc *sc;
+{
+ /*
+ * XXX: this flush/reset code was adapted from pmsprobe(),
+ * XXX: and is probably not the right thing.
+ */
+ u_char cmd[1], resp[2];
+ int res;
+
+ /* Flush any garbage. */
+ pckbc_flush(sc->sc_kbctag, sc->sc_kbcslot);
+
+ /* reset the device */
+ cmd[0] = PMS_RESET;
+ res = pckbc_poll_cmd(sc->sc_kbctag, sc->sc_kbcslot, cmd, 1, 2, resp, 1);
+ if (res) {
+#ifdef DEBUG
+ printf("pms do_really_reset: reset error %d\n", res);
+#endif
+ }
+ if (resp[0] != PMS_RSTDONE) {
+ printf("pms do_really_reset: reset response 0x%x\n", resp[0]);
+ }
+}
+
int
pms_enable(v)
void *v;
@@ -425,6 +453,7 @@
tsleep(&sc->sc_reset_flag, PWAIT, "pmsreset", 0);
printf("pms: resetting mouse interface\n");
pms_disable(sc);
+ do_really_reset(sc);
pms_enable(sc);
}
}
>Release-Note:
>Audit-Trail:
>Unformatted: