dev - Add kq support to mse
authorSamuel J. Greear <sjg@thesjg.com>
Mon, 5 Jul 2010 03:38:53 +0000 (03:38 +0000)
committerSamuel J. Greear <sjg@thesjg.com>
Mon, 5 Jul 2010 03:38:53 +0000 (03:38 +0000)
sys/dev/misc/mse/mse.c

index a7c432c..e65b672 100644 (file)
@@ -52,6 +52,7 @@
 #include <sys/kernel.h>
 #include <sys/bus.h>
 #include <sys/poll.h>
+#include <sys/event.h>
 #include <sys/selinfo.h>
 #include <sys/uio.h>
 #include <sys/rman.h>
@@ -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.
  */