Let lkms(4) support VSXXX-AB tablets in addition to the mice it already
authormiod <miod@openbsd.org>
Fri, 22 Aug 2008 21:05:04 +0000 (21:05 +0000)
committermiod <miod@openbsd.org>
Fri, 22 Aug 2008 21:05:04 +0000 (21:05 +0000)
supports, based on appendix C and D of the VCB02 (qdss) technical manual.

Also parse the selftest results and report device errors.

Not tested on actual tablet due to the lack of any; mouse operation is not
disturbed.

distrib/notes/vax/hardware
share/man/man4/man4.vax/lkms.4
sys/arch/vax/dec/dzms.c
sys/arch/vax/dec/vsms_ws.c
sys/arch/vax/dec/vsmsvar.h
sys/arch/vax/vxt/qscms.c

index f3f4ba5..51d0abd 100644 (file)
@@ -1,4 +1,4 @@
-dnl    $OpenBSD: hardware,v 1.26 2008/08/20 18:59:59 miod Exp $
+dnl    $OpenBSD: hardware,v 1.27 2008/08/22 21:05:04 miod Exp $
 OpenBSD/MACHINE OSREV runs on a wide variety of VAX hardware.
 The following systems have been tested:
        - VAXstation 2000
@@ -65,7 +65,7 @@ Supported devices {:-include-:}:
 
     * Input devices:
        - LK201 and LK401 keyboards (lkkbd)
-       - VSxxx mouse (lkms)
+       - VSxxx mice and tablets (lkms)
 
 The lowest amount of memory tested is 8MB; however, more is recommended.
 
index 6550a94..4a52779 100644 (file)
@@ -1,4 +1,4 @@
-.\"     $OpenBSD: lkms.4,v 1.4 2007/05/31 19:19:57 jmc Exp $
+.\"     $OpenBSD: lkms.4,v 1.5 2008/08/22 21:05:06 miod Exp $
 .\"
 .\" Copyright (c) 2003 Jason L. Wright (jason@thought.net)
 .\" All rights reserved.
@@ -24,7 +24,7 @@
 .\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd $Mdocdate: May 31 2007 $
+.Dd $Mdocdate: August 22 2008 $
 .Dt LKMS 4 vax
 .Os
 .Sh NAME
@@ -37,7 +37,7 @@
 .Sh DESCRIPTION
 The
 .Nm
-driver provides support for DEC mice hooked up to
+driver provides support for DEC mice and tablets hooked up to
 .Xr dz 4
 or
 .Xr qsc 4
index d933136..71deb85 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dzms.c,v 1.7 2006/08/27 16:52:15 miod Exp $   */
+/*     $OpenBSD: dzms.c,v 1.8 2008/08/22 21:05:07 miod Exp $   */
 /*     $NetBSD: dzms.c,v 1.1 2000/12/02 17:03:55 ragge Exp $   */
 
 /*
@@ -42,7 +42,7 @@
  */
 
 /*
- * VSXXX mice attached to line 1 of the DZ*
+ * VSXXX mouse or tablet, attached to line 1 of the DZ*
  */
 
 #include <sys/param.h>
@@ -125,8 +125,7 @@ dzms_attach(struct device *parent, struct device *self, void *aux)
        a.accessops = &dzms_accessops;
        a.accesscookie = dzms;
 
-       sc->sc_enabled = 0;
-       sc->sc_selftest = 0;
+       sc->sc_flags = 0;
        sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
 }
 
@@ -136,20 +135,20 @@ dzms_enable(void *v)
        struct dzms_softc *dzms = v;
        struct lkms_softc *sc = v;
 
-       if (sc->sc_enabled)
+       if (ISSET(sc->sc_flags, MS_ENABLED))
                return EBUSY;
 
