kmemcheck: add mm functions
[deliverable/linux.git] / arch / x86 / include / asm / dma-mapping.h
CommitLineData
1965aae3
PA
1#ifndef _ASM_X86_DMA_MAPPING_H
2#define _ASM_X86_DMA_MAPPING_H
6f536635
GC
3
4/*
5872fb94
RD
5 * IOMMU interface. See Documentation/PCI/PCI-DMA-mapping.txt and
6 * Documentation/DMA-API.txt for documentation.
6f536635
GC
7 */
8
9#include <linux/scatterlist.h>
2118d0c5 10#include <linux/dma-debug.h>
abe6602b 11#include <linux/dma-attrs.h>
6f536635
GC
12#include <asm/io.h>
13#include <asm/swiotlb.h>
6c505ce3 14#include <asm-generic/dma-coherent.h>
6f536635 15
7c183416 16extern dma_addr_t bad_dma_address;
b7107a3d 17extern int iommu_merge;
6c505ce3 18extern struct device x86_dma_fallback_dev;
b7107a3d 19extern int panic_on_overflow;
7c183416 20
160c1d8e
FT
21extern struct dma_map_ops *dma_ops;
22
23static inline struct dma_map_ops *get_dma_ops(struct device *dev)
c786df08 24{
8d8bb39b
FT
25#ifdef CONFIG_X86_32
26 return dma_ops;
27#else
28 if (unlikely(!dev) || !dev->archdata.dma_ops)
29 return dma_ops;
30 else
31 return dev->archdata.dma_ops;
cfb80c9e 32#endif
8d8bb39b
FT
33}
34
35/* Make sure we keep the same behaviour */
36static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
37{
160c1d8e 38 struct dma_map_ops *ops = get_dma_ops(dev);
8d8bb39b
FT
39 if (ops->mapping_error)
40 return ops->mapping_error(dev, dma_addr);
c786df08 41
7b1dedca 42 return (dma_addr == bad_dma_address);
c786df08
GC
43}
44
8d396ded
GC
45#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
46#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
6c505ce3 47#define dma_is_consistent(d, h) (1)
8d396ded 48
802c1f66
GC
49extern int dma_supported(struct device *hwdev, u64 mask);
50extern int dma_set_mask(struct device *dev, u64 mask);
51
9f6ac577
FT
52extern void *dma_generic_alloc_coherent(struct device *dev, size_t size,
53 dma_addr_t *dma_addr, gfp_t flag);
54
22456b97
GC
55static inline dma_addr_t
56dma_map_single(struct device *hwdev, void *ptr, size_t size,
160c1d8e 57 enum dma_data_direction dir)
22456b97 58{
160c1d8e 59 struct dma_map_ops *ops = get_dma_ops(hwdev);
2118d0c5 60 dma_addr_t addr;
8d8bb39b 61
160c1d8e 62 BUG_ON(!valid_dma_direction(dir));
2118d0c5 63 addr = ops->map_page(hwdev, virt_to_page(ptr),
d7dff840 64 (unsigned long)ptr & ~PAGE_MASK, size,
160c1d8e 65 dir, NULL);
2118d0c5
JR
66 debug_dma_map_page(hwdev, virt_to_page(ptr),
67 (unsigned long)ptr & ~PAGE_MASK, size,
68 dir, addr, true);
69 return addr;
22456b97
GC
70}
71
0cb0ae68
GC
72static inline void
73dma_unmap_single(struct device *dev, dma_addr_t addr, size_t size,
160c1d8e 74 enum dma_data_direction dir)
0cb0ae68 75{
160c1d8e 76 struct dma_map_ops *ops = get_dma_ops(dev);
8d8bb39b 77
160c1d8e 78 BUG_ON(!valid_dma_direction(dir));
d7dff840 79 if (ops->unmap_page)
160c1d8e 80 ops->unmap_page(dev, addr, size, dir, NULL);
2118d0c5 81 debug_dma_unmap_page(dev, addr, size, dir, true);
0cb0ae68
GC
82}
83
16a3ce9b
GC
84static inline int
85dma_map_sg(struct device *hwdev, struct scatterlist *sg,
160c1d8e 86 int nents, enum dma_data_direction dir)
16a3ce9b 87{
160c1d8e 88 struct dma_map_ops *ops = get_dma_ops(hwdev);
2118d0c5 89 int ents;
8d8bb39b 90
160c1d8e 91 BUG_ON(!valid_dma_direction(dir));
2118d0c5
JR
92 ents = ops->map_sg(hwdev, sg, nents, dir, NULL);
93 debug_dma_map_sg(hwdev, sg, nents, ents, dir);
94
95 return ents;
16a3ce9b 96}
72c784f8
GC
97
98static inline void
99dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
160c1d8e 100 enum dma_data_direction dir)
72c784f8 101{
160c1d8e 102 struct dma_map_ops *ops = get_dma_ops(hwdev);
8d8bb39b 103
160c1d8e 104 BUG_ON(!valid_dma_direction(dir));
2118d0c5 105 debug_dma_unmap_sg(hwdev, sg, nents, dir);
8d8bb39b 106 if (ops->unmap_sg)
160c1d8e 107 ops->unmap_sg(hwdev, sg, nents, dir, NULL);
72c784f8 108}
c01dd8cf
GC
109
110static inline void
111dma_sync_single_for_cpu(struct device *hwdev, dma_addr_t dma_handle,
160c1d8e 112 size_t size, enum dma_data_direction dir)
c01dd8cf 113{
160c1d8e 114 struct dma_map_ops *ops = get_dma_ops(hwdev);
8d8bb39b 115
160c1d8e 116 BUG_ON(!valid_dma_direction(dir));
8d8bb39b 117 if (ops->sync_single_for_cpu)
160c1d8e 118 ops->sync_single_for_cpu(hwdev, dma_handle, size, dir);
2118d0c5 119 debug_dma_sync_single_for_cpu(hwdev, dma_handle, size, dir);
c01dd8cf
GC
120 flush_write_buffers();
121}
122
9231b269
GC
123static inline void
124dma_sync_single_for_device(struct device *hwdev, dma_addr_t dma_handle,
160c1d8e 125 size_t size, enum dma_data_direction dir)
9231b269 126{
160c1d8e 127 struct dma_map_ops *ops = get_dma_ops(hwdev);
8d8bb39b 128
160c1d8e 129 BUG_ON(!valid_dma_direction(dir));
8d8bb39b 130 if (ops->sync_single_for_device)
160c1d8e 131 ops->sync_single_for_device(hwdev, dma_handle, size, dir);
2118d0c5 132 debug_dma_sync_single_for_device(hwdev, dma_handle, size, dir);
9231b269
GC
133 flush_write_buffers();
134}
135
627610fc
GC
136static inline void
137dma_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dma_handle,
160c1d8e
FT
138 unsigned long offset, size_t size,
139 enum dma_data_direction dir)
627610fc 140{
160c1d8e 141 struct dma_map_ops *ops = get_dma_ops(hwdev);
627610fc 142
160c1d8e 143 BUG_ON(!valid_dma_direction(dir));
8d8bb39b
FT
144 if (ops->sync_single_range_for_cpu)
145 ops->sync_single_range_for_cpu(hwdev, dma_handle, offset,
160c1d8e 146 size, dir);
2118d0c5
JR
147 debug_dma_sync_single_range_for_cpu(hwdev, dma_handle,
148 offset, size, dir);
627610fc
GC
149 flush_write_buffers();
150}
71362332
GC
151
152static inline void
153dma_sync_single_range_for_device(struct device *hwdev, dma_addr_t dma_handle,
154 unsigned long offset, size_t size,
160c1d8e 155 enum dma_data_direction dir)
71362332 156{
160c1d8e 157 struct dma_map_ops *ops = get_dma_ops(hwdev);
71362332 158
160c1d8e 159 BUG_ON(!valid_dma_direction(dir));
8d8bb39b
FT
160 if (ops->sync_single_range_for_device)
161 ops->sync_single_range_for_device(hwdev, dma_handle,
160c1d8e 162 offset, size, dir);
2118d0c5
JR
163 debug_dma_sync_single_range_for_device(hwdev, dma_handle,
164 offset, size, dir);
71362332
GC
165 flush_write_buffers();
166}
167
ed435dee
GC
168static inline void
169dma_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
160c1d8e 170 int nelems, enum dma_data_direction dir)
ed435dee 171{
160c1d8e 172 struct dma_map_ops *ops = get_dma_ops(hwdev);
8d8bb39b 173
160c1d8e 174 BUG_ON(!valid_dma_direction(dir));
8d8bb39b 175 if (ops->sync_sg_for_cpu)
160c1d8e 176 ops->sync_sg_for_cpu(hwdev, sg, nelems, dir);
2118d0c5 177 debug_dma_sync_sg_for_cpu(hwdev, sg, nelems, dir);
ed435dee
GC
178 flush_write_buffers();
179}
e7f3a913
GC
180
181static inline void
182dma_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,
160c1d8e 183 int nelems, enum dma_data_direction dir)
e7f3a913 184{
160c1d8e 185 struct dma_map_ops *ops = get_dma_ops(hwdev);
8d8bb39b 186
160c1d8e 187 BUG_ON(!valid_dma_direction(dir));
8d8bb39b 188 if (ops->sync_sg_for_device)
160c1d8e 189 ops->sync_sg_for_device(hwdev, sg, nelems, dir);
2118d0c5 190 debug_dma_sync_sg_for_device(hwdev, sg, nelems, dir);
e7f3a913
GC
191
192 flush_write_buffers();
193}
4d92fbf2
GC
194
195static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
196 size_t offset, size_t size,
160c1d8e 197 enum dma_data_direction dir)
4d92fbf2 198{
160c1d8e 199 struct dma_map_ops *ops = get_dma_ops(dev);
2118d0c5 200 dma_addr_t addr;
8d8bb39b 201
160c1d8e 202 BUG_ON(!valid_dma_direction(dir));
2118d0c5
JR
203 addr = ops->map_page(dev, page, offset, size, dir, NULL);
204 debug_dma_map_page(dev, page, offset, size, dir, addr, false);
205
206 return addr;
4d92fbf2
GC
207}
208
209static inline void dma_unmap_page(struct device *dev, dma_addr_t addr,
160c1d8e 210 size_t size, enum dma_data_direction dir)
4d92fbf2 211{
2118d0c5
JR
212 struct dma_map_ops *ops = get_dma_ops(dev);
213
214 BUG_ON(!valid_dma_direction(dir));
215 if (ops->unmap_page)
216 ops->unmap_page(dev, addr, size, dir, NULL);
217 debug_dma_unmap_page(dev, addr, size, dir, false);
4d92fbf2
GC
218}
219
3cb6a917
GC
220static inline void
221dma_cache_sync(struct device *dev, void *vaddr, size_t size,
222 enum dma_data_direction dir)
223{
224 flush_write_buffers();
225}
ae17a63b 226
b7107a3d
GC
227static inline int dma_get_cache_alignment(void)
228{
229 /* no easy way to get cache size on all x86, so return the
230 * maximum possible, to be safe */
231 return boot_cpu_data.x86_clflush_size;
232}
233
823e7e8c
FT
234static inline unsigned long dma_alloc_coherent_mask(struct device *dev,
235 gfp_t gfp)
236{
237 unsigned long dma_mask = 0;
b7107a3d 238
823e7e8c
FT
239 dma_mask = dev->coherent_dma_mask;
240 if (!dma_mask)
2f4f27d4 241 dma_mask = (gfp & GFP_DMA) ? DMA_BIT_MASK(24) : DMA_BIT_MASK(32);
823e7e8c
FT
242
243 return dma_mask;
244}
245
246static inline gfp_t dma_alloc_coherent_gfp_flags(struct device *dev, gfp_t gfp)
247{
248 unsigned long dma_mask = dma_alloc_coherent_mask(dev, gfp);
249
2f4f27d4 250 if (dma_mask <= DMA_BIT_MASK(24))
75bebb7f
FT
251 gfp |= GFP_DMA;
252#ifdef CONFIG_X86_64
284901a9 253 if (dma_mask <= DMA_BIT_MASK(32) && !(gfp & GFP_DMA))
823e7e8c
FT
254 gfp |= GFP_DMA32;
255#endif
256 return gfp;
257}
258
6c505ce3
JR
259static inline void *
260dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
261 gfp_t gfp)
262{
160c1d8e 263 struct dma_map_ops *ops = get_dma_ops(dev);
6c505ce3
JR
264 void *memory;
265
8a53ad67
FT
266 gfp &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32);
267
6c505ce3
JR
268 if (dma_alloc_from_coherent(dev, size, dma_handle, &memory))
269 return memory;
270
271 if (!dev) {
272 dev = &x86_dma_fallback_dev;
273 gfp |= GFP_DMA;
274 }
275
98216260 276 if (!is_device_dma_capable(dev))
de9f521f
FT
277 return NULL;
278
823e7e8c
FT
279 if (!ops->alloc_coherent)
280 return NULL;
281
2118d0c5
JR
282 memory = ops->alloc_coherent(dev, size, dma_handle,
283 dma_alloc_coherent_gfp_flags(dev, gfp));
284 debug_dma_alloc_coherent(dev, size, *dma_handle, memory);
285
286 return memory;
6c505ce3
JR
287}
288
289static inline void dma_free_coherent(struct device *dev, size_t size,
290 void *vaddr, dma_addr_t bus)
291{
160c1d8e 292 struct dma_map_ops *ops = get_dma_ops(dev);
6c505ce3
JR
293
294 WARN_ON(irqs_disabled()); /* for portability */
295
296 if (dma_release_from_coherent(dev, get_order(size), vaddr))
297 return;
298
2118d0c5 299 debug_dma_free_coherent(dev, size, vaddr, bus);
6c505ce3
JR
300 if (ops->free_coherent)
301 ops->free_coherent(dev, size, vaddr, bus);
302}
b7107a3d 303
6f536635 304#endif
This page took 1.46197 seconds and 5 git commands to generate.