diff options
Diffstat (limited to 'include/linux/dma-mapping.h')
-rw-r--r-- | include/linux/dma-mapping.h | 130 |
1 files changed, 85 insertions, 45 deletions
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 71c1b215e..dc69df04a 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -5,13 +5,58 @@ #include <linux/string.h> #include <linux/device.h> #include <linux/err.h> -#include <linux/dma-attrs.h> #include <linux/dma-debug.h> #include <linux/dma-direction.h> #include <linux/scatterlist.h> #include <linux/kmemcheck.h> #include <linux/bug.h> +/** + * List of possible attributes associated with a DMA mapping. The semantics + * of each attribute should be defined in Documentation/DMA-attributes.txt. + * + * DMA_ATTR_WRITE_BARRIER: DMA to a memory region with this attribute + * forces all pending DMA writes to complete. + */ +#define DMA_ATTR_WRITE_BARRIER (1UL << 0) +/* + * DMA_ATTR_WEAK_ORDERING: Specifies that reads and writes to the mapping + * may be weakly ordered, that is that reads and writes may pass each other. + */ +#define DMA_ATTR_WEAK_ORDERING (1UL << 1) +/* + * DMA_ATTR_WRITE_COMBINE: Specifies that writes to the mapping may be + * buffered to improve performance. + */ +#define DMA_ATTR_WRITE_COMBINE (1UL << 2) +/* + * DMA_ATTR_NON_CONSISTENT: Lets the platform to choose to return either + * consistent or non-consistent memory as it sees fit. + */ +#define DMA_ATTR_NON_CONSISTENT (1UL << 3) +/* + * DMA_ATTR_NO_KERNEL_MAPPING: Lets the platform to avoid creating a kernel + * virtual mapping for the allocated buffer. + */ +#define DMA_ATTR_NO_KERNEL_MAPPING (1UL << 4) +/* + * DMA_ATTR_SKIP_CPU_SYNC: Allows platform code to skip synchronization of + * the CPU cache for the given buffer assuming that it has been already + * transferred to 'device' domain. + */ +#define DMA_ATTR_SKIP_CPU_SYNC (1UL << 5) +/* + * DMA_ATTR_FORCE_CONTIGUOUS: Forces contiguous allocation of the buffer + * in physical memory. + */ +#define DMA_ATTR_FORCE_CONTIGUOUS (1UL << 6) +/* + * DMA_ATTR_ALLOC_SINGLE_PAGES: This is a hint to the DMA-mapping subsystem + * that it's probably not worth the time to try to allocate memory to in a way + * that gives better TLB efficiency. + */ +#define DMA_ATTR_ALLOC_SINGLE_PAGES (1UL << 7) + /* * A dma_addr_t can hold any valid DMA or bus address for the platform. * It can be given to a device to use as a DMA source or target. A CPU cannot @@ -21,34 +66,35 @@ struct dma_map_ops { void* (*alloc)(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp, - struct dma_attrs *attrs); + unsigned long attrs); void (*free)(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle, - struct dma_attrs *attrs); + unsigned long attrs); int (*mmap)(struct device *, struct vm_area_struct *, - void *, dma_addr_t, size_t, struct dma_attrs *attrs); + void *, dma_addr_t, size_t, + unsigned long attrs); int (*get_sgtable)(struct device *dev, struct sg_table *sgt, void *, - dma_addr_t, size_t, struct dma_attrs *attrs); + dma_addr_t, size_t, unsigned long attrs); dma_addr_t (*map_page)(struct device *dev, struct page *page, unsigned long offset, size_t size, enum dma_data_direction dir, - struct dma_attrs *attrs); + unsigned long attrs); void (*unmap_page)(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction dir, - struct dma_attrs *attrs); + unsigned long attrs); /* * map_sg returns 0 on error and a value > 0 on success. * It should never return a value < 0. */ int (*map_sg)(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, - struct dma_attrs *attrs); + unsigned long attrs); void (*unmap_sg)(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, - struct dma_attrs *attrs); + unsigned long attrs); void (*sync_single_for_cpu)(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction dir); @@ -123,7 +169,7 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev) static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr, size_t size, enum dma_data_direction dir, - struct dma_attrs *attrs) + unsigned long attrs) { struct dma_map_ops *ops = get_dma_ops(dev); dma_addr_t addr; @@ -142,7 +188,7 @@ static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr, static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr, size_t size, enum dma_data_direction dir, - struct dma_attrs *attrs) + unsigned long attrs) { struct dma_map_ops *ops = get_dma_ops(dev); @@ -158,7 +204,7 @@ static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr, */ static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, - struct dma_attrs *attrs) + unsigned long attrs) { struct dma_map_ops *ops = get_dma_ops(dev); int i, ents; @@ -176,7 +222,7 @@ static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, static inline void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, - struct dma_attrs *attrs) + unsigned long attrs) { struct dma_map_ops *ops = get_dma_ops(dev); @@ -195,7 +241,7 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, kmemcheck_mark_initialized(page_address(page) + offset, size); BUG_ON(!valid_dma_direction(dir)); - addr = ops->map_page(dev, page, offset, size, dir, NULL); + addr = ops->map_page(dev, page, offset, size, dir, 0); debug_dma_map_page(dev, page, offset, size, dir, addr, false); return addr; @@ -208,7 +254,7 @@ static inline void dma_unmap_page(struct device *dev, dma_addr_t addr, BUG_ON(!valid_dma_direction(dir)); if (ops->unmap_page) - ops->unmap_page(dev, addr, size, dir, NULL); + ops->unmap_page(dev, addr, size, dir, 0); debug_dma_unmap_page(dev, addr, size, dir, false); } @@ -289,10 +335,10 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, } -#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, NULL) -#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, NULL) -#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, NULL) -#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, NULL) +#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, 0) +#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, 0) +#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, 0) +#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, 0) extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma, void *cpu_addr, dma_addr_t dma_addr, size_t size); @@ -321,7 +367,7 @@ void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags); */ static inline int dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr, - dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs) + dma_addr_t dma_addr, size_t size, unsigned long attrs) { struct dma_map_ops *ops = get_dma_ops(dev); BUG_ON(!ops); @@ -330,7 +376,7 @@ dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr, return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size); } -#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, NULL) +#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, 0) int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt, @@ -338,7 +384,8 @@ dma_common_get_sgtable(struct device *dev, struct sg_table *sgt, static inline int dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr, - dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs) + dma_addr_t dma_addr, size_t size, + unsigned long attrs) { struct dma_map_ops *ops = get_dma_ops(dev); BUG_ON(!ops); @@ -348,7 +395,7 @@ dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr, return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr, size); } -#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, NULL) +#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, 0) #ifndef arch_dma_alloc_attrs #define arch_dma_alloc_attrs(dev, flag) (true) @@ -356,7 +403,7 @@ dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr, static inline void *dma_alloc_attrs(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag, - struct dma_attrs *attrs) + unsigned long attrs) { struct dma_map_ops *ops = get_dma_ops(dev); void *cpu_addr; @@ -378,7 +425,7 @@ static inline void *dma_alloc_attrs(struct device *dev, size_t size, static inline void dma_free_attrs(struct device *dev, size_t size, void *cpu_addr, dma_addr_t dma_handle, - struct dma_attrs *attrs) + unsigned long attrs) { struct dma_map_ops *ops = get_dma_ops(dev); @@ -398,31 +445,27 @@ static inline void dma_free_attrs(struct device *dev, size_t size, static inline void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag) { - return dma_alloc_attrs(dev, size, dma_handle, flag, NULL); + return dma_alloc_attrs(dev, size, dma_handle, flag, 0); } static inline void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t dma_handle) { - return dma_free_attrs(dev, size, cpu_addr, dma_handle, NULL); + return dma_free_attrs(dev, size, cpu_addr, dma_handle, 0); } static inline void *dma_alloc_noncoherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp) { - DEFINE_DMA_ATTRS(attrs); - - dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs); - return dma_alloc_attrs(dev, size, dma_handle, gfp, &attrs); + return dma_alloc_attrs(dev, size, dma_handle, gfp, + DMA_ATTR_NON_CONSISTENT); } static inline void dma_free_noncoherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t dma_handle) { - DEFINE_DMA_ATTRS(attrs); - - dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs); - dma_free_attrs(dev, size, cpu_addr, dma_handle, &attrs); + dma_free_attrs(dev, size, cpu_addr, dma_handle, + DMA_ATTR_NON_CONSISTENT); } static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) @@ -646,9 +689,8 @@ static inline void dmam_release_declared_memory(struct device *dev) static inline void *dma_alloc_wc(struct device *dev, size_t size, dma_addr_t *dma_addr, gfp_t gfp) { - DEFINE_DMA_ATTRS(attrs); - dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs); - return dma_alloc_attrs(dev, size, dma_addr, gfp, &attrs); + return dma_alloc_attrs(dev, size, dma_addr, gfp, + DMA_ATTR_WRITE_COMBINE); } #ifndef dma_alloc_writecombine #define dma_alloc_writecombine dma_alloc_wc @@ -657,9 +699,8 @@ static inline void *dma_alloc_wc(struct device *dev, size_t size, static inline void dma_free_wc(struct device *dev, size_t size, void *cpu_addr, dma_addr_t dma_addr) { - DEFINE_DMA_ATTRS(attrs); - dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs); - return dma_free_attrs(dev, size, cpu_addr, dma_addr, &attrs); + return dma_free_attrs(dev, size, cpu_addr, dma_addr, + DMA_ATTR_WRITE_COMBINE); } #ifndef dma_free_writecombine #define dma_free_writecombine dma_free_wc @@ -670,15 +711,14 @@ static inline int dma_mmap_wc(struct device *dev, void *cpu_addr, dma_addr_t dma_addr, size_t size) { - DEFINE_DMA_ATTRS(attrs); - dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs); - return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size, &attrs); + return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size, + DMA_ATTR_WRITE_COMBINE); } #ifndef dma_mmap_writecombine #define dma_mmap_writecombine dma_mmap_wc #endif -#ifdef CONFIG_NEED_DMA_MAP_STATE +#if defined(CONFIG_NEED_DMA_MAP_STATE) || defined(CONFIG_DMA_API_DEBUG) #define DEFINE_DMA_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME #define DEFINE_DMA_UNMAP_LEN(LEN_NAME) __u32 LEN_NAME #define dma_unmap_addr(PTR, ADDR_NAME) ((PTR)->ADDR_NAME) |