X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Farm%2Fmm%2Fconsistent.c;h=57b0be2ab3c93f972324dbde0dfd0efb4401041c;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=f9b8fe2c75942068786ed8b1439c714ea77ffa03;hpb=a2c21200f1c81b08cb55e417b68150bba439b646;p=linux-2.6.git diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c index f9b8fe2c7..57b0be2ab 100644 --- a/arch/arm/mm/consistent.c +++ b/arch/arm/mm/consistent.c @@ -138,7 +138,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, int gfp, struct page *page; struct vm_region *c; unsigned long order; - u64 mask = 0x00ffffff, limit; /* ISA default */ + u64 mask = ISA_DMA_THRESHOLD, limit; if (!consistent_pte) { 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, if (dev) { 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) { 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); limit = (mask + 1) & ~mask; - if ((limit && size >= limit) || size >= (CONSISTENT_END - CONSISTENT_BASE)) { - printk(KERN_WARNING "coherent allocation too big (requested %#x mask %#Lx)\n", - size, mask); - *handle = ~0; - return NULL; + if ((limit && size >= limit) || + size >= (CONSISTENT_END - CONSISTENT_BASE)) { + printk(KERN_WARNING "coherent allocation too big " + "(requested %#x mask %#llx)\n", size, mask); + goto no_page; } order = get_order(size); @@ -221,6 +236,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, int gfp, if (page) __free_pages(page, order); no_page: + *handle = ~0; return NULL; }