diff options
Diffstat (limited to 'lib/swiotlb.c')
-rw-r--r-- | lib/swiotlb.c | 290 |
1 files changed, 198 insertions, 92 deletions
diff --git a/lib/swiotlb.c b/lib/swiotlb.c index 10625785eefd..50a438010182 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Dynamic DMA mapping support. | 2 | * Dynamic DMA mapping support. |
3 | * | 3 | * |
4 | * This implementation is for IA-64 and EM64T platforms that do not support | 4 | * This implementation is a fallback for platforms that do not support |
5 | * I/O TLBs (aka DMA address translation hardware). | 5 | * I/O TLBs (aka DMA address translation hardware). |
6 | * Copyright (C) 2000 Asit Mallick <Asit.K.Mallick@intel.com> | 6 | * Copyright (C) 2000 Asit Mallick <Asit.K.Mallick@intel.com> |
7 | * Copyright (C) 2000 Goutham Rao <goutham.rao@intel.com> | 7 | * Copyright (C) 2000 Goutham Rao <goutham.rao@intel.com> |
@@ -28,6 +28,7 @@ | |||
28 | #include <asm/io.h> | 28 | #include <asm/io.h> |
29 | #include <asm/dma.h> | 29 | #include <asm/dma.h> |
30 | #include <asm/scatterlist.h> | 30 | #include <asm/scatterlist.h> |
31 | #include <asm/swiotlb.h> | ||
31 | 32 | ||
32 | #include <linux/init.h> | 33 | #include <linux/init.h> |
33 | #include <linux/bootmem.h> | 34 | #include <linux/bootmem.h> |
@@ -35,8 +36,10 @@ | |||
35 | #define OFFSET(val,align) ((unsigned long) \ | 36 | #define OFFSET(val,align) ((unsigned long) \ |
36 | ( (val) & ( (align) - 1))) | 37 | ( (val) & ( (align) - 1))) |
37 | 38 | ||
39 | #ifndef SG_ENT_VIRT_ADDRESS | ||
38 | #define SG_ENT_VIRT_ADDRESS(sg) (page_address((sg)->page) + (sg)->offset) | 40 | #define SG_ENT_VIRT_ADDRESS(sg) (page_address((sg)->page) + (sg)->offset) |
39 | #define SG_ENT_PHYS_ADDRESS(SG) virt_to_phys(SG_ENT_VIRT_ADDRESS(SG)) | 41 | #define SG_ENT_PHYS_ADDRESS(sg) virt_to_bus(SG_ENT_VIRT_ADDRESS(sg)) |
42 | #endif | ||
40 | 43 | ||
41 | /* | 44 | /* |
42 | * Maximum allowable number of contiguous slabs to map, | 45 | * Maximum allowable number of contiguous slabs to map, |
@@ -101,13 +104,25 @@ static unsigned int io_tlb_index; | |||
101 | * We need to save away the original address corresponding to a mapped entry | 104 | * We need to save away the original address corresponding to a mapped entry |
102 | * for the sync operations. | 105 | * for the sync operations. |
103 | */ | 106 | */ |
104 | static unsigned char **io_tlb_orig_addr; | 107 | #ifndef SWIOTLB_ARCH_HAS_IO_TLB_ADDR_T |
108 | typedef char *io_tlb_addr_t; | ||
109 | #define swiotlb_orig_addr_null(buffer) (!(buffer)) | ||
110 | #define ptr_to_io_tlb_addr(ptr) (ptr) | ||
111 | #define page_to_io_tlb_addr(pg, off) (page_address(pg) + (off)) | ||
112 | #define sg_to_io_tlb_addr(sg) SG_ENT_VIRT_ADDRESS(sg) | ||
113 | #endif | ||
114 | static io_tlb_addr_t *io_tlb_orig_addr; | ||
105 | 115 | ||
106 | /* | 116 | /* |
107 | * Protect the above data structures in the map and unmap calls | 117 | * Protect the above data structures in the map and unmap calls |
108 | */ | 118 | */ |
109 | static DEFINE_SPINLOCK(io_tlb_lock); | 119 | static DEFINE_SPINLOCK(io_tlb_lock); |
110 | 120 | ||
121 | #ifdef SWIOTLB_EXTRA_VARIABLES | ||
122 | SWIOTLB_EXTRA_VARIABLES; | ||
123 | #endif | ||
124 | |||
125 | #ifndef SWIOTLB_ARCH_HAS_SETUP_IO_TLB_NPAGES | ||
111 | static int __init | 126 | static int __init |
112 | setup_io_tlb_npages(char *str) | 127 | setup_io_tlb_npages(char *str) |
113 | { | 128 | { |
@@ -122,30 +137,50 @@ setup_io_tlb_npages(char *str) | |||
122 | swiotlb_force = 1; | 137 | swiotlb_force = 1; |
123 | return 1; | 138 | return 1; |
124 | } | 139 | } |
140 | #endif | ||
125 | __setup("swiotlb=", setup_io_tlb_npages); | 141 | __setup("swiotlb=", setup_io_tlb_npages); |
126 | /* make io_tlb_overflow tunable too? */ | 142 | /* make io_tlb_overflow tunable too? */ |
127 | 143 | ||
144 | #ifndef swiotlb_adjust_size | ||
145 | #define swiotlb_adjust_size(size) ((void)0) | ||
146 | #endif | ||
147 | |||
148 | #ifndef swiotlb_adjust_seg | ||
149 | #define swiotlb_adjust_seg(start, size) ((void)0) | ||
150 | #endif | ||
151 | |||
152 | #ifndef swiotlb_print_info | ||
153 | #define swiotlb_print_info(bytes) \ | ||
154 | printk(KERN_INFO "Placing %luMB software IO TLB between 0x%lx - " \ | ||
155 | "0x%lx\n", bytes >> 20, \ | ||
156 | virt_to_bus(io_tlb_start), virt_to_bus(io_tlb_end)) | ||
157 | #endif | ||
158 | |||
128 | /* | 159 | /* |
129 | * Statically reserve bounce buffer space and initialize bounce buffer data | 160 | * Statically reserve bounce buffer space and initialize bounce buffer data |
130 | * structures for the software IO TLB used to implement the DMA API. | 161 | * structures for the software IO TLB used to implement the DMA API. |
131 | */ | 162 | */ |
132 | void | 163 | void __init |
133 | swiotlb_init_with_default_size (size_t default_size) | 164 | swiotlb_init_with_default_size(size_t default_size) |
134 | { | 165 | { |
135 | unsigned long i; | 166 | unsigned long i, bytes; |
136 | 167 | ||
137 | if (!io_tlb_nslabs) { | 168 | if (!io_tlb_nslabs) { |
138 | io_tlb_nslabs = (default_size >> IO_TLB_SHIFT); | 169 | io_tlb_nslabs = (default_size >> IO_TLB_SHIFT); |
139 | io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE); | 170 | io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE); |
140 | } | 171 | } |
172 | swiotlb_adjust_size(io_tlb_nslabs); | ||
173 | swiotlb_adjust_size(io_tlb_overflow); | ||
174 | |||
175 | bytes = io_tlb_nslabs << IO_TLB_SHIFT; | ||
141 | 176 | ||
142 | /* | 177 | /* |
143 | * Get IO TLB memory from the low pages | 178 | * Get IO TLB memory from the low pages |
144 | */ | 179 | */ |
145 | io_tlb_start = alloc_bootmem_low_pages(io_tlb_nslabs * (1 << IO_TLB_SHIFT)); | 180 | io_tlb_start = alloc_bootmem_low_pages(bytes); |
146 | if (!io_tlb_start) | 181 | if (!io_tlb_start) |
147 | panic("Cannot allocate SWIOTLB buffer"); | 182 | panic("Cannot allocate SWIOTLB buffer"); |
148 | io_tlb_end = io_tlb_start + io_tlb_nslabs * (1 << IO_TLB_SHIFT); | 183 | io_tlb_end = io_tlb_start + bytes; |
149 | 184 | ||
150 | /* | 185 | /* |
151 | * Allocate and initialize the free list array. This array is used | 186 | * Allocate and initialize the free list array. This array is used |
@@ -153,34 +188,45 @@ swiotlb_init_with_default_size (size_t default_size) | |||
153 | * between io_tlb_start and io_tlb_end. | 188 | * between io_tlb_start and io_tlb_end. |
154 | */ | 189 | */ |
155 | io_tlb_list = alloc_bootmem(io_tlb_nslabs * sizeof(int)); | 190 | io_tlb_list = alloc_bootmem(io_tlb_nslabs * sizeof(int)); |
156 | for (i = 0; i < io_tlb_nslabs; i++) | 191 | for (i = 0; i < io_tlb_nslabs; i++) { |
192 | if ( !(i % IO_TLB_SEGSIZE) ) | ||
193 | swiotlb_adjust_seg(io_tlb_start + (i << IO_TLB_SHIFT), | ||
194 | IO_TLB_SEGSIZE << IO_TLB_SHIFT); | ||
157 | io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); | 195 | io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); |
196 | } | ||
158 | io_tlb_index = 0; | 197 | io_tlb_index = 0; |
159 | io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(char *)); | 198 | io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(io_tlb_addr_t)); |
160 | 199 | ||
161 | /* | 200 | /* |
162 | * Get the overflow emergency buffer | 201 | * Get the overflow emergency buffer |
163 | */ | 202 | */ |
164 | io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow); | 203 | io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow); |
165 | printk(KERN_INFO "Placing software IO TLB between 0x%lx - 0x%lx\n", | 204 | if (!io_tlb_overflow_buffer) |
166 | virt_to_phys(io_tlb_start), virt_to_phys(io_tlb_end)); | 205 | panic("Cannot allocate SWIOTLB overflow buffer!\n"); |
206 | swiotlb_adjust_seg(io_tlb_overflow_buffer, io_tlb_overflow); | ||
207 | |||
208 | swiotlb_print_info(bytes); | ||
167 | } | 209 | } |
210 | #ifndef __swiotlb_init_with_default_size | ||
211 | #define __swiotlb_init_with_default_size swiotlb_init_with_default_size | ||
212 | #endif | ||
168 | 213 | ||
169 | void | 214 | void __init |
170 | swiotlb_init (void) | 215 | swiotlb_init(void) |
171 | { | 216 | { |
172 | swiotlb_init_with_default_size(64 * (1<<20)); /* default to 64MB */ | 217 | __swiotlb_init_with_default_size(64 * (1<<20)); /* default to 64MB */ |
173 | } | 218 | } |
174 | 219 | ||
220 | #ifdef SWIOTLB_ARCH_NEED_LATE_INIT | ||
175 | /* | 221 | /* |
176 | * Systems with larger DMA zones (those that don't support ISA) can | 222 | * Systems with larger DMA zones (those that don't support ISA) can |
177 | * initialize the swiotlb later using the slab allocator if needed. | 223 | * initialize the swiotlb later using the slab allocator if needed. |
178 | * This should be just like above, but with some error catching. | 224 | * This should be just like above, but with some error catching. |
179 | */ | 225 | */ |
180 | int | 226 | int |
181 | swiotlb_late_init_with_default_size (size_t default_size) | 227 | swiotlb_late_init_with_default_size(size_t default_size) |
182 | { | 228 | { |
183 | unsigned long i, req_nslabs = io_tlb_nslabs; | 229 | unsigned long i, bytes, req_nslabs = io_tlb_nslabs; |
184 | unsigned int order; | 230 | unsigned int order; |
185 | 231 | ||
186 | if (!io_tlb_nslabs) { | 232 | if (!io_tlb_nslabs) { |
@@ -191,8 +237,9 @@ swiotlb_late_init_with_default_size (size_t default_size) | |||
191 | /* | 237 | /* |
192 | * Get IO TLB memory from the low pages | 238 | * Get IO TLB memory from the low pages |
193 | */ | 239 | */ |
194 | order = get_order(io_tlb_nslabs * (1 << IO_TLB_SHIFT)); | 240 | order = get_order(io_tlb_nslabs << IO_TLB_SHIFT); |
195 | io_tlb_nslabs = SLABS_PER_PAGE << order; | 241 | io_tlb_nslabs = SLABS_PER_PAGE << order; |
242 | bytes = io_tlb_nslabs << IO_TLB_SHIFT; | ||
196 | 243 | ||
197 | while ((SLABS_PER_PAGE << order) > IO_TLB_MIN_SLABS) { | 244 | while ((SLABS_PER_PAGE << order) > IO_TLB_MIN_SLABS) { |
198 | io_tlb_start = (char *)__get_free_pages(GFP_DMA | __GFP_NOWARN, | 245 | io_tlb_start = (char *)__get_free_pages(GFP_DMA | __GFP_NOWARN, |
@@ -205,13 +252,14 @@ swiotlb_late_init_with_default_size (size_t default_size) | |||
205 | if (!io_tlb_start) | 252 | if (!io_tlb_start) |
206 | goto cleanup1; | 253 | goto cleanup1; |
207 | 254 | ||
208 | if (order != get_order(io_tlb_nslabs * (1 << IO_TLB_SHIFT))) { | 255 | if (order != get_order(bytes)) { |
209 | printk(KERN_WARNING "Warning: only able to allocate %ld MB " | 256 | printk(KERN_WARNING "Warning: only able to allocate %ld MB " |
210 | "for software IO TLB\n", (PAGE_SIZE << order) >> 20); | 257 | "for software IO TLB\n", (PAGE_SIZE << order) >> 20); |
211 | io_tlb_nslabs = SLABS_PER_PAGE << order; | 258 | io_tlb_nslabs = SLABS_PER_PAGE << order; |
259 | bytes = io_tlb_nslabs << IO_TLB_SHIFT; | ||
212 | } | 260 | } |
213 | io_tlb_end = io_tlb_start + io_tlb_nslabs * (1 << IO_TLB_SHIFT); | 261 | io_tlb_end = io_tlb_start + bytes; |
214 | memset(io_tlb_start, 0, io_tlb_nslabs * (1 << IO_TLB_SHIFT)); | 262 | memset(io_tlb_start, 0, bytes); |
215 | 263 | ||
216 | /* | 264 | /* |
217 | * Allocate and initialize the free list array. This array is used | 265 | * Allocate and initialize the free list array. This array is used |
@@ -227,12 +275,12 @@ swiotlb_late_init_with_default_size (size_t default_size) | |||
227 | io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); | 275 | io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); |
228 | io_tlb_index = 0; | 276 | io_tlb_index = 0; |
229 | 277 | ||
230 | io_tlb_orig_addr = (unsigned char **)__get_free_pages(GFP_KERNEL, | 278 | io_tlb_orig_addr = (io_tlb_addr_t *)__get_free_pages(GFP_KERNEL, |
231 | get_order(io_tlb_nslabs * sizeof(char *))); | 279 | get_order(io_tlb_nslabs * sizeof(io_tlb_addr_t))); |
232 | if (!io_tlb_orig_addr) | 280 | if (!io_tlb_orig_addr) |
233 | goto cleanup3; | 281 | goto cleanup3; |
234 | 282 | ||
235 | memset(io_tlb_orig_addr, 0, io_tlb_nslabs * sizeof(char *)); | 283 | memset(io_tlb_orig_addr, 0, io_tlb_nslabs * sizeof(io_tlb_addr_t)); |
236 | 284 | ||
237 | /* | 285 | /* |
238 | * Get the overflow emergency buffer | 286 | * Get the overflow emergency buffer |
@@ -242,29 +290,29 @@ swiotlb_late_init_with_default_size (size_t default_size) | |||
242 | if (!io_tlb_overflow_buffer) | 290 | if (!io_tlb_overflow_buffer) |
243 | goto cleanup4; | 291 | goto cleanup4; |
244 | 292 | ||
245 | printk(KERN_INFO "Placing %ldMB software IO TLB between 0x%lx - " | 293 | swiotlb_print_info(bytes); |
246 | "0x%lx\n", (io_tlb_nslabs * (1 << IO_TLB_SHIFT)) >> 20, | ||
247 | virt_to_phys(io_tlb_start), virt_to_phys(io_tlb_end)); | ||
248 | 294 | ||
249 | return 0; | 295 | return 0; |
250 | 296 | ||
251 | cleanup4: | 297 | cleanup4: |
252 | free_pages((unsigned long)io_tlb_orig_addr, get_order(io_tlb_nslabs * | 298 | free_pages((unsigned long)io_tlb_orig_addr, |
253 | sizeof(char *))); | 299 | get_order(io_tlb_nslabs * sizeof(io_tlb_addr_t))); |
254 | io_tlb_orig_addr = NULL; | 300 | io_tlb_orig_addr = NULL; |
255 | cleanup3: | 301 | cleanup3: |
256 | free_pages((unsigned long)io_tlb_list, get_order(io_tlb_nslabs * | 302 | free_pages((unsigned long)io_tlb_list, |
257 | sizeof(int))); | 303 | get_order(io_tlb_nslabs * sizeof(int))); |
258 | io_tlb_list = NULL; | 304 | io_tlb_list = NULL; |
259 | io_tlb_end = NULL; | ||
260 | cleanup2: | 305 | cleanup2: |
306 | io_tlb_end = NULL; | ||
261 | free_pages((unsigned long)io_tlb_start, order); | 307 | free_pages((unsigned long)io_tlb_start, order); |
262 | io_tlb_start = NULL; | 308 | io_tlb_start = NULL; |
263 | cleanup1: | 309 | cleanup1: |
264 | io_tlb_nslabs = req_nslabs; | 310 | io_tlb_nslabs = req_nslabs; |
265 | return -ENOMEM; | 311 | return -ENOMEM; |
266 | } | 312 | } |
313 | #endif | ||
267 | 314 | ||
315 | #ifndef SWIOTLB_ARCH_HAS_NEEDS_MAPPING | ||
268 | static inline int | 316 | static inline int |
269 | address_needs_mapping(struct device *hwdev, dma_addr_t addr) | 317 | address_needs_mapping(struct device *hwdev, dma_addr_t addr) |
270 | { | 318 | { |
@@ -275,11 +323,35 @@ address_needs_mapping(struct device *hwdev, dma_addr_t addr) | |||
275 | return (addr & ~mask) != 0; | 323 | return (addr & ~mask) != 0; |
276 | } | 324 | } |
277 | 325 | ||
326 | static inline int range_needs_mapping(const void *ptr, size_t size) | ||
327 | { | ||
328 | return swiotlb_force; | ||
329 | } | ||
330 | |||
331 | static inline int order_needs_mapping(unsigned int order) | ||
332 | { | ||
333 | return 0; | ||
334 | } | ||
335 | #endif | ||
336 | |||
337 | static void | ||
338 | __sync_single(io_tlb_addr_t buffer, char *dma_addr, size_t size, int dir) | ||
339 | { | ||
340 | #ifndef SWIOTLB_ARCH_HAS_SYNC_SINGLE | ||
341 | if (dir == DMA_TO_DEVICE) | ||
342 | memcpy(dma_addr, buffer, size); | ||
343 | else | ||
344 | memcpy(buffer, dma_addr, size); | ||
345 | #else | ||
346 | __swiotlb_arch_sync_single(buffer, dma_addr, size, dir); | ||
347 | #endif | ||
348 | } | ||
349 | |||
278 | /* | 350 | /* |
279 | * Allocates bounce buffer and returns its kernel virtual address. | 351 | * Allocates bounce buffer and returns its kernel virtual address. |
280 | */ | 352 | */ |
281 | static void * | 353 | static void * |
282 | map_single(struct device *hwdev, char *buffer, size_t size, int dir) | 354 | map_single(struct device *hwdev, io_tlb_addr_t buffer, size_t size, int dir) |
283 | { | 355 | { |
284 | unsigned long flags; | 356 | unsigned long flags; |
285 | char *dma_addr; | 357 | char *dma_addr; |
@@ -352,7 +424,7 @@ map_single(struct device *hwdev, char *buffer, size_t size, int dir) | |||
352 | */ | 424 | */ |
353 | io_tlb_orig_addr[index] = buffer; | 425 | io_tlb_orig_addr[index] = buffer; |
354 | if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) | 426 | if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) |
355 | memcpy(dma_addr, buffer, size); | 427 | __sync_single(buffer, dma_addr, size, DMA_TO_DEVICE); |
356 | 428 | ||
357 | return dma_addr; | 429 | return dma_addr; |
358 | } | 430 | } |
@@ -366,17 +438,18 @@ unmap_single(struct device *hwdev, char *dma_addr, size_t size, int dir) | |||
366 | unsigned long flags; | 438 | unsigned long flags; |
367 | int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; | 439 | int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; |
368 | int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; | 440 | int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; |
369 | char *buffer = io_tlb_orig_addr[index]; | 441 | io_tlb_addr_t buffer = io_tlb_orig_addr[index]; |
370 | 442 | ||
371 | /* | 443 | /* |
372 | * First, sync the memory before unmapping the entry | 444 | * First, sync the memory before unmapping the entry |
373 | */ | 445 | */ |
374 | if (buffer && ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL))) | 446 | if (!swiotlb_orig_addr_null(buffer) |
447 | && ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL))) | ||
375 | /* | 448 | /* |
376 | * bounce... copy the data back into the original buffer * and | 449 | * bounce... copy the data back into the original buffer * and |
377 | * delete the bounce buffer. | 450 | * delete the bounce buffer. |
378 | */ | 451 | */ |
379 | memcpy(buffer, dma_addr, size); | 452 | __sync_single(buffer, dma_addr, size, DMA_FROM_DEVICE); |
380 | 453 | ||
381 | /* | 454 | /* |
382 | * Return the buffer to the free list by setting the corresponding | 455 | * Return the buffer to the free list by setting the corresponding |
@@ -409,18 +482,18 @@ sync_single(struct device *hwdev, char *dma_addr, size_t size, | |||
409 | int dir, int target) | 482 | int dir, int target) |
410 | { | 483 | { |
411 | int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; | 484 | int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; |
412 | char *buffer = io_tlb_orig_addr[index]; | 485 | io_tlb_addr_t buffer = io_tlb_orig_addr[index]; |
413 | 486 | ||
414 | switch (target) { | 487 | switch (target) { |
415 | case SYNC_FOR_CPU: | 488 | case SYNC_FOR_CPU: |
416 | if (likely(dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)) | 489 | if (likely(dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)) |
417 | memcpy(buffer, dma_addr, size); | 490 | __sync_single(buffer, dma_addr, size, DMA_FROM_DEVICE); |
418 | else | 491 | else |
419 | BUG_ON(dir != DMA_TO_DEVICE); | 492 | BUG_ON(dir != DMA_TO_DEVICE); |
420 | break; | 493 | break; |
421 | case SYNC_FOR_DEVICE: | 494 | case SYNC_FOR_DEVICE: |
422 | if (likely(dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)) | 495 | if (likely(dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)) |
423 | memcpy(dma_addr, buffer, size); | 496 | __sync_single(buffer, dma_addr, size, DMA_TO_DEVICE); |
424 | else | 497 | else |
425 | BUG_ON(dir != DMA_FROM_DEVICE); | 498 | BUG_ON(dir != DMA_FROM_DEVICE); |
426 | break; | 499 | break; |
@@ -429,11 +502,13 @@ sync_single(struct device *hwdev, char *dma_addr, size_t size, | |||
429 | } | 502 | } |
430 | } | 503 | } |
431 | 504 | ||
505 | #ifdef SWIOTLB_ARCH_NEED_ALLOC | ||
506 | |||
432 | void * | 507 | void * |
433 | swiotlb_alloc_coherent(struct device *hwdev, size_t size, | 508 | swiotlb_alloc_coherent(struct device *hwdev, size_t size, |
434 | dma_addr_t *dma_handle, gfp_t flags) | 509 | dma_addr_t *dma_handle, gfp_t flags) |
435 | { | 510 | { |
436 | unsigned long dev_addr; | 511 | dma_addr_t dev_addr; |
437 | void *ret; | 512 | void *ret; |
438 | int order = get_order(size); | 513 | int order = get_order(size); |
439 | 514 | ||
@@ -444,8 +519,11 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size, | |||
444 | */ | 519 | */ |
445 | flags |= GFP_DMA; | 520 | flags |= GFP_DMA; |
446 | 521 | ||
447 | ret = (void *)__get_free_pages(flags, order); | 522 | if (!order_needs_mapping(order)) |
448 | if (ret && address_needs_mapping(hwdev, virt_to_phys(ret))) { | 523 | ret = (void *)__get_free_pages(flags, order); |
524 | else | ||
525 | ret = NULL; | ||
526 | if (ret && address_needs_mapping(hwdev, virt_to_bus(ret))) { | ||
449 | /* | 527 | /* |
450 | * The allocated memory isn't reachable by the device. | 528 | * The allocated memory isn't reachable by the device. |
451 | * Fall back on swiotlb_map_single(). | 529 | * Fall back on swiotlb_map_single(). |
@@ -465,22 +543,24 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size, | |||
465 | if (swiotlb_dma_mapping_error(handle)) | 543 | if (swiotlb_dma_mapping_error(handle)) |
466 | return NULL; | 544 | return NULL; |
467 | 545 | ||
468 | ret = phys_to_virt(handle); | 546 | ret = bus_to_virt(handle); |
469 | } | 547 | } |
470 | 548 | ||
471 | memset(ret, 0, size); | 549 | memset(ret, 0, size); |
472 | dev_addr = virt_to_phys(ret); | 550 | dev_addr = virt_to_bus(ret); |
473 | 551 | ||
474 | /* Confirm address can be DMA'd by device */ | 552 | /* Confirm address can be DMA'd by device */ |
475 | if (address_needs_mapping(hwdev, dev_addr)) { | 553 | if (address_needs_mapping(hwdev, dev_addr)) { |
476 | printk("hwdev DMA mask = 0x%016Lx, dev_addr = 0x%016lx\n", | 554 | printk("hwdev DMA mask = 0x%016Lx, dev_addr = 0x%016Lx\n", |
477 | (unsigned long long)*hwdev->dma_mask, dev_addr); | 555 | (unsigned long long)*hwdev->dma_mask, |
556 | (unsigned long long)dev_addr); | ||
478 | panic("swiotlb_alloc_coherent: allocated memory is out of " | 557 | panic("swiotlb_alloc_coherent: allocated memory is out of " |
479 | "range for device"); | 558 | "range for device"); |
480 | } | 559 | } |
481 | *dma_handle = dev_addr; | 560 | *dma_handle = dev_addr; |
482 | return ret; | 561 | return ret; |
483 | } | 562 | } |
563 | EXPORT_SYMBOL(swiotlb_alloc_coherent); | ||
484 | 564 | ||
485 | void | 565 | void |
486 | swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, | 566 | swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, |
@@ -493,6 +573,9 @@ swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, | |||
493 | /* DMA_TO_DEVICE to avoid memcpy in unmap_single */ | 573 | /* DMA_TO_DEVICE to avoid memcpy in unmap_single */ |
494 | swiotlb_unmap_single (hwdev, dma_handle, size, DMA_TO_DEVICE); | 574 | swiotlb_unmap_single (hwdev, dma_handle, size, DMA_TO_DEVICE); |
495 | } | 575 | } |
576 | EXPORT_SYMBOL(swiotlb_free_coherent); | ||
577 | |||
578 | #endif | ||
496 | 579 | ||
497 | static void | 580 | static void |
498 | swiotlb_full(struct device *dev, size_t size, int dir, int do_panic) | 581 | swiotlb_full(struct device *dev, size_t size, int dir, int do_panic) |
@@ -504,7 +587,7 @@ swiotlb_full(struct device *dev, size_t size, int dir, int do_panic) | |||
504 | * When the mapping is small enough return a static buffer to limit | 587 | * When the mapping is small enough return a static buffer to limit |
505 | * the damage, or panic when the transfer is too big. | 588 | * the damage, or panic when the transfer is too big. |
506 | */ | 589 | */ |
507 | printk(KERN_ERR "DMA: Out of SW-IOMMU space for %lu bytes at " | 590 | printk(KERN_ERR "DMA: Out of SW-IOMMU space for %zu bytes at " |
508 | "device %s\n", size, dev ? dev->bus_id : "?"); | 591 | "device %s\n", size, dev ? dev->bus_id : "?"); |
509 | 592 | ||
510 | if (size > io_tlb_overflow && do_panic) { | 593 | if (size > io_tlb_overflow && do_panic) { |
@@ -525,7 +608,7 @@ swiotlb_full(struct device *dev, size_t size, int dir, int do_panic) | |||
525 | dma_addr_t | 608 | dma_addr_t |
526 | swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, int dir) | 609 | swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, int dir) |
527 | { | 610 | { |
528 | unsigned long dev_addr = virt_to_phys(ptr); | 611 | dma_addr_t dev_addr = virt_to_bus(ptr); |
529 | void *map; | 612 | void *map; |
530 | 613 | ||
531 | BUG_ON(dir == DMA_NONE); | 614 | BUG_ON(dir == DMA_NONE); |
@@ -534,19 +617,20 @@ swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, int dir) | |||
534 | * we can safely return the device addr and not worry about bounce | 617 | * we can safely return the device addr and not worry about bounce |
535 | * buffering it. | 618 | * buffering it. |
536 | */ | 619 | */ |
537 | if (!address_needs_mapping(hwdev, dev_addr) && !swiotlb_force) | 620 | if (!range_needs_mapping(ptr, size) |
621 | && !address_needs_mapping(hwdev, dev_addr)) | ||
538 | return dev_addr; | 622 | return dev_addr; |
539 | 623 | ||
540 | /* | 624 | /* |
541 | * Oh well, have to allocate and map a bounce buffer. | 625 | * Oh well, have to allocate and map a bounce buffer. |
542 | */ | 626 | */ |
543 | map = map_single(hwdev, ptr, size, dir); | 627 | map = map_single(hwdev, ptr_to_io_tlb_addr(ptr), size, dir); |
544 | if (!map) { | 628 | if (!map) { |
545 | swiotlb_full(hwdev, size, dir, 1); | 629 | swiotlb_full(hwdev, size, dir, 1); |
546 | map = io_tlb_overflow_buffer; | 630 | map = io_tlb_overflow_buffer; |
547 | } | 631 | } |
548 | 632 | ||
549 | dev_addr = virt_to_phys(map); | 633 | dev_addr = virt_to_bus(map); |
550 | 634 | ||
551 | /* | 635 | /* |
552 | * Ensure that the address returned is DMA'ble | 636 | * Ensure that the address returned is DMA'ble |
@@ -558,25 +642,6 @@ swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, int dir) | |||
558 | } | 642 | } |
559 | 643 | ||
560 | /* | 644 | /* |
561 | * Since DMA is i-cache coherent, any (complete) pages that were written via | ||
562 | * DMA can be marked as "clean" so that lazy_mmu_prot_update() doesn't have to | ||
563 | * flush them when they get mapped into an executable vm-area. | ||
564 | */ | ||
565 | static void | ||
566 | mark_clean(void *addr, size_t size) | ||
567 | { | ||
568 | unsigned long pg_addr, end; | ||
569 | |||
570 | pg_addr = PAGE_ALIGN((unsigned long) addr); | ||
571 | end = (unsigned long) addr + size; | ||
572 | while (pg_addr + PAGE_SIZE <= end) { | ||
573 | struct page *page = virt_to_page(pg_addr); | ||
574 | set_bit(PG_arch_1, &page->flags); | ||
575 | pg_addr += PAGE_SIZE; | ||
576 | } | ||
577 | } | ||
578 | |||
579 | /* | ||
580 | * Unmap a single streaming mode DMA translation. The dma_addr and size must | 645 | * Unmap a single streaming mode DMA translation. The dma_addr and size must |
581 | * match what was provided for in a previous swiotlb_map_single call. All | 646 | * match what was provided for in a previous swiotlb_map_single call. All |
582 | * other usages are undefined. | 647 | * other usages are undefined. |
@@ -588,13 +653,13 @@ void | |||
588 | swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, size_t size, | 653 | swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, size_t size, |
589 | int dir) | 654 | int dir) |
590 | { | 655 | { |
591 | char *dma_addr = phys_to_virt(dev_addr); | 656 | char *dma_addr = bus_to_virt(dev_addr); |
592 | 657 | ||
593 | BUG_ON(dir == DMA_NONE); | 658 | BUG_ON(dir == DMA_NONE); |
594 | if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end) | 659 | if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end) |
595 | unmap_single(hwdev, dma_addr, size, dir); | 660 | unmap_single(hwdev, dma_addr, size, dir); |
596 | else if (dir == DMA_FROM_DEVICE) | 661 | else if (dir == DMA_FROM_DEVICE) |
597 | mark_clean(dma_addr, size); | 662 | dma_mark_clean(dma_addr, size); |
598 | } | 663 | } |
599 | 664 | ||
600 | /* | 665 | /* |
@@ -611,13 +676,13 @@ static inline void | |||
611 | swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr, | 676 | swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr, |
612 | size_t size, int dir, int target) | 677 | size_t size, int dir, int target) |
613 | { | 678 | { |
614 | char *dma_addr = phys_to_virt(dev_addr); | 679 | char *dma_addr = bus_to_virt(dev_addr); |
615 | 680 | ||
616 | BUG_ON(dir == DMA_NONE); | 681 | BUG_ON(dir == DMA_NONE); |
617 | if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end) | 682 | if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end) |
618 | sync_single(hwdev, dma_addr, size, dir, target); | 683 | sync_single(hwdev, dma_addr, size, dir, target); |
619 | else if (dir == DMA_FROM_DEVICE) | 684 | else if (dir == DMA_FROM_DEVICE) |
620 | mark_clean(dma_addr, size); | 685 | dma_mark_clean(dma_addr, size); |
621 | } | 686 | } |
622 | 687 | ||
623 | void | 688 | void |
@@ -642,13 +707,13 @@ swiotlb_sync_single_range(struct device *hwdev, dma_addr_t dev_addr, | |||
642 | unsigned long offset, size_t size, | 707 | unsigned long offset, size_t size, |
643 | int dir, int target) | 708 | int dir, int target) |
644 | { | 709 | { |
645 | char *dma_addr = phys_to_virt(dev_addr) + offset; | 710 | char *dma_addr = bus_to_virt(dev_addr) + offset; |
646 | 711 | ||
647 | BUG_ON(dir == DMA_NONE); | 712 | BUG_ON(dir == DMA_NONE); |
648 | if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end) | 713 | if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end) |
649 | sync_single(hwdev, dma_addr, size, dir, target); | 714 | sync_single(hwdev, dma_addr, size, dir, target); |
650 | else if (dir == DMA_FROM_DEVICE) | 715 | else if (dir == DMA_FROM_DEVICE) |
651 | mark_clean(dma_addr, size); | 716 | dma_mark_clean(dma_addr, size); |
652 | } | 717 | } |
653 | 718 | ||
654 | void | 719 | void |
@@ -687,18 +752,16 @@ int | |||
687 | swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nelems, | 752 | swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nelems, |
688 | int dir) | 753 | int dir) |
689 | { | 754 | { |
690 | void *addr; | 755 | dma_addr_t dev_addr; |
691 | unsigned long dev_addr; | ||
692 | int i; | 756 | int i; |
693 | 757 | ||
694 | BUG_ON(dir == DMA_NONE); | 758 | BUG_ON(dir == DMA_NONE); |
695 | 759 | ||
696 | for (i = 0; i < nelems; i++, sg++) { | 760 | for (i = 0; i < nelems; i++, sg++) { |
697 | addr = SG_ENT_VIRT_ADDRESS(sg); | 761 | dev_addr = SG_ENT_PHYS_ADDRESS(sg); |
698 | dev_addr = virt_to_phys(addr); | 762 | if (range_needs_mapping(SG_ENT_VIRT_ADDRESS(sg), sg->length) |
699 | if (swiotlb_force || address_needs_mapping(hwdev, dev_addr)) { | 763 | || address_needs_mapping(hwdev, dev_addr)) { |
700 | void *map = map_single(hwdev, addr, sg->length, dir); | 764 | void *map = map_single(hwdev, sg_to_io_tlb_addr(sg), sg->length, dir); |
701 | sg->dma_address = virt_to_bus(map); | ||
702 | if (!map) { | 765 | if (!map) { |
703 | /* Don't panic here, we expect map_sg users | 766 | /* Don't panic here, we expect map_sg users |
704 | to do proper error handling. */ | 767 | to do proper error handling. */ |
@@ -707,6 +770,7 @@ swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nelems, | |||
707 | sg[0].dma_length = 0; | 770 | sg[0].dma_length = 0; |
708 | return 0; | 771 | return 0; |
709 | } | 772 | } |
773 | sg->dma_address = virt_to_bus(map); | ||
710 | } else | 774 | } else |
711 | sg->dma_address = dev_addr; | 775 | sg->dma_address = dev_addr; |
712 | sg->dma_length = sg->length; | 776 | sg->dma_length = sg->length; |
@@ -728,9 +792,10 @@ swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nelems, | |||
728 | 792 | ||
729 | for (i = 0; i < nelems; i++, sg++) | 793 | for (i = 0; i < nelems; i++, sg++) |
730 | if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) | 794 | if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) |
731 | unmap_single(hwdev, (void *) phys_to_virt(sg->dma_address), sg->dma_length, dir); | 795 | unmap_single(hwdev, bus_to_virt(sg->dma_address), |
796 | sg->dma_length, dir); | ||
732 | else if (dir == DMA_FROM_DEVICE) | 797 | else if (dir == DMA_FROM_DEVICE) |
733 | mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length); | 798 | dma_mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length); |
734 | } | 799 | } |
735 | 800 | ||
736 | /* | 801 | /* |
@@ -750,8 +815,10 @@ swiotlb_sync_sg(struct device *hwdev, struct scatterlist *sg, | |||
750 | 815 | ||
751 | for (i = 0; i < nelems; i++, sg++) | 816 | for (i = 0; i < nelems; i++, sg++) |
752 | if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) | 817 | if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) |
753 | sync_single(hwdev, (void *) sg->dma_address, | 818 | sync_single(hwdev, bus_to_virt(sg->dma_address), |
754 | sg->dma_length, dir, target); | 819 | sg->dma_length, dir, target); |
820 | else if (dir == DMA_FROM_DEVICE) | ||
821 | dma_mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length); | ||
755 | } | 822 | } |
756 | 823 | ||
757 | void | 824 | void |
@@ -768,10 +835,48 @@ swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, | |||
768 | swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_DEVICE); | 835 | swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_DEVICE); |
769 | } | 836 | } |
770 | 837 | ||
838 | #ifdef SWIOTLB_ARCH_NEED_MAP_PAGE | ||
839 | |||
840 | dma_addr_t | ||
841 | swiotlb_map_page(struct device *hwdev, struct page *page, | ||
842 | unsigned long offset, size_t size, | ||
843 | enum dma_data_direction direction) | ||
844 | { | ||
845 | dma_addr_t dev_addr; | ||
846 | char *map; | ||
847 | |||
848 | dev_addr = page_to_bus(page) + offset; | ||
849 | if (address_needs_mapping(hwdev, dev_addr)) { | ||
850 | map = map_single(hwdev, page_to_io_tlb_addr(page, offset), size, direction); | ||
851 | if (!map) { | ||
852 | swiotlb_full(hwdev, size, direction, 1); | ||
853 | map = io_tlb_overflow_buffer; | ||
854 | } | ||
855 | dev_addr = virt_to_bus(map); | ||
856 | } | ||
857 | |||
858 | return dev_addr; | ||
859 | } | ||
860 | |||
861 | void | ||
862 | swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr, | ||
863 | size_t size, enum dma_data_direction direction) | ||
864 | { | ||
865 | char *dma_addr = bus_to_virt(dev_addr); | ||
866 | |||
867 | BUG_ON(direction == DMA_NONE); | ||
868 | if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end) | ||
869 | unmap_single(hwdev, dma_addr, size, direction); | ||
870 | else if (direction == DMA_FROM_DEVICE) | ||
871 | dma_mark_clean(dma_addr, size); | ||
872 | } | ||
873 | |||
874 | #endif | ||
875 | |||
771 | int | 876 | int |
772 | swiotlb_dma_mapping_error(dma_addr_t dma_addr) | 877 | swiotlb_dma_mapping_error(dma_addr_t dma_addr) |
773 | { | 878 | { |
774 | return (dma_addr == virt_to_phys(io_tlb_overflow_buffer)); | 879 | return (dma_addr == virt_to_bus(io_tlb_overflow_buffer)); |
775 | } | 880 | } |
776 | 881 | ||
777 | /* | 882 | /* |
@@ -780,10 +885,13 @@ swiotlb_dma_mapping_error(dma_addr_t dma_addr) | |||
780 | * during bus mastering, then you would pass 0x00ffffff as the mask to | 885 | * during bus mastering, then you would pass 0x00ffffff as the mask to |
781 | * this function. | 886 | * this function. |
782 | */ | 887 | */ |
888 | #ifndef __swiotlb_dma_supported | ||
889 | #define __swiotlb_dma_supported(hwdev, mask) (virt_to_bus(io_tlb_end - 1) <= (mask)) | ||
890 | #endif | ||
783 | int | 891 | int |
784 | swiotlb_dma_supported (struct device *hwdev, u64 mask) | 892 | swiotlb_dma_supported(struct device *hwdev, u64 mask) |
785 | { | 893 | { |
786 | return (virt_to_phys (io_tlb_end) - 1) <= mask; | 894 | return __swiotlb_dma_supported(hwdev, mask); |
787 | } | 895 | } |
788 | 896 | ||
789 | EXPORT_SYMBOL(swiotlb_init); | 897 | EXPORT_SYMBOL(swiotlb_init); |
@@ -798,6 +906,4 @@ EXPORT_SYMBOL_GPL(swiotlb_sync_single_range_for_device); | |||
798 | EXPORT_SYMBOL(swiotlb_sync_sg_for_cpu); | 906 | EXPORT_SYMBOL(swiotlb_sync_sg_for_cpu); |
799 | EXPORT_SYMBOL(swiotlb_sync_sg_for_device); | 907 | EXPORT_SYMBOL(swiotlb_sync_sg_for_device); |
800 | EXPORT_SYMBOL(swiotlb_dma_mapping_error); | 908 | EXPORT_SYMBOL(swiotlb_dma_mapping_error); |
801 | EXPORT_SYMBOL(swiotlb_alloc_coherent); | ||
802 | EXPORT_SYMBOL(swiotlb_free_coherent); | ||
803 | EXPORT_SYMBOL(swiotlb_dma_supported); | 909 | EXPORT_SYMBOL(swiotlb_dma_supported); |