-       sc->sc_selftest = 4;    /* wait for 4 byte reply upto 1/2 sec */
-       dzputc(dzms->dzms_ls, MOUSE_SELF_TEST);
-       (void)tsleep(&sc->sc_enabled, TTIPRI, "dzmsopen", hz / 2);
-       if (sc->sc_selftest != 0) {
-               sc->sc_selftest = 0;
+       SET(sc->sc_flags, MS_SELFTEST);
+       dzputc(dzms->dzms_ls, VS_SELF_TEST);
+       /* selftest is supposed to complete within 500ms */
+       (void)tsleep(&sc->sc_flags, TTIPRI, "dzmsopen", hz / 2);
+       if (ISSET(sc->sc_flags, MS_SELFTEST)) {
+               CLR(sc->sc_flags, MS_SELFTEST);
                return ENXIO;
        }
        DELAY(150);
-       dzputc(dzms->dzms_ls, MOUSE_INCREMENTAL);
-       sc->sc_enabled = 1;
-       sc->inputstate = 0;
+       dzputc(dzms->dzms_ls, VS_INCREMENTAL);
+       SET(sc->sc_flags, MS_ENABLED);
        return 0;
 }
 
@@ -158,5 +157,5 @@ dzms_disable(void *v)
 {
        struct lkms_softc *sc = v;
 
-       sc->sc_enabled = 0;
+       CLR(sc->sc_flags, MS_ENABLED);
 }
index ea26e93..981002b 100644 (file)
@@ -1,6 +1,21 @@
-/*     $OpenBSD: vsms_ws.c,v 1.2 2007/04/10 22:37:17 miod Exp $        */
+/*     $OpenBSD: vsms_ws.c,v 1.3 2008/08/22 21:05:07 miod Exp $        */
 /*     $NetBSD: dzms.c,v 1.1 2000/12/02 17:03:55 ragge Exp $   */
 
