From owner-freebsd-hackers@FreeBSD.ORG Wed Oct 15 02:59:29 2003 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 52AC616A4B3; Wed, 15 Oct 2003 02:59:29 -0700 (PDT) Received: from elvis.mu.org (elvis.mu.org [192.203.228.196]) by mx1.FreeBSD.org (Postfix) with ESMTP id 8A64D43FA3; Wed, 15 Oct 2003 02:59:28 -0700 (PDT) (envelope-from bright@elvis.mu.org) Received: by elvis.mu.org (Postfix, from userid 1192) id 7EDC42ED43C; Wed, 15 Oct 2003 02:59:28 -0700 (PDT) Date: Wed, 15 Oct 2003 02:59:28 -0700 From: Alfred Perlstein To: hackers@freebsd.org Message-ID: <20031015095928.GC99943@elvis.mu.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.1i cc: yokota@freebsd.org Subject: [patch] psm hacks for kvm problems. X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 15 Oct 2003 09:59:29 -0000 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 #include #include +#include #include #include @@ -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: bright@mu.org cell: 408-480-4684