From: Samuel J. Greear Date: Mon, 5 Jul 2010 03:38:53 +0000 (+0000) Subject: dev - Add kq support to mse X-Git-Tag: v2.9.0~690^2~39 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/6edc75f2141b1a01b17dd561e512731b041ec422 dev - Add kq support to mse --- diff --git a/sys/dev/misc/mse/mse.c b/sys/dev/misc/mse/mse.c index a7c432c877..e65b672e6f 100644 --- a/sys/dev/misc/mse/mse.c +++ b/sys/dev/misc/mse/mse.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -135,6 +136,10 @@ static d_close_t mseclose; static d_read_t mseread; static d_ioctl_t mseioctl; static d_poll_t msepoll; +static d_kqfilter_t msekqfilter; + +static void msefilter_detach(struct knote *); +static int msefilter(struct knote *, long); #define CDEV_MAJOR 27 static struct dev_ops mse_ops = { @@ -144,6 +149,7 @@ static struct dev_ops mse_ops = { .d_read = mseread, .d_ioctl = mseioctl, .d_poll = msepoll, + .d_kqfilter = msekqfilter }; static void mseintr (void *); @@ -634,6 +640,66 @@ msepoll(struct dev_poll_args *ap) return (0); } +static struct filterops msefiltops = + { 1, NULL, msefilter_detach, msefilter }; + +static int +msekqfilter(struct dev_kqfilter_args *ap) +{ + cdev_t dev = ap->a_head.a_dev; + mse_softc_t *sc = devclass_get_softc(mse_devclass, MSE_UNIT(dev)); + struct knote *kn = ap->a_kn; + struct klist *klist; + + ap->a_result = 0; + + switch (kn->kn_filter) { + case EVFILT_READ: + kn->kn_fop = &msefiltops; + kn->kn_hook = (caddr_t)sc; + break; + default: + ap->a_result = 1; + return (0); + } + + crit_enter(); + klist = &sc->sc_selp.si_note; + SLIST_INSERT_HEAD(klist, kn, kn_selnext); + crit_exit(); + + return (0); +} + +static void +msefilter_detach(struct knote *kn) +{ + mse_softc_t *sc = (mse_softc_t *)kn->kn_hook; + struct klist *klist; + + crit_enter(); + klist = &sc->sc_selp.si_note; + SLIST_REMOVE(klist, kn, knote, kn_selnext); + crit_exit(); +} + +static int +msefilter(struct knote *kn, long hint) +{ + mse_softc_t *sc = (mse_softc_t *)kn->kn_hook; + int ready = 0; + + crit_enter(); + if (sc->sc_bytesread != sc->mode.packetsize || + sc->sc_deltax != 0 || sc->sc_deltay != 0 || + (sc->sc_obuttons ^ sc->sc_buttons) != 0) + ready = 1; + + crit_exit(); + + return (ready); +} + /* * msetimeout: watchdog timer routine. */