Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 24 Aug 2010 20:40:12 +0000 (UTC)
From:      Jeff Roberson <jeff@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r211770 - projects/ofed/head/sys/ofed/include/linux
Message-ID:  <201008242040.o7OKeC1O087142@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jeff
Date: Tue Aug 24 20:40:12 2010
New Revision: 211770
URL: http://svn.freebsd.org/changeset/base/211770

Log:
   - Provide a mmap_single interface as well as mmap.  mmap_single gives
     the device pager an offset based on the physical address returned by
     the linux mmap handler so that the normal mmap handler can simply
     return the offset as the paddr when a fault happens and we no longer
     have the context required to resolve the address.
  
  Sponsored by:	Isilon Systems, iX Systems, and Panasas

Modified:
  projects/ofed/head/sys/ofed/include/linux/linux_compat.c

Modified: projects/ofed/head/sys/ofed/include/linux/linux_compat.c
==============================================================================
--- projects/ofed/head/sys/ofed/include/linux/linux_compat.c	Tue Aug 24 20:38:01 2010	(r211769)
+++ projects/ofed/head/sys/ofed/include/linux/linux_compat.c	Tue Aug 24 20:40:12 2010	(r211770)
@@ -46,6 +46,8 @@
 #include <linux/sysfs.h>
 #include <linux/mm.h>
 
+#include <vm/vm_pager.h>
+
 MALLOC_DEFINE(M_KMALLOC, "linux", "Linux kmalloc compat");
 
 #include <linux/rbtree.h>
@@ -376,29 +378,48 @@ static int
 linux_dev_mmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr,
     int nprot, vm_memattr_t *memattr)
 {
+
+	/* XXX memattr not honored. */
+	*paddr = offset;
+	return (0);
+}
+
+static int
+linux_dev_mmap_single(struct cdev *dev, vm_ooffset_t *offset,
+    vm_size_t size, struct vm_object **object, int nprot)
+{
 	struct linux_cdev *ldev;
 	struct linux_file *filp;
 	struct file *file;
 	struct vm_area_struct vma;
+	vm_paddr_t paddr;
+	vm_page_t m;
 	int error;
 
 	file = curthread->td_fpop;
 	ldev = dev->si_drv1;
 	if (ldev == NULL)
-		return (0);
+		return (ENODEV);
+	if (size != PAGE_SIZE)
+		return (EINVAL);
 	if ((error = devfs_get_cdevpriv((void **)&filp)) != 0)
 		return (error);
 	filp->f_flags = file->f_flag;
 	vma.vm_start = 0;
 	vma.vm_end = PAGE_SIZE;
-	vma.vm_pgoff = offset / PAGE_SIZE;
+	vma.vm_pgoff = *offset / PAGE_SIZE;
 	vma.vm_pfn = 0;
-	vma.vm_page_prot = *memattr;
+	vma.vm_page_prot = 0;
 	if (filp->f_op->mmap) {
 		error = -filp->f_op->mmap(filp, &vma);
 		if (error == 0) {
-			*paddr = (vm_paddr_t)vma.vm_pfn << PAGE_SHIFT;
-			*memattr = vma.vm_page_prot;
+			paddr = (vm_paddr_t)vma.vm_pfn << PAGE_SHIFT;
+			*offset = paddr;
+			m = PHYS_TO_VM_PAGE(paddr);
+			*object = vm_pager_allocate(OBJT_DEVICE, dev,
+			    PAGE_SIZE, nprot, *offset, curthread->td_ucred);
+		        if (*object == NULL)
+               			 return (EINVAL);
 		}
 	} else
 		error = ENODEV;
@@ -406,6 +427,8 @@ linux_dev_mmap(struct cdev *dev, vm_ooff
 	return (error);
 }
 
+
+
 struct cdevsw linuxcdevsw = {
 	.d_version = D_VERSION,
 	.d_flags = D_TRACKCLOSE,
@@ -414,6 +437,7 @@ struct cdevsw linuxcdevsw = {
 	.d_read = linux_dev_read,
 	.d_write = linux_dev_write,
 	.d_ioctl = linux_dev_ioctl,
+	.d_mmap_single = linux_dev_mmap_single,
 	.d_mmap = linux_dev_mmap,
 	.d_poll = linux_dev_poll,
 };



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201008242040.o7OKeC1O087142>