]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - lib/swiotlb.c
tracing: disable tracepoints by default
[linux-2.6-omap-h63xx.git] / lib / swiotlb.c
index 2fb485d0e7eb7d445a36288a86db658106ba1a08..f8eebd489149e5c0cd7177ce98a5246bc25b32f3 100644 (file)
@@ -274,13 +274,14 @@ cleanup1:
 }
 
 static int
-address_needs_mapping(struct device *hwdev, dma_addr_t addr)
+address_needs_mapping(struct device *hwdev, dma_addr_t addr, size_t size)
 {
-       dma_addr_t mask = 0xffffffff;
-       /* If the device has a mask, use it, otherwise default to 32 bits */
-       if (hwdev && hwdev->dma_mask)
-               mask = *hwdev->dma_mask;
-       return (addr & ~mask) != 0;
+       return !is_buffer_dma_capable(dma_get_mask(hwdev), addr, size);
+}
+
+static int is_swiotlb_buffer(char *addr)
+{
+       return addr >= io_tlb_start && addr < io_tlb_end;
 }
 
 /*
@@ -468,7 +469,7 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size,
        int order = get_order(size);
 
        ret = (void *)__get_free_pages(flags, order);
-       if (ret && address_needs_mapping(hwdev, virt_to_bus(ret))) {
+       if (ret && address_needs_mapping(hwdev, virt_to_bus(ret), size)) {
                /*
                 * The allocated memory isn't reachable by the device.
                 * Fall back on swiotlb_map_single().
@@ -492,7 +493,7 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size,
        dev_addr = virt_to_bus(ret);
 
        /* Confirm address can be DMA'd by device */
-       if (address_needs_mapping(hwdev, dev_addr)) {
+       if (address_needs_mapping(hwdev, dev_addr, size)) {
                printk("hwdev DMA mask = 0x%016Lx, dev_addr = 0x%016Lx\n",
                       (unsigned long long)*hwdev->dma_mask,
                       (unsigned long long)dev_addr);
@@ -508,12 +509,11 @@ swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
                      dma_addr_t dma_handle)
 {
        WARN_ON(irqs_disabled());
-       if (!(vaddr >= (void *)io_tlb_start
-                    && vaddr < (void *)io_tlb_end))
+       if (!is_swiotlb_buffer(vaddr))
                free_pages((unsigned long) vaddr, get_order(size));
        else
                /* DMA_TO_DEVICE to avoid memcpy in unmap_single */
-               swiotlb_unmap_single (hwdev, dma_handle, size, DMA_TO_DEVICE);
+               unmap_single(hwdev, vaddr, size, DMA_TO_DEVICE);
 }
 
 static void
@@ -557,7 +557,7 @@ swiotlb_map_single_attrs(struct device *hwdev, void *ptr, size_t size,
         * we can safely return the device addr and not worry about bounce
         * buffering it.
         */
-       if (!address_needs_mapping(hwdev, dev_addr) && !swiotlb_force)
+       if (!address_needs_mapping(hwdev, dev_addr, size) && !swiotlb_force)
                return dev_addr;
 
        /*
@@ -574,7 +574,7 @@ swiotlb_map_single_attrs(struct device *hwdev, void *ptr, size_t size,
        /*
         * Ensure that the address returned is DMA'ble
         */
-       if (address_needs_mapping(hwdev, dev_addr))
+       if (address_needs_mapping(hwdev, dev_addr, size))
                panic("map_single: bounce buffer is not DMA'ble");
 
        return dev_addr;
@@ -602,7 +602,7 @@ swiotlb_unmap_single_attrs(struct device *hwdev, dma_addr_t dev_addr,
        char *dma_addr = bus_to_virt(dev_addr);
 
        BUG_ON(dir == DMA_NONE);
-       if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end)
+       if (is_swiotlb_buffer(dma_addr))
                unmap_single(hwdev, dma_addr, size, dir);
        else if (dir == DMA_FROM_DEVICE)
                dma_mark_clean(dma_addr, size);
@@ -632,7 +632,7 @@ swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr,
        char *dma_addr = bus_to_virt(dev_addr);
 
        BUG_ON(dir == DMA_NONE);
-       if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end)
+       if (is_swiotlb_buffer(dma_addr))
                sync_single(hwdev, dma_addr, size, dir, target);
        else if (dir == DMA_FROM_DEVICE)
                dma_mark_clean(dma_addr, size);
@@ -663,7 +663,7 @@ swiotlb_sync_single_range(struct device *hwdev, dma_addr_t dev_addr,
        char *dma_addr = bus_to_virt(dev_addr) + offset;
 
        BUG_ON(dir == DMA_NONE);
-       if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end)
+       if (is_swiotlb_buffer(dma_addr))
                sync_single(hwdev, dma_addr, size, dir, target);
        else if (dir == DMA_FROM_DEVICE)
                dma_mark_clean(dma_addr, size);
@@ -717,7 +717,8 @@ swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
        for_each_sg(sgl, sg, nelems, i) {
                addr = SG_ENT_VIRT_ADDRESS(sg);
                dev_addr = virt_to_bus(addr);
-               if (swiotlb_force || address_needs_mapping(hwdev, dev_addr)) {
+               if (swiotlb_force ||
+                   address_needs_mapping(hwdev, dev_addr, sg->length)) {
                        void *map = map_single(hwdev, addr, sg->length, dir);
                        if (!map) {
                                /* Don't panic here, we expect map_sg users