kernel - Add kqueue read support to memio devices
authorSamuel J. Greear <sjg@thesjg.com>
Tue, 15 Jun 2010 16:13:45 +0000 (16:13 +0000)
committerSamuel J. Greear <sjg@thesjg.com>
Wed, 30 Jun 2010 00:31:44 +0000 (00:31 +0000)
 memio devices: mem, kmem, null, random, urandom, zero, io

sys/kern/kern_memio.c
sys/kern/kern_nrandom.c
sys/sys/random.h

index 47e12fc..f50a7a7 100644 (file)
@@ -75,16 +75,18 @@ static      d_write_t       mmwrite;
 static d_ioctl_t       mmioctl;
 static d_mmap_t        memmmap;
 static d_poll_t        mmpoll;
+static d_kqfilter_t    mmkqfilter;
 
 #define CDEV_MAJOR 2
 static struct dev_ops mem_ops = {
-       { "mem", CDEV_MAJOR, D_MEM | D_MPSAFE_READ | D_MPSAFE_WRITE },
+       { "mem", CDEV_MAJOR, D_MEM | D_MPSAFE_READ | D_MPSAFE_WRITE | D_KQFILTER },
        .d_open =       mmopen,
        .d_close =      mmclose,
        .d_read =       mmread,
        .d_write =      mmwrite,
        .d_ioctl =      mmioctl,
        .d_poll =       mmpoll,
+       .d_kqfilter =   mmkqfilter,
        .d_mmap =       memmmap,
 };
 
@@ -546,6 +548,47 @@ mmpoll(struct dev_poll_args *ap)
        return (0);
 }
 
+static int
+mm_filter_read(struct knote *kn, long hint)
+{
+       return (1);
+}
+
+static void
+dummy_filter_detach(struct knote *kn) {}
+
+static struct filterops random_read_filtops =
+        { 1, NULL, dummy_filter_detach, random_filter_read };
+
+static struct filterops mm_read_filtops =
+        { 1, NULL, dummy_filter_detach, mm_filter_read };
+
+int
+mmkqfilter(struct dev_kqfilter_args *ap)
+{
+       struct knote *kn = ap->a_kn;
+       cdev_t dev = ap->a_head.a_dev;
+
+       ap->a_result = 0;
+       switch (kn->kn_filter) {
+       case EVFILT_READ:
+               switch (minor(dev)) {
+               case 3:
+                       kn->kn_fop = &random_read_filtops;
+                       break;
+               default:
+                       kn->kn_fop = &mm_read_filtops;
+                       break;
+               }
+               break;
+       default:
+               ap->a_result = 1;
+               return (0);
+       }
+
+       return (0);
+}
+
 int
 iszerodev(cdev_t dev)
 {
index 60205a4..5ad67d6 100644 (file)
 #include <sys/kernel.h>
 #include <sys/systm.h>
 #include <sys/poll.h>
+#include <sys/event.h>
 #include <sys/random.h>
 #include <sys/systimer.h>
 #include <sys/time.h>
@@ -521,6 +522,15 @@ random_poll(cdev_t dev, int events)
        return (revents);
 }
 
+/*
+ * Kqueue filter (always succeeds)
+ */
+int
+random_filter_read(struct knote *kn, long hint)
+{
+       return (1);
+}
+
 /*
  * Heavy weight random number generator.  May return less then the
  * requested number of bytes.
index c53817d..f19d562 100644 (file)
@@ -95,7 +95,9 @@ u_int read_random_unlimited(void *buf, u_int size);
 u_int write_random(const char *buf, u_int nbytes);
 #endif
 struct thread;
+struct knote;
 int random_poll(cdev_t dev, int events);
+int random_filter_read(struct knote *kn, long hint);
 
 #endif /* _KERNEL */