Commit c6d508b9 authored by Russell King's avatar Russell King

[ARM] Fix consistent.c for DMA allocations.

- Use ISA_DMA_THRESHOLD as the mask for GFP_DMA allocations.
- Don't allow DMA allocations which are for a "smaller" mask than
  ISA_DMA_THRESHOLD.
- Ensure that "handle" is initialised to our error value when
  returning an error.
parent 4b006a3b
...@@ -138,7 +138,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, int gfp, ...@@ -138,7 +138,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, int gfp,
struct page *page; struct page *page;
struct vm_region *c; struct vm_region *c;
unsigned long order; unsigned long order;
u64 mask = 0x00ffffff, limit; /* ISA default */ u64 mask = ISA_DMA_THRESHOLD, limit;
if (!consistent_pte) { if (!consistent_pte) {
printk(KERN_ERR "%s: not initialised\n", __func__); printk(KERN_ERR "%s: not initialised\n", __func__);
...@@ -148,19 +148,34 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, int gfp, ...@@ -148,19 +148,34 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, int gfp,
if (dev) { if (dev) {
mask = dev->coherent_dma_mask; mask = dev->coherent_dma_mask;
/*
* Sanity check the DMA mask - it must be non-zero, and
* must be able to be satisfied by a DMA allocation.
*/
if (mask == 0) { if (mask == 0) {
dev_warn(dev, "coherent DMA mask is unset\n"); dev_warn(dev, "coherent DMA mask is unset\n");
return NULL; goto no_page;
}
if ((~mask) & ISA_DMA_THRESHOLD) {
dev_warn(dev, "coherent DMA mask %#llx is smaller "
"than system GFP_DMA mask %#llx\n",
mask, (unsigned long long)ISA_DMA_THRESHOLD);
goto no_page;
} }
} }
/*
* Sanity check the allocation size.
*/
size = PAGE_ALIGN(size); size = PAGE_ALIGN(size);
limit = (mask + 1) & ~mask; limit = (mask + 1) & ~mask;
if ((limit && size >= limit) || size >= (CONSISTENT_END - CONSISTENT_BASE)) { if ((limit && size >= limit) ||
printk(KERN_WARNING "coherent allocation too big (requested %#x mask %#Lx)\n", size >= (CONSISTENT_END - CONSISTENT_BASE)) {
size, mask); printk(KERN_WARNING "coherent allocation too big "
*handle = ~0; "(requested %#x mask %#llx)\n", size, mask);
return NULL; goto no_page;
} }
order = get_order(size); order = get_order(size);
...@@ -221,6 +236,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, int gfp, ...@@ -221,6 +236,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, int gfp,
if (page) if (page)
__free_pages(page, order); __free_pages(page, order);
no_page: no_page:
*handle = ~0;
return NULL; return NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment