From fe22f0da24f74b30d40c1ffbe201aaeb94fc041f Mon Sep 17 00:00:00 2001 From: Samuel J. Greear Date: Wed, 18 May 2011 10:44:19 -0600 Subject: [PATCH] Make compile -- Fix up includes (poll->kq) Fix an kmem_alloc_nofault call (add alignment) Tear out poll and plug in kq Comment out strsep (conflicts w/ one in libkern) --- src/nv-freebsd.h | 8 ++-- src/nvidia_ctl.c | 83 ++++++++++++++++++++++++++++++++--------- src/nvidia_dev.c | 92 +++++++++++++++++++++++++++++++++------------ src/nvidia_os_registry.c | 2 + src/nvidia_subr.c | 2 +- 5 files changed, 138 insertions(+), 49 deletions(-) diff --git a/src/nv-freebsd.h b/src/nv-freebsd.h index 62085b9..29a0269 100644 --- a/src/nv-freebsd.h +++ b/src/nv-freebsd.h @@ -76,7 +76,7 @@ #include #include #include -#include +#include #include #include @@ -264,8 +264,7 @@ struct nvidia_softc { STAILQ_HEAD(filep_queue, nvidia_filep) filep_queue; struct sysctl_ctx_list sysctl_ctx; - struct selinfo rsel; - + struct kqinfo rkq; struct callout timer_ch; /* list of allocations */ @@ -348,7 +347,8 @@ static inline void *pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, int mode) vm_offset_t tmp, va; uint32_t cache_bits; - va = kmem_alloc_nofault(&kernel_map, size); + /* XXX: SJG: No idea if PAGE_SIZE is correct alignment */ + va = kmem_alloc_nofault(&kernel_map, size, PAGE_SIZE); if (va != 0) { cache_bits = (mode != PAT_WRITE_BACK) ? PG_N : 0; for (tmp = va; tmp < (va + size); tmp += PAGE_SIZE) { diff --git a/src/nvidia_ctl.c b/src/nvidia_ctl.c index 2d60f46..8578421 100644 --- a/src/nvidia_ctl.c +++ b/src/nvidia_ctl.c @@ -13,19 +13,22 @@ #include "nv.h" #include "nv-freebsd.h" -static d_open_t nvidia_ctl_open; -static d_close_t nvidia_ctl_close; -static d_ioctl_t nvidia_ctl_ioctl; -static d_poll_t nvidia_ctl_poll; +static d_open_t nvidia_ctl_open; +static d_close_t nvidia_ctl_close; +static d_ioctl_t nvidia_ctl_ioctl; +static d_kqfilter_t nvidia_ctl_kqfilter; static struct dev_ops nvidia_ctl_ops = { { "nvidiactl", CDEV_MAJOR, D_TRACKCLOSE }, .d_open = nvidia_ctl_open, .d_close = nvidia_ctl_close, .d_ioctl = nvidia_ctl_ioctl, - .d_poll = nvidia_ctl_poll, + .d_kqfilter = nvidia_ctl_kqfilter }; +void nvidia_ctl_filter_detach(struct knote *); +int nvidia_ctl_filter_read(struct knote *, long); + static struct cdev *nvidia_ctl_cdev = NULL; struct nvidia_softc nvidia_ctl_sc; @@ -81,35 +84,77 @@ int nvidia_ctl_ioctl( return status; } -int nvidia_ctl_poll( - struct dev_poll_args *ap +static struct filterops nvidia_ctl_read_filtops = + { FILTEROP_ISFD, NULL, nvidia_ctl_filter_detach, nvidia_ctl_filter_read }; + +int nvidia_ctl_kqfilter( + struct dev_kqfilter_args *ap ) { - int events = ap->a_events; nv_state_t *nv; struct nvidia_softc *sc; - struct nvidia_event *et; + struct knote *kn = ap->a_kn; + struct klist *klist; nv = &nvidia_ctl_state; sc = nv->os_state; - nv_lock_rm(nv); + ap->a_result = 0; + + switch (kn->kn_filter) { + case EVFILT_READ: + kn->kn_fop = &nvidia_ctl_read_filtops; + kn->kn_hook = (caddr_t)sc; + break; + default: + ap->a_result = EOPNOTSUPP; + return (0); + } + + klist = &sc->rkq.ki_note; + knote_insert(klist, kn); + + return (0); +} + +void +nvidia_ctl_filter_detach( + struct knote *kn +) +{ + struct nvidia_softc *sc; + struct klist *klist; + sc = (struct nvidia_softc *)kn->kn_hook; + klist = &sc->rkq.ki_note; + knote_remove(klist, kn); +} + +int +nvidia_ctl_filter_read( + struct knote *kn, + long hint +) +{ + int ready = 0; + nv_state_t *nv; + struct nvidia_softc *sc; + struct nvidia_event *et; + + nv = &nvidia_ctl_state; + sc = (struct nvidia_softc *)kn->kn_hook; + + nv_lock_rm(nv); STAILQ_FOREACH(et, &sc->event_queue, queue) { if (et->event.file == __TD_FDT(curthread)) break; } + nv_unlock_rm(nv); - if (et == NULL) { - nv_unlock_rm(nv); - selrecord(curthread, &sc->rsel); - ap->a_events = 0; - } else { - nv_unlock_rm(nv); - ap->a_events = events & (POLLIN | POLLPRI | POLLRDNORM); - } + if (et != NULL) + ready = 1; - return 0; + return (ready); } int nvidia_ctl_attach(void) diff --git a/src/nvidia_dev.c b/src/nvidia_dev.c index 6f21b7a..08e8f9b 100644 --- a/src/nvidia_dev.c +++ b/src/nvidia_dev.c @@ -13,21 +13,24 @@ #include "nv.h" #include "nv-freebsd.h" -static d_open_t nvidia_dev_open; -static d_close_t nvidia_dev_close; -static d_ioctl_t nvidia_dev_ioctl; -static d_poll_t nvidia_dev_poll; -static d_mmap_t nvidia_dev_mmap; +static d_open_t nvidia_dev_open; +static d_close_t nvidia_dev_close; +static d_ioctl_t nvidia_dev_ioctl; +static d_kqfilter_t nvidia_dev_kqfilter; +static d_mmap_t nvidia_dev_mmap; static struct dev_ops nvidia_dev_ops = { { "nvidia", CDEV_MAJOR, D_MEM|D_TRACKCLOSE }, .d_open = nvidia_dev_open, .d_close = nvidia_dev_close, .d_ioctl = nvidia_dev_ioctl, - .d_poll = nvidia_dev_poll, + .d_kqfilter = nvidia_dev_kqfilter, .d_mmap = nvidia_dev_mmap, }; +void nvidia_dev_filter_detach(struct knote *); +int nvidia_dev_filter_read(struct knote *, long); + int nvidia_dev_open( struct dev_open_args *ap ) @@ -100,38 +103,77 @@ int nvidia_dev_ioctl( return status; } -int nvidia_dev_poll( - struct dev_poll_args *ap +static struct filterops nvidia_dev_read_filtops = + { FILTEROP_ISFD, NULL, nvidia_dev_filter_detach, nvidia_dev_filter_read }; + +int nvidia_dev_kqfilter( + struct dev_kqfilter_args *ap +) +{ + nv_state_t *nv; + struct nvidia_softc *sc; + struct knote *kn = ap->a_kn; + struct klist *klist; + + nv = &nvidia_ctl_state; + sc = nv->os_state; + + ap->a_result = 0; + + switch (kn->kn_filter) { + case EVFILT_READ: + kn->kn_fop = &nvidia_dev_read_filtops; + kn->kn_hook = (caddr_t)sc; + break; + default: + ap->a_result = EOPNOTSUPP; + return (0); + } + + klist = &sc->rkq.ki_note; + knote_insert(klist, kn); + + return (0); +} + +void +nvidia_dev_filter_detach( + struct knote *kn ) { - struct cdev *dev = ap->a_head.a_dev; - int events = ap->a_events; - d_thread_t *td = curthread; struct nvidia_softc *sc; + struct klist *klist; + + sc = (struct nvidia_softc *)kn->kn_hook; + klist = &sc->rkq.ki_note; + knote_remove(klist, kn); +} + +int +nvidia_dev_filter_read( + struct knote *kn, + long hint +) +{ + int ready = 0; nv_state_t *nv; + struct nvidia_softc *sc; struct nvidia_event *et; - int unit = minor(dev); - sc = devclass_get_softc(nvidia_devclass, unit); - nv = sc->nv_state; + nv = &nvidia_ctl_state; + sc = (struct nvidia_softc *)kn->kn_hook; nv_lock_rm(nv); - STAILQ_FOREACH(et, &sc->event_queue, queue) { - if (et->event.file == __TD_FDT(td)) + if (et->event.file == __TD_FDT(curthread)) break; } + nv_unlock_rm(nv); - if (et == NULL) { - nv_unlock_rm(nv); - selrecord(td, &sc->rsel); - ap->a_events = 0; - } else { - nv_unlock_rm(nv); - ap->a_events = (events & (POLLIN | POLLPRI | POLLRDNORM)); - } + if (et != NULL) + ready = 1; - return 0; + return (ready); } int nvidia_dev_mmap( diff --git a/src/nvidia_os_registry.c b/src/nvidia_os_registry.c index d420bf9..4084207 100644 --- a/src/nvidia_os_registry.c +++ b/src/nvidia_os_registry.c @@ -16,6 +16,7 @@ #include "nv-freebsd.h" #include "nv-reg.h" +#if 0 static char * strsep(char **strp, const char *delim) { @@ -39,6 +40,7 @@ strsep(char **strp, const char *delim) return (start); } +#endif void nvidia_update_registry(char *new_option_string) { diff --git a/src/nvidia_subr.c b/src/nvidia_subr.c index efbfdbf..4da7eb4 100644 --- a/src/nvidia_subr.c +++ b/src/nvidia_subr.c @@ -994,7 +994,7 @@ void NV_API_CALL nv_post_event( nv_unlock_rm(nv); - selwakeup(&sc->rsel); + KNOTE(&sc->rkq.ki_note, 0); } S032 NV_API_CALL nv_get_event( -- 1.7.0.5