diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-30 16:41:00 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-30 16:41:00 -0400 |
commit | 712b0006bf3a9ed0b14a56c3291975e582127766 (patch) | |
tree | aff33e947673137ae21734321e1f036600297223 /arch/x86 | |
parent | e1c502482853f84606928f5a2f2eb6da1993cda1 (diff) | |
parent | b0d44c0dbbd52effb731b1c0af9afd56215c48de (diff) |
Merge branch 'iommu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'iommu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (60 commits)
dma-debug: make memory range checks more consistent
dma-debug: warn of unmapping an invalid dma address
dma-debug: fix dma_debug_add_bus() definition for !CONFIG_DMA_API_DEBUG
dma-debug/x86: register pci bus for dma-debug leak detection
dma-debug: add a check dma memory leaks
dma-debug: add checks for kernel text and rodata
dma-debug: print stacktrace of mapping path on unmap error
dma-debug: Documentation update
dma-debug: x86 architecture bindings
dma-debug: add function to dump dma mappings
dma-debug: add checks for sync_single_sg_*
dma-debug: add checks for sync_single_range_*
dma-debug: add checks for sync_single_*
dma-debug: add checking for [alloc|free]_coherent
dma-debug: add add checking for map/unmap_sg
dma-debug: add checking for map/unmap_page/single
dma-debug: add core checking functions
dma-debug: add debugfs interface
dma-debug: add kernel command line parameters
dma-debug: add initialization code
...
Fix trivial conflicts due to whitespace changes in arch/x86/kernel/pci-nommu.c
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/Kconfig | 1 | ||||
-rw-r--r-- | arch/x86/include/asm/device.h | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/dma-mapping.h | 188 | ||||
-rw-r--r-- | arch/x86/include/asm/iommu.h | 2 | ||||
-rw-r--r-- | arch/x86/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/x86/kernel/amd_iommu.c | 26 | ||||
-rw-r--r-- | arch/x86/kernel/pci-calgary_64.c | 38 | ||||
-rw-r--r-- | arch/x86/kernel/pci-dma.c | 14 | ||||
-rw-r--r-- | arch/x86/kernel/pci-gart_64.c | 34 | ||||
-rw-r--r-- | arch/x86/kernel/pci-nommu.c | 21 | ||||
-rw-r--r-- | arch/x86/kernel/pci-swiotlb.c (renamed from arch/x86/kernel/pci-swiotlb_64.c) | 19 |
11 files changed, 181 insertions, 166 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 34bc3a89228b..45161b816313 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -40,6 +40,7 @@ config X86 | |||
40 | select HAVE_GENERIC_DMA_COHERENT if X86_32 | 40 | select HAVE_GENERIC_DMA_COHERENT if X86_32 |
41 | select HAVE_EFFICIENT_UNALIGNED_ACCESS | 41 | select HAVE_EFFICIENT_UNALIGNED_ACCESS |
42 | select USER_STACKTRACE_SUPPORT | 42 | select USER_STACKTRACE_SUPPORT |
43 | select HAVE_DMA_API_DEBUG | ||
43 | select HAVE_KERNEL_GZIP | 44 | select HAVE_KERNEL_GZIP |
44 | select HAVE_KERNEL_BZIP2 | 45 | select HAVE_KERNEL_BZIP2 |
45 | select HAVE_KERNEL_LZMA | 46 | select HAVE_KERNEL_LZMA |
diff --git a/arch/x86/include/asm/device.h b/arch/x86/include/asm/device.h index 3c034f48fdb0..4994a20acbcb 100644 --- a/arch/x86/include/asm/device.h +++ b/arch/x86/include/asm/device.h | |||
@@ -6,7 +6,7 @@ struct dev_archdata { | |||
6 | void *acpi_handle; | 6 | void *acpi_handle; |
7 | #endif | 7 | #endif |
8 | #ifdef CONFIG_X86_64 | 8 | #ifdef CONFIG_X86_64 |
9 | struct dma_mapping_ops *dma_ops; | 9 | struct dma_map_ops *dma_ops; |
10 | #endif | 10 | #endif |
11 | #ifdef CONFIG_DMAR | 11 | #ifdef CONFIG_DMAR |
12 | void *iommu; /* hook for IOMMU specific extension */ | 12 | void *iommu; /* hook for IOMMU specific extension */ |
diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h index 132a134d12f2..cea7b74963e9 100644 --- a/arch/x86/include/asm/dma-mapping.h +++ b/arch/x86/include/asm/dma-mapping.h | |||
@@ -7,6 +7,8 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/scatterlist.h> | 9 | #include <linux/scatterlist.h> |
10 | #include <linux/dma-debug.h> | ||
11 | #include <linux/dma-attrs.h> | ||
10 | #include <asm/io.h> | 12 | #include <asm/io.h> |
11 | #include <asm/swiotlb.h> | 13 | #include <asm/swiotlb.h> |
12 | #include <asm-generic/dma-coherent.h> | 14 | #include <asm-generic/dma-coherent.h> |
@@ -16,47 +18,9 @@ extern int iommu_merge; | |||
16 | extern struct device x86_dma_fallback_dev; | 18 | extern struct device x86_dma_fallback_dev; |
17 | extern int panic_on_overflow; | 19 | extern int panic_on_overflow; |
18 | 20 | ||
19 | struct dma_mapping_ops { | 21 | extern struct dma_map_ops *dma_ops; |
20 | int (*mapping_error)(struct device *dev, | 22 | |
21 | dma_addr_t dma_addr); | 23 | static inline struct dma_map_ops *get_dma_ops(struct device *dev) |
22 | 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); | ||
26 | dma_addr_t (*map_single)(struct device *hwdev, phys_addr_t ptr, | ||
27 | size_t size, int direction); | ||
28 | void (*unmap_single)(struct device *dev, dma_addr_t addr, | ||
29 | size_t size, int direction); | ||
30 | void (*sync_single_for_cpu)(struct device *hwdev, | ||
31 | dma_addr_t dma_handle, size_t size, | ||
32 | int direction); | ||
33 | void (*sync_single_for_device)(struct device *hwdev, | ||
34 | dma_addr_t dma_handle, size_t size, | ||
35 | int direction); | ||
36 | void (*sync_single_range_for_cpu)(struct device *hwdev, | ||
37 | dma_addr_t dma_handle, unsigned long offset, | ||
38 | size_t size, int direction); | ||
39 | void (*sync_single_range_for_device)(struct device *hwdev, | ||
40 | dma_addr_t dma_handle, unsigned long offset, | ||
41 | size_t size, int direction); | ||
42 | void (*sync_sg_for_cpu)(struct device *hwdev, | ||
43 | struct scatterlist *sg, int nelems, | ||
44 | int direction); | ||
45 | void (*sync_sg_for_device)(struct device *hwdev, | ||
46 | struct scatterlist *sg, int nelems, | ||
47 | int direction); | ||
48 | int (*map_sg)(struct device *hwdev, struct scatterlist *sg, | ||
49 | int nents, int direction); | ||
50 | void (*unmap_sg)(struct device *hwdev, | ||
51 | struct scatterlist *sg, int nents, | ||
52 | int direction); | ||
53 | int (*dma_supported)(struct device *hwdev, u64 mask); | ||
54 | int is_phys; | ||
55 | }; | ||
56 | |||
57 | extern struct dma_mapping_ops *dma_ops; | ||
58 | |||
59 | static inline struct dma_mapping_ops *get_dma_ops(struct device *dev) | ||
60 | { | 24 | { |
61 | #ifdef CONFIG_X86_32 | 25 | #ifdef CONFIG_X86_32 |
62 | return dma_ops; | 26 | return dma_ops; |
@@ -71,7 +35,7 @@ static inline struct dma_mapping_ops *get_dma_ops(struct device *dev) | |||
71 | /* Make sure we keep the same behaviour */ | 35 | /* Make sure we keep the same behaviour */ |
72 | static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) | 36 | static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) |
73 | { | 37 | { |
74 | struct dma_mapping_ops *ops = get_dma_ops(dev); | 38 | struct dma_map_ops *ops = get_dma_ops(dev); |
75 | if (ops->mapping_error) | 39 | if (ops->mapping_error) |
76 | return ops->mapping_error(dev, dma_addr); | 40 | return ops->mapping_error(dev, dma_addr); |
77 | 41 | ||
@@ -90,137 +54,167 @@ extern void *dma_generic_alloc_coherent(struct device *dev, size_t size, | |||
90 | 54 | ||
91 | static inline dma_addr_t | 55 | static inline dma_addr_t |
92 | dma_map_single(struct device *hwdev, void *ptr, size_t size, | 56 | dma_map_single(struct device *hwdev, void *ptr, size_t size, |
93 | int direction) | 57 | enum dma_data_direction dir) |
94 | { | 58 | { |
95 | struct dma_mapping_ops *ops = get_dma_ops(hwdev); | 59 | struct dma_map_ops *ops = get_dma_ops(hwdev); |
96 | 60 | dma_addr_t addr; | |
97 | BUG_ON(!valid_dma_direction(direction)); | 61 | |
98 | return ops->map_single(hwdev, virt_to_phys(ptr), size, direction); | 62 | BUG_ON(!valid_dma_direction(dir)); |
63 | addr = ops->map_page(hwdev, virt_to_page(ptr), | ||
64 | (unsigned long)ptr & ~PAGE_MASK, size, | ||
65 | dir, NULL); | ||
66 | debug_dma_map_page(hwdev, virt_to_page(ptr), | ||
67 | (unsigned long)ptr & ~PAGE_MASK, size, | ||
68 | dir, addr, true); | ||
69 | return addr; | ||
99 | } | 70 | } |
100 | 71 | ||
101 | static inline void | 72 | static inline void |
102 | dma_unmap_single(struct device *dev, dma_addr_t addr, size_t size, | 73 | dma_unmap_single(struct device *dev, dma_addr_t addr, size_t size, |
103 | int direction) | 74 | enum dma_data_direction dir) |
104 | { | 75 | { |
105 | struct dma_mapping_ops *ops = get_dma_ops(dev); | 76 | struct dma_map_ops *ops = get_dma_ops(dev); |
106 | 77 | ||
107 | BUG_ON(!valid_dma_direction(direction)); | 78 | BUG_ON(!valid_dma_direction(dir)); |
108 | if (ops->unmap_single) | 79 | if (ops->unmap_page) |
109 | ops->unmap_single(dev, addr, size, direction); | 80 | ops->unmap_page(dev, addr, size, dir, NULL); |
81 | debug_dma_unmap_page(dev, addr, size, dir, true); | ||
110 | } | 82 | } |
111 | 83 | ||
112 | static inline int | 84 | static inline int |
113 | dma_map_sg(struct device *hwdev, struct scatterlist *sg, | 85 | dma_map_sg(struct device *hwdev, struct scatterlist *sg, |
114 | int nents, int direction) | 86 | int nents, enum dma_data_direction dir) |
115 | { | 87 | { |
116 | struct dma_mapping_ops *ops = get_dma_ops(hwdev); | 88 | struct dma_map_ops *ops = get_dma_ops(hwdev); |
89 | int ents; | ||
90 | |||
91 | BUG_ON(!valid_dma_direction(dir)); | ||
92 | ents = ops->map_sg(hwdev, sg, nents, dir, NULL); | ||
93 | debug_dma_map_sg(hwdev, sg, nents, ents, dir); | ||
117 | 94 | ||
118 | BUG_ON(!valid_dma_direction(direction)); | 95 | return ents; |
119 | return ops->map_sg(hwdev, sg, nents, direction); | ||
120 | } | 96 | } |
121 | 97 | ||
122 | static inline void | 98 | static inline void |
123 | dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents, | 99 | dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents, |
124 | int direction) | 100 | enum dma_data_direction dir) |
125 | { | 101 | { |
126 | struct dma_mapping_ops *ops = get_dma_ops(hwdev); | 102 | struct dma_map_ops *ops = get_dma_ops(hwdev); |
127 | 103 | ||
128 | BUG_ON(!valid_dma_direction(direction)); | 104 | BUG_ON(!valid_dma_direction(dir)); |
105 | debug_dma_unmap_sg(hwdev, sg, nents, dir); | ||
129 | if (ops->unmap_sg) | 106 | if (ops->unmap_sg) |
130 | ops->unmap_sg(hwdev, sg, nents, direction); | 107 | ops->unmap_sg(hwdev, sg, nents, dir, NULL); |
131 | } | 108 | } |
132 | 109 | ||
133 | static inline void | 110 | static inline void |
134 | dma_sync_single_for_cpu(struct device *hwdev, dma_addr_t dma_handle, | 111 | dma_sync_single_for_cpu(struct device *hwdev, dma_addr_t dma_handle, |
135 | size_t size, int direction) | 112 | size_t size, enum dma_data_direction dir) |
136 | { | 113 | { |
137 | struct dma_mapping_ops *ops = get_dma_ops(hwdev); | 114 | struct dma_map_ops *ops = get_dma_ops(hwdev); |
138 | 115 | ||
139 | BUG_ON(!valid_dma_direction(direction)); | 116 | BUG_ON(!valid_dma_direction(dir)); |
140 | if (ops->sync_single_for_cpu) | 117 | if (ops->sync_single_for_cpu) |
141 | ops->sync_single_for_cpu(hwdev, dma_handle, size, direction); | 118 | ops->sync_single_for_cpu(hwdev, dma_handle, size, dir); |
119 | debug_dma_sync_single_for_cpu(hwdev, dma_handle, size, dir); | ||
142 | flush_write_buffers(); | 120 | flush_write_buffers(); |
143 | } | 121 | } |
144 | 122 | ||
145 | static inline void | 123 | static inline void |
146 | dma_sync_single_for_device(struct device *hwdev, dma_addr_t dma_handle, | 124 | dma_sync_single_for_device(struct device *hwdev, dma_addr_t dma_handle, |
147 | size_t size, int direction) | 125 | size_t size, enum dma_data_direction dir) |
148 | { | 126 | { |
149 | struct dma_mapping_ops *ops = get_dma_ops(hwdev); | 127 | struct dma_map_ops *ops = get_dma_ops(hwdev); |
150 | 128 | ||
151 | BUG_ON(!valid_dma_direction(direction)); | 129 | BUG_ON(!valid_dma_direction(dir)); |
152 | if (ops->sync_single_for_device) | 130 | if (ops->sync_single_for_device) |
153 | ops->sync_single_for_device(hwdev, dma_handle, size, direction); | 131 | ops->sync_single_for_device(hwdev, dma_handle, size, dir); |
132 | debug_dma_sync_single_for_device(hwdev, dma_handle, size, dir); | ||
154 | flush_write_buffers(); | 133 | flush_write_buffers(); |
155 | } | 134 | } |
156 | 135 | ||
157 | static inline void | 136 | static inline void |
158 | dma_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dma_handle, | 137 | dma_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dma_handle, |
159 | unsigned long offset, size_t size, int direction) | 138 | unsigned long offset, size_t size, |
139 | enum dma_data_direction dir) | ||
160 | { | 140 | { |
161 | struct dma_mapping_ops *ops = get_dma_ops(hwdev); | 141 | struct dma_map_ops *ops = get_dma_ops(hwdev); |
162 | 142 | ||
163 | BUG_ON(!valid_dma_direction(direction)); | 143 | BUG_ON(!valid_dma_direction(dir)); |
164 | if (ops->sync_single_range_for_cpu) | 144 | if (ops->sync_single_range_for_cpu) |
165 | ops->sync_single_range_for_cpu(hwdev, dma_handle, offset, | 145 | ops->sync_single_range_for_cpu(hwdev, dma_handle, offset, |
166 | size, direction); | 146 | size, dir); |
147 | debug_dma_sync_single_range_for_cpu(hwdev, dma_handle, | ||
148 | offset, size, dir); | ||
167 | flush_write_buffers(); | 149 | flush_write_buffers(); |
168 | } | 150 | } |
169 | 151 | ||
170 | static inline void | 152 | static inline void |
171 | dma_sync_single_range_for_device(struct device *hwdev, dma_addr_t dma_handle, | 153 | dma_sync_single_range_for_device(struct device *hwdev, dma_addr_t dma_handle, |
172 | unsigned long offset, size_t size, | 154 | unsigned long offset, size_t size, |
173 | int direction) | 155 | enum dma_data_direction dir) |
174 | { | 156 | { |
175 | struct dma_mapping_ops *ops = get_dma_ops(hwdev); | 157 | struct dma_map_ops *ops = get_dma_ops(hwdev); |
176 | 158 | ||
177 | BUG_ON(!valid_dma_direction(direction)); | 159 | BUG_ON(!valid_dma_direction(dir)); |
178 | if (ops->sync_single_range_for_device) | 160 | if (ops->sync_single_range_for_device) |
179 | ops->sync_single_range_for_device(hwdev, dma_handle, | 161 | ops->sync_single_range_for_device(hwdev, dma_handle, |
180 | offset, size, direction); | 162 | offset, size, dir); |
163 | debug_dma_sync_single_range_for_device(hwdev, dma_handle, | ||
164 | offset, size, dir); | ||
181 | flush_write_buffers(); | 165 | flush_write_buffers(); |
182 | } | 166 | } |
183 | 167 | ||
184 | static inline void | 168 | static inline void |
185 | dma_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, | 169 | dma_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, |
186 | int nelems, int direction) | 170 | int nelems, enum dma_data_direction dir) |
187 | { | 171 | { |
188 | struct dma_mapping_ops *ops = get_dma_ops(hwdev); | 172 | struct dma_map_ops *ops = get_dma_ops(hwdev); |
189 | 173 | ||
190 | BUG_ON(!valid_dma_direction(direction)); | 174 | BUG_ON(!valid_dma_direction(dir)); |
191 | if (ops->sync_sg_for_cpu) | 175 | if (ops->sync_sg_for_cpu) |
192 | ops->sync_sg_for_cpu(hwdev, sg, nelems, direction); | 176 | ops->sync_sg_for_cpu(hwdev, sg, nelems, dir); |
177 | debug_dma_sync_sg_for_cpu(hwdev, sg, nelems, dir); | ||
193 | flush_write_buffers(); | 178 | flush_write_buffers(); |
194 | } | 179 | } |
195 | 180 | ||
196 | static inline void | 181 | static inline void |
197 | dma_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, | 182 | dma_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, |
198 | int nelems, int direction) | 183 | int nelems, enum dma_data_direction dir) |
199 | { | 184 | { |
200 | struct dma_mapping_ops *ops = get_dma_ops(hwdev); | 185 | struct dma_map_ops *ops = get_dma_ops(hwdev); |
201 | 186 | ||
202 | BUG_ON(!valid_dma_direction(direction)); | 187 | BUG_ON(!valid_dma_direction(dir)); |
203 | if (ops->sync_sg_for_device) | 188 | if (ops->sync_sg_for_device) |
204 | ops->sync_sg_for_device(hwdev, sg, nelems, direction); | 189 | ops->sync_sg_for_device(hwdev, sg, nelems, dir); |
190 | debug_dma_sync_sg_for_device(hwdev, sg, nelems, dir); | ||
205 | 191 | ||
206 | flush_write_buffers(); | 192 | flush_write_buffers(); |
207 | } | 193 | } |
208 | 194 | ||
209 | static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, | 195 | static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, |
210 | size_t offset, size_t size, | 196 | size_t offset, size_t size, |
211 | int direction) | 197 | enum dma_data_direction dir) |
212 | { | 198 | { |
213 | struct dma_mapping_ops *ops = get_dma_ops(dev); | 199 | struct dma_map_ops *ops = get_dma_ops(dev); |
200 | dma_addr_t addr; | ||
214 | 201 | ||
215 | BUG_ON(!valid_dma_direction(direction)); | 202 | BUG_ON(!valid_dma_direction(dir)); |
216 | return ops->map_single(dev, page_to_phys(page) + offset, | 203 | addr = ops->map_page(dev, page, offset, size, dir, NULL); |
217 | size, direction); | 204 | debug_dma_map_page(dev, page, offset, size, dir, addr, false); |
205 | |||
206 | return addr; | ||
218 | } | 207 | } |
219 | 208 | ||
220 | static inline void dma_unmap_page(struct device *dev, dma_addr_t addr, | 209 | static inline void dma_unmap_page(struct device *dev, dma_addr_t addr, |
221 | size_t size, int direction) | 210 | size_t size, enum dma_data_direction dir) |
222 | { | 211 | { |
223 | dma_unmap_single(dev, addr, size, direction); | 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); | ||
224 | } | 218 | } |
225 | 219 | ||
226 | static inline void | 220 | static inline void |
@@ -266,7 +260,7 @@ static inline void * | |||
266 | dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, | 260 | dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, |
267 | gfp_t gfp) | 261 | gfp_t gfp) |
268 | { | 262 | { |
269 | struct dma_mapping_ops *ops = get_dma_ops(dev); | 263 | struct dma_map_ops *ops = get_dma_ops(dev); |
270 | void *memory; | 264 | void *memory; |
271 | 265 | ||
272 | gfp &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32); | 266 | gfp &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32); |
@@ -285,20 +279,24 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, | |||
285 | if (!ops->alloc_coherent) | 279 | if (!ops->alloc_coherent) |
286 | return NULL; | 280 | return NULL; |
287 | 281 | ||
288 | return ops->alloc_coherent(dev, size, dma_handle, | 282 | memory = ops->alloc_coherent(dev, size, dma_handle, |
289 | dma_alloc_coherent_gfp_flags(dev, gfp)); | 283 | dma_alloc_coherent_gfp_flags(dev, gfp)); |
284 | debug_dma_alloc_coherent(dev, size, *dma_handle, memory); | ||
285 | |||
286 | return memory; | ||
290 | } | 287 | } |
291 | 288 | ||
292 | static inline void dma_free_coherent(struct device *dev, size_t size, | 289 | static inline void dma_free_coherent(struct device *dev, size_t size, |
293 | void *vaddr, dma_addr_t bus) | 290 | void *vaddr, dma_addr_t bus) |
294 | { | 291 | { |
295 | struct dma_mapping_ops *ops = get_dma_ops(dev); | 292 | struct dma_map_ops *ops = get_dma_ops(dev); |
296 | 293 | ||
297 | WARN_ON(irqs_disabled()); /* for portability */ | 294 | WARN_ON(irqs_disabled()); /* for portability */ |
298 | 295 | ||
299 | if (dma_release_from_coherent(dev, get_order(size), vaddr)) | 296 | if (dma_release_from_coherent(dev, get_order(size), vaddr)) |
300 | return; | 297 | return; |
301 | 298 | ||
299 | debug_dma_free_coherent(dev, size, vaddr, bus); | ||
302 | if (ops->free_coherent) | 300 | if (ops->free_coherent) |
303 | ops->free_coherent(dev, size, vaddr, bus); | 301 | ops->free_coherent(dev, size, vaddr, bus); |
304 | } | 302 | } |
diff --git a/arch/x86/include/asm/iommu.h b/arch/x86/include/asm/iommu.h index a6ee9e6f530f..af326a2975b5 100644 --- a/arch/x86/include/asm/iommu.h +++ b/arch/x86/include/asm/iommu.h | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | extern void pci_iommu_shutdown(void); | 4 | extern void pci_iommu_shutdown(void); |
5 | extern void no_iommu_init(void); | 5 | extern void no_iommu_init(void); |
6 | extern struct dma_mapping_ops nommu_dma_ops; | 6 | extern struct dma_map_ops nommu_dma_ops; |
7 | extern int force_iommu, no_iommu; | 7 | extern int force_iommu, no_iommu; |
8 | extern int iommu_detected; | 8 | extern int iommu_detected; |
9 | 9 | ||
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 6e9c1f320acf..c611ad64137f 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
@@ -105,7 +105,7 @@ obj-$(CONFIG_MICROCODE) += microcode.o | |||
105 | 105 | ||
106 | obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o | 106 | obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o |
107 | 107 | ||
108 | obj-$(CONFIG_SWIOTLB) += pci-swiotlb_64.o # NB rename without _64 | 108 | obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o |
109 | 109 | ||
110 | ### | 110 | ### |
111 | # 64 bit specific files | 111 | # 64 bit specific files |
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 5113c080f0c4..c5962fe3796f 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
@@ -22,10 +22,9 @@ | |||
22 | #include <linux/bitops.h> | 22 | #include <linux/bitops.h> |
23 | #include <linux/debugfs.h> | 23 | #include <linux/debugfs.h> |
24 | #include <linux/scatterlist.h> | 24 | #include <linux/scatterlist.h> |
25 | #include <linux/dma-mapping.h> | ||
25 | #include <linux/iommu-helper.h> | 26 | #include <linux/iommu-helper.h> |
26 | #ifdef CONFIG_IOMMU_API | ||
27 | #include <linux/iommu.h> | 27 | #include <linux/iommu.h> |
28 | #endif | ||
29 | #include <asm/proto.h> | 28 | #include <asm/proto.h> |
30 | #include <asm/iommu.h> | 29 | #include <asm/iommu.h> |
31 | #include <asm/gart.h> | 30 | #include <asm/gart.h> |
@@ -1297,8 +1296,10 @@ static void __unmap_single(struct amd_iommu *iommu, | |||
1297 | /* | 1296 | /* |
1298 | * The exported map_single function for dma_ops. | 1297 | * The exported map_single function for dma_ops. |
1299 | */ | 1298 | */ |
1300 | static dma_addr_t map_single(struct device *dev, phys_addr_t paddr, | 1299 | static dma_addr_t map_page(struct device *dev, struct page *page, |
1301 | size_t size, int dir) | 1300 | unsigned long offset, size_t size, |
1301 | enum dma_data_direction dir, | ||
1302 | struct dma_attrs *attrs) | ||
1302 | { | 1303 | { |
1303 | unsigned long flags; | 1304 | unsigned long flags; |
1304 | struct amd_iommu *iommu; | 1305 | struct amd_iommu *iommu; |
@@ -1306,6 +1307,7 @@ static dma_addr_t map_single(struct device *dev, phys_addr_t paddr, | |||
1306 | u16 devid; | 1307 | u16 devid; |
1307 | dma_addr_t addr; | 1308 | dma_addr_t addr; |
1308 | u64 dma_mask; | 1309 | u64 dma_mask; |
1310 | phys_addr_t paddr = page_to_phys(page) + offset; | ||
1309 | 1311 | ||
1310 | INC_STATS_COUNTER(cnt_map_single); | 1312 | INC_STATS_COUNTER(cnt_map_single); |
1311 | 1313 | ||
@@ -1340,8 +1342,8 @@ out: | |||
1340 | /* | 1342 | /* |
1341 | * The exported unmap_single function for dma_ops. | 1343 | * The exported unmap_single function for dma_ops. |
1342 | */ | 1344 | */ |
1343 | static void unmap_single(struct device *dev, dma_addr_t dma_addr, | 1345 | static void unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size, |
1344 | size_t size, int dir) | 1346 | enum dma_data_direction dir, struct dma_attrs *attrs) |
1345 | { | 1347 | { |
1346 | unsigned long flags; | 1348 | unsigned long flags; |
1347 | struct amd_iommu *iommu; | 1349 | struct amd_iommu *iommu; |
@@ -1390,7 +1392,8 @@ static int map_sg_no_iommu(struct device *dev, struct scatterlist *sglist, | |||
1390 | * lists). | 1392 | * lists). |
1391 | */ | 1393 | */ |
1392 | static int map_sg(struct device *dev, struct scatterlist *sglist, | 1394 | static int map_sg(struct device *dev, struct scatterlist *sglist, |
1393 | int nelems, int dir) | 1395 | int nelems, enum dma_data_direction dir, |
1396 | struct dma_attrs *attrs) | ||
1394 | { | 1397 | { |
1395 | unsigned long flags; | 1398 | unsigned long flags; |
1396 | struct amd_iommu *iommu; | 1399 | struct amd_iommu *iommu; |
@@ -1457,7 +1460,8 @@ unmap: | |||
1457 | * lists). | 1460 | * lists). |
1458 | */ | 1461 | */ |
1459 | static void unmap_sg(struct device *dev, struct scatterlist *sglist, | 1462 | static void unmap_sg(struct device *dev, struct scatterlist *sglist, |
1460 | int nelems, int dir) | 1463 | int nelems, enum dma_data_direction dir, |
1464 | struct dma_attrs *attrs) | ||
1461 | { | 1465 | { |
1462 | unsigned long flags; | 1466 | unsigned long flags; |
1463 | struct amd_iommu *iommu; | 1467 | struct amd_iommu *iommu; |
@@ -1644,11 +1648,11 @@ static void prealloc_protection_domains(void) | |||
1644 | } | 1648 | } |
1645 | } | 1649 | } |
1646 | 1650 | ||
1647 | static struct dma_mapping_ops amd_iommu_dma_ops = { | 1651 | static struct dma_map_ops amd_iommu_dma_ops = { |
1648 | .alloc_coherent = alloc_coherent, | 1652 | .alloc_coherent = alloc_coherent, |
1649 | .free_coherent = free_coherent, | 1653 | .free_coherent = free_coherent, |
1650 | .map_single = map_single, | 1654 | .map_page = map_page, |
1651 | .unmap_single = unmap_single, | 1655 | .unmap_page = unmap_page, |
1652 | .map_sg = map_sg, | 1656 | .map_sg = map_sg, |
1653 | .unmap_sg = unmap_sg, | 1657 | .unmap_sg = unmap_sg, |
1654 | .dma_supported = amd_iommu_dma_supported, | 1658 | .dma_supported = amd_iommu_dma_supported, |
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c index d28bbdc35e4e..755c21e906f3 100644 --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c | |||
@@ -380,8 +380,9 @@ static inline struct iommu_table *find_iommu_table(struct device *dev) | |||
380 | return tbl; | 380 | return tbl; |
381 | } | 381 | } |
382 | 382 | ||
383 | static void calgary_unmap_sg(struct device *dev, | 383 | static void calgary_unmap_sg(struct device *dev, struct scatterlist *sglist, |
384 | struct scatterlist *sglist, int nelems, int direction) | 384 | int nelems,enum dma_data_direction dir, |
385 | struct dma_attrs *attrs) | ||
385 | { | 386 | { |
386 | struct iommu_table *tbl = find_iommu_table(dev); | 387 | struct iommu_table *tbl = find_iommu_table(dev); |
387 | struct scatterlist *s; | 388 | struct scatterlist *s; |
@@ -404,7 +405,8 @@ static void calgary_unmap_sg(struct device *dev, | |||
404 | } | 405 | } |
405 | 406 | ||
406 | static int calgary_map_sg(struct device *dev, struct scatterlist *sg, | 407 | static int calgary_map_sg(struct device *dev, struct scatterlist *sg, |
407 | int nelems, int direction) | 408 | int nelems, enum dma_data_direction dir, |
409 | struct dma_attrs *attrs) | ||
408 | { | 410 | { |
409 | struct iommu_table *tbl = find_iommu_table(dev); | 411 | struct iommu_table *tbl = find_iommu_table(dev); |
410 | struct scatterlist *s; | 412 | struct scatterlist *s; |
@@ -429,15 +431,14 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg, | |||
429 | s->dma_address = (entry << PAGE_SHIFT) | s->offset; | 431 | s->dma_address = (entry << PAGE_SHIFT) | s->offset; |
430 | 432 | ||
431 | /* insert into HW table */ | 433 | /* insert into HW table */ |
432 | tce_build(tbl, entry, npages, vaddr & PAGE_MASK, | 434 | tce_build(tbl, entry, npages, vaddr & PAGE_MASK, dir); |
433 | direction); | ||
434 | 435 | ||
435 | s->dma_length = s->length; | 436 | s->dma_length = s->length; |
436 | } | 437 | } |
437 | 438 | ||
438 | return nelems; | 439 | return nelems; |
439 | error: | 440 | error: |
440 | calgary_unmap_sg(dev, sg, nelems, direction); | 441 | calgary_unmap_sg(dev, sg, nelems, dir, NULL); |
441 | for_each_sg(sg, s, nelems, i) { | 442 | for_each_sg(sg, s, nelems, i) { |
442 | sg->dma_address = bad_dma_address; | 443 | sg->dma_address = bad_dma_address; |
443 | sg->dma_length = 0; | 444 | sg->dma_length = 0; |
@@ -445,10 +446,12 @@ error: | |||
445 | return 0; | 446 | return 0; |
446 | } | 447 | } |
447 | 448 | ||
448 | static dma_addr_t calgary_map_single(struct device *dev, phys_addr_t paddr, | 449 | static dma_addr_t calgary_map_page(struct device *dev, struct page *page, |
449 | size_t size, int direction) | 450 | unsigned long offset, size_t size, |
451 | enum dma_data_direction dir, | ||
452 | struct dma_attrs *attrs) | ||
450 | { | 453 | { |
451 | void *vaddr = phys_to_virt(paddr); | 454 | void *vaddr = page_address(page) + offset; |
452 | unsigned long uaddr; | 455 | unsigned long uaddr; |
453 | unsigned int npages; | 456 | unsigned int npages; |
454 | struct iommu_table *tbl = find_iommu_table(dev); | 457 | struct iommu_table *tbl = find_iommu_table(dev); |
@@ -456,17 +459,18 @@ static dma_addr_t calgary_map_single(struct device *dev, phys_addr_t paddr, | |||
456 | uaddr = (unsigned long)vaddr; | 459 | uaddr = (unsigned long)vaddr; |
457 | npages = iommu_num_pages(uaddr, size, PAGE_SIZE); | 460 | npages = iommu_num_pages(uaddr, size, PAGE_SIZE); |
458 | 461 | ||
459 | return iommu_alloc(dev, tbl, vaddr, npages, direction); | 462 | return iommu_alloc(dev, tbl, vaddr, npages, dir); |
460 | } | 463 | } |
461 | 464 | ||
462 | static void calgary_unmap_single(struct device *dev, dma_addr_t dma_handle, | 465 | static void calgary_unmap_page(struct device *dev, dma_addr_t dma_addr, |
463 | size_t size, int direction) | 466 | size_t size, enum dma_data_direction dir, |
467 | struct dma_attrs *attrs) | ||
464 | { | 468 | { |
465 | struct iommu_table *tbl = find_iommu_table(dev); | 469 | struct iommu_table *tbl = find_iommu_table(dev); |
466 | unsigned int npages; | 470 | unsigned int npages; |
467 | 471 | ||
468 | npages = iommu_num_pages(dma_handle, size, PAGE_SIZE); | 472 | npages = iommu_num_pages(dma_addr, size, PAGE_SIZE); |
469 | iommu_free(tbl, dma_handle, npages); | 473 | iommu_free(tbl, dma_addr, npages); |
470 | } | 474 | } |
471 | 475 | ||
472 | static void* calgary_alloc_coherent(struct device *dev, size_t size, | 476 | static void* calgary_alloc_coherent(struct device *dev, size_t size, |
@@ -515,13 +519,13 @@ static void calgary_free_coherent(struct device *dev, size_t size, | |||
515 | free_pages((unsigned long)vaddr, get_order(size)); | 519 | free_pages((unsigned long)vaddr, get_order(size)); |
516 | } | 520 | } |
517 | 521 | ||
518 | static struct dma_mapping_ops calgary_dma_ops = { | 522 | static struct dma_map_ops calgary_dma_ops = { |
519 | .alloc_coherent = calgary_alloc_coherent, | 523 | .alloc_coherent = calgary_alloc_coherent, |
520 | .free_coherent = calgary_free_coherent, | 524 | .free_coherent = calgary_free_coherent, |
521 | .map_single = calgary_map_single, | ||
522 | .unmap_single = calgary_unmap_single, | ||
523 | .map_sg = calgary_map_sg, | 525 | .map_sg = calgary_map_sg, |
524 | .unmap_sg = calgary_unmap_sg, | 526 | .unmap_sg = calgary_unmap_sg, |
527 | .map_page = calgary_map_page, | ||
528 | .unmap_page = calgary_unmap_page, | ||
525 | }; | 529 | }; |
526 | 530 | ||
527 | static inline void __iomem * busno_to_bbar(unsigned char num) | 531 | static inline void __iomem * busno_to_bbar(unsigned char num) |
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index b25428533141..c7c4776ff630 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c | |||
@@ -1,4 +1,5 @@ | |||
1 | #include <linux/dma-mapping.h> | 1 | #include <linux/dma-mapping.h> |
2 | #include <linux/dma-debug.h> | ||
2 | #include <linux/dmar.h> | 3 | #include <linux/dmar.h> |
3 | #include <linux/bootmem.h> | 4 | #include <linux/bootmem.h> |
4 | #include <linux/pci.h> | 5 | #include <linux/pci.h> |
@@ -12,7 +13,7 @@ | |||
12 | 13 | ||
13 | static int forbid_dac __read_mostly; | 14 | static int forbid_dac __read_mostly; |
14 | 15 | ||
15 | struct dma_mapping_ops *dma_ops; | 16 | struct dma_map_ops *dma_ops; |
16 | EXPORT_SYMBOL(dma_ops); | 17 | EXPORT_SYMBOL(dma_ops); |
17 | 18 | ||
18 | static int iommu_sac_force __read_mostly; | 19 | static int iommu_sac_force __read_mostly; |
@@ -44,6 +45,9 @@ struct device x86_dma_fallback_dev = { | |||
44 | }; | 45 | }; |
45 | EXPORT_SYMBOL(x86_dma_fallback_dev); | 46 | EXPORT_SYMBOL(x86_dma_fallback_dev); |
46 | 47 | ||
48 | /* Number of entries preallocated for DMA-API debugging */ | ||
49 | #define PREALLOC_DMA_DEBUG_ENTRIES 32768 | ||
50 | |||
47 | int dma_set_mask(struct device *dev, u64 mask) | 51 | int dma_set_mask(struct device *dev, u64 mask) |
48 | { | 52 | { |
49 | if (!dev->dma_mask || !dma_supported(dev, mask)) | 53 | if (!dev->dma_mask || !dma_supported(dev, mask)) |
@@ -224,7 +228,7 @@ early_param("iommu", iommu_setup); | |||
224 | 228 | ||
225 | int dma_supported(struct device *dev, u64 mask) | 229 | int dma_supported(struct device *dev, u64 mask) |
226 | { | 230 | { |
227 | struct dma_mapping_ops *ops = get_dma_ops(dev); | 231 | struct dma_map_ops *ops = get_dma_ops(dev); |
228 | 232 | ||
229 | #ifdef CONFIG_PCI | 233 | #ifdef CONFIG_PCI |
230 | if (mask > 0xffffffff && forbid_dac > 0) { | 234 | if (mask > 0xffffffff && forbid_dac > 0) { |
@@ -265,6 +269,12 @@ EXPORT_SYMBOL(dma_supported); | |||
265 | 269 | ||
266 | static int __init pci_iommu_init(void) | 270 | static int __init pci_iommu_init(void) |
267 | { | 271 | { |
272 | dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); | ||
273 | |||
274 | #ifdef CONFIG_PCI | ||
275 | dma_debug_add_bus(&pci_bus_type); | ||
276 | #endif | ||
277 | |||
268 | calgary_iommu_init(); | 278 | calgary_iommu_init(); |
269 | 279 | ||
270 | intel_iommu_init(); | 280 | intel_iommu_init(); |
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index d5768b1af080..b284b58c035c 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c | |||
@@ -255,10 +255,13 @@ static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem, | |||
255 | } | 255 | } |
256 | 256 | ||
257 | /* Map a single area into the IOMMU */ | 257 | /* Map a single area into the IOMMU */ |
258 | static dma_addr_t | 258 | static dma_addr_t gart_map_page(struct device *dev, struct page *page, |
259 | gart_map_single(struct device *dev, phys_addr_t paddr, size_t size, int dir) | 259 | unsigned long offset, size_t size, |
260 | enum dma_data_direction dir, | ||
261 | struct dma_attrs *attrs) | ||
260 | { | 262 | { |
261 | unsigned long bus; | 263 | unsigned long bus; |
264 | phys_addr_t paddr = page_to_phys(page) + offset; | ||
262 | 265 | ||
263 | if (!dev) | 266 | if (!dev) |
264 | dev = &x86_dma_fallback_dev; | 267 | dev = &x86_dma_fallback_dev; |
@@ -275,8 +278,9 @@ gart_map_single(struct device *dev, phys_addr_t paddr, size_t size, int dir) | |||
275 | /* | 278 | /* |
276 | * Free a DMA mapping. | 279 | * Free a DMA mapping. |
277 | */ | 280 | */ |
278 | static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr, | 281 | static void gart_unmap_page(struct device *dev, dma_addr_t dma_addr, |
279 | size_t size, int direction) | 282 | size_t size, enum dma_data_direction dir, |
283 | struct dma_attrs *attrs) | ||
280 | { | 284 | { |
281 | unsigned long iommu_page; | 285 | unsigned long iommu_page; |
282 | int npages; | 286 | int npages; |
@@ -298,8 +302,8 @@ static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr, | |||
298 | /* | 302 | /* |
299 | * Wrapper for pci_unmap_single working with scatterlists. | 303 | * Wrapper for pci_unmap_single working with scatterlists. |
300 | */ | 304 | */ |
301 | static void | 305 | static void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, |
302 | gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) | 306 | enum dma_data_direction dir, struct dma_attrs *attrs) |
303 | { | 307 | { |
304 | struct scatterlist *s; | 308 | struct scatterlist *s; |
305 | int i; | 309 | int i; |
@@ -307,7 +311,7 @@ gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) | |||
307 | for_each_sg(sg, s, nents, i) { | 311 | for_each_sg(sg, s, nents, i) { |
308 | if (!s->dma_length || !s->length) | 312 | if (!s->dma_length || !s->length) |
309 | break; | 313 | break; |
310 | gart_unmap_single(dev, s->dma_address, s->dma_length, dir); | 314 | gart_unmap_page(dev, s->dma_address, s->dma_length, dir, NULL); |
311 | } | 315 | } |
312 | } | 316 | } |
313 | 317 | ||
@@ -329,7 +333,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg, | |||
329 | addr = dma_map_area(dev, addr, s->length, dir, 0); | 333 | addr = dma_map_area(dev, addr, s->length, dir, 0); |
330 | if (addr == bad_dma_address) { | 334 | if (addr == bad_dma_address) { |
331 | if (i > 0) | 335 | if (i > 0) |
332 | gart_unmap_sg(dev, sg, i, dir); | 336 | gart_unmap_sg(dev, sg, i, dir, NULL); |
333 | nents = 0; | 337 | nents = 0; |
334 | sg[0].dma_length = 0; | 338 | sg[0].dma_length = 0; |
335 | break; | 339 | break; |
@@ -400,8 +404,8 @@ dma_map_cont(struct device *dev, struct scatterlist *start, int nelems, | |||
400 | * DMA map all entries in a scatterlist. | 404 | * DMA map all entries in a scatterlist. |
401 | * Merge chunks that have page aligned sizes into a continuous mapping. | 405 | * Merge chunks that have page aligned sizes into a continuous mapping. |
402 | */ | 406 | */ |
403 | static int | 407 | static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, |
404 | gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) | 408 | enum dma_data_direction dir, struct dma_attrs *attrs) |
405 | { | 409 | { |
406 | struct scatterlist *s, *ps, *start_sg, *sgmap; | 410 | struct scatterlist *s, *ps, *start_sg, *sgmap; |
407 | int need = 0, nextneed, i, out, start; | 411 | int need = 0, nextneed, i, out, start; |
@@ -468,7 +472,7 @@ gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) | |||
468 | 472 | ||
469 | error: | 473 | error: |
470 | flush_gart(); | 474 | flush_gart(); |
471 | gart_unmap_sg(dev, sg, out, dir); | 475 | gart_unmap_sg(dev, sg, out, dir, NULL); |
472 | 476 | ||
473 | /* When it was forced or merged try again in a dumb way */ | 477 | /* When it was forced or merged try again in a dumb way */ |
474 | if (force_iommu || iommu_merge) { | 478 | if (force_iommu || iommu_merge) { |
@@ -521,7 +525,7 @@ static void | |||
521 | gart_free_coherent(struct device *dev, size_t size, void *vaddr, | 525 | gart_free_coherent(struct device *dev, size_t size, void *vaddr, |
522 | dma_addr_t dma_addr) | 526 | dma_addr_t dma_addr) |
523 | { | 527 | { |
524 | gart_unmap_single(dev, dma_addr, size, DMA_BIDIRECTIONAL); | 528 | gart_unmap_page(dev, dma_addr, size, DMA_BIDIRECTIONAL, NULL); |
525 | free_pages((unsigned long)vaddr, get_order(size)); | 529 | free_pages((unsigned long)vaddr, get_order(size)); |
526 | } | 530 | } |
527 | 531 | ||
@@ -707,11 +711,11 @@ static __init int init_k8_gatt(struct agp_kern_info *info) | |||
707 | return -1; | 711 | return -1; |
708 | } | 712 | } |
709 | 713 | ||
710 | static struct dma_mapping_ops gart_dma_ops = { | 714 | static struct dma_map_ops gart_dma_ops = { |
711 | .map_single = gart_map_single, | ||
712 | .unmap_single = gart_unmap_single, | ||
713 | .map_sg = gart_map_sg, | 715 | .map_sg = gart_map_sg, |
714 | .unmap_sg = gart_unmap_sg, | 716 | .unmap_sg = gart_unmap_sg, |
717 | .map_page = gart_map_page, | ||
718 | .unmap_page = gart_unmap_page, | ||
715 | .alloc_coherent = gart_alloc_coherent, | 719 | .alloc_coherent = gart_alloc_coherent, |
716 | .free_coherent = gart_free_coherent, | 720 | .free_coherent = gart_free_coherent, |
717 | }; | 721 | }; |
diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c index 8b02a3936d42..c6d703b39326 100644 --- a/arch/x86/kernel/pci-nommu.c +++ b/arch/x86/kernel/pci-nommu.c | |||
@@ -25,19 +25,19 @@ check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t size) | |||
25 | return 1; | 25 | return 1; |
26 | } | 26 | } |
27 | 27 | ||
28 | static dma_addr_t | 28 | static dma_addr_t nommu_map_page(struct device *dev, struct page *page, |
29 | nommu_map_single(struct device *hwdev, phys_addr_t paddr, size_t size, | 29 | unsigned long offset, size_t size, |
30 | int direction) | 30 | enum dma_data_direction dir, |
31 | struct dma_attrs *attrs) | ||
31 | { | 32 | { |
32 | dma_addr_t bus = paddr; | 33 | dma_addr_t bus = page_to_phys(page) + offset; |
33 | WARN_ON(size == 0); | 34 | WARN_ON(size == 0); |
34 | if (!check_addr("map_single", hwdev, bus, size)) | 35 | if (!check_addr("map_single", dev, bus, size)) |
35 | return bad_dma_address; | 36 | return bad_dma_address; |
36 | flush_write_buffers(); | 37 | flush_write_buffers(); |
37 | return bus; | 38 | return bus; |
38 | } | 39 | } |
39 | 40 | ||
40 | |||
41 | /* Map a set of buffers described by scatterlist in streaming | 41 | /* Map a set of buffers described by scatterlist in streaming |
42 | * mode for DMA. This is the scatter-gather version of the | 42 | * mode for DMA. This is the scatter-gather version of the |
43 | * above pci_map_single interface. Here the scatter gather list | 43 | * above pci_map_single interface. Here the scatter gather list |
@@ -54,7 +54,8 @@ nommu_map_single(struct device *hwdev, phys_addr_t paddr, size_t size, | |||
54 | * the same here. | 54 | * the same here. |
55 | */ | 55 | */ |
56 | static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg, | 56 | static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg, |
57 | int nents, int direction) | 57 | int nents, enum dma_data_direction dir, |
58 | struct dma_attrs *attrs) | ||
58 | { | 59 | { |
59 | struct scatterlist *s; | 60 | struct scatterlist *s; |
60 | int i; | 61 | int i; |
@@ -78,11 +79,11 @@ static void nommu_free_coherent(struct device *dev, size_t size, void *vaddr, | |||
78 | free_pages((unsigned long)vaddr, get_order(size)); | 79 | free_pages((unsigned long)vaddr, get_order(size)); |
79 | } | 80 | } |
80 | 81 | ||
81 | struct dma_mapping_ops nommu_dma_ops = { | 82 | struct dma_map_ops nommu_dma_ops = { |
82 | .alloc_coherent = dma_generic_alloc_coherent, | 83 | .alloc_coherent = dma_generic_alloc_coherent, |
83 | .free_coherent = nommu_free_coherent, | 84 | .free_coherent = nommu_free_coherent, |
84 | .map_single = nommu_map_single, | ||
85 | .map_sg = nommu_map_sg, | 85 | .map_sg = nommu_map_sg, |
86 | .map_page = nommu_map_page, | ||
86 | .is_phys = 1, | 87 | .is_phys = 1, |
87 | }; | 88 | }; |
88 | 89 | ||
diff --git a/arch/x86/kernel/pci-swiotlb_64.c b/arch/x86/kernel/pci-swiotlb.c index d59c91747665..34f12e9996ed 100644 --- a/arch/x86/kernel/pci-swiotlb_64.c +++ b/arch/x86/kernel/pci-swiotlb.c | |||
@@ -33,18 +33,11 @@ phys_addr_t swiotlb_bus_to_phys(dma_addr_t baddr) | |||
33 | return baddr; | 33 | return baddr; |
34 | } | 34 | } |
35 | 35 | ||
36 | int __weak swiotlb_arch_range_needs_mapping(void *ptr, size_t size) | 36 | int __weak swiotlb_arch_range_needs_mapping(phys_addr_t paddr, size_t size) |
37 | { | 37 | { |
38 | return 0; | 38 | return 0; |
39 | } | 39 | } |
40 | 40 | ||
41 | static dma_addr_t | ||
42 | swiotlb_map_single_phys(struct device *hwdev, phys_addr_t paddr, size_t size, | ||
43 | int direction) | ||
44 | { | ||
45 | return swiotlb_map_single(hwdev, phys_to_virt(paddr), size, direction); | ||
46 | } | ||
47 | |||
48 | static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, | 41 | static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, |
49 | dma_addr_t *dma_handle, gfp_t flags) | 42 | dma_addr_t *dma_handle, gfp_t flags) |
50 | { | 43 | { |
@@ -57,20 +50,20 @@ static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, | |||
57 | return swiotlb_alloc_coherent(hwdev, size, dma_handle, flags); | 50 | return swiotlb_alloc_coherent(hwdev, size, dma_handle, flags); |
58 | } | 51 | } |
59 | 52 | ||
60 | struct dma_mapping_ops swiotlb_dma_ops = { | 53 | struct dma_map_ops swiotlb_dma_ops = { |
61 | .mapping_error = swiotlb_dma_mapping_error, | 54 | .mapping_error = swiotlb_dma_mapping_error, |
62 | .alloc_coherent = x86_swiotlb_alloc_coherent, | 55 | .alloc_coherent = x86_swiotlb_alloc_coherent, |
63 | .free_coherent = swiotlb_free_coherent, | 56 | .free_coherent = swiotlb_free_coherent, |
64 | .map_single = swiotlb_map_single_phys, | ||
65 | .unmap_single = swiotlb_unmap_single, | ||
66 | .sync_single_for_cpu = swiotlb_sync_single_for_cpu, | 57 | .sync_single_for_cpu = swiotlb_sync_single_for_cpu, |
67 | .sync_single_for_device = swiotlb_sync_single_for_device, | 58 | .sync_single_for_device = swiotlb_sync_single_for_device, |
68 | .sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu, | 59 | .sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu, |
69 | .sync_single_range_for_device = swiotlb_sync_single_range_for_device, | 60 | .sync_single_range_for_device = swiotlb_sync_single_range_for_device, |
70 | .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu, | 61 | .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu, |
71 | .sync_sg_for_device = swiotlb_sync_sg_for_device, | 62 | .sync_sg_for_device = swiotlb_sync_sg_for_device, |
72 | .map_sg = swiotlb_map_sg, | 63 | .map_sg = swiotlb_map_sg_attrs, |
73 | .unmap_sg = swiotlb_unmap_sg, | 64 | .unmap_sg = swiotlb_unmap_sg_attrs, |
65 | .map_page = swiotlb_map_page, | ||
66 | .unmap_page = swiotlb_unmap_page, | ||
74 | .dma_supported = NULL, | 67 | .dma_supported = NULL, |
75 | }; | 68 | }; |
76 | 69 | ||