I was getting fustrated with the effect my KVM was having on my PS/2
mouse, basically after switching to the FreeBSD box I was getting
random mouse movement for a second or two including button clicks
as the kvm "settled".

Windows doesn't have this problem.

I have some hacks here that get me close to a solution but not all
the way there. 

This change signifigantly reduces the "jitter" by detecting when
we get out of sync and just dropping data for two seconds (tunable
via sysctl).

I also tried to get the mouse status if there has been no activity
for more than two seconds however this doesn't seem to work.  I
still get an initial jitter.

Does anyone have any suggestions how I could ask the mouse "are you
ok" from within the context of the interrupt routine?  If I could
do that reliably (check to make sure mouse is sane) then I could
get rid of the jitter entirely.

thank you.


Index: psm.c
===================================================================
RCS file: /home/ncvs/src/sys/isa/psm.c,v
retrieving revision 1.61
diff -u -r1.61 psm.c
--- psm.c       12 Jul 2003 18:36:04 -0000      1.61
+++ psm.c       15 Oct 2003 09:43:58 -0000
@@ -74,6 +74,7 @@
 #include <machine/bus.h>
 #include <sys/rman.h>
 #include <sys/selinfo.h>
+#include <sys/sysctl.h>
 #include <sys/time.h>
 #include <sys/uio.h>
 
@@ -99,7 +100,7 @@
 #endif
 
 #ifndef PSM_INPUT_TIMEOUT
-#define PSM_INPUT_TIMEOUT      2000000 /* 2 sec */
+#define PSM_INPUT_TIMEOUT      500000  /* .5 sec */
 #endif
 
 /* end of driver specific options */
@@ -158,7 +159,9 @@
     int                  xold; /* previous absolute X position */
     int                  yold; /* previous absolute Y position */
     int                  syncerrors;
-    struct timeval inputtimeout;
+    struct timeval inputtimeout; /* max delay between bytes per packet */
+    struct timeval syncholdtime; /* how long to backoff when sync error */
+    struct timeval lastvalid;  /* last valid packet time */
     int                  watchdog;     /* watchdog timer flag */
     struct callout_handle callout;     /* watchdog timer call out */
     dev_t        dev;
@@ -1951,6 +1954,15 @@
     sc->callout = timeout(psmtimeout, (void *)(uintptr_t)sc, hz);
 }
 
+static int syncholdtime = 2;
+static int lastvalidthresh = 2;
+
+SYSCTL_NODE(_hw, OID_AUTO, psm, CTLFLAG_RD, 0, "ps/2 mouse");
+SYSCTL_INT(_hw_psm, OID_AUTO, syncholdtime, CTLFLAG_RW, &syncholdtime, 0,
+    "block mouse input when out of sync for this long.");
+SYSCTL_INT(_hw_psm, OID_AUTO, lastvalidthresh, CTLFLAG_RW, &lastvalidthresh, 0,
+    "time between packets to check for status.");
+
 static void
 psmintr(void *arg)
 {
@@ -1980,11 +1992,12 @@
     };
     register struct psm_softc *sc = arg;
     mousestatus_t ms;
-    struct timeval tv;
+    struct timeval tv, tv2;
     int x, y, z;
     int c;
     int l;
     int x0, y0;
+    int stat[3];
 
     /* read until there is nothing to read */
     while((c = read_aux_data_no_wait(sc->kbdc)) != -1) {
@@ -2018,6 +2031,14 @@
        if ((c & sc->mode.syncmask[0]) != sc->mode.syncmask[1]) {
             log(LOG_DEBUG, "psmintr: out of sync (%04x != %04x).\n", 
                c & sc->mode.syncmask[0], sc->mode.syncmask[1]);
+           /*
+            * When we get out of sync record when it happened so that
+            * we can temporarily turn off data until we're back in sync
+            * for 'syncholdtime' seconds.
+            */
+           sc->syncholdtime.tv_sec = syncholdtime;
+           sc->syncholdtime.tv_usec = 0;
+           timevaladd(&sc->syncholdtime, &tv);
            ++sc->syncerrors;
            if (sc->syncerrors < sc->mode.packetsize) {
                log(LOG_DEBUG, "psmintr: discard a byte (%d).\n", sc->syncerrors);
@@ -2038,6 +2059,28 @@
            }
            continue;
        }
+
+       /*
+        * Are we still possibly resyncing?
+        */
+       if (timevalcmp(&tv, &sc->syncholdtime, <)) {
+               sc->inputbytes = 0;
+               continue;
+       }
+       /* If more than 2 seconds have gone by since the last packet
+        * then make sure our mouse is alright.
+        */
+       tv2.tv_sec = lastvalidthresh;
+       tv2.tv_usec = 0;
+       timevaladd(&tv2, &sc->lastvalid);
+       if (timevalcmp(&tv2, &tv, <) &&
+           get_mouse_status(sc->kbdc, stat, 0, 3) < 3) {
+               log(LOG_DEBUG, "psm%d: failed to get status (psmintr).\n",
+                   sc->unit);
+               sc->inputbytes = 0;
+               continue;
+       }
+       sc->lastvalid = tv;
 
        /* 
         * A kludge for Kensington device! 


-- 
- Alfred Perlstein
- Research Engineering Development Inc.
- email: [EMAIL PROTECTED] cell: 408-480-4684
_______________________________________________
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to