aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/xen/swiotlb-xen.c2
-rw-r--r--include/linux/dma-mapping.h7
-rw-r--r--kernel/dma/mapping.c23
3 files changed, 21 insertions, 11 deletions
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index 470757ddddea..28819a0e61d0 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -689,7 +689,7 @@ xen_swiotlb_get_sgtable(struct device *dev, struct sg_table *sgt,
689 handle, size, attrs); 689 handle, size, attrs);
690 } 690 }
691#endif 691#endif
692 return dma_common_get_sgtable(dev, sgt, cpu_addr, handle, size); 692 return dma_common_get_sgtable(dev, sgt, cpu_addr, handle, size, attrs);
693} 693}
694 694
695static int xen_swiotlb_mapping_error(struct device *dev, dma_addr_t dma_addr) 695static int xen_swiotlb_mapping_error(struct device *dev, dma_addr_t dma_addr)
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index c3378d4e0d57..bd81e74cca7b 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -483,8 +483,8 @@ dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr,
483#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, 0) 483#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, 0)
484 484
485int 485int
486dma_common_get_sgtable(struct device *dev, struct sg_table *sgt, 486dma_common_get_sgtable(struct device *dev, struct sg_table *sgt, void *cpu_addr,
487 void *cpu_addr, dma_addr_t dma_addr, size_t size); 487 dma_addr_t dma_addr, size_t size, unsigned long attrs);
488 488
489static inline int 489static inline int
490dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr, 490dma_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 if (ops->get_sgtable) 496 if (ops->get_sgtable)
497 return ops->get_sgtable(dev, sgt, cpu_addr, dma_addr, size, 497 return ops->get_sgtable(dev, sgt, cpu_addr, dma_addr, size,
498 attrs); 498 attrs);
499 return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr, size); 499 return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr, size,
500 attrs);
500} 501}
501 502
502#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, 0) 503#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, 0)
diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
index 42fd73aca305..58dec7a92b7b 100644
--- a/kernel/dma/mapping.c
+++ b/kernel/dma/mapping.c
@@ -202,17 +202,26 @@ EXPORT_SYMBOL(dmam_release_declared_memory);
202 * Create scatter-list for the already allocated DMA buffer. 202 * Create scatter-list for the already allocated DMA buffer.
203 */ 203 */
204int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt, 204int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
205 void *cpu_addr, dma_addr_t handle, size_t size) 205 void *cpu_addr, dma_addr_t dma_addr, size_t size,
206 unsigned long attrs)
206{ 207{
207 struct page *page = virt_to_page(cpu_addr); 208 struct page *page;
208 int ret; 209 int ret;
209 210
210 ret = sg_alloc_table(sgt, 1, GFP_KERNEL); 211 if (!dev_is_dma_coherent(dev)) {
211 if (unlikely(ret)) 212 if (!IS_ENABLED(CONFIG_ARCH_HAS_DMA_COHERENT_TO_PFN))
212 return ret; 213 return -ENXIO;
213 214
214 sg_set_page(sgt->sgl, page, PAGE_ALIGN(size), 0); 215 page = pfn_to_page(arch_dma_coherent_to_pfn(dev, cpu_addr,
215 return 0; 216 dma_addr));
217 } else {
218 page = virt_to_page(cpu_addr);
219 }
220
221 ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
222 if (!ret)
223 sg_set_page(sgt->sgl, page, PAGE_ALIGN(size), 0);
224 return ret;
216} 225}
217EXPORT_SYMBOL(dma_common_get_sgtable); 226EXPORT_SYMBOL(dma_common_get_sgtable);
218 227