Home | History | Annotate | Line # | Download | only in iomd
qms.c revision 1.1.14.1
      1  1.1.14.1  gehenna /*	$NetBSD: qms.c,v 1.1.14.1 2002/05/17 15:41:03 gehenna Exp $	*/
      2       1.1  reinoud 
      3       1.1  reinoud /*
      4       1.1  reinoud  * Copyright (c) Scott Stevens 1995 All rights reserved
      5       1.1  reinoud  * Copyright (c) Melvin Tang-Richardson 1995 All rights reserved
      6       1.1  reinoud  * Copyright (c) Mark Brinicombe 1995 All rights reserved
      7       1.1  reinoud  *
      8       1.1  reinoud  * Redistribution and use in source and binary forms, with or without
      9       1.1  reinoud  * modification, are permitted provided that the following conditions
     10       1.1  reinoud  * are met:
     11       1.1  reinoud  * 1. Redistributions of source code must retain the above copyright
     12       1.1  reinoud  *    notice, this list of conditions and the following disclaimer.
     13       1.1  reinoud  * 2. Redistributions in binary form must reproduce the above copyright
     14       1.1  reinoud  *    notice, this list of conditions and the following disclaimer in the
     15       1.1  reinoud  *    documentation and/or other materials provided with the distribution.
     16       1.1  reinoud  * 3. All advertising materials mentioning features or use of this software
     17       1.1  reinoud  *    must display the following acknowledgement:
     18       1.1  reinoud  *	This product includes software developed for the NetBSD Project.
     19       1.1  reinoud  * 4. The name of the author may not be used to endorse or promote products
     20       1.1  reinoud  *    derived from this software without specific prior written permission.
     21       1.1  reinoud  *
     22       1.1  reinoud  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     23       1.1  reinoud  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     24       1.1  reinoud  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     25       1.1  reinoud  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     26       1.1  reinoud  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     27       1.1  reinoud  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     28       1.1  reinoud  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     29       1.1  reinoud  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30       1.1  reinoud  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     31       1.1  reinoud  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32       1.1  reinoud  */
     33       1.1  reinoud 
     34       1.1  reinoud /*
     35       1.1  reinoud  * Quadrature mouse driver
     36       1.1  reinoud  */
     37       1.1  reinoud 
     38       1.1  reinoud #include <sys/param.h>
     39       1.1  reinoud #include <sys/systm.h>
     40       1.1  reinoud #include <sys/conf.h>
     41       1.1  reinoud #include <sys/ioctl.h>
     42       1.1  reinoud #include <sys/tty.h>
     43       1.1  reinoud #include <sys/kernel.h>
     44       1.1  reinoud #include <sys/types.h>
     45       1.1  reinoud #include <sys/device.h>
     46       1.1  reinoud #include <sys/proc.h>
     47       1.1  reinoud #include <sys/time.h>
     48       1.1  reinoud #include <sys/errno.h>
     49       1.1  reinoud #include <dev/cons.h>
     50       1.1  reinoud #include <sys/fcntl.h>
     51       1.1  reinoud #include <sys/signalvar.h>
     52       1.1  reinoud #include <sys/vnode.h>
     53       1.1  reinoud #include <sys/time.h>
     54       1.1  reinoud #include <sys/poll.h>
     55       1.1  reinoud 
     56       1.1  reinoud #include <machine/bus.h>
     57       1.1  reinoud #include <machine/mouse.h>
     58       1.1  reinoud #include <arm/iomd/qmsvar.h>
     59       1.1  reinoud 
     60       1.1  reinoud #define MOUSE_IOC_ACK
     61       1.1  reinoud 
     62       1.1  reinoud #define QMOUSE_BSIZE 12*64
     63       1.1  reinoud 
     64       1.1  reinoud #ifdef MOUSE_IOC_ACK
     65       1.1  reinoud static void qmsputbuffer	__P((struct qms_softc *sc, struct mousebufrec *buf));
     66       1.1  reinoud #endif
     67       1.1  reinoud 
     68       1.1  reinoud extern struct cfdriver qms_cd;
     69  1.1.14.1  gehenna 
     70  1.1.14.1  gehenna dev_type_open(qmsopen);
     71  1.1.14.1  gehenna dev_type_close(qmsclose);
     72  1.1.14.1  gehenna dev_type_read(qmsread);
     73  1.1.14.1  gehenna dev_type_ioctl(qmsioctl);
     74  1.1.14.1  gehenna dev_type_poll(qmspoll);
     75  1.1.14.1  gehenna 
     76  1.1.14.1  gehenna const struct cdevsw qms_cdevsw = {
     77  1.1.14.1  gehenna 	qmsopen, qmsclose, qmsread, nowrite, qmsioctl,
     78  1.1.14.1  gehenna 	nostop, notty, qmspoll, nommap,
     79  1.1.14.1  gehenna };
     80       1.1  reinoud 
     81       1.1  reinoud /* qms device structure */
     82       1.1  reinoud 
     83       1.1  reinoud /* Offsets of hardware registers */
     84       1.1  reinoud #define QMS_MOUSEX	0		/* 16 bit X register */
     85       1.1  reinoud #define QMS_MOUSEY	1		/* 16 bit Y register */
     86       1.1  reinoud 
     87       1.1  reinoud #define QMS_BUTTONS	0		/* mouse buttons register */
     88       1.1  reinoud 
     89       1.1  reinoud /*
     90       1.1  reinoud  * generic attach routine. This does the generic part of the driver
     91       1.1  reinoud  * attachment and is called from the bus specific attach routine.
     92       1.1  reinoud  */
     93       1.1  reinoud 
     94       1.1  reinoud void
     95       1.1  reinoud qmsattach(sc)
     96       1.1  reinoud 	struct qms_softc *sc;
     97       1.1  reinoud {
     98       1.1  reinoud 	/* Set up origin and multipliers */
     99       1.1  reinoud 	sc->origx = 0;
    100       1.1  reinoud 	sc->origy = 0;
    101       1.1  reinoud 	sc->xmult = 2;
    102       1.1  reinoud 	sc->ymult = 2;
    103       1.1  reinoud 
    104       1.1  reinoud 	/* Set up bounding box */
    105       1.1  reinoud 	sc->boundx = -4095;
    106       1.1  reinoud 	sc->boundy = -4095;
    107       1.1  reinoud 	sc->bounda = 4096;
    108       1.1  reinoud 	sc->boundb = 4096;
    109       1.1  reinoud 
    110       1.1  reinoud 	sc->sc_state = 0;
    111       1.1  reinoud 
    112       1.1  reinoud 	/* Set the mouse X & Y registers to a known state */
    113       1.1  reinoud 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEX, sc->origx);
    114       1.1  reinoud 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEX, sc->origx);
    115       1.1  reinoud }
    116       1.1  reinoud 
    117       1.1  reinoud int
    118       1.1  reinoud qmsopen(dev, flag, mode, p)
    119       1.1  reinoud 	dev_t dev;
    120       1.1  reinoud 	int flag;
    121       1.1  reinoud 	int mode;
    122       1.1  reinoud 	struct proc *p;
    123       1.1  reinoud {
    124       1.1  reinoud 	struct qms_softc *sc;
    125       1.1  reinoud 	int unit = minor(dev);
    126       1.1  reinoud 
    127       1.1  reinoud  	/* validate the unit and softc */
    128       1.1  reinoud 	if (unit >= qms_cd.cd_ndevs)
    129       1.1  reinoud 		return(ENXIO);
    130       1.1  reinoud 
    131       1.1  reinoud 	sc = qms_cd.cd_devs[unit];
    132       1.1  reinoud 
    133       1.1  reinoud 	if (!sc) return(ENXIO);
    134       1.1  reinoud 
    135       1.1  reinoud 	/* check if we are already open */
    136       1.1  reinoud 	if (sc->sc_state & QMOUSE_OPEN) return(EBUSY);
    137       1.1  reinoud 
    138       1.1  reinoud 	/* update softc */
    139       1.1  reinoud 	sc->sc_proc = p;
    140       1.1  reinoud 
    141       1.1  reinoud 	sc->lastx = -1;
    142       1.1  reinoud 	sc->lasty = -1;
    143       1.1  reinoud 	sc->lastb = -1;
    144       1.1  reinoud 
    145       1.1  reinoud 	/* initialise buffer */
    146       1.1  reinoud 	if (clalloc(&sc->sc_buffer, QMOUSE_BSIZE, 0) == -1)
    147       1.1  reinoud 		return(ENOMEM);
    148       1.1  reinoud 
    149       1.1  reinoud 	/* set mode and state */
    150       1.1  reinoud 	sc->sc_mode = MOUSEMODE_ABS;
    151       1.1  reinoud 	sc->sc_state |= QMOUSE_OPEN;
    152       1.1  reinoud 
    153       1.1  reinoud 	/* enable interrupts */
    154       1.1  reinoud 	sc->sc_intenable(sc, 1);
    155       1.1  reinoud 
    156       1.1  reinoud 	return(0);
    157       1.1  reinoud }
    158       1.1  reinoud 
    159       1.1  reinoud 
    160       1.1  reinoud int
    161       1.1  reinoud qmsclose(dev, flag, mode, p)
    162       1.1  reinoud 	dev_t dev;
    163       1.1  reinoud 	int flag;
    164       1.1  reinoud 	int mode;
    165       1.1  reinoud 	struct proc *p;
    166       1.1  reinoud {
    167       1.1  reinoud 	int unit = minor(dev);
    168       1.1  reinoud 	struct qms_softc *sc = qms_cd.cd_devs[unit];
    169       1.1  reinoud 
    170       1.1  reinoud  	/* disable interrupts */
    171       1.1  reinoud 	sc->sc_intenable(sc, 0);
    172       1.1  reinoud 
    173       1.1  reinoud 	/* clean up */
    174       1.1  reinoud 	sc->sc_proc = NULL;
    175       1.1  reinoud 	sc->sc_state = 0;
    176       1.1  reinoud 
    177       1.1  reinoud 	clfree(&sc->sc_buffer);
    178       1.1  reinoud 
    179       1.1  reinoud 	return(0);
    180       1.1  reinoud }
    181       1.1  reinoud 
    182       1.1  reinoud int
    183       1.1  reinoud qmsread(dev, uio, flag)
    184       1.1  reinoud 	dev_t dev;
    185       1.1  reinoud 	struct uio *uio;
    186       1.1  reinoud 	int flag;
    187       1.1  reinoud {
    188       1.1  reinoud 	int unit = minor(dev);
    189       1.1  reinoud 	struct qms_softc *sc = qms_cd.cd_devs[unit];
    190       1.1  reinoud 	int error;
    191       1.1  reinoud 	int s;
    192       1.1  reinoud 	int length;
    193       1.1  reinoud 	u_char buffer[128];
    194       1.1  reinoud 
    195       1.1  reinoud 	error = 0;
    196       1.1  reinoud 	s = spltty();
    197       1.1  reinoud 	while (sc->sc_buffer.c_cc == 0) {
    198       1.1  reinoud 		if (flag & IO_NDELAY) {
    199       1.1  reinoud 			(void)splx(s);
    200       1.1  reinoud 			return(EWOULDBLOCK);
    201       1.1  reinoud 		}
    202       1.1  reinoud 		sc->sc_state |= QMOUSE_ASLEEP;
    203       1.1  reinoud 		if ((error = tsleep((caddr_t)sc, PZERO | PCATCH, "qmsread", 0))) {
    204       1.1  reinoud 			sc->sc_state &= ~QMOUSE_ASLEEP;
    205       1.1  reinoud 			(void)splx(s);
    206       1.1  reinoud 			return(error);
    207       1.1  reinoud 		}
    208       1.1  reinoud 	}
    209       1.1  reinoud 
    210       1.1  reinoud 	while (sc->sc_buffer.c_cc > 0 && uio->uio_resid > 0) {
    211       1.1  reinoud 		length = min(sc->sc_buffer.c_cc, uio->uio_resid);
    212       1.1  reinoud 		if(length>sizeof(buffer))
    213       1.1  reinoud 			length=sizeof(buffer);
    214       1.1  reinoud 
    215       1.1  reinoud 		(void)q_to_b(&sc->sc_buffer, buffer, length);
    216       1.1  reinoud 
    217       1.1  reinoud 		if ((error = (uiomove(buffer, length, uio))))
    218       1.1  reinoud 			break;
    219       1.1  reinoud 	}
    220       1.1  reinoud 	(void)splx(s);
    221       1.1  reinoud 	return(error);
    222       1.1  reinoud }
    223       1.1  reinoud 
    224       1.1  reinoud 
    225       1.1  reinoud #define FMT_START								\
    226       1.1  reinoud 	int x = bus_space_read_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEX) & 0xffff;	\
    227       1.1  reinoud 	int y = bus_space_read_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEY) & 0xffff;	\
    228       1.1  reinoud 	int b = bus_space_read_1(sc->sc_iot, sc->sc_butioh, QMS_BUTTONS) & 0x70;\
    229       1.1  reinoud 	if (x & 0x8000) x |= 0xffff0000;					\
    230       1.1  reinoud 	if (y & 0x8000) y |= 0xffff0000;					\
    231       1.1  reinoud 	x = (x - sc->origx);							\
    232       1.1  reinoud 	y = (y - sc->origy);							\
    233       1.1  reinoud 	if (x < (sc->boundx)) x = sc->boundx;					\
    234       1.1  reinoud 	if (x > (sc->bounda)) x = sc->bounda;					\
    235       1.1  reinoud 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEX, x + sc->origx);	\
    236       1.1  reinoud 	if (y < (sc->boundy)) y = sc->boundy;					\
    237       1.1  reinoud 	if (y > (sc->boundb)) y = sc->boundb;					\
    238       1.1  reinoud 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEY, y + sc->origy);	\
    239       1.1  reinoud 	x = x * sc->xmult;							\
    240       1.1  reinoud 	y = y * sc->ymult;
    241       1.1  reinoud 
    242       1.1  reinoud #define	FMT_END
    243       1.1  reinoud 
    244       1.1  reinoud 
    245       1.1  reinoud int
    246       1.1  reinoud qmsioctl(dev, cmd, data, flag, p)
    247       1.1  reinoud 	dev_t dev;
    248       1.1  reinoud 	u_long cmd;
    249       1.1  reinoud 	caddr_t data;
    250       1.1  reinoud 	int flag;
    251       1.1  reinoud 	struct proc *p;
    252       1.1  reinoud {
    253       1.1  reinoud 	struct qms_softc *sc = qms_cd.cd_devs[minor(dev)];
    254       1.1  reinoud 
    255       1.1  reinoud 	switch (cmd) {
    256       1.1  reinoud 	case MOUSEIOC_WRITEX:
    257       1.1  reinoud 		bus_space_write_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEX,
    258       1.1  reinoud 		    *(int *)data + sc->origx);
    259       1.1  reinoud 		return 0;
    260       1.1  reinoud 	case MOUSEIOC_WRITEY:
    261       1.1  reinoud 		bus_space_write_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEY,
    262       1.1  reinoud 		    *(int *)data + sc->origy);
    263       1.1  reinoud 		return 0;
    264       1.1  reinoud 	case MOUSEIOC_SETSTATE:
    265       1.1  reinoud 	{
    266       1.1  reinoud 		struct mouse_state *co = (void *)data;
    267       1.1  reinoud 		bus_space_write_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEX, co->x);
    268       1.1  reinoud 		bus_space_write_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEY, co->y);
    269       1.1  reinoud 		return 0;
    270       1.1  reinoud 	}
    271       1.1  reinoud 	case MOUSEIOC_SETBOUNDS:
    272       1.1  reinoud 	{
    273       1.1  reinoud 		struct mouse_boundingbox *bo = (void *)data;
    274       1.1  reinoud 		struct mousebufrec buffer;
    275       1.1  reinoud #ifdef MOUSE_IOC_ACK
    276       1.1  reinoud 		int s;
    277       1.1  reinoud 
    278       1.1  reinoud 		s = spltty();
    279       1.1  reinoud #endif
    280       1.1  reinoud 
    281       1.1  reinoud 		sc->boundx = bo->x;
    282       1.1  reinoud 		sc->boundy = bo->y;
    283       1.1  reinoud 		sc->bounda = bo->a;
    284       1.1  reinoud 		sc->boundb = bo->b;
    285       1.1  reinoud 
    286       1.1  reinoud 		buffer.status = IOC_ACK;
    287       1.1  reinoud 		buffer.x = sc->origx;
    288       1.1  reinoud 		buffer.y = sc->origy;
    289       1.1  reinoud #ifdef MOUSE_IOC_ACK
    290       1.1  reinoud 		if (sc->sc_buffer.c_cc > 0)
    291       1.1  reinoud 			printf("%s: setting bounding with non empty buffer (%d)\n",
    292       1.1  reinoud 			    sc->sc_device.dv_xname, sc->sc_buffer.c_cc);
    293       1.1  reinoud 		qmsputbuffer(sc, &buffer);
    294       1.1  reinoud 		(void)splx(s);
    295       1.1  reinoud #endif
    296       1.1  reinoud 		return 0;
    297       1.1  reinoud 	}
    298       1.1  reinoud 	case MOUSEIOC_SETMODE:
    299       1.1  reinoud 	{
    300       1.1  reinoud 		struct mousebufrec buffer;
    301       1.1  reinoud #ifdef MOUSE_IOC_ACK
    302       1.1  reinoud 		int s;
    303       1.1  reinoud 
    304       1.1  reinoud 		s = spltty();
    305       1.1  reinoud #endif
    306       1.1  reinoud 		sc->sc_mode = *(int *)data;
    307       1.1  reinoud 
    308       1.1  reinoud 		buffer.status = IOC_ACK;
    309       1.1  reinoud 		buffer.x = sc->origx;
    310       1.1  reinoud 		buffer.y = sc->origy;
    311       1.1  reinoud #ifdef MOUSE_IOC_ACK
    312       1.1  reinoud 		if (sc->sc_buffer.c_cc > 0)
    313       1.1  reinoud 			printf("%s: setting mode with non empty buffer (%d)\n",
    314       1.1  reinoud 			    sc->sc_device.dv_xname, sc->sc_buffer.c_cc);
    315       1.1  reinoud 		qmsputbuffer(sc, &buffer);
    316       1.1  reinoud 		(void)splx(s);
    317       1.1  reinoud #endif
    318       1.1  reinoud 		return 0;
    319       1.1  reinoud 	}
    320       1.1  reinoud 	case MOUSEIOC_SETORIGIN:
    321       1.1  reinoud 	{
    322       1.1  reinoud 		struct mouse_origin *oo = (void *)data;
    323       1.1  reinoud 		struct mousebufrec buffer;
    324       1.1  reinoud #ifdef MOUSE_IOC_ACK
    325       1.1  reinoud 		int s;
    326       1.1  reinoud 
    327       1.1  reinoud 		s = spltty();
    328       1.1  reinoud #endif
    329       1.1  reinoud 		/* Need to fix up! */
    330       1.1  reinoud 		sc->origx = oo->x;
    331       1.1  reinoud 		sc->origy = oo->y;
    332       1.1  reinoud 
    333       1.1  reinoud 		buffer.status = IOC_ACK;
    334       1.1  reinoud 		buffer.x = sc->origx;
    335       1.1  reinoud 		buffer.y = sc->origy;
    336       1.1  reinoud #ifdef MOUSE_IOC_ACK
    337       1.1  reinoud 		if (sc->sc_buffer.c_cc > 0)
    338       1.1  reinoud 			printf("%s: setting origin with non empty buffer (%d)\n",
    339       1.1  reinoud 			    sc->sc_device.dv_xname, sc->sc_buffer.c_cc);
    340       1.1  reinoud 		qmsputbuffer(sc, &buffer);
    341       1.1  reinoud 		(void)splx(s);
    342       1.1  reinoud #endif
    343       1.1  reinoud 		return 0;
    344       1.1  reinoud 	}
    345       1.1  reinoud 	case MOUSEIOC_GETSTATE:
    346       1.1  reinoud 	{
    347       1.1  reinoud 		struct mouse_state *co = (void *)data;
    348       1.1  reinoud 		FMT_START
    349       1.1  reinoud 		co->x = x;
    350       1.1  reinoud 		co->y = y;
    351       1.1  reinoud 		co->buttons = b ^ 0x70;
    352       1.1  reinoud 		FMT_END
    353       1.1  reinoud 		return 0;
    354       1.1  reinoud 	}
    355       1.1  reinoud 	case MOUSEIOC_GETBOUNDS:
    356       1.1  reinoud 	{
    357       1.1  reinoud 		struct mouse_boundingbox *bo = (void *)data;
    358       1.1  reinoud 		bo->x = sc->boundx;
    359       1.1  reinoud 		bo->y = sc->boundy;
    360       1.1  reinoud 		bo->a = sc->bounda;
    361       1.1  reinoud 		bo->b = sc->boundb;
    362       1.1  reinoud 		return 0;
    363       1.1  reinoud 	}
    364       1.1  reinoud 	case MOUSEIOC_GETORIGIN:
    365       1.1  reinoud 	{
    366       1.1  reinoud 		struct mouse_origin *oo = (void *)data;
    367       1.1  reinoud 		oo->x = sc->origx;
    368       1.1  reinoud 		oo->y = sc->origy;
    369       1.1  reinoud 		return 0;
    370       1.1  reinoud 	}
    371       1.1  reinoud 	}
    372       1.1  reinoud 
    373       1.1  reinoud 	return (EINVAL);
    374       1.1  reinoud }
    375       1.1  reinoud 
    376       1.1  reinoud 
    377       1.1  reinoud int
    378       1.1  reinoud qmsintr(arg)
    379       1.1  reinoud 	void *arg;
    380       1.1  reinoud {
    381       1.1  reinoud 	struct qms_softc *sc = arg;
    382       1.1  reinoud 	int s;
    383       1.1  reinoud 	struct mousebufrec buffer;
    384       1.1  reinoud 	int dosignal=0;
    385       1.1  reinoud 
    386       1.1  reinoud 	FMT_START
    387       1.1  reinoud 
    388       1.1  reinoud 	b &= 0x70;
    389       1.1  reinoud 	b >>= 4;
    390       1.1  reinoud         if (x != sc->lastx || y != sc->lasty || b != sc->lastb) {
    391       1.1  reinoud 		/* Mouse state changed */
    392       1.1  reinoud 		buffer.status = b | ( b ^ sc->lastb) << 3 | (((x==sc->lastx) && (y==sc->lasty))?0:MOVEMENT);
    393       1.1  reinoud 		if(sc->sc_mode == MOUSEMODE_REL) {
    394       1.1  reinoud 			sc->origx = sc->origy = 0;
    395       1.1  reinoud 			bus_space_write_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEX, sc->origx);
    396       1.1  reinoud 			bus_space_write_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEY, sc->origy);
    397       1.1  reinoud 		}
    398       1.1  reinoud 		buffer.x = x;
    399       1.1  reinoud 		buffer.y = y;
    400       1.1  reinoud 		microtime(&buffer.event_time);
    401       1.1  reinoud 
    402       1.1  reinoud 		if (sc->sc_buffer.c_cc == 0)
    403       1.1  reinoud 			dosignal = 1;
    404       1.1  reinoud 
    405       1.1  reinoud 		s = spltty();
    406       1.1  reinoud 		(void)b_to_q((char *)&buffer, sizeof(buffer), &sc->sc_buffer);
    407       1.1  reinoud 		(void)splx(s);
    408       1.1  reinoud 		selwakeup(&sc->sc_rsel);
    409       1.1  reinoud 
    410       1.1  reinoud 		if (sc->sc_state & QMOUSE_ASLEEP) {
    411       1.1  reinoud 			sc->sc_state &= ~QMOUSE_ASLEEP;
    412       1.1  reinoud 			wakeup((caddr_t)sc);
    413       1.1  reinoud 		}
    414       1.1  reinoud 
    415       1.1  reinoud /*		if (dosignal)*/
    416       1.1  reinoud 			psignal(sc->sc_proc, SIGIO);
    417       1.1  reinoud 
    418       1.1  reinoud 		sc->lastx = x;
    419       1.1  reinoud 		sc->lasty = y;
    420       1.1  reinoud 		sc->lastb = b;
    421       1.1  reinoud 	}
    422       1.1  reinoud 
    423       1.1  reinoud 	FMT_END
    424       1.1  reinoud 	return(0);	/* Pass interrupt on down the chain */
    425       1.1  reinoud }
    426       1.1  reinoud 
    427       1.1  reinoud 
    428       1.1  reinoud int
    429       1.1  reinoud qmspoll(dev, events, p)
    430       1.1  reinoud 	dev_t dev;
    431       1.1  reinoud 	int events;
    432       1.1  reinoud 	struct proc *p;
    433       1.1  reinoud {
    434       1.1  reinoud 	struct qms_softc *sc = qms_cd.cd_devs[minor(dev)];
    435       1.1  reinoud 	int revents = 0;
    436       1.1  reinoud 	int s = spltty();
    437       1.1  reinoud 
    438       1.1  reinoud 	if (events & (POLLIN | POLLRDNORM)) {
    439       1.1  reinoud 		if (sc->sc_buffer.c_cc > 0)
    440       1.1  reinoud 			revents |= events & (POLLIN | POLLRDNORM);
    441       1.1  reinoud 		else
    442       1.1  reinoud 			selrecord(p, &sc->sc_rsel);
    443       1.1  reinoud 	}
    444       1.1  reinoud 
    445       1.1  reinoud 	(void)splx(s);
    446       1.1  reinoud 	return (revents);
    447       1.1  reinoud }
    448       1.1  reinoud 
    449       1.1  reinoud 
    450       1.1  reinoud #ifdef MOUSE_IOC_ACK
    451       1.1  reinoud static void
    452       1.1  reinoud qmsputbuffer(sc, buffer)
    453       1.1  reinoud 	struct qms_softc *sc;
    454       1.1  reinoud 	struct mousebufrec *buffer;
    455       1.1  reinoud {
    456       1.1  reinoud 	int s;
    457       1.1  reinoud 	int dosignal = 0;
    458       1.1  reinoud 
    459       1.1  reinoud 	/* Time stamp the buffer */
    460       1.1  reinoud 	microtime(&buffer->event_time);
    461       1.1  reinoud 
    462       1.1  reinoud 	if (sc->sc_buffer.c_cc == 0)
    463       1.1  reinoud 		dosignal=1;
    464       1.1  reinoud 
    465       1.1  reinoud 	s = spltty();
    466       1.1  reinoud 	(void)b_to_q((char *)buffer, sizeof(*buffer), &sc->sc_buffer);
    467       1.1  reinoud 	(void)splx(s);
    468       1.1  reinoud 	selwakeup(&sc->sc_rsel);
    469       1.1  reinoud 
    470       1.1  reinoud 	if (sc->sc_state & QMOUSE_ASLEEP) {
    471       1.1  reinoud 		sc->sc_state &= ~QMOUSE_ASLEEP;
    472       1.1  reinoud 		wakeup((caddr_t)sc);
    473       1.1  reinoud 	}
    474       1.1  reinoud 
    475       1.1  reinoud 	if (dosignal)
    476       1.1  reinoud 		psignal(sc->sc_proc, SIGIO);
    477       1.1  reinoud }
    478       1.1  reinoud #endif
    479       1.1  reinoud 
    480       1.1  reinoud /* End of qms.c */
    481