Reimplement kvmem.[ch] code in comedi_fops
authorDavid Schleef <ds@schleef.org>
Thu, 21 Nov 2002 04:43:59 +0000 (04:43 +0000)
committerDavid Schleef <ds@schleef.org>
Thu, 21 Nov 2002 04:43:59 +0000 (04:43 +0000)
comedi/Makefile.in
comedi/comedi_fops.c
comedi/drivers.c

index 80e172c3f098341f87ed8ff41d3118bda371a029..428eff968f4426a6dc4e23b31f60fcd25d66a25f 100644 (file)
@@ -1,7 +1,7 @@
 
 expsyms(comedi_ksyms.o)
 
-objlink(comedi.o comedi_fops.o proc.o range.o drivers.o kvmem.o comedi_ksyms.o)
+objlink(comedi.o comedi_fops.o proc.o range.o drivers.o comedi_ksyms.o)
 
 ifsel(CONFIG_COMEDI_RT)
   objlink(comedi.o rt_pend_tq.o rt.o)
index af8ebd059dc1831ce6f3c613e1a844d192fb7b8e..efe29e9eeb5cb04c9ccc0ee4f43568eee5699f26 100644 (file)
 #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");
@@ -1199,16 +1200,20 @@ static struct vm_operations_struct comedi_vm_ops={
 };
 /*
    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)
        {
@@ -1225,20 +1230,38 @@ static int comedi_mmap_v22(struct file * file, struct vm_area_struct *vma)
                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;
index d79267059ed21598a04f0186795e03209a3827bb..c2c4e96626671ad6aaee129f80b40749c143bf7f 100644 (file)
 #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,
@@ -375,16 +376,42 @@ static int buf_alloc(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;