+/*
+ * Copyright (c) 2008 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
 /*
  * Copyright (c) 1992, 1993
  *     The Regents of the University of California.  All rights reserved.
 #include <dev/wscons/wsconsio.h>
 #include <dev/wscons/wsmousevar.h>
 
+int    lkms_handle_error(struct lkms_softc *, int);
+void   lkms_input_disabled(struct lkms_softc *, int);
+void   lkms_input_mouse(struct lkms_softc *, int);
+void   lkms_input_tablet(struct lkms_softc *, int);
+
+#define WSMS_BUTTON(x) (1 << ((x) - 1))
+
 struct cfdriver lkms_cd = {
        NULL, "lkms", DV_DULL
 };
 
+/*
+ * Report the device type and status on attachment, and return nonzero
+ * if it is not in working state.
+ */
+int
+lkms_handle_error(struct lkms_softc *sc, int mask)
+{
+       int error = sc->sc_error;
+
+#ifdef DEBUG
+       printf("%s: ", sc->dzms_dev.dv_xname);
+#endif
+
+       if (ISSET(sc->sc_flags, MS_TABLET)) {
+#ifdef DEBUG
+               printf("tablet, ");
+#endif
+               /*
+                * If we are a tablet, the stylet vs puck information
+                * is returned as a non-fatal status code.  Handle
+                * it there so that this does not get in the way.
+                */
+               switch (error) {
+               case ERROR_TABLET_NO_POINTER:
+                       /* i can has cheezpuck? */
+#ifdef DEBUG
+                       printf("neither stylus nor puck connected\n");
+#else
+                       printf("%s: neither stylus nor puck connected\n",
+                           sc->dzms_dev.dv_xname);
+#endif
+                       error = ERROR_OK;
+                       break;
+               case ERROR_TABLET_STYLUS:
+#ifdef DEBUG
+                       printf("stylus\n");
+#endif
+                       SET(sc->sc_flags, MS_STYLUS);
+                       error = ERROR_OK;
+                       break;
+               default:
+#ifdef DEBUG
+                       printf("puck\n");
+#endif
+                       break;
+               }
+       } else {
+#ifdef DEBUG
+               printf("mouse\n");
+#endif
+       }
+
+       switch (error) {
+       case ERROR_MEMORY_CKSUM_ERROR:
+               printf("%s: memory checksum error\n",
+                   sc->dzms_dev.dv_xname);
+               break;
+       case ERROR_BUTTON_ERROR:
+           {
+               int btn;
+
+               /*
+                * Print the list of defective parts
+                */
+               if (ISSET(sc->sc_flags, MS_TABLET)) {
+                       if ((mask & FRAME_T_PR) != 0)
+                               printf("%s: proximity sensor defective\n",
+                                   sc->dzms_dev.dv_xname);
+               } else
+                       mask <<= 1;
+
+               for (btn = 1; btn < 4; btn++)
+                       if ((mask & (1 << btn)) != 0)
+                               printf("%s: button %d held down or defective\n",
+                                   sc->dzms_dev.dv_xname, btn);
+           }
+               break;
+       case ERROR_TABLET_LINK:
+               /* how vague this error is... */
+               printf("%s: analog or digital error\n",
+                   sc->dzms_dev.dv_xname);
+               break;
+       default:
+               printf("%s: %sselftest error %02x\n", sc->dzms_dev.dv_xname,
+                   error >= ERROR_FATAL ? "fatal " : "", error);
+               break;
+       case ERROR_OK:
+               break;
+       }
+
+       if (error >= ERROR_FATAL)
+               return ENXIO;
+
+       return 0;
+}
+
 int
 lkms_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
 {
-#if 0
        struct lkms_softc *sc = v;
-#endif
+       struct wsmouse_calibcoords *wsmc = (struct wsmouse_calibcoords *)data;
 
        switch (cmd) {
        case WSMOUSEIO_GTYPE:
                *(int *)data = WSMOUSE_TYPE_VSXXX;
                return 0;
+
+       case WSMOUSEIO_GCALIBCOORDS:
+               if (ISSET(sc->sc_flags, MS_TABLET)) {
+                       /*
+                        * The tablet has a usable size of 11 inch on each
+                        * axis, with a 200dpi resolution.
+                        */
+                       wsmc->minx = 0;
+                       wsmc->maxx = 200 * 11;
+                       wsmc->miny = 0;
+                       wsmc->maxy = 200 * 11;
+                       wsmc->swapxy = 0;
+                       wsmc->resx = wsmc->maxx;        /* anything better? */
+                       wsmc->resy = wsmc->maxy;        /* anything better? */
+                       wsmc->samplelen = 0;
+                       return 0;
+               } else
+                       break;
        }
 
        return -1;
@@ -86,49 +221,170 @@ lkms_input(void *vsc, int data)
 {
        struct lkms_softc *sc = vsc;
 
-       if (!sc->sc_enabled) {
-               if (sc->sc_selftest > 0) {
-                       sc->sc_selftest--;
-                       if (sc->sc_selftest == 0)
-                               wakeup(&sc->sc_enabled);
+       if ((data & FRAME_MASK) != 0) {
+               sc->sc_frametype = data & FRAME_TYPE_MASK;
+               sc->sc_framepos = 0;
+       } else
+               sc->sc_framepos++;
+
+       if (ISSET(sc->sc_flags, MS_ENABLED) &&
+           !ISSET(sc->sc_flags, MS_SELFTEST)) {
+               switch (sc->sc_frametype) {
+               case FRAME_MOUSE:
+                       lkms_input_mouse(sc, data);
+                       break;
+               case FRAME_TABLET:
+                       lkms_input_tablet(sc, data);
+                       break;
                }
-               return (1);
-       }
+       } else
+               lkms_input_disabled(sc, data);
+
+       return 1;
+}
+
+/*
+ * Input processing while the device is disabled.  We only are
+ * interested in processing self test frames, so as to identify
+ * the device and report its state.
+ */
+void
+lkms_input_disabled(struct lkms_softc *sc, int data)
+{
+       if (!ISSET(sc->sc_flags, MS_SELFTEST))
+               return;
 
-#define WSMS_BUTTON1    0x01
-#define WSMS_BUTTON2    0x02
-#define WSMS_BUTTON3    0x04
+       if (sc->sc_frametype == FRAME_SELFTEST) {
+               switch (sc->sc_framepos) {
+               case 0:
+                       break;
+               case 1:
+                       data &= FRAME_ST_DEVICE_MASK;
+                       if (data == FRAME_ST_DEVICE_TABLET)
+                               SET(sc->sc_flags, MS_TABLET);
+                       else if (data != FRAME_ST_DEVICE_MOUSE) {
+                               printf("%s: unrecognized device type %02x\n",
+                                   sc->dzms_dev.dv_xname, data);
+                               goto fail;
+                       }
+                       break;
+               case 2:
+                       sc->sc_error = data;
+                       break;
+               case 3:
+                       if (lkms_handle_error(sc, data) != 0)
+                               goto fail;
+
+                       CLR(sc->sc_flags, MS_SELFTEST);
+                       goto success;
+                       break;
+               }
 
-       if ((data & MOUSE_START_FRAME) != 0)
-               sc->inputstate = 1;
-       else
-               sc->inputstate++;
+               return;
+       } /* else goto fail; */
+
+fail:
+       /*
+        * Our self test frame has been truncated, or we have received
+        * incorrect data (both could be a cable problem), or the
+        * selftest reported an error.  The device is unusable.
+        */
+       CLR(sc->sc_flags, MS_TABLET | MS_STYLUS);
+
+success:
+       sc->sc_frametype = 0;
+       wakeup(&sc->sc_flags);
+}
 
-       if (sc->inputstate == 1) {
+/*
+ * Input processing while the device is enabled, for mouse frames.
+ */
+void
+lkms_input_mouse(struct lkms_softc *sc, int data)
+{
+       switch (sc->sc_framepos) {
+       case 0:
                sc->buttons = 0;
-               if ((data & LEFT_BUTTON) != 0)
-                       sc->buttons |= WSMS_BUTTON1;
-               if ((data & MIDDLE_BUTTON) != 0)
-                       sc->buttons |= WSMS_BUTTON2;
-               if ((data & RIGHT_BUTTON) != 0)
-                       sc->buttons |= WSMS_BUTTON3;
-           
-               sc->dx = data & MOUSE_X_SIGN;
-               sc->dy = data & MOUSE_Y_SIGN;
-       } else if (sc->inputstate == 2) {
+               /* button order is inverted from wscons */
+               if ((data & FRAME_MS_B3) != 0)
+                       sc->buttons |= WSMS_BUTTON(1);
+               if ((data & FRAME_MS_B2) != 0)
+                       sc->buttons |= WSMS_BUTTON(2);
+               if ((data & FRAME_MS_B1) != 0)
+                       sc->buttons |= WSMS_BUTTON(3);
+
+               sc->dx = data & FRAME_MS_X_SIGN;
+               sc->dy = data & FRAME_MS_Y_SIGN;
+               break;
+       case 1:
                if (sc->dx == 0)
                        sc->dx = -data;
                else
                        sc->dx = data;
-       } else if (sc->inputstate == 3) {
-               sc->inputstate = 0;
+               break;
+       case 2:
                if (sc->dy == 0)
                        sc->dy = -data;
                else
                        sc->dy = data;
                wsmouse_input(sc->sc_wsmousedev, sc->buttons,
                    sc->dx, sc->dy, 0, 0, WSMOUSE_INPUT_DELTA);
+
+               sc->sc_frametype = 0;
+               break;
        }
+}
+
+/*
+ * Input processing while the device is enabled, for tablet frames.
+ */
+void
+lkms_input_tablet(struct lkms_softc *sc, int data)
+{
+       switch (sc->sc_framepos) {
+       case 0:
+               /*
+                * Button information will depend on the type of positional
+                * device:
+                * - puck buttons get reported as is, as a 4 button mouse.
+                *   Button order is opposite from mouse.
+                * - stylus barrel gets reported as left button, while tip
+                *   gets reported as right button.
+                *   Proximity sensor gets reported as a fictitious fifth
+                *   button.
+                */
+               sc->buttons = 0;
+               if ((data & FRAME_T_B1) != 0)
+                       sc->buttons |= WSMS_BUTTON(1);
+               if ((data & FRAME_T_B2) != 0) {
+                       if (ISSET(sc->sc_flags, MS_STYLUS))
+                               sc->buttons |= WSMS_BUTTON(3);
+                       else
+                               sc->buttons |= WSMS_BUTTON(2);
+               }
+               if ((data & FRAME_T_B3) != 0)
+                       sc->buttons |= WSMS_BUTTON(3);
+               if ((data & FRAME_T_B4) != 0)
+                       sc->buttons |= WSMS_BUTTON(4);
+               if ((data & FRAME_T_PR) != 0)
+                       sc->buttons |= WSMS_BUTTON(5);
+               break;
+       case 1:
+               sc->dx = data & 0x3f;
+               break;
+       case 2:
+               sc->dx |= (data & 0x3f) << 6;
+               break;
+       case 3:
+               sc->dy = data & 0x3f;
+               break;
+       case 4:
+               sc->dy |= (data & 0x3f) << 6;
+               wsmouse_input(sc->sc_wsmousedev, sc->buttons,
+                   sc->dx, sc->dy, 0, 0,
+                   WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y);
 
-       return (1);
+               sc->sc_frametype = 0;
+               break;
+       }
 }
index 4c2d538..1b998e0 100644 (file)
@@ -1,4 +1,19 @@
-/*     $OpenBSD: vsmsvar.h,v 1.1 2006/08/27 16:52:15 miod Exp $        */
+/*     $OpenBSD: vsmsvar.h,v 1.2 2008/08/22 21:05:07 miod Exp $        */
+/*
+ * Copyright (c) 2008 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
 /*
  * Copyright (c) 1992, 1993
  *     The Regents of the University of California.  All rights reserved.
  */
 
 /*
- * Command characters for the mouse.
+ * Command characters
  */
-#define MOUSE_SELF_TEST                'T'
-#define MOUSE_INCREMENTAL      'R'
+#define        VS_B9600                'B'     /* T only: switch to 9600 bps */
+#define        VS_REQUEST_POINT        'D'     /* stop incremental position reports */
+#define        VS_FREQ_55              'K'     /* T only: 55Hz report rate */
+#define        VS_FREQ_72              'L'     /* T only: 72Hz report rate */
+#define        VS_FREQ_120             'M'     /* T only: 120Hz report rate, 9600bps */
+#define        VS_REQUEST_POSITION     'P'     /* request position (in point mode) */
+#define VS_INCREMENTAL         'R'     /* incremental position reports */
+#define VS_SELF_TEST           'T'     /* reset and self test */
 
 /*
- * Mouse output bits.
- *
- *             MOUSE_START_FRAME       Start of report frame bit.
- *     MOUSE_X_SIGN            Sign bit for X.
- *     MOUSE_Y_SIGN            Sign bit for Y.
- *     MOUSE_X_OFFSET          X offset to start cursor at.
- *     MOUSE_Y_OFFSET          Y offset to start cursor at.
+ * Data frame types
+ */
+
+#define        FRAME_MASK              0x80
+#define        FRAME_TYPE_MASK         0xe0
+#define        FRAME_MOUSE             0x80    /* 1 0 0 - mouse 3 byte packet */
+#define        FRAME_SELFTEST          0xa0    /* 1 0 1 - selftest 4 byte packet */
+#define        FRAME_TABLET            0xc0    /* 1 1 0 - tablet 5 byte packet */
+
+/*
+ * Selftest frame layout
+ *     byte 0: frame type and device revision
+ *     byte 1: manufacturing location code and device type
+ *     byte 2: self test result
+ *     byte 3: button mask (if result == button error)
+ */
+
+/* byte 0 */
+#define        FRAME_ST_REV_MASK               0x0f    /* device revision */
+
+/* byte 1 */
+#define        FRAME_ST_LOCATION_MASK          0x70
+#define        FRAME_ST_DEVICE_MASK            0x0f
+#define        FRAME_ST_DEVICE_MOUSE           0x02
+#define        FRAME_ST_DEVICE_TABLET          0x04
+
+/* status test error codes */
+#define        ERROR_OK                        0x00
+#define        ERROR_TABLET_STYLUS             0x11    /* stylus only, no puck */
+#define        ERROR_TABLET_NO_POINTER         0x13    /* neither stylus nor puck */
+#define        ERROR_FATAL                     0x20    /* fatal errors from here */
+#define        ERROR_TABLET_LINK               0x3a    /* tablet internal error */
+#define        ERROR_BUTTON_ERROR              0x3d    /* button malfunction */
+#define        ERROR_MEMORY_CKSUM_ERROR        0x3e    /* firmware malfunction */
+
+/*
+ * Mouse frame layout
+ *     byte 0: frame type, delta signs, button mask
+ *     byte 1: unsigned X delta
+ *     byte 2: unsigned Y delta
  */
-#define MOUSE_START_FRAME      0x80
-#define MOUSE_X_SIGN           0x10
-#define MOUSE_Y_SIGN           0x08
+#define        FRAME_MS_X_SIGN                 0x10    /* set if positive */
+#define        FRAME_MS_Y_SIGN                 0x08    /* set if positive */
+#define        FRAME_MS_B3                     0x04    /* left button */
+#define        FRAME_MS_B2                     0x02    /* middle button */
+#define        FRAME_MS_B1                     0x01    /* right button */
 
 /*
- * Definitions for mouse buttons
+ * Tablet frame layout
+ *     byte 0: frame type, button and proximity sensor mask
+ *     byte 1: low 6 bits of absolute X position
+ *     byte 2: high 6 bits of absolute X position
+ *     byte 3: low 6 bits of absolute Y position
+ *     byte 4: high 6 bits of absolute Y position
  */
-#define RIGHT_BUTTON           0x01
-#define MIDDLE_BUTTON          0x02
-#define LEFT_BUTTON            0x04
+#define        FRAME_T_B4                      0x10    /* puck bottom button */
+#define        FRAME_T_B3                      0x08    /* puck right button */
+#define        FRAME_T_B2                      0x04    /* puck top / stylus tip */
+#define        FRAME_T_B1                      0x02    /* puck left / stylus barrel */
+#define        FRAME_T_PR                      0x01    /* stylus proximity (if zero) */
 
 struct lkms_softc {            /* driver status information */
        struct  device dzms_dev;        /* required first: base device */
 
-       int sc_enabled;         /* input enabled? */
-       int sc_selftest;
+       int     sc_flags;
+#define        MS_ENABLED              0x01    /* input enabled */
+#define        MS_SELFTEST             0x02    /* selftest in progress */
+#define        MS_TABLET               0x04    /* device is a tablet */
+#define        MS_STYLUS               0x08    /* tablet has a stylus, not a puck */
+
+       int     sc_frametype;           /* frame type being processed */
+       u_int   sc_framepos;            /* position in the frame */
+       int     sc_error;               /* selftest error result */
 
-       int inputstate;
-       u_int buttons;
-       int dx, dy;
+       u_int   buttons;
+       int     dx, dy;
 
        struct device *sc_wsmousedev;
 };
index 6ec2bd2..798a8f9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: qscms.c,v 1.1 2006/08/27 16:55:41 miod Exp $  */
+/*     $OpenBSD: qscms.c,v 1.2 2008/08/22 21:05:07 miod Exp $  */
 /*     from OpenBSD: qscms.c,v 1.6 2006/07/31 18:50:13 miod Exp        */
 /*
  * Copyright (c) 2006 Miodrag Vallat.
@@ -57,7 +57,7 @@
  */
 
 /*
- * VSXXX mice attached to line D of the SC26C94
+ * VSXXX mouse or tablet, attached to line D of the SC26C94
  */
 
 #include <sys/param.h>
@@ -130,8 +130,7 @@ qscms_attach(struct device *parent, struct device *self, void *aux)
        a.accessops = &qscms_accessops;
        a.accesscookie = qscms;
 
-       sc->sc_enabled = 0;
-       sc->sc_selftest = 0;
+       sc->sc_flags = 0;
        sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
 }
 
@@ -141,20 +140,20 @@ qscms_enable(void *v)
        struct qscms_softc *qscms = v;
        struct lkms_softc *sc = v;
 
-       if (sc->sc_enabled)
+       if (ISSET(sc->sc_flags, MS_ENABLED))
                return EBUSY;
 
-       sc->sc_selftest = 4;    /* wait for 4 byte reply upto 1/2 sec */
-       qscputc(qscms->sc_line, MOUSE_SELF_TEST);
-       (void)tsleep(&sc->sc_enabled, TTIPRI, "qscmsopen", hz / 2);
-       if (sc->sc_selftest != 0) {
-               sc->sc_selftest = 0;
+       SET(sc->sc_flags, MS_SELFTEST);
+       qscputc(qscms->sc_line, VS_SELF_TEST);
+       /* selftest is supposed to complete within 500ms */
+       (void)tsleep(&sc->sc_flags, TTIPRI, "qscmsopen", hz / 2);
+       if (ISSET(sc->sc_flags, MS_SELFTEST)) {
+               CLR(sc->sc_flags, MS_SELFTEST);
                return ENXIO;
        }
        DELAY(150);
-       qscputc(qscms->sc_line, MOUSE_INCREMENTAL);
-       sc->sc_enabled = 1;
-       sc->inputstate = 0;
+       qscputc(qscms->sc_line, VS_INCREMENTAL);
+       SET(sc->sc_flags, MS_ENABLED);
        return 0;
 }
 
@@ -163,5 +162,5 @@ qscms_disable(void *v)
 {
        struct lkms_softc *sc = v;
 
-       sc->sc_enabled = 0;
+       CLR(sc->sc_flags, MS_ENABLED);
 }