gcov: enable GCOV_PROFILE_ALL for x86_64
[linux-2.6.git] / kernel / dma-coherent.c
index 0387074..962a3b5 100644 (file)
@@ -98,7 +98,7 @@ EXPORT_SYMBOL(dma_mark_declared_memory_occupied);
  * @size:      size of requested memory area
  * @dma_handle:        This will be filled with the correct dma handle
  * @ret:       This pointer will be filled with the virtual address
- *             to allocated area.
+ *             to allocated area.
  *
  * This function should be only called from per-arch dma_alloc_coherent()
  * to support allocation from per-device coherent memory pools.
@@ -118,31 +118,32 @@ int dma_alloc_from_coherent(struct device *dev, ssize_t size,
        mem = dev->dma_mem;
        if (!mem)
                return 0;
-       if (unlikely(size > mem->size))
-               return 0;
+
+       *ret = NULL;
+
+       if (unlikely(size > (mem->size << PAGE_SHIFT)))
+               goto err;
 
        pageno = bitmap_find_free_region(mem->bitmap, mem->size, order);
-       if (pageno >= 0) {
-               /*
-                * Memory was found in the per-device arena.
-                */
-               *dma_handle = mem->device_base + (pageno << PAGE_SHIFT);
-               *ret = mem->virt_base + (pageno << PAGE_SHIFT);
-               memset(*ret, 0, size);
-       } else if (mem->flags & DMA_MEMORY_EXCLUSIVE) {
-               /*
-                * The per-device arena is exhausted and we are not
-                * permitted to fall back to generic memory.
-                */
-               *ret = NULL;
-       } else {
-               /*
-                * The per-device arena is exhausted and we are
-                * permitted to fall back to generic memory.
-                */
-                return 0;
-       }
+       if (unlikely(pageno < 0))
+               goto err;
+
+       /*
+        * Memory was found in the per-device area.
+        */
+       *dma_handle = mem->device_base + (pageno << PAGE_SHIFT);
+       *ret = mem->virt_base + (pageno << PAGE_SHIFT);
+       memset(*ret, 0, size);
+
        return 1;
+
+err:
+       /*
+        * In the case where the allocation can not be satisfied from the
+        * per-device area, try to fall back to generic memory if the
+        * constraints allow it.
+        */
+       return mem->flags & DMA_MEMORY_EXCLUSIVE;
 }
 EXPORT_SYMBOL(dma_alloc_from_coherent);