svn commit: r211770 - projects/ofed/head/sys/ofed/include/linux
Jeff Roberson
jeff at FreeBSD.org
Tue Aug 24 20:40:12 UTC 2010
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,
};
More information about the svn-src-projects
mailing list