[PATCH 1/2] Add support for MMAP handler for file operations

Kevin Kirspel kevin-kirspel at idexx.com
Tue May 23 01:42:24 UTC 2017


---
 freebsd/sys/sys/conf.h             |  4 ++--
 freebsd/sys/sys/file.h             | 20 +++++++++++++++++
 rtemsbsd/sys/fs/devfs/devfs_devs.c | 46 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/freebsd/sys/sys/conf.h b/freebsd/sys/sys/conf.h
index d5ced5c..6ae0f52 100644
--- a/freebsd/sys/sys/conf.h
+++ b/freebsd/sys/sys/conf.h
@@ -202,8 +202,8 @@ struct cdevsw {
 	d_write_t		*d_write;
 	d_ioctl_t		*d_ioctl;
 	d_poll_t		*d_poll;
-#ifndef __rtems__
 	d_mmap_t		*d_mmap;
+#ifndef __rtems__
 	d_strategy_t		*d_strategy;
 	dumper_t		*d_dump;
 #endif /* __rtems__ */
diff --git a/freebsd/sys/sys/file.h b/freebsd/sys/sys/file.h
index c52dc7a..673a102 100644
--- a/freebsd/sys/sys/file.h
+++ b/freebsd/sys/sys/file.h
@@ -555,6 +555,7 @@ fo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)

 	return ((*fp->f_ops->fo_fill_kinfo)(fp, kif, fdp));
 }
+#endif /* __rtems__ */

 static __inline int
 fo_mmap(struct file *fp, vm_map_t map, vm_offset_t *addr, vm_size_t size,
@@ -562,12 +563,31 @@ fo_mmap(struct file *fp, vm_map_t map, vm_offset_t *addr, vm_size_t size,
     struct thread *td)
 {

+#ifndef __rtems__
 	if (fp->f_ops->fo_mmap == NULL)
 		return (ENODEV);
 	return ((*fp->f_ops->fo_mmap)(fp, map, addr, size, prot, cap_maxprot,
 	    flags, foff, td));
+#else /* __rtems__ */
+	int rv;
+
+	(void) map;
+	(void) cap_maxprot;
+	(void) flags;
+	(void) td;
+
+	errno = 0;
+	rv = ((*fp->f_io.pathinfo.handlers->mmap_h)(&fp->f_io, (void**)&addr,
+	    (size_t)size, (int)prot, (off_t)foff));
+	if (rv == 0) {
+		return (0);
+	} else {
+		return (errno);
+	}
+#endif /* __rtems__ */
 }

+#ifndef __rtems__
 static __inline int
 fo_aio_queue(struct file *fp, struct kaiocb *job)
 {
diff --git a/rtemsbsd/sys/fs/devfs/devfs_devs.c b/rtemsbsd/sys/fs/devfs/devfs_devs.c
index 7d89c49..4e6dfe0 100644
--- a/rtemsbsd/sys/fs/devfs/devfs_devs.c
+++ b/rtemsbsd/sys/fs/devfs/devfs_devs.c
@@ -386,6 +386,51 @@ devfs_imfs_kqfilter(rtems_libio_t *iop, struct knote *kn)
 	return error;
 }

+static int
+devfs_imfs_mmap(rtems_libio_t *iop, void **addr, size_t len, int prot, off_t off)
+{
+	struct cdev *cdev = devfs_imfs_get_context_by_iop(iop);
+	struct file *fp = rtems_bsd_iop_to_fp(iop);
+	struct thread *td = rtems_bsd_get_curthread_or_null();
+	struct file *fpop;
+	struct cdevsw *dsw;
+	int error, ref;
+	vm_object_t object;
+	vm_paddr_t paddr;
+
+	if (td != 0) {
+		if (cdev == NULL) {
+			error = ENXIO;
+			goto err;
+		}
+		if (cdev->si_flags & SI_ALIAS) {
+			cdev = cdev->si_parent;
+		}
+		dsw = dev_refthread(cdev, &ref);
+		if (dsw == NULL) {
+			error = ENXIO;
+			goto err;
+		}
+		fpop = td->td_fpop;
+		curthread->td_fpop = fp;
+		error = dsw->d_mmap(cdev, (vm_ooffset_t)off, &paddr, prot, &object);
+		*addr = paddr;
+		td->td_fpop = fpop;
+		dev_relthread(cdev, ref);
+	} else {
+		error = ENOMEM;
+	}
+
+err:
+	return rtems_bsd_error_to_status_and_errno(error);
+}
+
+typedef int d_mmap_t(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr,
+		     int nprot, vm_memattr_t *memattr);
+typedef int d_mmap_single_t(struct cdev *cdev, vm_ooffset_t *offset,
+    vm_size_t size, struct vm_object **object, int nprot);
+
+
 static const rtems_filesystem_file_handlers_r devfs_imfs_handlers = {
 	.open_h = devfs_imfs_open,
 	.close_h = devfs_imfs_close,
@@ -400,6 +445,7 @@ static const rtems_filesystem_file_handlers_r devfs_imfs_handlers = {
 	.fcntl_h = rtems_filesystem_default_fcntl,
 	.poll_h = devfs_imfs_poll,
 	.kqfilter_h = devfs_imfs_kqfilter,
+	.mmap_h = devfs_imfs_mmap,
 	.readv_h = devfs_imfs_readv,
 	.writev_h = devfs_imfs_writev,
 };
--
1.9.1



More information about the devel mailing list