Line data Source code
1 : #ifndef _ASM_GENERIC_DMA_MAPPING_H
2 : #define _ASM_GENERIC_DMA_MAPPING_H
3 :
4 : #include <linux/kmemcheck.h>
5 : #include <linux/scatterlist.h>
6 : #include <linux/dma-debug.h>
7 : #include <linux/dma-attrs.h>
8 :
9 : static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
10 : size_t size,
11 : enum dma_data_direction dir,
12 : struct dma_attrs *attrs)
13 : {
14 : struct dma_map_ops *ops = get_dma_ops(dev);
15 : dma_addr_t addr;
16 :
17 : kmemcheck_mark_initialized(ptr, size);
18 : BUG_ON(!valid_dma_direction(dir));
19 : addr = ops->map_page(dev, virt_to_page(ptr),
20 : (unsigned long)ptr & ~PAGE_MASK, size,
21 : dir, attrs);
22 : debug_dma_map_page(dev, virt_to_page(ptr),
23 : (unsigned long)ptr & ~PAGE_MASK, size,
24 : dir, addr, true);
25 : return addr;
26 : }
27 :
28 : static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr,
29 : size_t size,
30 : enum dma_data_direction dir,
31 : struct dma_attrs *attrs)
32 : {
33 : struct dma_map_ops *ops = get_dma_ops(dev);
34 :
35 : BUG_ON(!valid_dma_direction(dir));
36 : if (ops->unmap_page)
37 : ops->unmap_page(dev, addr, size, dir, attrs);
38 : debug_dma_unmap_page(dev, addr, size, dir, true);
39 : }
40 :
41 : static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
42 : int nents, enum dma_data_direction dir,
43 : struct dma_attrs *attrs)
44 0 : {
45 0 : struct dma_map_ops *ops = get_dma_ops(dev);
46 0 : int i, ents;
47 0 : struct scatterlist *s;
48 0 :
49 0 : for_each_sg(sg, s, nents, i)
50 0 : kmemcheck_mark_initialized(sg_virt(s), s->length);
51 0 : BUG_ON(!valid_dma_direction(dir));
52 0 : ents = ops->map_sg(dev, sg, nents, dir, attrs);
53 0 : debug_dma_map_sg(dev, sg, nents, ents, dir);
54 :
55 0 : return ents;
56 : }
57 :
58 : static inline void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg,
59 : int nents, enum dma_data_direction dir,
60 : struct dma_attrs *attrs)
61 : {
62 0 : struct dma_map_ops *ops = get_dma_ops(dev);
63 0 :
64 0 : BUG_ON(!valid_dma_direction(dir));
65 0 : debug_dma_unmap_sg(dev, sg, nents, dir);
66 0 : if (ops->unmap_sg)
67 0 : ops->unmap_sg(dev, sg, nents, dir, attrs);
68 0 : }
69 :
70 : static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
71 : size_t offset, size_t size,
72 : enum dma_data_direction dir)
73 : {
74 : struct dma_map_ops *ops = get_dma_ops(dev);
75 : dma_addr_t addr;
76 :
77 : kmemcheck_mark_initialized(page_address(page) + offset, size);
78 : BUG_ON(!valid_dma_direction(dir));
79 : addr = ops->map_page(dev, page, offset, size, dir, NULL);
80 : debug_dma_map_page(dev, page, offset, size, dir, addr, false);
81 :
82 : return addr;
83 : }
84 :
85 : static inline void dma_unmap_page(struct device *dev, dma_addr_t addr,
86 : size_t size, enum dma_data_direction dir)
87 : {
88 : struct dma_map_ops *ops = get_dma_ops(dev);
89 :
90 : BUG_ON(!valid_dma_direction(dir));
91 : if (ops->unmap_page)
92 : ops->unmap_page(dev, addr, size, dir, NULL);
93 : debug_dma_unmap_page(dev, addr, size, dir, false);
94 : }
95 :
96 : static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t addr,
97 : size_t size,
98 : enum dma_data_direction dir)
99 : {
100 : struct dma_map_ops *ops = get_dma_ops(dev);
101 :
102 : BUG_ON(!valid_dma_direction(dir));
103 : if (ops->sync_single_for_cpu)
104 : ops->sync_single_for_cpu(dev, addr, size, dir);
105 : debug_dma_sync_single_for_cpu(dev, addr, size, dir);
106 : }
107 :
108 : static inline void dma_sync_single_for_device(struct device *dev,
109 : dma_addr_t addr, size_t size,
110 : enum dma_data_direction dir)
111 : {
112 : struct dma_map_ops *ops = get_dma_ops(dev);
113 :
114 : BUG_ON(!valid_dma_direction(dir));
115 : if (ops->sync_single_for_device)
116 : ops->sync_single_for_device(dev, addr, size, dir);
117 : debug_dma_sync_single_for_device(dev, addr, size, dir);
118 : }
119 :
120 : static inline void dma_sync_single_range_for_cpu(struct device *dev,
121 : dma_addr_t addr,
122 : unsigned long offset,
123 : size_t size,
124 : enum dma_data_direction dir)
125 : {
126 : struct dma_map_ops *ops = get_dma_ops(dev);
127 :
128 : BUG_ON(!valid_dma_direction(dir));
129 : if (ops->sync_single_range_for_cpu) {
130 : ops->sync_single_range_for_cpu(dev, addr, offset, size, dir);
131 : debug_dma_sync_single_range_for_cpu(dev, addr, offset, size, dir);
132 :
133 : } else
134 : dma_sync_single_for_cpu(dev, addr + offset, size, dir);
135 : }
136 :
137 : static inline void dma_sync_single_range_for_device(struct device *dev,
138 : dma_addr_t addr,
139 : unsigned long offset,
140 : size_t size,
141 : enum dma_data_direction dir)
142 : {
143 : struct dma_map_ops *ops = get_dma_ops(dev);
144 :
145 : BUG_ON(!valid_dma_direction(dir));
146 : if (ops->sync_single_range_for_device) {
147 : ops->sync_single_range_for_device(dev, addr, offset, size, dir);
148 : debug_dma_sync_single_range_for_device(dev, addr, offset, size, dir);
149 :
150 : } else
151 : dma_sync_single_for_device(dev, addr + offset, size, dir);
152 : }
153 :
154 : static inline void
155 : dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
156 : int nelems, enum dma_data_direction dir)
157 : {
158 : struct dma_map_ops *ops = get_dma_ops(dev);
159 :
160 : BUG_ON(!valid_dma_direction(dir));
161 : if (ops->sync_sg_for_cpu)
162 : ops->sync_sg_for_cpu(dev, sg, nelems, dir);
163 : debug_dma_sync_sg_for_cpu(dev, sg, nelems, dir);
164 : }
165 :
166 : static inline void
167 : dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
168 : int nelems, enum dma_data_direction dir)
169 : {
170 : struct dma_map_ops *ops = get_dma_ops(dev);
171 :
172 : BUG_ON(!valid_dma_direction(dir));
173 : if (ops->sync_sg_for_device)
174 : ops->sync_sg_for_device(dev, sg, nelems, dir);
175 : debug_dma_sync_sg_for_device(dev, sg, nelems, dir);
176 :
177 : }
178 :
179 : #define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, NULL)
180 : #define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, NULL)
181 : #define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, NULL)
182 : #define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, NULL)
183 :
184 : #endif
|