aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/comedi
diff options
context:
space:
mode:
authorIan Abbott <abbotti@mev.co.uk>2014-09-12 10:04:43 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-09-19 15:36:25 -0700
commitf39f87e9ea944ca07b53d8261ba60bfbf4f097da (patch)
treeb2f8014cd3c9bc232cc49f165f5146eef545520c /drivers/staging/comedi
parentstaging: comedi: adl_pci9118: don't allocate 2nd DMA buffer on failure (diff)
downloadlinux-dev-f39f87e9ea944ca07b53d8261ba60bfbf4f097da.tar.xz
linux-dev-f39f87e9ea944ca07b53d8261ba60bfbf4f097da.zip
staging: comedi: adl_pci9118: don't overallocate DMA buffer
The last parameter of `__get_free_pages()` is log2 (the 'order') of the number of pages to be allocated. This driver seems to think it is the linear number of pages, so `pci9118_alloc_dma()` first tries to allocate 16 pages, but only uses 4 of them, setting the buffer size to PAGE_SIZE multiplied by the 'order'. If the allocation fails, it tries progressively smaller orders, down to 0. If the allocation at order 0 succeeds, the buffer size is set to 0, which is likely to cause problems. Set the buffer size to `PAGE_SIZE` shifted left by the allocation order. Since the maximum buffer size previously used was 4, start with an allocation order of 2 instead of 4. Rename the `pages` member of `struct pci9118_dmabuf` (and the local variable in `pci9118_alloc_dma()`) to `order` to make it clearer what it is. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/comedi')
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9118.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c
index 116910401067..6ab9e0a27588 100644
--- a/drivers/staging/comedi/drivers/adl_pci9118.c
+++ b/drivers/staging/comedi/drivers/adl_pci9118.c
@@ -208,7 +208,7 @@ struct pci9118_dmabuf {
unsigned long hw; /* hardware (bus) address of buffer */
unsigned int size; /* size of dma buffer in bytes */
unsigned int use_size; /* which size we may now use for transfer */
- int pages; /* number of pages in buffer */
+ int order; /* log2 number of pages in buffer */
};
struct pci9118_private {
@@ -1479,20 +1479,20 @@ static void pci9118_alloc_dma(struct comedi_device *dev)
{
struct pci9118_private *devpriv = dev->private;
struct pci9118_dmabuf *dmabuf;
- int pages;
+ int order;
int i;
for (i = 0; i < 2; i++) {
dmabuf = &devpriv->dmabuf[i];
- for (pages = 4; pages >= 0; pages--) {
- dmabuf->virt = __get_free_pages(GFP_KERNEL, pages);
+ for (order = 2; order >= 0; order--) {
+ dmabuf->virt = __get_free_pages(GFP_KERNEL, order);
if (dmabuf->virt)
break;
}
if (!dmabuf->virt)
break;
- dmabuf->pages = pages;
- dmabuf->size = PAGE_SIZE * pages;
+ dmabuf->order = order;
+ dmabuf->size = PAGE_SIZE << order;
dmabuf->hw = virt_to_bus((void *)dmabuf->virt);
if (i == 0)
@@ -1514,7 +1514,7 @@ static void pci9118_free_dma(struct comedi_device *dev)
for (i = 0; i < 2; i++) {
dmabuf = &devpriv->dmabuf[i];
if (dmabuf->virt)
- free_pages(dmabuf->virt, dmabuf->pages);
+ free_pages(dmabuf->virt, dmabuf->order);
}
}