diff options
| -rw-r--r-- | drivers/xen/swiotlb-xen.c | 2 | ||||
| -rw-r--r-- | include/linux/dma-mapping.h | 7 | ||||
| -rw-r--r-- | kernel/dma/mapping.c | 23 |
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 | ||
| 695 | static int xen_swiotlb_mapping_error(struct device *dev, dma_addr_t dma_addr) | 695 | static 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 | ||
| 485 | int | 485 | int |
| 486 | dma_common_get_sgtable(struct device *dev, struct sg_table *sgt, | 486 | dma_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 | ||
| 489 | static inline int | 489 | static inline int |
| 490 | dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr, | 490 | 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 | 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 | */ |
| 204 | int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt, | 204 | int 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 | } |
| 217 | EXPORT_SYMBOL(dma_common_get_sgtable); | 226 | EXPORT_SYMBOL(dma_common_get_sgtable); |
| 218 | 227 | ||
