diff options
author | H Hartley Sweeten <hsweeten@visionengravers.com> | 2013-01-09 13:26:26 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-01-17 16:53:58 -0800 |
commit | 6bd764573179f3f7c165b1ee093aff2d7ad3c59e (patch) | |
tree | 20760eb69560c6ed39338908ae2839bdcb71c720 /drivers/staging/comedi/comedi_buf.c | |
parent | 718c4d68d9491e8bc16a614d193b257efc41723e (diff) |
staging: comedi: comedi_buf: factor out new buffer allocation code
The function comedi_buf_alloc() first frees any allocated buffer then,
optionally, allocates a new buffer.
Factor out the new buffer allocation code to a new function. This
allows reducing the indent level and makes the code a bit cleaner.
Also, cleanup to factored out code to make it a bit more concise.
Use a local variable for the current comedi_buf_page being allocated.
This cleans up the ugly line breaks used to keep the lines < 80 chars.
Move the #ifdef'ery for the page protection determination out of the
vmap() call.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/comedi/comedi_buf.c')
-rw-r--r-- | drivers/staging/comedi/comedi_buf.c | 97 |
1 files changed, 52 insertions, 45 deletions
diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index 3f01b0badd0..2fc89816f10 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -22,6 +22,12 @@ #include "comedidev.h" #include "comedi_internal.h" +#ifdef PAGE_KERNEL_NOCACHE +#define COMEDI_PAGE_PROTECTION PAGE_KERNEL_NOCACHE +#else +#define COMEDI_PAGE_PROTECTION PAGE_KERNEL +#endif + static void __comedi_buf_free(struct comedi_device *dev, struct comedi_subdevice *s, unsigned n_pages) @@ -59,6 +65,48 @@ static void __comedi_buf_free(struct comedi_device *dev, async->n_buf_pages = 0; } +static void __comedi_buf_alloc(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned n_pages) +{ + struct comedi_async *async = s->async; + struct page **pages = NULL; + struct comedi_buf_page *buf; + unsigned i; + + async->buf_page_list = vzalloc(sizeof(*buf) * n_pages); + if (async->buf_page_list) + pages = vmalloc(sizeof(struct page *) * n_pages); + + if (!pages) + return; + + for (i = 0; i < n_pages; i++) { + buf = &async->buf_page_list[i]; + if (s->async_dma_dir != DMA_NONE) + buf->virt_addr = dma_alloc_coherent(dev->hw_dev, + PAGE_SIZE, + &buf->dma_addr, + GFP_KERNEL | + __GFP_COMP); + else + buf->virt_addr = (void *)get_zeroed_page(GFP_KERNEL); + if (!buf->virt_addr) + break; + + set_bit(PG_reserved, &(virt_to_page(buf->virt_addr)->flags)); + + pages[i] = virt_to_page(buf->virt_addr); + } + + /* vmap the prealloc_buf if all the pages were allocated */ + if (i == n_pages) + async->prealloc_buf = vmap(pages, n_pages, VM_MAP, + COMEDI_PAGE_PROTECTION); + + vfree(pages); +} + int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size) { @@ -74,55 +122,14 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, /* deallocate old buffer */ __comedi_buf_free(dev, s, async->n_buf_pages); - /* allocate new buffer */ + /* allocate new buffer */ if (new_size) { - unsigned i = 0; unsigned n_pages = new_size >> PAGE_SHIFT; - struct page **pages = NULL; - - async->buf_page_list = - vzalloc(sizeof(struct comedi_buf_page) * n_pages); - if (async->buf_page_list) - pages = vmalloc(sizeof(struct page *) * n_pages); - - if (pages) { - for (i = 0; i < n_pages; i++) { - if (s->async_dma_dir != DMA_NONE) { - async->buf_page_list[i].virt_addr = - dma_alloc_coherent(dev->hw_dev, - PAGE_SIZE, - &async-> - buf_page_list - [i].dma_addr, - GFP_KERNEL | - __GFP_COMP); - } else { - async->buf_page_list[i].virt_addr = - (void *) - get_zeroed_page(GFP_KERNEL); - } - if (async->buf_page_list[i].virt_addr == NULL) - break; - - set_bit(PG_reserved, - &(virt_to_page(async->buf_page_list[i]. - virt_addr)->flags)); - pages[i] = virt_to_page(async->buf_page_list[i]. - virt_addr); - } - } - if (i == n_pages) { - async->prealloc_buf = -#ifdef PAGE_KERNEL_NOCACHE - vmap(pages, n_pages, VM_MAP, PAGE_KERNEL_NOCACHE); -#else - vmap(pages, n_pages, VM_MAP, PAGE_KERNEL); -#endif - } - vfree(pages); + + __comedi_buf_alloc(dev, s, n_pages); if (!async->prealloc_buf) { - /* Some allocation failed above */ + /* allocation failed */ __comedi_buf_free(dev, s, n_pages); return -ENOMEM; } |