Commit 9406a49f authored by Christoph Hellwig's avatar Christoph Hellwig

dma-mapping: support non-coherent devices in dma_common_get_sgtable

We can use the arch_dma_coherent_to_pfn hook to provide a ->get_sgtable
implementation.  Note that this isn't an endorsement of this interface
(which is a horrible bad idea), but it is required to move arm64 over
to the generic code without a loss of functionality.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent 58b04406
...@@ -689,7 +689,7 @@ xen_swiotlb_get_sgtable(struct device *dev, struct sg_table *sgt, ...@@ -689,7 +689,7 @@ xen_swiotlb_get_sgtable(struct device *dev, struct sg_table *sgt,
handle, size, attrs); handle, size, attrs);
} }
#endif #endif
return dma_common_get_sgtable(dev, sgt, cpu_addr, handle, size); return dma_common_get_sgtable(dev, sgt, cpu_addr, handle, size, attrs);
} }
static int xen_swiotlb_mapping_error(struct device *dev, dma_addr_t dma_addr) static int xen_swiotlb_mapping_error(struct device *dev, dma_addr_t dma_addr)
......
...@@ -483,8 +483,8 @@ dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr, ...@@ -483,8 +483,8 @@ dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr,
#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, 0) #define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, 0)
int int
dma_common_get_sgtable(struct device *dev, struct sg_table *sgt, dma_common_get_sgtable(struct device *dev, struct sg_table *sgt, void *cpu_addr,
void *cpu_addr, dma_addr_t dma_addr, size_t size); dma_addr_t dma_addr, size_t size, unsigned long attrs);
static inline int static inline int
dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr, dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
...@@ -496,7 +496,8 @@ dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr, ...@@ -496,7 +496,8 @@ dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
if (ops->get_sgtable) if (ops->get_sgtable)
return ops->get_sgtable(dev, sgt, cpu_addr, dma_addr, size, return ops->get_sgtable(dev, sgt, cpu_addr, dma_addr, size,
attrs); attrs);
return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr, size); return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr, size,
attrs);
} }
#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, 0) #define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, 0)
......
...@@ -202,17 +202,26 @@ EXPORT_SYMBOL(dmam_release_declared_memory); ...@@ -202,17 +202,26 @@ EXPORT_SYMBOL(dmam_release_declared_memory);
* Create scatter-list for the already allocated DMA buffer. * Create scatter-list for the already allocated DMA buffer.
*/ */
int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt, int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
void *cpu_addr, dma_addr_t handle, size_t size) void *cpu_addr, dma_addr_t dma_addr, size_t size,
unsigned long attrs)
{ {
struct page *page = virt_to_page(cpu_addr); struct page *page;
int ret; int ret;
ret = sg_alloc_table(sgt, 1, GFP_KERNEL); if (!dev_is_dma_coherent(dev)) {
if (unlikely(ret)) if (!IS_ENABLED(CONFIG_ARCH_HAS_DMA_COHERENT_TO_PFN))
return ret; return -ENXIO;
page = pfn_to_page(arch_dma_coherent_to_pfn(dev, cpu_addr,
dma_addr));
} else {
page = virt_to_page(cpu_addr);
}
ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
if (!ret)
sg_set_page(sgt->sgl, page, PAGE_ALIGN(size), 0); sg_set_page(sgt->sgl, page, PAGE_ALIGN(size), 0);
return 0; return ret;
} }
EXPORT_SYMBOL(dma_common_get_sgtable); EXPORT_SYMBOL(dma_common_get_sgtable);
......
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