Fixed horrible grinding noises on mmap.
authorFrank Mori Hess <fmhess@speakeasy.net>
Tue, 1 May 2007 21:16:15 +0000 (21:16 +0000)
committerFrank Mori Hess <fmhess@speakeasy.net>
Tue, 1 May 2007 21:16:15 +0000 (21:16 +0000)
comedi/comedi_fops.c
comedi/drivers.c
comedi/drivers/mite.c

index c54b8ba1e7195ce61145cd37f86aef89f5b4d544..daa4b78856c354235a0a2bd01db0f8d155969f11 100644 (file)
@@ -1310,7 +1310,7 @@ static int comedi_mmap(struct file * file, struct vm_area_struct *vma)
 
        n_pages = size >> PAGE_SHIFT;
        for(i = 0; i < n_pages; ++i){
-               if(remap_pfn_range(vma, start, page_to_pfn(virt_to_page(async->prealloc_buf + PAGE_SIZE * i)),
+               if(remap_pfn_range(vma, start, page_to_pfn(virt_to_page(async->buf_page_list[i].virt_addr)),
                                PAGE_SIZE, PAGE_SHARED)){
                        return -EAGAIN;
                }
index 293fdfc4574fcf9c2d24b34b60307105ae1d1ac7..e96cd2d36fc0cd875434717ae4bffa767a6097cd 100644 (file)
@@ -432,25 +432,11 @@ int comedi_buf_alloc(comedi_device *dev, comedi_subdevice *s,
        unsigned long new_size)
 {
        comedi_async *async = s->async;
-       unsigned long adr;
 
        /* if no change is required, do nothing */
        if(async->prealloc_buf && async->prealloc_bufsz == new_size){
                return 0;
        }
-       // cleanup old buffer
-       if(async->prealloc_bufsz)
-       {
-               int i;
-               unsigned n_pages = async->prealloc_bufsz >> PAGE_SHIFT;
-
-               adr = (unsigned long) async->prealloc_buf;
-               for(i = 0; i < n_pages; i++){
-                       mem_map_unreserve(virt_to_page(adr));
-                       adr += PAGE_SIZE;
-               }
-               async->prealloc_bufsz = 0;
-       }
        if(async->prealloc_buf)
        {
                if(s->async_dma_dir != DMA_NONE)
@@ -461,6 +447,7 @@ int comedi_buf_alloc(comedi_device *dev, comedi_subdevice *s,
                        vfree(async->prealloc_buf);
                }
                async->prealloc_buf = NULL;
+               async->prealloc_bufsz = 0;
        }
        if(async->buf_page_list)
        {
@@ -468,6 +455,8 @@ int comedi_buf_alloc(comedi_device *dev, comedi_subdevice *s,
                for(i = 0; i < async->n_buf_pages; ++i)
                {
                        if(async->buf_page_list[i].virt_addr)
+                               mem_map_unreserve(virt_to_page(async->buf_page_list[i].virt_addr));
+                       if(async->buf_page_list[i].dma_addr)
                        {
                                dma_free_coherent(dev->hw_dev, PAGE_SIZE,
                                        async->buf_page_list[i].virt_addr, async->buf_page_list[i].dma_addr);
@@ -485,18 +474,18 @@ int comedi_buf_alloc(comedi_device *dev, comedi_subdevice *s,
                // size is rounded up to nearest multiple of PAGE_SIZE
                new_size = n_pages << PAGE_SHIFT;
 
+               async->buf_page_list = vmalloc(sizeof(struct comedi_buf_page) * n_pages);
+               if(async->buf_page_list == NULL)
+               {
+                       return -ENOMEM;
+               }
+               memset(async->buf_page_list, 0, sizeof(struct comedi_buf_page) * n_pages);
+               async->n_buf_pages = n_pages;
+
                if(s->async_dma_dir != DMA_NONE)
                {
                        struct page** pages = NULL;
 
-                       async->buf_page_list = vmalloc(sizeof(struct comedi_buf_page) * n_pages);
-                       if(async->buf_page_list == NULL)
-                       {
-                               return -ENOMEM;
-                       }
-                       memset(async->buf_page_list, 0, sizeof(struct comedi_buf_page) * n_pages);
-                       async->n_buf_pages = n_pages;
-
                        pages = vmalloc(sizeof(struct page*) * n_pages);
                        if(pages == NULL)
                        {
@@ -511,6 +500,7 @@ int comedi_buf_alloc(comedi_device *dev, comedi_subdevice *s,
                                        vfree(pages);
                                        return -ENOMEM;
                                }
+                               mem_map_reserve(virt_to_page(async->buf_page_list[i].virt_addr));
                                pages[i] = virt_to_page(async->buf_page_list[i].virt_addr);
                        }
                        async->prealloc_buf = vmap(pages, n_pages, VM_MAP, PAGE_KERNEL_NOCACHE);
@@ -523,13 +513,11 @@ int comedi_buf_alloc(comedi_device *dev, comedi_subdevice *s,
                        {
                                return -ENOMEM;
                        }
-               }
-
-               adr = (unsigned long)async->prealloc_buf;
-               for(i = 0; i < n_pages; i++)
-               {
-                       mem_map_reserve(virt_to_page(adr));
-                       adr += PAGE_SIZE;
+                       for(i = 0; i < n_pages; i++)
+                       {
+                               async->buf_page_list[i].virt_addr = async->prealloc_buf + PAGE_SIZE * i;
+                               mem_map_reserve(virt_to_page(async->buf_page_list[i].virt_addr));
+                       }
                }
        }
        async->prealloc_bufsz = new_size;
index 6b4f3e82d96390139efd019ae7a6322f135e5872..55d9511a7f526f863403e7ecad737399b8550916 100644 (file)
@@ -520,7 +520,7 @@ int mite_sync_output_dma(struct mite_channel *mite_chan, comedi_async *async)
        u32 nbytes_ub, nbytes_lb;
        unsigned int old_alloc_count;
        u32 stop_count = async->cmd.stop_arg * bytes_per_sample(async->subdevice) *
-               async->cmd.chanlist_len;
+               async->cmd.chanlist_len;        //FIXME will be wrong for digital commands
 
        old_alloc_count = async->buf_read_alloc_count;
        // read alloc as much as we can