]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - lib/swiotlb.c
h63xx: nfs mount works, gpe image boots to ts config screen.
[linux-2.6-omap-h63xx.git] / lib / swiotlb.c
index f8eebd489149e5c0cd7177ce98a5246bc25b32f3..5f6c629a924d8da3a5e126b6fa76e12e562fe768 100644 (file)
@@ -467,9 +467,13 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size,
        dma_addr_t dev_addr;
        void *ret;
        int order = get_order(size);
+       u64 dma_mask = DMA_32BIT_MASK;
+
+       if (hwdev && hwdev->coherent_dma_mask)
+               dma_mask = hwdev->coherent_dma_mask;
 
        ret = (void *)__get_free_pages(flags, order);
-       if (ret && address_needs_mapping(hwdev, virt_to_bus(ret), size)) {
+       if (ret && !is_buffer_dma_capable(dma_mask, virt_to_bus(ret), size)) {
                /*
                 * The allocated memory isn't reachable by the device.
                 * Fall back on swiotlb_map_single().
@@ -493,12 +497,14 @@ 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, size)) {
+       if (!is_buffer_dma_capable(dma_mask, dev_addr, size)) {
                printk("hwdev DMA mask = 0x%016Lx, dev_addr = 0x%016Lx\n",
-                      (unsigned long long)*hwdev->dma_mask,
+                      (unsigned long long)dma_mask,
                       (unsigned long long)dev_addr);
-               panic("swiotlb_alloc_coherent: allocated memory is out of "
-                     "range for device");
+
+               /* DMA_TO_DEVICE to avoid memcpy in unmap_single */
+               unmap_single(hwdev, ret, size, DMA_TO_DEVICE);
+               return NULL;
        }
        *dma_handle = dev_addr;
        return ret;