Diff below implements kqfilter for the 3 remaining drivers in the tree,
that I could find, supporting poll(2) but not kqueue(2).

magma(4) and spif(4) call seltrue() so their diff is trivial.

This change is required to be able to switch poll(2) and select(2) to
use the *kqfilter() handlers on sparc64.  If one values coherency, it
also makes sense on its own.

ok?

Index: arch/sparc64//dev/vldcp.c
===================================================================
RCS file: /cvs/src/sys/arch/sparc64/dev/vldcp.c,v
retrieving revision 1.19
diff -u -p -r1.19 vldcp.c
--- arch/sparc64//dev/vldcp.c   19 Dec 2019 12:04:38 -0000      1.19
+++ arch/sparc64//dev/vldcp.c   20 May 2020 09:21:20 -0000
@@ -70,6 +70,11 @@ struct vldcp_softc {
 
 int    vldcp_match(struct device *, void *, void *);
 void   vldcp_attach(struct device *, struct device *, void *);
+void   filt_vldcprdetach(struct knote *);
+void   filt_vldcpwdetach(struct knote *);
+int    filt_vldcpread(struct knote *, long);
+int    filt_vldcpwrite(struct knote *, long);
+int    vldcpkqfilter(dev_t, struct knote *);
 
 struct cfattach vldcp_ca = {
        sizeof(struct vldcp_softc), vldcp_match, vldcp_attach
@@ -614,4 +619,122 @@ vldcppoll(dev_t dev, int events, struct 
        }
        splx(s);
        return revents;
+}
+
+void
+filt_vldcprdetach(struct knote *kn)
+{
+       struct vldcp_softc *sc = (void *)kn->kn_hook;
+       int s;
+
+       s = spltty();
+       klist_remove(&sc->sc_rsel.si_note, kn);
+       splx(s);
+}
+
+void
+filt_vldcpwdetach(struct knote *kn)
+{
+       struct vldcp_softc *sc = (void *)kn->kn_hook;
+       int s;
+
+       s = spltty();
+       klist_remove(&sc->sc_wsel.si_note, kn);
+       splx(s);
+}
+
+int
+filt_vldcpread(struct knote *kn, long hint)
+{
+       struct vldcp_softc *sc = (void *)kn->kn_hook;
+       struct ldc_conn *lc = &sc->sc_lc;
+       uint64_t head, tail, avail, state;
+       int s, err;
+
+       s = spltty();
+       err = hv_ldc_rx_get_state(lc->lc_id, &head, &tail, &state);
+       if (err == 0 && state == LDC_CHANNEL_UP && head != tail) {
+               avail = (head - tail) / sizeof(struct ldc_pkt) +
+                   lc->lc_rxq->lq_nentries - 1;
+               avail %= lc->lc_rxq->lq_nentries;
+               kn->kn_data = avail;
+       } else {
+               cbus_intr_setenabled(sc->sc_bustag, sc->sc_rx_ino,
+                   INTR_ENABLED);
+       }
+       splx(s);
+
+       return (kn->kn_data > 0);
+}
+
+int
+filt_vldcwrite(struct knote *kn, long hint)
+{
+       struct vldcp_softc *sc = (void *)kn->kn_hook;
+       struct ldc_conn *lc = &sc->sc_lc;
+       uint64_t head, tail, avail, state;
+       int s, err;
+
+       s = spltty();
+       err = hv_ldc_tx_get_state(lc->lc_id, &head, &tail, &state);
+       if (err == 0 && state == LDC_CHANNEL_UP && head != tail) {
+               avail = (head - tail) / sizeof(struct ldc_pkt) +
+                   lc->lc_rxq->lq_nentries - 1;
+               avail %= lc->lc_rxq->lq_nentries;
+               kn->kn_data = avail;
+       } else {
+               cbus_intr_setenabled(sc->sc_bustag, sc->sc_tx_ino,
+                   INTR_ENABLED);
+       }
+       splx(s);
+
+       return (kn->kn_data > 0);
+}
+
+const struct filterops vldcpread_filtops = {
+       .f_flags        = FILTEROP_ISFD,
+       .f_attach       = NULL,
+       .f_detach       = filt_vldcprdetach,
+       .f_event        = filt_vldcpread,
+};
+
+const struct filterops vldcpwrite_filtops = {
+       .f_flags        = FILTEROP_ISFD,
+       .f_attach       = NULL,
+       .f_detach       = filt_vldcpwdetach,
+       .f_event        = filt_vldcwrite,
+};
+
+int
+vldcpkqfilter(dev_t dev, struct knote *kn)
+{
+       struct vldcp_softc *sc;
+       struct klist *klist;
+       int s;
+
+       sc = vldcp_lookup(dev);
+       if (sc == NULL)
+               return (ENXIO);
+
+       switch (kn->kn_filter) {
+       case EVFILT_READ:
+               klist = &sc->sc_rsel.si_note;
+               kn->kn_fop = &vldcpread_filtops;
+               break;
+       case EVFILT_WRITE:
+               klist = &sc->sc_wsel.si_note;
+               kn->kn_fop = &vldcpwrite_filtops;
+               break;
+
+       default:
+               return (EINVAL);
+       }
+
+       kn->kn_hook = sc;
+
+       s = spltty();
+       klist_insert(klist, kn);
+       splx(s);
+
+       return (0);
 }
Index: arch/sparc64//include/conf.h
===================================================================
RCS file: /cvs/src/sys/arch/sparc64/include/conf.h,v
retrieving revision 1.25
diff -u -p -r1.25 conf.h
--- arch/sparc64//include/conf.h        13 May 2020 08:10:03 -0000      1.25
+++ arch/sparc64//include/conf.h        20 May 2020 09:15:55 -0000
@@ -64,7 +64,8 @@ cdev_decl(vdsp);
 #define        cdev_gen_init(c,n) { \
        dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
        dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) nullop, \
