Since the pms(4) driver started to support more and more touchpad
protocols and with the recent activation of elantech 1 & 2 support,
we realized that the current protocol detection code can confuse
various touchpads responding to more than one magic sequence.
So this diff change the way protocols are probed to stop right after
one supported protocol has been found. This way if your touchpad
responds to various different magic sequences it will not be left in
a half configured state after the probing routine has finished its
execution.
I'm not expecting any regression with this diff but I'd like to have
various tests reports from various different touchpads and mouses to
be sure.
Please don't forget to indicate which protocol/firmware/version of your
touchpad you tested this diff with. "$ dmesg | grep pms" should be
enough.
Martin
Index: pms.c
===================================================================
RCS file: /cvs/src/sys/dev/pckbc/pms.c,v
retrieving revision 1.37
diff -u -p -r1.37 pms.c
--- pms.c 18 Mar 2013 16:31:01 -0000 1.37
+++ pms.c 23 Mar 2013 17:33:11 -0000
@@ -39,6 +39,8 @@
#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wsmousevar.h>
+#define DEBUG
+
#ifdef DEBUG
#define DPRINTF(x...) do { printf(x); } while (0);
#else
@@ -233,6 +235,7 @@ int pms_set_scaling(struct pms_softc *,
int pms_reset(struct pms_softc *);
int pms_dev_enable(struct pms_softc *);
int pms_dev_disable(struct pms_softc *);
+void pms_protocol_lookup(struct pms_softc *);
int pms_enable_intelli(struct pms_softc *);
@@ -490,6 +493,23 @@ pms_dev_disable(struct pms_softc *sc)
return (res);
}
+void
+pms_protocol_lookup(struct pms_softc *sc)
+{
+ int i;
+
+ sc->protocol = &pms_protocols[0];
+ for (i = 1; i < nitems(pms_protocols); i++) {
+ pms_reset(sc);
+ if (pms_protocols[i].enable(sc)) {
+ sc->protocol = &pms_protocols[i];
+ break;
+ }
+ }
+
+ DPRINTF("%s: protocol type %d\n", DEVNAME(sc), sc->protocol->type);
+}
+
int
pms_enable_intelli(struct pms_softc *sc)
{
@@ -611,7 +631,6 @@ pmsattach(struct device *parent, struct
struct pms_softc *sc = (void *)self;
struct pckbc_attach_args *pa = aux;
struct wsmousedev_attach_args a;
- int i;
sc->sc_kbctag = pa->pa_tag;
@@ -634,14 +653,8 @@ pmsattach(struct device *parent, struct
sc->poll = 1;
sc->sc_dev_enable = 0;
- sc->protocol = &pms_protocols[0];
- for (i = 1; i < nitems(pms_protocols); i++) {
- pms_reset(sc);
- if (pms_protocols[i].enable(sc))
- sc->protocol = &pms_protocols[i];
- }
-
- DPRINTF("%s: protocol type %d\n", DEVNAME(sc), sc->protocol->type);
+ /* See if the device understands an extended (touchpad) protocol. */
+ pms_protocol_lookup(sc);
/* no interrupts until enabled */
pms_change_state(sc, PMS_STATE_DISABLED, PMS_DEV_IGNORE);
@@ -670,8 +683,6 @@ pmsactivate(struct device *self, int act
int
pms_change_state(struct pms_softc *sc, int newstate, int dev)
{
- int i;
-
if (dev != PMS_DEV_IGNORE) {
switch (newstate) {
case PMS_STATE_ENABLED:
@@ -704,21 +715,9 @@ pms_change_state(struct pms_softc *sc, i
pckbc_flush(sc->sc_kbctag, PCKBC_AUX_SLOT);
pms_reset(sc);
-
- if (sc->protocol->type != PMS_STANDARD &&
+ if (sc->protocol->type == PMS_STANDARD ||
sc->protocol->enable(sc) == 0)
- sc->protocol = &pms_protocols[0];
-
- if (sc->protocol->type == PMS_STANDARD)
- for (i = 1; i < nitems(pms_protocols); i++) {
- pms_reset(sc);
- if (pms_protocols[i].enable(sc))
- sc->protocol = &pms_protocols[i];
- }
-
-#ifdef DEBUG
- printf("%s: protocol type %d\n", DEVNAME(sc),
sc->protocol->type);
-#endif
+ pms_protocol_lookup(sc);
pms_dev_enable(sc);
break;
@@ -726,7 +725,7 @@ pms_change_state(struct pms_softc *sc, i
case PMS_STATE_SUSPENDED:
pms_dev_disable(sc);
- if (sc->protocol && sc->protocol->disable)
+ if (sc->protocol->disable)
sc->protocol->disable(sc);
pckbc_slot_enable(sc->sc_kbctag, PCKBC_AUX_SLOT, 0);
@@ -760,7 +759,7 @@ pms_ioctl(void *v, u_long cmd, caddr_t d
{
struct pms_softc *sc = v;
- if (sc->protocol && sc->protocol->ioctl)
+ if (sc->protocol->ioctl)
return (sc->protocol->ioctl(sc, cmd, data, flag, p));
else
return (-1);