Home | History | Annotate | Line # | Download | only in iomd
qms.c revision 1.2.2.1
      1  1.2.2.1    bjh21 /*	$NetBSD: qms.c,v 1.2.2.1 2002/10/24 22:33:51 bjh21 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.2  gehenna 
     70      1.2  gehenna dev_type_open(qmsopen);
     71      1.2  gehenna dev_type_close(qmsclose);
     72      1.2  gehenna dev_type_read(qmsread);
     73      1.2  gehenna dev_type_ioctl(qmsioctl);
     74      1.2  gehenna dev_type_poll(qmspoll);
     75  1.2.2.1    bjh21 dev_type_kqfilter(qmskqfilter);
     76      1.2  gehenna 
     77      1.2  gehenna const struct cdevsw qms_cdevsw = {
     78      1.2  gehenna 	qmsopen, qmsclose, qmsread, nowrite, qmsioctl,
     79  1.2.2.1    bjh21 	nostop, notty, qmspoll, nommap, qmskqfilter,
     80      1.2  gehenna };
     81      1.1  reinoud 
     82      1.1  reinoud /* qms device structure */
     83      1.1  reinoud 
     84      1.1  reinoud /* Offsets of hardware registers */
     85      1.1  reinoud #define QMS_MOUSEX	0		/* 16 bit X register */
     86      1.1  reinoud #define QMS_MOUSEY	1		/* 16 bit Y register */
     87      1.1  reinoud 
     88      1.1  reinoud #define QMS_BUTTONS	0		/* mouse buttons register */
     89      1.1  reinoud 
     90      1.1  reinoud /*
     91      1.1  reinoud  * generic attach routine. This does the generic part of the driver
     92      1.1  reinoud  * attachment and is called from the bus specific attach routine.
     93      1.1  reinoud  */
     94      1.1  reinoud 
     95      1.1  reinoud void
     96      1.1  reinoud qmsattach(sc)
     97      1.1  reinoud 	struct qms_softc *sc;
     98      1.1  reinoud {
     99      1.1  reinoud 	/* Set up origin and multipliers */
    100      1.1  reinoud 	sc->origx = 0;
    101      1.1  reinoud 	sc->origy = 0;
    102      1.1  reinoud 	sc->xmult = 2;
    103      1.1  reinoud 	sc->ymult = 2;
    104      1.1  reinoud 
    105      1.1  reinoud 	/* Set up bounding box */
    106      1.1  reinoud 	sc->boundx = -4095;
    107      1.1  reinoud 	sc->boundy = -4095;
    108      1.1  reinoud 	sc->bounda = 4096;
    109      1.1  reinoud 	sc->boundb = 4096;
    110      1.1  reinoud 
    111      1.1  reinoud 	sc->sc_state = 0;
    112      1.1  reinoud 
    113      1.1  reinoud 	/* Set the mouse X & Y registers to a known state */
    114      1.1  reinoud 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEX, sc->origx);
    115      1.1  reinoud 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEX, sc->origx);
    116      1.1  reinoud }
    117      1.1  reinoud 
    118      1.1  reinoud int
    119      1.1  reinoud qmsopen(dev, flag, mode, p)
    120      1.1  reinoud 	dev_t dev;
    121      1.1  reinoud 	int flag;
    122      1.1  reinoud 	int mode;
    123      1.1  reinoud 	struct proc *p;
    124      1.1  reinoud {
    125      1.1  reinoud 	struct qms_softc *sc;
    126      1.1  reinoud 	int unit = minor(dev);
    127      1.1  reinoud 
    128      1.1  reinoud  	/* validate the unit and softc */
    129      1.1  reinoud 	if (unit >= qms_cd.cd_ndevs)
    130      1.1  reinoud 		return(ENXIO);
    131      1.1  reinoud 
    132      1.1  reinoud 	sc = qms_cd.cd_devs[unit];
    133      1.1  reinoud 
    134      1.1  reinoud 	if (!sc) return(ENXIO);
    135      1.1  reinoud 
    136      1.1  reinoud 	/* check if we are already open */
    137      1.1  reinoud 	if (sc->sc_state & QMOUSE_OPEN) return(EBUSY);
    138      1.1  reinoud 
    139      1.1  reinoud 	/* update softc */
    140      1.1  reinoud 	sc->sc_proc = p;
    141      1.1  reinoud 
    142      1.1  reinoud 	sc->lastx = -1;
    143      1.1  reinoud 	sc->lasty = -1;
    144      1.1  reinoud 	sc->lastb = -1;
    145      1.1  reinoud 
    146      1.1  reinoud 	/* initialise buffer */
    147      1.1  reinoud 	if (clalloc(&sc->sc_buffer, QMOUSE_BSIZE, 0) == -1)
    148      1.1  reinoud 		return(ENOMEM);
    149      1.1  reinoud 
    150      1.1  reinoud 	/* set mode and state */
    151      1.1  reinoud 	sc->sc_mode = MOUSEMODE_ABS;
    152      1.1  reinoud 	sc->sc_state |= QMOUSE_OPEN;
    153      1.1  reinoud 
    154      1.1  reinoud 	/* enable interrupts */
    155      1.1  reinoud 	sc->sc_intenable(sc, 1);
    156      1.1  reinoud 
    157      1.1  reinoud 	return(0);
    158      1.1  reinoud }
    159      1.1  reinoud 
    160      1.1  reinoud 
    161      1.1  reinoud int
    162      1.1  reinoud qmsclose(dev, flag, mode, p)
    163      1.1  reinoud 	dev_t dev;
    164      1.1  reinoud 	int flag;
    165      1.1  reinoud 	int mode;
    166      1.1  reinoud 	struct proc *p;
    167      1.1  reinoud {
    168      1.1  reinoud 	int unit = minor(dev);
    169      1.1  reinoud 	struct qms_softc *sc = qms_cd.cd_devs[unit];
    170      1.1  reinoud 
    171      1.1  reinoud  	/* disable interrupts */
    172      1.1  reinoud 	sc->sc_intenable(sc, 0);
    173      1.1  reinoud 
    174      1.1  reinoud 	/* clean up */
    175      1.1  reinoud 	sc->sc_proc = NULL;
    176      1.1  reinoud 	sc->sc_state = 0;
    177      1.1  reinoud 
    178      1.1  reinoud 	clfree(&sc->sc_buffer);
    179      1.1  reinoud 
    180      1.1  reinoud 	return(0);
    181      1.1  reinoud }
    182      1.1  reinoud 
    183      1.1  reinoud int
    184      1.1  reinoud qmsread(dev, uio, flag)
    185      1.1  reinoud 	dev_t dev;
    186      1.1  reinoud 	struct uio *uio;
    187      1.1  reinoud 	int flag;
    188      1.1  reinoud {
    189      1.1  reinoud 	int unit = minor(dev);
    190      1.1  reinoud 	struct qms_softc *sc = qms_cd.cd_devs[unit];
    191      1.1  reinoud 	int error;
    192      1.1  reinoud 	int s;
    193      1.1  reinoud 	int length;
    194      1.1  reinoud 	u_char buffer[128];
    195      1.1  reinoud 
    196      1.1  reinoud 	error = 0;
    197      1.1  reinoud 	s = spltty();
    198      1.1  reinoud 	while (sc->sc_buffer.c_cc == 0) {
    199      1.1  reinoud 		if (flag & IO_NDELAY) {
    200      1.1  reinoud 			(void)splx(s);
    201      1.1  reinoud 			return(EWOULDBLOCK);
    202      1.1  reinoud 		}
    203      1.1  reinoud 		sc->sc_state |= QMOUSE_ASLEEP;
    204      1.1  reinoud 		if ((error = tsleep((caddr_t)sc, PZERO | PCATCH, "qmsread", 0))) {
    205      1.1  reinoud 			sc->sc_state &= ~QMOUSE_ASLEEP;
    206      1.1  reinoud 			(void)splx(s);
    207      1.1  reinoud 			return(error);
    208      1.1  reinoud 		}
    209      1.1  reinoud 	}
    210      1.1  reinoud 
    211      1.1  reinoud 	while (sc->sc_buffer.c_cc > 0 && uio->uio_resid > 0) {
    212      1.1  reinoud 		length = min(sc->sc_buffer.c_cc, uio->uio_resid);
    213      1.1  reinoud 		if(length>sizeof(buffer))
    214      1.1  reinoud 			length=sizeof(buffer);
    215      1.1  reinoud 
    216      1.1  reinoud 		(void)q_to_b(&sc->sc_buffer, buffer, length);
    217      1.1  reinoud 
    218      1.1  reinoud 		if ((error = (uiomove(buffer, length, uio))))
    219      1.1  reinoud 			break;
    220      1.1  reinoud 	}
    221      1.1  reinoud 	(void)splx(s);
    222      1.1  reinoud 	return(error);
    223      1.1  reinoud }
    224      1.1  reinoud 
    225      1.1  reinoud 
    226      1.1  reinoud #define FMT_START								\
    227      1.1  reinoud 	int x = bus_space_read_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEX) & 0xffff;	\
    228      1.1  reinoud 	int y = bus_space_read_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEY) & 0xffff;	\
    229      1.1  reinoud 	int b = bus_space_read_1(sc->sc_iot, sc->sc_butioh, QMS_BUTTONS) & 0x70;\
    230      1.1  reinoud 	if (x & 0x8000) x |= 0xffff0000;					\
    231      1.1  reinoud 	if (y & 0x8000) y |= 0xffff0000;					\
    232      1.1  reinoud 	x = (x - sc->origx);							\
    233      1.1  reinoud 	y = (y - sc->origy);							\
    234      1.1  reinoud 	if (x < (sc->boundx)) x = sc->boundx;					\
    235      1.1  reinoud 	if (x > (sc->bounda)) x = sc->bounda;					\
    236      1.1  reinoud 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEX, x + sc->origx);	\
    237      1.1  reinoud 	if (y < (sc->boundy)) y = sc->boundy;					\
    238      1.1  reinoud 	if (y > (sc->boundb)) y = sc->boundb;					\
    239      1.1  reinoud 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEY, y + sc->origy);	\
    240      1.1  reinoud 	x = x * sc->xmult;							\
    241      1.1  reinoud 	y = y * sc->ymult;
    242      1.1  reinoud 
    243      1.1  reinoud #define	FMT_END
    244      1.1  reinoud 
    245      1.1  reinoud 
    246      1.1  reinoud int
    247      1.1  reinoud qmsioctl(dev, cmd, data, flag, p)
    248      1.1  reinoud 	dev_t dev;
    249      1.1  reinoud 	u_long cmd;
    250      1.1  reinoud 	caddr_t data;
    251      1.1  reinoud 	int flag;
    252      1.1  reinoud 	struct proc *p;
    253      1.1  reinoud {
    254      1.1  reinoud 	struct qms_softc *sc = qms_cd.cd_devs[minor(dev)];
    255      1.1  reinoud 
    256      1.1  reinoud 	switch (cmd) {
    257      1.1  reinoud 	case MOUSEIOC_WRITEX:
    258      1.1  reinoud 		bus_space_write_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEX,
    259      1.1  reinoud 		    *(int *)data + sc->origx);
    260      1.1  reinoud 		return 0;
    261      1.1  reinoud 	case MOUSEIOC_WRITEY:
    262      1.1  reinoud 		bus_space_write_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEY,
    263      1.1  reinoud 		    *(int *)data + sc->origy);
    264      1.1  reinoud 		return 0;
    265      1.1  reinoud 	case MOUSEIOC_SETSTATE:
    266      1.1  reinoud 	{
    267      1.1  reinoud 		struct mouse_state *co = (void *)data;
    268      1.1  reinoud 		bus_space_write_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEX, co->x);
    269      1.1  reinoud 		bus_space_write_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEY, co->y);
    270      1.1  reinoud 		return 0;
    271      1.1  reinoud 	}
    272      1.1  reinoud 	case MOUSEIOC_SETBOUNDS:
    273      1.1  reinoud 	{
    274      1.1  reinoud 		struct mouse_boundingbox *bo = (void *)data;
    275      1.1  reinoud 		struct mousebufrec buffer;
    276      1.1  reinoud #ifdef MOUSE_IOC_ACK
    277      1.1  reinoud 		int s;
    278      1.1  reinoud 
    279      1.1  reinoud 		s = spltty();
    280      1.1  reinoud #endif
    281      1.1  reinoud 
    282      1.1  reinoud 		sc->boundx = bo->x;
    283      1.1  reinoud 		sc->boundy = bo->y;
    284      1.1  reinoud 		sc->bounda = bo->a;
    285      1.1  reinoud 		sc->boundb = bo->b;
    286      1.1  reinoud 
    287      1.1  reinoud 		buffer.status = IOC_ACK;
    288      1.1  reinoud 		buffer.x = sc->origx;
    289      1.1  reinoud 		buffer.y = sc->origy;
    290      1.1  reinoud #ifdef MOUSE_IOC_ACK
    291      1.1  reinoud 		if (sc->sc_buffer.c_cc > 0)
    292      1.1  reinoud 			printf("%s: setting bounding with non empty buffer (%d)\n",
    293      1.1  reinoud 			    sc->sc_device.dv_xname, sc->sc_buffer.c_cc);
    294      1.1  reinoud 		qmsputbuffer(sc, &buffer);
    295      1.1  reinoud 		(void)splx(s);
    296      1.1  reinoud #endif
    297      1.1  reinoud 		return 0;
    298      1.1  reinoud 	}
    299      1.1  reinoud 	case MOUSEIOC_SETMODE:
    300      1.1  reinoud 	{
    301      1.1  reinoud 		struct mousebufrec buffer;
    302      1.1  reinoud #ifdef MOUSE_IOC_ACK
    303      1.1  reinoud 		int s;
    304      1.1  reinoud 
    305      1.1  reinoud 		s = spltty();
    306      1.1  reinoud #endif
    307      1.1  reinoud 		sc->sc_mode = *(int *)data;
    308      1.1  reinoud 
    309      1.1  reinoud 		buffer.status = IOC_ACK;
    310      1.1  reinoud 		buffer.x = sc->origx;
    311      1.1  reinoud 		buffer.y = sc->origy;
    312      1.1  reinoud #ifdef MOUSE_IOC_ACK
    313      1.1  reinoud 		if (sc->sc_buffer.c_cc > 0)
    314      1.1  reinoud 			printf("%s: setting mode with non empty buffer (%d)\n",
    315      1.1  reinoud 			    sc->sc_device.dv_xname, sc->sc_buffer.c_cc);
    316      1.1  reinoud 		qmsputbuffer(sc, &buffer);
    317      1.1  reinoud 		(void)splx(s);
    318      1.1  reinoud #endif
    319      1.1  reinoud 		return 0;
    320      1.1  reinoud 	}
    321      1.1  reinoud 	case MOUSEIOC_SETORIGIN:
    322      1.1  reinoud 	{
    323      1.1  reinoud 		struct mouse_origin *oo = (void *)data;
    324      1.1  reinoud 		struct mousebufrec buffer;
    325      1.1  reinoud #ifdef MOUSE_IOC_ACK
    326      1.1  reinoud 		int s;
    327      1.1  reinoud 
    328      1.1  reinoud 		s = spltty();
    329      1.1  reinoud #endif
    330      1.1  reinoud 		/* Need to fix up! */
    331      1.1  reinoud 		sc->origx = oo->x;
    332      1.1  reinoud 		sc->origy = oo->y;
    333      1.1  reinoud 
    334      1.1  reinoud 		buffer.status = IOC_ACK;
    335      1.1  reinoud 		buffer.x = sc->origx;
    336      1.1  reinoud 		buffer.y = sc->origy;
    337      1.1  reinoud #ifdef MOUSE_IOC_ACK
    338      1.1  reinoud 		if (sc->sc_buffer.c_cc > 0)
    339      1.1  reinoud 			printf("%s: setting origin with non empty buffer (%d)\n",
    340      1.1  reinoud 			    sc->sc_device.dv_xname, sc->sc_buffer.c_cc);
    341      1.1  reinoud 		qmsputbuffer(sc, &buffer);
    342      1.1  reinoud 		(void)splx(s);
    343      1.1  reinoud #endif
    344      1.1  reinoud 		return 0;
    345      1.1  reinoud 	}
    346      1.1  reinoud 	case MOUSEIOC_GETSTATE:
    347      1.1  reinoud 	{
    348      1.1  reinoud 		struct mouse_state *co = (void *)data;
    349      1.1  reinoud 		FMT_START
    350      1.1  reinoud 		co->x = x;
    351      1.1  reinoud 		co->y = y;
    352      1.1  reinoud 		co->buttons = b ^ 0x70;
    353      1.1  reinoud 		FMT_END
    354      1.1  reinoud 		return 0;
    355      1.1  reinoud 	}
    356      1.1  reinoud 	case MOUSEIOC_GETBOUNDS:
    357      1.1  reinoud 	{
    358      1.1  reinoud 		struct mouse_boundingbox *bo = (void *)data;
    359      1.1  reinoud 		bo->x = sc->boundx;
    360      1.1  reinoud 		bo->y = sc->boundy;
    361      1.1  reinoud 		bo->a = sc->bounda;
    362      1.1  reinoud 		bo->b = sc->boundb;
    363      1.1  reinoud 		return 0;
    364      1.1  reinoud 	}
    365      1.1  reinoud 	case MOUSEIOC_GETORIGIN:
    366      1.1  reinoud 	{
    367      1.1  reinoud 		struct mouse_origin *oo = (void *)data;
    368      1.1  reinoud 		oo->x = sc->origx;
    369      1.1  reinoud 		oo->y = sc->origy;
    370      1.1  reinoud 		return 0;
    371      1.1  reinoud 	}
    372      1.1  reinoud 	}
    373      1.1  reinoud 
    374      1.1  reinoud 	return (EINVAL);
    375      1.1  reinoud }
    376      1.1  reinoud 
    377      1.1  reinoud 
    378      1.1  reinoud int
    379      1.1  reinoud qmsintr(arg)
    380      1.1  reinoud 	void *arg;
    381      1.1  reinoud {
    382      1.1  reinoud 	struct qms_softc *sc = arg;
    383      1.1  reinoud 	int s;
    384      1.1  reinoud 	struct mousebufrec buffer;
    385      1.1  reinoud 	int dosignal=0;
    386      1.1  reinoud 
    387      1.1  reinoud 	FMT_START
    388      1.1  reinoud 
    389      1.1  reinoud 	b &= 0x70;
    390      1.1  reinoud 	b >>= 4;
    391      1.1  reinoud         if (x != sc->lastx || y != sc->lasty || b != sc->lastb) {
    392      1.1  reinoud 		/* Mouse state changed */
    393      1.1  reinoud 		buffer.status = b | ( b ^ sc->lastb) << 3 | (((x==sc->lastx) && (y==sc->lasty))?0:MOVEMENT);
    394      1.1  reinoud 		if(sc->sc_mode == MOUSEMODE_REL) {
    395      1.1  reinoud 			sc->origx = sc->origy = 0;
    396      1.1  reinoud 			bus_space_write_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEX, sc->origx);
    397      1.1  reinoud 			bus_space_write_4(sc->sc_iot, sc->sc_ioh, QMS_MOUSEY, sc->origy);
    398      1.1  reinoud 		}
    399      1.1  reinoud 		buffer.x = x;
    400      1.1  reinoud 		buffer.y = y;
    401      1.1  reinoud 		microtime(&buffer.event_time);
    402      1.1  reinoud 
    403      1.1  reinoud 		if (sc->sc_buffer.c_cc == 0)
    404      1.1  reinoud 			dosignal = 1;
    405      1.1  reinoud 
    406      1.1  reinoud 		s = spltty();
    407      1.1  reinoud 		(void)b_to_q((char *)&buffer, sizeof(buffer), &sc->sc_buffer);
    408      1.1  reinoud 		(void)splx(s);
    409      1.1  reinoud 		selwakeup(&sc->sc_rsel);
    410      1.1  reinoud 
    411      1.1  reinoud 		if (sc->sc_state & QMOUSE_ASLEEP) {
    412      1.1  reinoud 			sc->sc_state &= ~QMOUSE_ASLEEP;
    413      1.1  reinoud 			wakeup((caddr_t)sc);
    414      1.1  reinoud 		}
    415      1.1  reinoud 
    416      1.1  reinoud /*		if (dosignal)*/
    417      1.1  reinoud 			psignal(sc->sc_proc, SIGIO);
    418      1.1  reinoud 
    419      1.1  reinoud 		sc->lastx = x;
    420      1.1  reinoud 		sc->lasty = y;
    421      1.1  reinoud 		sc->lastb = b;
    422      1.1  reinoud 	}
    423      1.1  reinoud 
    424      1.1  reinoud 	FMT_END
    425      1.1  reinoud 	return(0);	/* Pass interrupt on down the chain */
    426      1.1  reinoud }
    427      1.1  reinoud 
    428      1.1  reinoud 
    429      1.1  reinoud int
    430      1.1  reinoud qmspoll(dev, events, p)
    431      1.1  reinoud 	dev_t dev;
    432      1.1  reinoud 	int events;
    433      1.1  reinoud 	struct proc *p;
    434      1.1  reinoud {
    435      1.1  reinoud 	struct qms_softc *sc = qms_cd.cd_devs[minor(dev)];
    436      1.1  reinoud 	int revents = 0;
    437      1.1  reinoud 	int s = spltty();
    438      1.1  reinoud 
    439      1.1  reinoud 	if (events & (POLLIN | POLLRDNORM)) {
    440      1.1  reinoud 		if (sc->sc_buffer.c_cc > 0)
    441      1.1  reinoud 			revents |= events & (POLLIN | POLLRDNORM);
    442      1.1  reinoud 		else
    443      1.1  reinoud 			selrecord(p, &sc->sc_rsel);
    444      1.1  reinoud 	}
    445      1.1  reinoud 
    446      1.1  reinoud 	(void)splx(s);
    447      1.1  reinoud 	return (revents);
    448      1.1  reinoud }
    449      1.1  reinoud 
    450      1.1  reinoud 
    451      1.1  reinoud #ifdef MOUSE_IOC_ACK
    452      1.1  reinoud static void
    453      1.1  reinoud qmsputbuffer(sc, buffer)
    454      1.1  reinoud 	struct qms_softc *sc;
    455      1.1  reinoud 	struct mousebufrec *buffer;
    456      1.1  reinoud {
    457      1.1  reinoud 	int s;
    458      1.1  reinoud 	int dosignal = 0;
    459      1.1  reinoud 
    460      1.1  reinoud 	/* Time stamp the buffer */
    461      1.1  reinoud 	microtime(&buffer->event_time);
    462      1.1  reinoud 
    463      1.1  reinoud 	if (sc->sc_buffer.c_cc == 0)
    464      1.1  reinoud 		dosignal=1;
    465      1.1  reinoud 
    466      1.1  reinoud 	s = spltty();
    467      1.1  reinoud 	(void)b_to_q((char *)buffer, sizeof(*buffer), &sc->sc_buffer);
    468      1.1  reinoud 	(void)splx(s);
    469      1.1  reinoud 	selwakeup(&sc->sc_rsel);
    470      1.1  reinoud 
    471      1.1  reinoud 	if (sc->sc_state & QMOUSE_ASLEEP) {
    472      1.1  reinoud 		sc->sc_state &= ~QMOUSE_ASLEEP;
    473      1.1  reinoud 		wakeup((caddr_t)sc);
    474      1.1  reinoud 	}
    475      1.1  reinoud 
    476      1.1  reinoud 	if (dosignal)
    477      1.1  reinoud 		psignal(sc->sc_proc, SIGIO);
    478      1.1  reinoud }
    479      1.1  reinoud #endif
    480  1.2.2.1    bjh21 
    481  1.2.2.1    bjh21 /* XXXLUKEM (jdolecek) kqueue hooks not tested */
    482  1.2.2.1    bjh21 static void
    483  1.2.2.1    bjh21 filt_qmsrdetach(struct knote *kn)
    484  1.2.2.1    bjh21 {
    485  1.2.2.1    bjh21 	struct qms_softc *sc = kn->kn_hook;
    486  1.2.2.1    bjh21 	int s;
    487  1.2.2.1    bjh21 
    488  1.2.2.1    bjh21 	s = spltty();
    489  1.2.2.1    bjh21 	SLIST_REMOVE(&sc->sc_rsel.si_klist, kn, knote, kn_selnext);
    490  1.2.2.1    bjh21 	splx(s);
    491  1.2.2.1    bjh21 }
    492  1.2.2.1    bjh21 
    493  1.2.2.1    bjh21 static int
    494  1.2.2.1    bjh21 filt_qmsread(struct knote *kn, long hint)
    495  1.2.2.1    bjh21 {
    496  1.2.2.1    bjh21 	struct qms_softc *sc = kn->kn_hook;
    497  1.2.2.1    bjh21 
    498  1.2.2.1    bjh21 	kn->kn_data = sc->sc_buffer.c_cc;
    499  1.2.2.1    bjh21 	return (kn->kn_data > 0);
    500  1.2.2.1    bjh21 }
    501  1.2.2.1    bjh21 
    502  1.2.2.1    bjh21 static const struct filterops qmsread_filtops =
    503  1.2.2.1    bjh21 	{ 1, NULL, filt_qmsrdetach, filt_qmsread };
    504  1.2.2.1    bjh21 
    505  1.2.2.1    bjh21 int
    506  1.2.2.1    bjh21 qmskqfilter(dev_t dev, struct knote *kn)
    507  1.2.2.1    bjh21 {
    508  1.2.2.1    bjh21 	struct qms_softc *sc = qms_cd.cd_devs[minor(dev)];
    509  1.2.2.1    bjh21 	struct klist *klist;
    510  1.2.2.1    bjh21 	int s;
    511  1.2.2.1    bjh21 
    512  1.2.2.1    bjh21 	switch (kn->kn_filter) {
    513  1.2.2.1    bjh21 	case EVFILT_READ:
    514  1.2.2.1    bjh21 		klist = &sc->sc_rsel.si_klist;
    515  1.2.2.1    bjh21 		kn->kn_fop = &qmsread_filtops;
    516  1.2.2.1    bjh21 		break;
    517  1.2.2.1    bjh21 
    518  1.2.2.1    bjh21 	default:
    519  1.2.2.1    bjh21 		return (1);
    520  1.2.2.1    bjh21 	}
    521  1.2.2.1    bjh21 
    522  1.2.2.1    bjh21 	kn->kn_hook = sc;
    523  1.2.2.1    bjh21 
    524  1.2.2.1    bjh21 	s = spltty();
    525  1.2.2.1    bjh21 	SLIST_INSERT_HEAD(klist, kn, kn_selnext);
    526  1.2.2.1    bjh21 	splx(s);
    527  1.2.2.1    bjh21 
    528  1.2.2.1    bjh21 	return (0);
    529  1.2.2.1    bjh21 }
    530      1.1  reinoud 
    531      1.1  reinoud /* End of qms.c */
    532