static int randomdev_poll(int events, struct thread *td) { int revents = 0; #ifndef __OSV__ mtx_lock(&random_reseed_mtx); if (random_context.seeded) revents = events & (POLLIN | POLLRDNORM); else selrecord(td, &random_context.rsel); mtx_unlock(&random_reseed_mtx); #endif return (revents); }
static int apmpoll(struct cdev *dev, int events, struct thread *td) { struct apm_clone_data *clone; int revents; revents = 0; ACPI_LOCK(acpi); clone = dev->si_drv1; if (clone->acpi_sc->acpi_next_sstate) revents |= events & (POLLIN | POLLRDNORM); else selrecord(td, &clone->sel_read); ACPI_UNLOCK(acpi); return (revents); }
int wsevent_poll(struct wseventvar *ev, int events, struct proc *p) { int revents = 0; int s = splwsevent(); if (events & (POLLIN | POLLRDNORM)) { if (ev->get != ev->put) revents |= events & (POLLIN | POLLRDNORM); else selrecord(p, &ev->sel); } splx(s); return (revents); }
int tctrlpoll(dev_t dev, int events, struct lwp *l) { struct tctrl_softc *sc = device_lookup_private(&tctrl_cd, TCTRL_STD_DEV); int revents = 0; if (events & (POLLIN | POLLRDNORM)) { if (sc->sc_event_count) revents |= events & (POLLIN | POLLRDNORM); else selrecord(l, &sc->sc_rsel); } return (revents); }
int apmpoll(dev_t dev, int events, struct lwp *l) { struct apm_softc *sc = device_lookup_private(&apm_cd, APMUNIT(dev)); int revents = 0; APM_LOCK(sc); if (events & (POLLIN | POLLRDNORM)) { if (sc->sc_event_count) revents |= events & (POLLIN | POLLRDNORM); else selrecord(l, &sc->sc_rsel); } APM_UNLOCK(sc); return (revents); }
static int chpoll(dev_t dev, int events, struct lwp *l) { struct ch_softc *sc = device_lookup_private(&ch_cd, CHUNIT(dev)); int revents; revents = events & (POLLOUT | POLLWRNORM); if ((events & (POLLIN | POLLRDNORM)) == 0) return (revents); if (sc->sc_events == 0) revents |= events & (POLLIN | POLLRDNORM); else selrecord(l, &sc->sc_selq); return (revents); }
int xfs_devpoll(dev_t dev, int events, d_thread_t * p) { struct xfs_channel *chan = &xfs_channel[minor(dev)]; NNPFSDEB(XDEBDEV, ("xfs_devpoll dev = %d(%d), events = 0x%x\n", major(dev), minor(dev), events)); if ((events & (POLLIN | POLLRDNORM)) == 0) return 0; /* only supports read */ if (!xfs_emptyq(&chan->messageq)) return (events & (POLLIN | POLLRDNORM)); selrecord (p, &chan->selinfo); return 0; }
ipfpoll(dev_t dev, int events, struct proc *td) #endif { int unit = GET_MINOR(dev); int revents; if (unit < 0 || unit > IPL_LOGMAX) return 0; revents = 0; CURVNET_SET(TD_TO_VNET(td)); switch (unit) { case IPL_LOGIPF : case IPL_LOGNAT : case IPL_LOGSTATE : #ifdef IPFILTER_LOG if ((events & (POLLIN | POLLRDNORM)) && ipf_log_canread(&V_ipfmain, unit)) revents |= events & (POLLIN | POLLRDNORM); #endif break; case IPL_LOGAUTH : if ((events & (POLLIN | POLLRDNORM)) && ipf_auth_waiting(&V_ipfmain)) revents |= events & (POLLIN | POLLRDNORM); break; case IPL_LOGSYNC : if ((events & (POLLIN | POLLRDNORM)) && ipf_sync_canread(&V_ipfmain)) revents |= events & (POLLIN | POLLRDNORM); if ((events & (POLLOUT | POLLWRNORM)) && ipf_sync_canwrite(&V_ipfmain)) revents |= events & (POLLOUT | POLLWRNORM); break; case IPL_LOGSCAN : case IPL_LOGLOOKUP : default : break; } if ((revents == 0) && ((events & (POLLIN|POLLRDNORM)) != 0)) selrecord(td, &V_ipfmain.ipf_selwait[unit]); CURVNET_RESTORE(); return revents; }
iplpoll(dev_t dev, int events, struct proc *td) #endif { u_int xmin = GET_MINOR(dev); int revents; if (xmin < 0 || xmin > IPL_LOGMAX) return 0; revents = 0; switch (xmin) { case IPL_LOGIPF : case IPL_LOGNAT : case IPL_LOGSTATE : #ifdef IPFILTER_LOG if ((events & (POLLIN | POLLRDNORM)) && ipflog_canread(xmin)) revents |= events & (POLLIN | POLLRDNORM); #endif break; case IPL_LOGAUTH : if ((events & (POLLIN | POLLRDNORM)) && fr_auth_waiting()) revents |= events & (POLLIN | POLLRDNORM); break; case IPL_LOGSYNC : #ifdef IPFILTER_SYNC if ((events & (POLLIN | POLLRDNORM)) && ipfsync_canread()) revents |= events & (POLLIN | POLLRDNORM); if ((events & (POLLOUT | POLLWRNORM)) && ipfsync_canwrite()) revents |= events & (POLLOUT | POLLWRNORM); #endif break; case IPL_LOGSCAN : case IPL_LOGLOOKUP : default : break; } if ((revents == 0) && ((events & (POLLIN|POLLRDNORM)) != 0)) selrecord(td, &ipfselwait[xmin]); return revents; }
int aedpoll(dev_t dev, int events, struct lwp *l) { int s, revents; revents = events & (POLLOUT | POLLWRNORM); if ((events & (POLLIN | POLLRDNORM)) == 0) return (revents); s = splvm(); if (aed_sc->sc_evq_len > 0) revents |= events & (POLLIN | POLLRDNORM); else selrecord(l, &aed_sc->sc_selinfo); splx(s); return (revents); }
int cprng_strong_poll(struct cprng_strong *cprng, int events) { int revents; if (!ISSET(events, (POLLIN | POLLRDNORM))) return 0; mutex_enter(&cprng->cs_lock); if (cprng->cs_ready) { revents = (events & (POLLIN | POLLRDNORM)); } else { selrecord(curlwp, &cprng->cs_selq); revents = 0; } mutex_exit(&cprng->cs_lock); return revents; }
static int uvfs_select (dev_t dev, int which, struct proc *p) { uvfs_softc *st = getstate (dev); #ifdef UVFS_DEBUG_DEV warn ("uvfs%d: select\n", minor (dev)); #endif /* UVFS_DEBUG_DEV */ if (which & FWRITE) return 1; else { if (st->rpcq.inq.tqh_first) return 1; st->flags |= UVFS_RSEL; selrecord (p, &st->sel); return 0; } }
/* * dmio_poll: * * Poll file op. */ static int dmio_poll(struct file *fp, int events) { struct dmio_state *ds = (struct dmio_state *) fp->f_data; int s, revents = 0; if ((events & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM)) == 0) return (revents); s = splsoftclock(); simple_lock(&ds->ds_slock); if (ds->ds_flags & DMIO_STATE_DEAD) { /* EOF */ revents |= events & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM); goto out; } /* We can read if there are completed requests. */ if (events & (POLLIN | POLLRDNORM)) if (TAILQ_EMPTY(&ds->ds_complete) == 0) revents |= events & (POLLIN | POLLRDNORM); /* * We can write if there is there are fewer then DMIO_NREQS_MAX * are already in the queue. */ if (events & (POLLOUT | POLLWRNORM)) if (ds->ds_nreqs < DMIO_NREQS_MAX) revents |= events & (POLLOUT | POLLWRNORM); if (revents == 0) { selrecord(curlwp, &ds->ds_selq); ds->ds_flags |= DMIO_STATE_SEL; } out: simple_unlock(&ds->ds_slock); splx(s); return (revents); }
int videopoll(dev_t dev, int events, struct proc *p) { int unit = VIDEOUNIT(dev); struct video_softc *sc; int error, revents = 0; if (unit >= video_cd.cd_ndevs || (sc = video_cd.cd_devs[unit]) == NULL) return (POLLERR); if (sc->sc_dying) return (POLLERR); DPRINTF(("%s: events=0x%x\n", __func__, events)); if (events & (POLLIN | POLLRDNORM)) { if (sc->sc_frames_ready > 0) revents |= events & (POLLIN | POLLRDNORM); } if (revents == 0) { if (events & (POLLIN | POLLRDNORM)) /* * Start the stream in read() mode if not already * started. If the user wanted mmap() mode, * he should have called mmap() before now. */ if (sc->sc_vidmode == VIDMODE_NONE && sc->hw_if->start_read) { error = sc->hw_if->start_read(sc->hw_hdl); if (error) return (POLLERR); sc->sc_vidmode = VIDMODE_READ; } selrecord(p, &sc->sc_rsel); } DPRINTF(("%s: revents=0x%x\n", __func__, revents)); return (revents); }
/* * Support for poll() system call */ int bpfpoll(dev_t dev, int events, struct proc *p) { struct bpf_d *d; int s, revents; /* * An imitation of the FIONREAD ioctl code. */ d = bpfilter_lookup(minor(dev)); /* * XXX The USB stack manages it to trigger some race condition * which causes bpfilter_lookup to return NULL when a USB device * gets detached while it is up and has an open bpf handler (e.g. * dhclient). We still should recheck if we can fix the root * cause of this issue. */ if (d == NULL) return (POLLERR); /* Always ready to write data */ revents = events & (POLLOUT | POLLWRNORM); if (events & (POLLIN | POLLRDNORM)) { s = splnet(); if (d->bd_hlen != 0 || (d->bd_immediate && d->bd_slen != 0)) revents |= events & (POLLIN | POLLRDNORM); else { /* * if there's a timeout, mark the time we * started waiting. */ if (d->bd_rtout != -1 && d->bd_rdStart == 0) d->bd_rdStart = ticks; selrecord(p, &d->bd_sel); } splx(s); } return (revents); }
static int sms1xxx_demux_poll(struct cdev *dev, int events, struct thread *p) { int revents = 0; struct sms1xxx_softc *sc; struct filter *f; TRACE(TRACE_POLL,"thread=%p, events=%d, f=%p\n", p, events, dev->si_drv2); sc = dev->si_drv1; if(sc == NULL || sc->sc_dying) { TRACE(TRACE_MODULE,"dying! sc=%p\n",sc); return ((events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)) | POLLHUP); } f = dev->si_drv2; if (f == NULL) { ERR("no filter found\n"); return (EFAULT); } /* XXX POLLERR POLLPRI */ if(events & (POLLIN | POLLRDNORM)) { if(f->cnt == 0) { selrecord(p,&f->rsel); f->state |= FILTER_POLL; TRACE(TRACE_POLL,"will block\n"); } else { revents |= events & (POLLIN | POLLRDNORM); TRACE(TRACE_POLL,"poll not blocking\n"); } } if(events & (POLLOUT | POLLWRNORM)) { /* Write is not allowed, so no point blocking on it */ revents |= events & (POLLOUT | POLLWRNORM); } return (revents); }
int psmselect(dev_t dev, int rw, struct proc *p) { int s, ret; struct psm_softc *sc = &psm_softc[PSMUNIT(dev)]; /* Silly to select for output */ if (rw == FWRITE) return (0); /* Return true if a mouse event available */ s = spltty(); if (sc->inq.count) ret = 1; else { selrecord(p, &sc->rsel); ret = 0; } splx(s); return (ret); }
/* * Poll handler. Writing is always possible, reading is only possible * if BSR_BULK_IN_FULL is set. Will start the cmx_tick callout and * set sc->polling. */ static int cmx_poll(struct cdev *cdev, int events, struct thread *td) { struct cmx_softc *sc = cdev->si_drv1; int revents = 0; uint8_t bsr = 0; if (sc == NULL || sc->dying) return ENXIO; bsr = cmx_read_BSR(sc); DEBUG_printf(sc->dev, "called (events=%b BSR=%b)\n", events, POLLBITS, bsr, BSRBITS); revents = events & (POLLOUT | POLLWRNORM); if (events & (POLLIN | POLLRDNORM)) { if (cmx_test(bsr, BSR_BULK_IN_FULL, 1)) { revents |= events & (POLLIN | POLLRDNORM); } else { selrecord(td, &sc->sel); CMX_LOCK(sc); if (!sc->polling) { DEBUG_printf(sc->dev, "enabling polling\n"); sc->polling = 1; callout_reset(&sc->ch, POLL_TICKS, cmx_tick, sc); } else { DEBUG_printf(sc->dev, "already polling\n"); } CMX_UNLOCK(sc); } } DEBUG_printf(sc->dev, "success (revents=%b)\n", revents, POLLBITS); return revents; }
int satlinkpoll(dev_t dev, int events, struct lwp *l) { struct satlink_softc *sc; int s, revents; sc = device_lookup_private(&satlink_cd, minor(dev)); revents = events & (POLLOUT | POLLWRNORM); /* Attempt to save some work. */ if ((events & (POLLIN | POLLRDNORM)) == 0) return (revents); /* We're timeout-driven, so must block the clock. */ s = splsoftclock(); if (sc->sc_uptr != sc->sc_sptr) revents |= events & (POLLIN | POLLRDNORM); else selrecord(l, &sc->sc_selq); splx(s); return (revents); }
/* * msepoll: check for mouse input to be processed. */ static int msepoll(struct cdev *dev, int events, struct thread *td) { mse_softc_t *sc = dev->si_drv1; int s; int revents = 0; s = spltty(); if (events & (POLLIN | POLLRDNORM)) { if (sc->sc_bytesread != sc->mode.packetsize || sc->sc_deltax != 0 || sc->sc_deltay != 0 || (sc->sc_obuttons ^ sc->sc_buttons) != 0) revents |= events & (POLLIN | POLLRDNORM); else { /* * Since this is an exclusive open device, any previous * proc pointer is trash now, so we can just assign it. */ selrecord(td, &sc->sc_selp); } } splx(s); return (revents); }
int fuse_device_poll(struct cdev *dev, int events, struct thread *td) { struct fuse_data *data; int error, revents = 0; error = devfs_get_cdevpriv((void **)&data); if (error != 0) return (events & (POLLHUP|POLLIN|POLLRDNORM|POLLOUT|POLLWRNORM)); if (events & (POLLIN | POLLRDNORM)) { fuse_lck_mtx_lock(data->ms_mtx); if (fdata_get_dead(data) || STAILQ_FIRST(&data->ms_head)) revents |= events & (POLLIN | POLLRDNORM); else selrecord(td, &data->ks_rsel); fuse_lck_mtx_unlock(data->ms_mtx); } if (events & (POLLOUT | POLLWRNORM)) { revents |= events & (POLLOUT | POLLWRNORM); } return (revents); }
static int xenevt_fioctl(struct file *fp, u_long cmd, void *addr) { struct xenevt_d *d = fp->f_data; evtchn_op_t op = { .cmd = 0 }; int error; switch(cmd) { case EVTCHN_RESET: case IOCTL_EVTCHN_RESET: mutex_enter(&d->lock); d->ring_read = d->ring_write = 0; d->flags = 0; mutex_exit(&d->lock); break; case IOCTL_EVTCHN_BIND_VIRQ: { struct ioctl_evtchn_bind_virq *bind_virq = addr; op.cmd = EVTCHNOP_bind_virq; op.u.bind_virq.virq = bind_virq->virq; op.u.bind_virq.vcpu = 0; if ((error = HYPERVISOR_event_channel_op(&op))) { printf("IOCTL_EVTCHN_BIND_VIRQ failed: virq %d error %d\n", bind_virq->virq, error); return -error; } bind_virq->port = op.u.bind_virq.port; mutex_enter(&devevent_lock); KASSERT(devevent[bind_virq->port] == NULL); devevent[bind_virq->port] = d; mutex_exit(&devevent_lock); xen_atomic_set_bit(&d->ci->ci_evtmask[0], bind_virq->port); hypervisor_unmask_event(bind_virq->port); break; } case IOCTL_EVTCHN_BIND_INTERDOMAIN: { struct ioctl_evtchn_bind_interdomain *bind_intd = addr; op.cmd = EVTCHNOP_bind_interdomain; op.u.bind_interdomain.remote_dom = bind_intd->remote_domain; op.u.bind_interdomain.remote_port = bind_intd->remote_port; if ((error = HYPERVISOR_event_channel_op(&op))) return -error; bind_intd->port = op.u.bind_interdomain.local_port; mutex_enter(&devevent_lock); KASSERT(devevent[bind_intd->port] == NULL); devevent[bind_intd->port] = d; mutex_exit(&devevent_lock); xen_atomic_set_bit(&d->ci->ci_evtmask[0], bind_intd->port); hypervisor_unmask_event(bind_intd->port); break; } case IOCTL_EVTCHN_BIND_UNBOUND_PORT: { struct ioctl_evtchn_bind_unbound_port *bind_unbound = addr; op.cmd = EVTCHNOP_alloc_unbound; op.u.alloc_unbound.dom = DOMID_SELF; op.u.alloc_unbound.remote_dom = bind_unbound->remote_domain; if ((error = HYPERVISOR_event_channel_op(&op))) return -error; bind_unbound->port = op.u.alloc_unbound.port; mutex_enter(&devevent_lock); KASSERT(devevent[bind_unbound->port] == NULL); devevent[bind_unbound->port] = d; mutex_exit(&devevent_lock); xen_atomic_set_bit(&d->ci->ci_evtmask[0], bind_unbound->port); hypervisor_unmask_event(bind_unbound->port); break; } case IOCTL_EVTCHN_UNBIND: { struct ioctl_evtchn_unbind *unbind = addr; if (unbind->port > NR_EVENT_CHANNELS) return EINVAL; mutex_enter(&devevent_lock); if (devevent[unbind->port] != d) { mutex_exit(&devevent_lock); return ENOTCONN; } devevent[unbind->port] = NULL; mutex_exit(&devevent_lock); hypervisor_mask_event(unbind->port); xen_atomic_clear_bit(&d->ci->ci_evtmask[0], unbind->port); op.cmd = EVTCHNOP_close; op.u.close.port = unbind->port; if ((error = HYPERVISOR_event_channel_op(&op))) return -error; break; } case IOCTL_EVTCHN_NOTIFY: { struct ioctl_evtchn_notify *notify = addr; if (notify->port > NR_EVENT_CHANNELS) return EINVAL; mutex_enter(&devevent_lock); if (devevent[notify->port] != d) { mutex_exit(&devevent_lock); return ENOTCONN; } hypervisor_notify_via_evtchn(notify->port); mutex_exit(&devevent_lock); break; } case FIONBIO: break; default: return EINVAL; } return 0; } /* * Support for poll() system call * * Return true if the specific operation will not block indefinitely. */ static int xenevt_fpoll(struct file *fp, int events) { struct xenevt_d *d = fp->f_data; int revents = events & (POLLOUT | POLLWRNORM); /* we can always write */ mutex_enter(&d->lock); if (events & (POLLIN | POLLRDNORM)) { if (d->ring_read != d->ring_write) { revents |= events & (POLLIN | POLLRDNORM); } else { /* Record that someone is waiting */ selrecord(curlwp, &d->sel); } } mutex_exit(&d->lock); return (revents); }