summaryrefslogtreecommitdiffstats
path: root/driver/dev.c
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@suren.me>2016-05-14 01:10:33 +0200
committerSuren A. Chilingaryan <csa@suren.me>2016-05-14 01:10:33 +0200
commita21dea7a0d06cbdfe9a94c88b1ba99425bf2e102 (patch)
tree1c08af911cef8869ed1eb90902f89db83b524c53 /driver/dev.c
parent71f64d82453f5c86dd40104839d98fc12ae44ddf (diff)
downloadpcitool-a21dea7a0d06cbdfe9a94c88b1ba99425bf2e102.tar.gz
pcitool-a21dea7a0d06cbdfe9a94c88b1ba99425bf2e102.tar.bz2
pcitool-a21dea7a0d06cbdfe9a94c88b1ba99425bf2e102.tar.xz
pcitool-a21dea7a0d06cbdfe9a94c88b1ba99425bf2e102.zip
Allow mapping of arbitrary memory areas
Diffstat (limited to 'driver/dev.c')
-rw-r--r--driver/dev.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/driver/dev.c b/driver/dev.c
index 1292110..75b2516 100644
--- a/driver/dev.c
+++ b/driver/dev.c
@@ -127,6 +127,35 @@ static int pcidriver_mmap_bar(pcidriver_privdata_t *privdata, struct vm_area_str
#endif /* PCIDRIVER_DUMMY_DEVICE */
}
+
+static int pcidriver_mmap_area(pcidriver_privdata_t *privdata, struct vm_area_struct *vmap)
+{
+ int ret = 0;
+
+ unsigned long vma_size;
+ unsigned long addr = vmap->vm_pgoff;
+
+ mod_info_dbg("Entering mmap_addr\n");
+
+ /* Check sizes */
+ vma_size = (vmap->vm_end - vmap->vm_start);
+
+ if (addr % PAGE_SIZE) {
+ mod_info("mmap addr (0x%lx) is not aligned to page boundary\n", addr);
+ return -EINVAL;
+ }
+
+ ret = remap_pfn_range(vmap, vmap->vm_start, (addr >> PAGE_SHIFT), vma_size, vmap->vm_page_prot);
+
+ if (ret) {
+ mod_info("remap_pfn_range failed\n");
+ return -EAGAIN;
+ }
+
+ return 0; /* success */
+}
+
+
/**
*
* This function is the entry point for mmap() and calls either pcidriver_mmap_bar
@@ -156,6 +185,9 @@ static int pcidriver_mmap(struct file *filp, struct vm_area_struct *vma)
}
ret = pcidriver_mmap_bar(privdata, vma, bar);
break;
+ case PCIDRIVER_MMAP_AREA:
+ ret = pcidriver_mmap_area(privdata, vma);
+ break;
case PCIDRIVER_MMAP_KMEM:
ret = pcidriver_mmap_kmem(privdata, vma);
break;