#include <linux/poll.h>
#include <linux/init.h>
#include <linux/devfs_fs_kernel.h>
+#include <linux/vmalloc.h>
#include <linux/comedidev.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#include "kvmem.h"
+//#include "kvmem.h"
MODULE_AUTHOR("David Schleef <ds@schleef.org>");
MODULE_DESCRIPTION("Comedi core module");
};
/*
comedi_mmap_v22
-
- issues:
- what happens when the underlying buffer gets changed?
-
*/
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,17)
+#define page_address(x) x
+#endif
+
static int comedi_mmap_v22(struct file * file, struct vm_area_struct *vma)
{
kdev_t minor=MINOR(RDEV_OF_FILE(file));
comedi_device *dev=comedi_get_device_by_minor(minor);
comedi_async *async = NULL;
+ unsigned long pos;
+ unsigned long start = vma->vm_start;
+ unsigned long size;
+ unsigned long page;
if(!dev->attached)
{
return -EINVAL;
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
+#if LINUX_VERSION_CODE < 0x020300
if(vma->vm_offset != 0){
+ DPRINTK("comedi: mmap() offset must be 0.\n");
+ return -EINVAL;
+ }
#else
if(vma->vm_pgoff != 0){
-#endif
DPRINTK("comedi: mmap() offset must be 0.\n");
return -EINVAL;
}
+#endif
+
+ size = vma->vm_end - vma->vm_start;
+ if(size>=async->prealloc_bufsz)
+ return -EFAULT;
+ if(size&(~PAGE_MASK))
+ return -EFAULT;
- rvmmap(async->prealloc_buf,async->prealloc_bufsz,vma);
+ pos = (unsigned long)async->prealloc_buf;
+ while(size>0){
+ page = kvirt_to_pa(pos);
+ if(remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)){
+ return -EAGAIN;
+ }
+
+ pos += PAGE_SIZE;
+ start += PAGE_SIZE;
+ size -= PAGE_SIZE;
+ }
- //vma->vm_file = file;
vma->vm_ops = &comedi_vm_ops;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,17)
+#if LINUX_VERSION_CODE < 0x020300
(void *)vma->vm_pte = async;
#else
vma->vm_private_data = async;
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/comedidev.h>
+#include <linux/wrapper.h>
#include <asm/io.h>
-#include "kvmem.h"
+//#include "kvmem.h"
static int postconfig(comedi_device *dev);
static int insn_rw_emulate_bits(comedi_device *dev,comedi_subdevice *s,
}
if(async->prealloc_bufsz){
- rvfree(async->prealloc_buf, async->prealloc_bufsz);
+ unsigned long adr, size;
+ unsigned long page;
+
+ size = async->prealloc_bufsz;
+ adr = (unsigned long)async->prealloc_buf;
+ while(size>0){
+ page = kvirt_to_pa(adr);
+ mem_map_unreserve(virt_to_page(__va(page)));
+ adr += PAGE_SIZE;
+ size -= PAGE_SIZE;
+ }
+
+ vfree(async->prealloc_buf);
async->prealloc_buf = NULL;
}
if(new_size){
- async->prealloc_buf = rvmalloc(new_size);
+ unsigned long adr;
+ unsigned long size;
+ unsigned long page;
+
+ async->prealloc_buf = vmalloc_32(new_size);
if(async->prealloc_buf == NULL){
async->prealloc_bufsz = 0;
return -ENOMEM;
}
+ memset(async->prealloc_buf,0,new_size);
+
+ adr = (unsigned long)async->prealloc_buf;
+ size = new_size;
+ while(size > 0){
+ page = kvirt_to_pa(adr);
+ mem_map_reserve(virt_to_page(__va(page)));
+ adr += PAGE_SIZE;
+ size -= PAGE_SIZE;
+ }
}
async->prealloc_bufsz = new_size;