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