blob: ad9cd6d49bfc9bc624747709da188301b35f5b55 [file] [log] [blame]
Glauber Costa6f536632008-03-25 18:36:20 -03001#ifndef _ASM_DMA_MAPPING_H_
2#define _ASM_DMA_MAPPING_H_
3
4/*
5 * IOMMU interface. See Documentation/DMA-mapping.txt and DMA-API.txt for
6 * documentation.
7 */
8
9#include <linux/scatterlist.h>
10#include <asm/io.h>
11#include <asm/swiotlb.h>
12
Glauber Costa7c183412008-03-25 18:36:36 -030013extern dma_addr_t bad_dma_address;
Glauber Costab7107a32008-03-25 18:36:39 -030014extern int iommu_merge;
15extern struct device fallback_dev;
16extern int panic_on_overflow;
Glauber Costafae9a0d2008-04-08 13:20:56 -030017extern int force_iommu;
Glauber Costa7c183412008-03-25 18:36:36 -030018
Glauber Costa6f536632008-03-25 18:36:20 -030019struct dma_mapping_ops {
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -070020 int (*mapping_error)(struct device *dev,
21 dma_addr_t dma_addr);
Glauber Costa6f536632008-03-25 18:36:20 -030022 void* (*alloc_coherent)(struct device *dev, size_t size,
23 dma_addr_t *dma_handle, gfp_t gfp);
24 void (*free_coherent)(struct device *dev, size_t size,
25 void *vaddr, dma_addr_t dma_handle);
Ingo Molnar2be62142008-04-19 19:19:56 +020026 dma_addr_t (*map_single)(struct device *hwdev, phys_addr_t ptr,
Glauber Costa6f536632008-03-25 18:36:20 -030027 size_t size, int direction);
28 /* like map_single, but doesn't check the device mask */
Ingo Molnar2be62142008-04-19 19:19:56 +020029 dma_addr_t (*map_simple)(struct device *hwdev, phys_addr_t ptr,
Glauber Costa6f536632008-03-25 18:36:20 -030030 size_t size, int direction);
31 void (*unmap_single)(struct device *dev, dma_addr_t addr,
32 size_t size, int direction);
33 void (*sync_single_for_cpu)(struct device *hwdev,
34 dma_addr_t dma_handle, size_t size,
35 int direction);
36 void (*sync_single_for_device)(struct device *hwdev,
37 dma_addr_t dma_handle, size_t size,
38 int direction);
39 void (*sync_single_range_for_cpu)(struct device *hwdev,
40 dma_addr_t dma_handle, unsigned long offset,
41 size_t size, int direction);
42 void (*sync_single_range_for_device)(struct device *hwdev,
43 dma_addr_t dma_handle, unsigned long offset,
44 size_t size, int direction);
45 void (*sync_sg_for_cpu)(struct device *hwdev,
46 struct scatterlist *sg, int nelems,
47 int direction);
48 void (*sync_sg_for_device)(struct device *hwdev,
49 struct scatterlist *sg, int nelems,
50 int direction);
51 int (*map_sg)(struct device *hwdev, struct scatterlist *sg,
52 int nents, int direction);
53 void (*unmap_sg)(struct device *hwdev,
54 struct scatterlist *sg, int nents,
55 int direction);
56 int (*dma_supported)(struct device *hwdev, u64 mask);
57 int is_phys;
58};
59
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -070060extern struct dma_mapping_ops *dma_ops;
Glauber Costa22456b92008-03-25 18:36:21 -030061
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -070062static inline struct dma_mapping_ops *get_dma_ops(struct device *dev)
Glauber Costac786df02008-03-25 18:36:37 -030063{
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -070064#ifdef CONFIG_X86_32
65 return dma_ops;
66#else
67 if (unlikely(!dev) || !dev->archdata.dma_ops)
68 return dma_ops;
69 else
70 return dev->archdata.dma_ops;
71#endif
72}
73
74/* Make sure we keep the same behaviour */
75static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
76{
77#ifdef CONFIG_X86_32
78 return 0;
79#else
80 struct dma_mapping_ops *ops = get_dma_ops(dev);
81 if (ops->mapping_error)
82 return ops->mapping_error(dev, dma_addr);
Glauber Costac786df02008-03-25 18:36:37 -030083
84 return (dma_addr == bad_dma_address);
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -070085#endif
Glauber Costac786df02008-03-25 18:36:37 -030086}
87
Glauber Costa8d396de2008-03-25 18:36:31 -030088#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
89#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
90
91void *dma_alloc_coherent(struct device *dev, size_t size,
92 dma_addr_t *dma_handle, gfp_t flag);
93
94void dma_free_coherent(struct device *dev, size_t size,
95 void *vaddr, dma_addr_t dma_handle);
96
97
Glauber Costa802c1f62008-03-25 18:36:34 -030098extern int dma_supported(struct device *hwdev, u64 mask);
99extern int dma_set_mask(struct device *dev, u64 mask);
100
Glauber Costa22456b92008-03-25 18:36:21 -0300101static inline dma_addr_t
102dma_map_single(struct device *hwdev, void *ptr, size_t size,
103 int direction)
104{
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -0700105 struct dma_mapping_ops *ops = get_dma_ops(hwdev);
106
Glauber Costa22456b92008-03-25 18:36:21 -0300107 BUG_ON(!valid_dma_direction(direction));
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -0700108 return ops->map_single(hwdev, virt_to_phys(ptr), size, direction);
Glauber Costa22456b92008-03-25 18:36:21 -0300109}
110
Glauber Costa0cb0ae62008-03-25 18:36:22 -0300111static inline void
112dma_unmap_single(struct device *dev, dma_addr_t addr, size_t size,
113 int direction)
114{
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -0700115 struct dma_mapping_ops *ops = get_dma_ops(dev);
116
Glauber Costa0cb0ae62008-03-25 18:36:22 -0300117 BUG_ON(!valid_dma_direction(direction));
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -0700118 if (ops->unmap_single)
119 ops->unmap_single(dev, addr, size, direction);
Glauber Costa0cb0ae62008-03-25 18:36:22 -0300120}
121
Glauber Costa16a3ce92008-03-25 18:36:23 -0300122static inline int
123dma_map_sg(struct device *hwdev, struct scatterlist *sg,
124 int nents, int direction)
125{
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -0700126 struct dma_mapping_ops *ops = get_dma_ops(hwdev);
127
Glauber Costa16a3ce92008-03-25 18:36:23 -0300128 BUG_ON(!valid_dma_direction(direction));
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -0700129 return ops->map_sg(hwdev, sg, nents, direction);
Glauber Costa16a3ce92008-03-25 18:36:23 -0300130}
Glauber Costa72c784f2008-03-25 18:36:24 -0300131
132static inline void
133dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
134 int direction)
135{
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -0700136 struct dma_mapping_ops *ops = get_dma_ops(hwdev);
137
Glauber Costa72c784f2008-03-25 18:36:24 -0300138 BUG_ON(!valid_dma_direction(direction));
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -0700139 if (ops->unmap_sg)
140 ops->unmap_sg(hwdev, sg, nents, direction);
Glauber Costa72c784f2008-03-25 18:36:24 -0300141}
Glauber Costac01dd8c2008-03-25 18:36:25 -0300142
143static inline void
144dma_sync_single_for_cpu(struct device *hwdev, dma_addr_t dma_handle,
145 size_t size, int direction)
146{
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -0700147 struct dma_mapping_ops *ops = get_dma_ops(hwdev);
148
Glauber Costac01dd8c2008-03-25 18:36:25 -0300149 BUG_ON(!valid_dma_direction(direction));
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -0700150 if (ops->sync_single_for_cpu)
151 ops->sync_single_for_cpu(hwdev, dma_handle, size, direction);
Glauber Costac01dd8c2008-03-25 18:36:25 -0300152 flush_write_buffers();
153}
154
Glauber Costa9231b262008-03-25 18:36:26 -0300155static inline void
156dma_sync_single_for_device(struct device *hwdev, dma_addr_t dma_handle,
157 size_t size, int direction)
158{
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -0700159 struct dma_mapping_ops *ops = get_dma_ops(hwdev);
160
Glauber Costa9231b262008-03-25 18:36:26 -0300161 BUG_ON(!valid_dma_direction(direction));
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -0700162 if (ops->sync_single_for_device)
163 ops->sync_single_for_device(hwdev, dma_handle, size, direction);
Glauber Costa9231b262008-03-25 18:36:26 -0300164 flush_write_buffers();
165}
166
Glauber Costa627610f2008-03-25 18:36:27 -0300167static inline void
168dma_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dma_handle,
169 unsigned long offset, size_t size, int direction)
170{
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -0700171 struct dma_mapping_ops *ops = get_dma_ops(hwdev);
Glauber Costa627610f2008-03-25 18:36:27 -0300172
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -0700173 BUG_ON(!valid_dma_direction(direction));
174 if (ops->sync_single_range_for_cpu)
175 ops->sync_single_range_for_cpu(hwdev, dma_handle, offset,
176 size, direction);
Glauber Costa627610f2008-03-25 18:36:27 -0300177 flush_write_buffers();
178}
Glauber Costa71362332008-03-25 18:36:28 -0300179
180static inline void
181dma_sync_single_range_for_device(struct device *hwdev, dma_addr_t dma_handle,
182 unsigned long offset, size_t size,
183 int direction)
184{
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -0700185 struct dma_mapping_ops *ops = get_dma_ops(hwdev);
Glauber Costa71362332008-03-25 18:36:28 -0300186
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -0700187 BUG_ON(!valid_dma_direction(direction));
188 if (ops->sync_single_range_for_device)
189 ops->sync_single_range_for_device(hwdev, dma_handle,
190 offset, size, direction);
Glauber Costa71362332008-03-25 18:36:28 -0300191 flush_write_buffers();
192}
193
Glauber Costaed435de2008-03-25 18:36:29 -0300194static inline void
195dma_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
196 int nelems, int direction)
197{
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -0700198 struct dma_mapping_ops *ops = get_dma_ops(hwdev);
199
Glauber Costaed435de2008-03-25 18:36:29 -0300200 BUG_ON(!valid_dma_direction(direction));
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -0700201 if (ops->sync_sg_for_cpu)
202 ops->sync_sg_for_cpu(hwdev, sg, nelems, direction);
Glauber Costaed435de2008-03-25 18:36:29 -0300203 flush_write_buffers();
204}
Glauber Costae7f3a912008-03-25 18:36:30 -0300205
206static inline void
207dma_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,
208 int nelems, int direction)
209{
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -0700210 struct dma_mapping_ops *ops = get_dma_ops(hwdev);
211
Glauber Costae7f3a912008-03-25 18:36:30 -0300212 BUG_ON(!valid_dma_direction(direction));
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -0700213 if (ops->sync_sg_for_device)
214 ops->sync_sg_for_device(hwdev, sg, nelems, direction);
Glauber Costae7f3a912008-03-25 18:36:30 -0300215
216 flush_write_buffers();
217}
Glauber Costa4d92fbf2008-03-25 18:36:32 -0300218
219static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
220 size_t offset, size_t size,
221 int direction)
222{
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -0700223 struct dma_mapping_ops *ops = get_dma_ops(dev);
224
Ingo Molnar2be62142008-04-19 19:19:56 +0200225 BUG_ON(!valid_dma_direction(direction));
FUJITA Tomonori8d8bb392008-07-25 19:44:49 -0700226 return ops->map_single(dev, page_to_phys(page) + offset,
227 size, direction);
Glauber Costa4d92fbf2008-03-25 18:36:32 -0300228}
229
230static inline void dma_unmap_page(struct device *dev, dma_addr_t addr,
231 size_t size, int direction)
232{
233 dma_unmap_single(dev, addr, size, direction);
234}
235
Glauber Costa3cb6a912008-03-25 18:36:33 -0300236static inline void
237dma_cache_sync(struct device *dev, void *vaddr, size_t size,
238 enum dma_data_direction dir)
239{
240 flush_write_buffers();
241}
Glauber Costaae17a63b2008-03-25 18:36:38 -0300242
Glauber Costab7107a32008-03-25 18:36:39 -0300243static inline int dma_get_cache_alignment(void)
244{
245 /* no easy way to get cache size on all x86, so return the
246 * maximum possible, to be safe */
247 return boot_cpu_data.x86_clflush_size;
248}
249
250#define dma_is_consistent(d, h) (1)
251
Dmitry Baryshkov323ec002008-06-29 14:19:31 +0400252#include <asm-generic/dma-coherent.h>
Glauber Costa6f536632008-03-25 18:36:20 -0300253#endif