diff options
Diffstat (limited to 'sys/dev/atkbdc/psm.c')
-rw-r--r-- | sys/dev/atkbdc/psm.c | 366 |
1 files changed, 256 insertions, 110 deletions
diff --git a/sys/dev/atkbdc/psm.c b/sys/dev/atkbdc/psm.c index 2c14bbe..4b12776 100644 --- a/sys/dev/atkbdc/psm.c +++ b/sys/dev/atkbdc/psm.c @@ -74,6 +74,7 @@ __FBSDID("$FreeBSD$"); #include <machine/bus.h> #include <sys/rman.h> #include <sys/selinfo.h> +#include <sys/sysctl.h> #include <sys/time.h> #include <sys/uio.h> @@ -137,6 +138,16 @@ typedef struct ringbuf { unsigned char buf[PSM_BUFSIZE]; } ringbuf_t; +/* data buffer */ +typedef struct packetbuf { + unsigned char ipacket[16]; /* interim input buffer */ + int inputbytes; /* # of bytes in the input buffer */ +} packetbuf_t; + +#ifndef PSM_PACKETQUEUE +#define PSM_PACKETQUEUE 128 +#endif + /* driver control block */ struct psm_softc { /* Driver status information */ int unit; @@ -152,17 +163,23 @@ struct psm_softc { /* Driver status information */ mousemode_t dflt_mode; /* default operation mode */ mousestatus_t status; /* accumulated mouse movement */ ringbuf_t queue; /* mouse status queue */ - unsigned char ipacket[16]; /* interim input buffer */ - int inputbytes; /* # of bytes in the input buffer */ + packetbuf_t pqueue[PSM_PACKETQUEUE]; /* mouse data queue */ + int pqueue_start; /* start of data in queue */ + int pqueue_end; /* end of data in queue */ int button; /* the latest button state */ int xold; /* previous absolute X position */ int yold; /* previous absolute Y position */ - int syncerrors; + int syncerrors; /* XXX: KILL ME! */ struct timeval inputtimeout; + struct timeval lastsoftintr; /* time of last soft interrupt */ + struct timeval lastinputerr; /* time last sync error happened */ int watchdog; /* watchdog timer flag */ struct callout_handle callout; /* watchdog timer call out */ + struct callout_handle softcallout; /* buffer timer call out */ dev_t dev; dev_t bdev; + int lasterr; + int cmdcount; }; static devclass_t psm_devclass; #define PSM_SOFTC(unit) ((struct psm_softc*)devclass_get_softc(psm_devclass, unit)) @@ -171,6 +188,7 @@ static devclass_t psm_devclass; #define PSM_VALID 0x80 #define PSM_OPEN 1 /* Device is open */ #define PSM_ASLP 2 /* Waiting for mouse data */ +#define PSM_SOFTARMED 4 /* Software interrupt armed */ /* driver configuration flags (config) */ #define PSM_CONFIG_RESOLUTION 0x000f /* resolution */ @@ -250,8 +268,13 @@ static int doinitialize(struct psm_softc *, mousemode_t *); static int doopen(struct psm_softc *, int); static int reinitialize(struct psm_softc *, int); static char *model_name(int); +static void psmsoftintr(void *); static void psmintr(void *); static void psmtimeout(void *); +static int timeelapsed(const struct timeval *, + int, int, const struct timeval *); +static void dropqueue(struct psm_softc *); +static void flushpackets(struct psm_softc *); /* vendor specific features */ typedef int probefunc_t(struct psm_softc *); @@ -268,7 +291,7 @@ static probefunc_t enable_4dmouse; static probefunc_t enable_4dplus; static probefunc_t enable_mmanplus; static probefunc_t enable_versapad; -static int tame_mouse(struct psm_softc *, mousestatus_t *, unsigned char *); +static int tame_mouse(struct psm_softc *, packetbuf_t *, mousestatus_t *, unsigned char *); static struct { int model; @@ -816,7 +839,7 @@ reinitialize(struct psm_softc *sc, int doinit) disable_aux_dev(sc->kbdc); /* this may fail; but never mind... */ empty_aux_buffer(sc->kbdc, 10); } - sc->inputbytes = 0; + flushpackets(sc); sc->syncerrors = 0; /* try to detect the aux device; are you still there? */ @@ -1323,10 +1346,11 @@ psmopen(dev_t dev, int flag, int fmt, struct thread *td) sc->status.dy = 0; sc->status.dz = 0; sc->button = 0; + sc->pqueue_start = 0; + sc->pqueue_end = 0; /* empty input buffer */ - bzero(sc->ipacket, sizeof(sc->ipacket)); - sc->inputbytes = 0; + flushpackets(sc); sc->syncerrors = 0; /* don't let timeout routines in the keyboard driver to poll the kbdc */ @@ -1454,7 +1478,7 @@ psmclose(dev_t dev, int flag, int fmt, struct thread *td) } static int -tame_mouse(struct psm_softc *sc, mousestatus_t *status, unsigned char *buf) +tame_mouse(struct psm_softc *sc, packetbuf_t *pb, mousestatus_t *status, unsigned char *buf) { static unsigned char butmapps2[8] = { 0, @@ -1508,7 +1532,7 @@ tame_mouse(struct psm_softc *sc, mousestatus_t *status, unsigned char *buf) buf[7] = (~status->button >> 3) & 0x7f; return MOUSE_SYS_PACKETSIZE; } - return sc->inputbytes; + return pb->inputbytes; } static int @@ -1605,12 +1629,34 @@ block_mouse_data(struct psm_softc *sc, int *c) */ empty_aux_buffer(sc->kbdc, 0); /* flush the queue */ read_aux_data_no_wait(sc->kbdc); /* throw away data if any */ - sc->inputbytes = 0; + flushpackets(sc); splx(s); return 0; } +static void +dropqueue(struct psm_softc *sc) +{ + + sc->queue.count = 0; + sc->queue.head = 0; + sc->queue.tail = 0; + if ((sc->state & PSM_SOFTARMED) != 0) { + sc->state &= ~PSM_SOFTARMED; + untimeout(psmsoftintr, (void *)(uintptr_t)sc, sc->softcallout); + } + sc->pqueue_start = sc->pqueue_end; +} + +static void +flushpackets(struct psm_softc *sc) +{ + + dropqueue(sc); + bzero(&sc->pqueue, sizeof(sc->pqueue)); +} + static int unblock_mouse_data(struct psm_softc *sc, int c) { @@ -1951,105 +1997,176 @@ psmtimeout(void *arg) sc->callout = timeout(psmtimeout, (void *)(uintptr_t)sc, hz); } +static int psmhz = 20; +SYSCTL_INT(_debug, OID_AUTO, psmhz, CTLFLAG_RW, &psmhz, 0, ""); + +static int psm_soft_timeout = 500000; /* 0.5 sec */ +SYSCTL_INT(_debug, OID_AUTO, psm_soft_timeout, CTLFLAG_RW, + &psm_soft_timeout, 0, ""); + +static int psmerrsecs = 2; +SYSCTL_INT(_debug, OID_AUTO, psmerrsecs, CTLFLAG_RW, &psmerrsecs, 0, ""); +static int psmerrusecs = 0; +SYSCTL_INT(_debug, OID_AUTO, psmerrusecs, CTLFLAG_RW, &psmerrusecs, 0, ""); +static int psmsecs = 0; +SYSCTL_INT(_debug, OID_AUTO, psmsecs, CTLFLAG_RW, &psmsecs, 0, ""); +static int psmusecs = 500000; +SYSCTL_INT(_debug, OID_AUTO, psmusecs, CTLFLAG_RW, &psmusecs, 0, ""); + static void psmintr(void *arg) { - /* - * the table to turn PS/2 mouse button bits (MOUSE_PS2_BUTTON?DOWN) - * into `mousestatus' button bits (MOUSE_BUTTON?DOWN). - */ - static int butmap[8] = { - 0, - MOUSE_BUTTON1DOWN, - MOUSE_BUTTON3DOWN, - MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN, - MOUSE_BUTTON2DOWN, - MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN, - MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN, - MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN - }; - static int butmap_versapad[8] = { - 0, - MOUSE_BUTTON3DOWN, - 0, - MOUSE_BUTTON3DOWN, - MOUSE_BUTTON1DOWN, - MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN, - MOUSE_BUTTON1DOWN, - MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN - }; - register struct psm_softc *sc = arg; - mousestatus_t ms; - struct timeval tv; - int x, y, z; + struct psm_softc *sc = arg; + struct timeval now; int c; - int l; - int x0, y0; + packetbuf_t *pb; + int haderror = 0; + /* read until there is nothing to read */ while((c = read_aux_data_no_wait(sc->kbdc)) != -1) { + pb = &sc->pqueue[sc->pqueue_end]; /* discard the byte if the device is not open */ if ((sc->state & PSM_OPEN) == 0) continue; - getmicrouptime(&tv); - if ((sc->inputbytes > 0) && timevalcmp(&tv, &sc->inputtimeout, >)) { + getmicrouptime(&now); + if ((pb->inputbytes > 0) && timevalcmp(&now, &sc->inputtimeout, >)) { log(LOG_DEBUG, "psmintr: delay too long; resetting byte count\n"); - sc->inputbytes = 0; + pb->inputbytes = 0; sc->syncerrors = 0; } sc->inputtimeout.tv_sec = PSM_INPUT_TIMEOUT/1000000; sc->inputtimeout.tv_usec = PSM_INPUT_TIMEOUT%1000000; - timevaladd(&sc->inputtimeout, &tv); + timevaladd(&sc->inputtimeout, &now); - sc->ipacket[sc->inputbytes++] = c; - if (sc->inputbytes < sc->mode.packetsize) + pb->ipacket[pb->inputbytes++] = c; + if (pb->inputbytes < sc->mode.packetsize) continue; #if 0 log(LOG_DEBUG, "psmintr: %02x %02x %02x %02x %02x %02x\n", - sc->ipacket[0], sc->ipacket[1], sc->ipacket[2], - sc->ipacket[3], sc->ipacket[4], sc->ipacket[5]); + pb->ipacket[0], pb->ipacket[1], pb->ipacket[2], + pb->ipacket[3], pb->ipacket[4], pb->ipacket[5]); #endif - c = sc->ipacket[0]; + c = pb->ipacket[0]; 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]); + log(LOG_DEBUG, "psmintr: out of sync (%04x != %04x) %d" + " cmds since last error.\n", + c & sc->mode.syncmask[0], sc->mode.syncmask[1], + sc->cmdcount - sc->lasterr); + haderror = 1; + sc->lasterr = sc->cmdcount; + dropqueue(sc); ++sc->syncerrors; + sc->lastinputerr = now; if (sc->syncerrors < sc->mode.packetsize) { log(LOG_DEBUG, "psmintr: discard a byte (%d).\n", sc->syncerrors); - --sc->inputbytes; - bcopy(&sc->ipacket[1], &sc->ipacket[0], sc->inputbytes); + --pb->inputbytes; + bcopy(&pb->ipacket[1], &pb->ipacket[0], pb->inputbytes); } else if (sc->syncerrors == sc->mode.packetsize) { log(LOG_DEBUG, "psmintr: re-enable the mouse.\n"); - sc->inputbytes = 0; + pb->inputbytes = 0; disable_aux_dev(sc->kbdc); enable_aux_dev(sc->kbdc); } else if (sc->syncerrors < PSM_SYNCERR_THRESHOLD1) { log(LOG_DEBUG, "psmintr: discard a byte (%d).\n", sc->syncerrors); - --sc->inputbytes; - bcopy(&sc->ipacket[1], &sc->ipacket[0], sc->inputbytes); + --pb->inputbytes; + bcopy(&pb->ipacket[1], &pb->ipacket[0], pb->inputbytes); } else if (sc->syncerrors >= PSM_SYNCERR_THRESHOLD1) { log(LOG_DEBUG, "psmintr: reset the mouse.\n"); reinitialize(sc, TRUE); } continue; } + /* if this packet is at all bogus then drop the packet. */ + if (haderror || + !timeelapsed(&sc->lastinputerr, psmerrsecs, psmerrusecs, &now)) { + pb->inputbytes = 0; + haderror = 0; + continue; + } + + sc->cmdcount++; + if (++sc->pqueue_end >= PSM_PACKETQUEUE) + sc->pqueue_end = 0; + /* + * If we've filled the queue then call the softintr ourselves, + * otherwise schedule the interrupt for later. + */ + if (!timeelapsed(&sc->lastsoftintr, psmsecs, psmusecs, &now) || + (sc->pqueue_end == sc->pqueue_start)) { + if ((sc->state & PSM_SOFTARMED) != 0) { + sc->state &= ~PSM_SOFTARMED; + untimeout(psmsoftintr, arg, sc->softcallout); + } + psmsoftintr(arg); + } else if ((sc->state & PSM_SOFTARMED) == 0) { + sc->state |= PSM_SOFTARMED; + sc->softcallout = timeout(psmsoftintr, arg, + psmhz < 1 ? 1 : (hz/psmhz)); + } + } +} + +static void +psmsoftintr(void *arg) +{ + /* + * the table to turn PS/2 mouse button bits (MOUSE_PS2_BUTTON?DOWN) + * into `mousestatus' button bits (MOUSE_BUTTON?DOWN). + */ + static int butmap[8] = { + 0, + MOUSE_BUTTON1DOWN, + MOUSE_BUTTON3DOWN, + MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN, + MOUSE_BUTTON2DOWN, + MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN, + MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN, + MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN + }; + static int butmap_versapad[8] = { + 0, + MOUSE_BUTTON3DOWN, + 0, + MOUSE_BUTTON3DOWN, + MOUSE_BUTTON1DOWN, + MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN, + MOUSE_BUTTON1DOWN, + MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN + }; + register struct psm_softc *sc = arg; + mousestatus_t ms; + int x, y, z; + int c; + int l; + int x0, y0; + int s; + packetbuf_t *pb; + + getmicrouptime(&sc->lastsoftintr); + s = spltty(); + + do { + + pb = &sc->pqueue[sc->pqueue_start]; + c = pb->ipacket[0]; /* * A kludge for Kensington device! * The MSB of the horizontal count appears to be stored in * a strange place. */ if (sc->hw.model == MOUSE_MODEL_THINK) - sc->ipacket[1] |= (c & MOUSE_PS2_XOVERFLOW) ? 0x80 : 0; + pb->ipacket[1] |= (c & MOUSE_PS2_XOVERFLOW) ? 0x80 : 0; /* ignore the overflow bits... */ - x = (c & MOUSE_PS2_XNEG) ? sc->ipacket[1] - 256 : sc->ipacket[1]; - y = (c & MOUSE_PS2_YNEG) ? sc->ipacket[2] - 256 : sc->ipacket[2]; + x = (c & MOUSE_PS2_XNEG) ? pb->ipacket[1] - 256 : pb->ipacket[1]; + y = (c & MOUSE_PS2_YNEG) ? pb->ipacket[2] - 256 : pb->ipacket[2]; z = 0; ms.obutton = sc->button; /* previous button state */ ms.button = butmap[c & MOUSE_PS2_BUTTONS]; @@ -2071,18 +2188,18 @@ psmintr(void *arg) * s: wheel data sign bit * d2-d0: wheel data */ - z = (sc->ipacket[3] & MOUSE_EXPLORER_ZNEG) - ? (sc->ipacket[3] & 0x0f) - 16 : (sc->ipacket[3] & 0x0f); - ms.button |= (sc->ipacket[3] & MOUSE_EXPLORER_BUTTON4DOWN) + z = (pb->ipacket[3] & MOUSE_EXPLORER_ZNEG) + ? (pb->ipacket[3] & 0x0f) - 16 : (pb->ipacket[3] & 0x0f); + ms.button |= (pb->ipacket[3] & MOUSE_EXPLORER_BUTTON4DOWN) ? MOUSE_BUTTON4DOWN : 0; - ms.button |= (sc->ipacket[3] & MOUSE_EXPLORER_BUTTON5DOWN) + ms.button |= (pb->ipacket[3] & MOUSE_EXPLORER_BUTTON5DOWN) ? MOUSE_BUTTON5DOWN : 0; break; case MOUSE_MODEL_INTELLI: case MOUSE_MODEL_NET: /* wheel data is in the fourth byte */ - z = (char)sc->ipacket[3]; + z = (char)pb->ipacket[3]; /* some mice may send 7 when there is no Z movement?! XXX */ if ((z >= 7) || (z <= -7)) z = 0; @@ -2123,23 +2240,23 @@ psmintr(void *arg) */ if (((c & MOUSE_PS2PLUS_SYNCMASK) == MOUSE_PS2PLUS_SYNC) && (abs(x) > 191) - && MOUSE_PS2PLUS_CHECKBITS(sc->ipacket)) { + && MOUSE_PS2PLUS_CHECKBITS(pb->ipacket)) { /* the extended data packet encodes button and wheel events */ - switch (MOUSE_PS2PLUS_PACKET_TYPE(sc->ipacket)) { + switch (MOUSE_PS2PLUS_PACKET_TYPE(pb->ipacket)) { case 1: /* wheel data packet */ x = y = 0; - if (sc->ipacket[2] & 0x80) { + if (pb->ipacket[2] & 0x80) { /* horizontal roller count - ignore it XXX*/ } else { /* vertical roller count */ - z = (sc->ipacket[2] & MOUSE_PS2PLUS_ZNEG) - ? (sc->ipacket[2] & 0x0f) - 16 - : (sc->ipacket[2] & 0x0f); + z = (pb->ipacket[2] & MOUSE_PS2PLUS_ZNEG) + ? (pb->ipacket[2] & 0x0f) - 16 + : (pb->ipacket[2] & 0x0f); } - ms.button |= (sc->ipacket[2] & MOUSE_PS2PLUS_BUTTON4DOWN) + ms.button |= (pb->ipacket[2] & MOUSE_PS2PLUS_BUTTON4DOWN) ? MOUSE_BUTTON4DOWN : 0; - ms.button |= (sc->ipacket[2] & MOUSE_PS2PLUS_BUTTON5DOWN) + ms.button |= (pb->ipacket[2] & MOUSE_PS2PLUS_BUTTON5DOWN) ? MOUSE_BUTTON5DOWN : 0; break; case 2: @@ -2150,20 +2267,20 @@ psmintr(void *arg) */ x = y = 0; /* horizontal count */ - if (sc->ipacket[2] & 0x0f) - z = (sc->ipacket[2] & MOUSE_SPOINT_WNEG) ? -2 : 2; + if (pb->ipacket[2] & 0x0f) + z = (pb->ipacket[2] & MOUSE_SPOINT_WNEG) ? -2 : 2; /* vertical count */ - if (sc->ipacket[2] & 0xf0) - z = (sc->ipacket[2] & MOUSE_SPOINT_ZNEG) ? -1 : 1; + if (pb->ipacket[2] & 0xf0) + z = (pb->ipacket[2] & MOUSE_SPOINT_ZNEG) ? -1 : 1; #if 0 /* vertical count */ - z = (sc->ipacket[2] & MOUSE_SPOINT_ZNEG) - ? ((sc->ipacket[2] >> 4) & 0x0f) - 16 - : ((sc->ipacket[2] >> 4) & 0x0f); + z = (pb->ipacket[2] & MOUSE_SPOINT_ZNEG) + ? ((pb->ipacket[2] >> 4) & 0x0f) - 16 + : ((pb->ipacket[2] >> 4) & 0x0f); /* horizontal count */ - w = (sc->ipacket[2] & MOUSE_SPOINT_WNEG) - ? (sc->ipacket[2] & 0x0f) - 16 - : (sc->ipacket[2] & 0x0f); + w = (pb->ipacket[2] & MOUSE_SPOINT_WNEG) + ? (pb->ipacket[2] & 0x0f) - 16 + : (pb->ipacket[2] & 0x0f); #endif break; case 0: @@ -2175,8 +2292,8 @@ psmintr(void *arg) if (bootverbose) log(LOG_DEBUG, "psmintr: unknown PS2++ packet type %d: " "0x%02x 0x%02x 0x%02x\n", - MOUSE_PS2PLUS_PACKET_TYPE(sc->ipacket), - sc->ipacket[0], sc->ipacket[1], sc->ipacket[2]); + MOUSE_PS2PLUS_PACKET_TYPE(pb->ipacket), + pb->ipacket[0], pb->ipacket[1], pb->ipacket[2]); break; } } else { @@ -2192,12 +2309,12 @@ psmintr(void *arg) case MOUSE_MODEL_NETSCROLL: /* three addtional bytes encode buttons and wheel events */ - ms.button |= (sc->ipacket[3] & MOUSE_PS2_BUTTON3DOWN) + ms.button |= (pb->ipacket[3] & MOUSE_PS2_BUTTON3DOWN) ? MOUSE_BUTTON4DOWN : 0; - ms.button |= (sc->ipacket[3] & MOUSE_PS2_BUTTON1DOWN) + ms.button |= (pb->ipacket[3] & MOUSE_PS2_BUTTON1DOWN) ? MOUSE_BUTTON5DOWN : 0; - z = (sc->ipacket[3] & MOUSE_PS2_XNEG) - ? sc->ipacket[4] - 256 : sc->ipacket[4]; + z = (pb->ipacket[3] & MOUSE_PS2_XNEG) + ? pb->ipacket[4] - 256 : pb->ipacket[4]; break; case MOUSE_MODEL_THINK: @@ -2231,8 +2348,8 @@ psmintr(void *arg) ms.button |= (c & MOUSE_PS2VERSA_TAP) ? MOUSE_BUTTON4DOWN : 0; x = y = 0; if (c & MOUSE_PS2VERSA_IN_USE) { - x0 = sc->ipacket[1] | (((sc->ipacket[4]) & 0x0f) << 8); - y0 = sc->ipacket[2] | (((sc->ipacket[4]) & 0xf0) << 4); + x0 = pb->ipacket[1] | (((pb->ipacket[4]) & 0x0f) << 8); + y0 = pb->ipacket[2] | (((pb->ipacket[4]) & 0xf0) << 4); if (x0 & 0x800) x0 -= 0x1000; if (y0 & 0x800) @@ -2272,8 +2389,8 @@ psmintr(void *arg) * s2: wheel 2 direction * d2: wheel 2 data */ - x = (sc->ipacket[1] & 0x80) ? sc->ipacket[1] - 256 : sc->ipacket[1]; - y = (sc->ipacket[2] & 0x80) ? sc->ipacket[2] - 256 : sc->ipacket[2]; + x = (pb->ipacket[1] & 0x80) ? pb->ipacket[1] - 256 : pb->ipacket[1]; + y = (pb->ipacket[2] & 0x80) ? pb->ipacket[2] - 256 : pb->ipacket[2]; switch (c & MOUSE_4D_WHEELBITS) { case 0x10: z = 1; @@ -2303,11 +2420,11 @@ psmintr(void *arg) * d1-d0: wheel data */ x = y = 0; - if (sc->ipacket[2] & MOUSE_4DPLUS_BUTTON4DOWN) + if (pb->ipacket[2] & MOUSE_4DPLUS_BUTTON4DOWN) ms.button |= MOUSE_BUTTON4DOWN; - z = (sc->ipacket[2] & MOUSE_4DPLUS_ZNEG) - ? ((sc->ipacket[2] & 0x07) - 8) - : (sc->ipacket[2] & 0x07) ; + z = (pb->ipacket[2] & MOUSE_4DPLUS_ZNEG) + ? ((pb->ipacket[2] & 0x07) - 8) + : (pb->ipacket[2] & 0x07) ; } else { /* preserve previous button states */ ms.button |= ms.obutton & MOUSE_EXTBUTTONS; @@ -2344,7 +2461,7 @@ psmintr(void *arg) | (ms.obutton ^ ms.button); if (sc->mode.level < PSM_LEVEL_NATIVE) - sc->inputbytes = tame_mouse(sc, &ms, sc->ipacket); + pb->inputbytes = tame_mouse(sc, pb, &ms, pb->ipacket); sc->status.flags |= ms.flags; sc->status.dx += ms.dx; @@ -2356,23 +2473,27 @@ psmintr(void *arg) sc->watchdog = FALSE; /* queue data */ - if (sc->queue.count + sc->inputbytes < sizeof(sc->queue.buf)) { - l = imin(sc->inputbytes, sizeof(sc->queue.buf) - sc->queue.tail); - bcopy(&sc->ipacket[0], &sc->queue.buf[sc->queue.tail], l); - if (sc->inputbytes > l) - bcopy(&sc->ipacket[l], &sc->queue.buf[0], sc->inputbytes - l); + if (sc->queue.count + pb->inputbytes < sizeof(sc->queue.buf)) { + l = imin(pb->inputbytes, sizeof(sc->queue.buf) - sc->queue.tail); + bcopy(&pb->ipacket[0], &sc->queue.buf[sc->queue.tail], l); + if (pb->inputbytes > l) + bcopy(&pb->ipacket[l], &sc->queue.buf[0], pb->inputbytes - l); sc->queue.tail = - (sc->queue.tail + sc->inputbytes) % sizeof(sc->queue.buf); - sc->queue.count += sc->inputbytes; + (sc->queue.tail + pb->inputbytes) % sizeof(sc->queue.buf); + sc->queue.count += pb->inputbytes; } - sc->inputbytes = 0; + pb->inputbytes = 0; - if (sc->state & PSM_ASLP) { - sc->state &= ~PSM_ASLP; - wakeup( sc); - } - selwakeuppri(&sc->rsel, PZERO); + if (++sc->pqueue_start >= PSM_PACKETQUEUE) + sc->pqueue_start = 0; + } while (sc->pqueue_start != sc->pqueue_end); + if (sc->state & PSM_ASLP) { + sc->state &= ~PSM_ASLP; + wakeup( sc); } + selwakeuppri(&sc->rsel, PZERO); + sc->state &= ~PSM_SOFTARMED; + splx(s); } static int @@ -2973,5 +3094,30 @@ psmcpnp_attach(device_t dev) return 0; } +/* + * Return true if 'now' is earlier than (start + (secs.usecs)). + * Now may be NULL and the function will fetch the current time from + * getmicrouptime(), or a cached 'now' can be passed in. + * All values should be numbers derived from getmicrouptime(). + */ +static int +timeelapsed(start, secs, usecs, now) + const struct timeval *start, *now; + int secs, usecs; +{ + struct timeval snow, tv; + + /* if there is no 'now' passed in, the get it as a convience. */ + if (now == NULL) { + getmicrouptime(&snow); + now = &snow; + } + + tv.tv_sec = secs; + tv.tv_usec = usecs; + timevaladd(&tv, start); + return (timevalcmp(&tv, now, <)); +} + DRIVER_MODULE(psmcpnp, isa, psmcpnp_driver, psmcpnp_devclass, 0, 0); DRIVER_MODULE(psmcpnp, acpi, psmcpnp_driver, psmcpnp_devclass, 0, 0); |