-       0, dev_init(c,n,poll), (dev_type_mmap((*))) enodev }
+       0, dev_init(c,n,poll), (dev_type_mmap((*))) enodev, \
+       0, 0, dev_init(c,n,kqfilter) }
 
 cdev_decl(cn);
 
Index: dev/sbus/magma.c
===================================================================
RCS file: /cvs/src/sys/dev/sbus/magma.c,v
retrieving revision 1.31
diff -u -p -r1.31 magma.c
--- dev/sbus/magma.c    18 Feb 2020 00:12:08 -0000      1.31
+++ dev/sbus/magma.c    20 May 2020 09:15:55 -0000
@@ -1340,6 +1340,7 @@ mtty_param(struct tty *tp, struct termio
  *     mbppwrite       write to mbpp
  *     mbppioctl       do ioctl on mbpp
  *     mbpppoll        do poll on mbpp
+ *     mbppkqfilter    kqueue on mbpp
  *     mbpp_rw         general rw routine
  *     mbpp_timeout    rw timeout
  *     mbpp_start      rw start after delay
@@ -1513,6 +1514,12 @@ int
 mbpppoll(dev_t dev, int events, struct proc *p)
 {
        return (seltrue(dev, events, p));
+}
+
+int
+mbppkqfilter(dev_t dev, struct knote *kn)
+{
+       return (seltrue_kqfilter(dev, kn));
 }
 
 int
Index: dev/sbus/spif.c
===================================================================
RCS file: /cvs/src/sys/dev/sbus/spif.c,v
retrieving revision 1.23
diff -u -p -r1.23 spif.c
--- dev/sbus/spif.c     19 Jul 2019 00:17:15 -0000      1.23
+++ dev/sbus/spif.c     20 May 2020 09:15:55 -0000
@@ -91,6 +91,7 @@ int   sbppwrite(dev_t, struct uio *, int);
 int    sbpp_rw(dev_t, struct uio *);
 int    spifppcintr(void *);
 int    sbpppoll(dev_t, int, struct proc *);
+int    sbppkqfilter(dev_t, struct knote *);
 int    sbppioctl(dev_t, u_long, caddr_t, int, struct proc *);
 
 struct cfattach spif_ca = {
@@ -1043,6 +1044,11 @@ int
 sbpppoll(dev_t dev, int events, struct proc *p)
 {
        return (seltrue(dev, events, p));
+}
+int
+sbppkqfilter(dev_t dev, struct knote *kn)
+{
+       return (seltrue_kqfilter(dev, kn));
 }
 
 int

Reply via email to