diff options
Diffstat (limited to 'lib/swiotlb.c')
| -rw-r--r-- | lib/swiotlb.c | 184 |
1 files changed, 35 insertions, 149 deletions
diff --git a/lib/swiotlb.c b/lib/swiotlb.c index 623a68af8b18..9970e55c90bd 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c | |||
| @@ -28,7 +28,6 @@ | |||
| 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> | ||
| 32 | 31 | ||
| 33 | #include <linux/init.h> | 32 | #include <linux/init.h> |
| 34 | #include <linux/bootmem.h> | 33 | #include <linux/bootmem.h> |
| @@ -36,10 +35,8 @@ | |||
| 36 | #define OFFSET(val,align) ((unsigned long) \ | 35 | #define OFFSET(val,align) ((unsigned long) \ |
| 37 | ( (val) & ( (align) - 1))) | 36 | ( (val) & ( (align) - 1))) |
| 38 | 37 | ||
| 39 | #ifndef SG_ENT_VIRT_ADDRESS | ||
| 40 | #define SG_ENT_VIRT_ADDRESS(sg) (page_address((sg)->page) + (sg)->offset) | 38 | #define SG_ENT_VIRT_ADDRESS(sg) (page_address((sg)->page) + (sg)->offset) |
| 41 | #define SG_ENT_PHYS_ADDRESS(sg) virt_to_bus(SG_ENT_VIRT_ADDRESS(sg)) | 39 | #define SG_ENT_PHYS_ADDRESS(sg) virt_to_bus(SG_ENT_VIRT_ADDRESS(sg)) |
| 42 | #endif | ||
| 43 | 40 | ||
| 44 | /* | 41 | /* |
| 45 | * Maximum allowable number of contiguous slabs to map, | 42 | * Maximum allowable number of contiguous slabs to map, |
| @@ -104,25 +101,13 @@ static unsigned int io_tlb_index; | |||
| 104 | * We need to save away the original address corresponding to a mapped entry | 101 | * We need to save away the original address corresponding to a mapped entry |
| 105 | * for the sync operations. | 102 | * for the sync operations. |
| 106 | */ | 103 | */ |
| 107 | #ifndef SWIOTLB_ARCH_HAS_IO_TLB_ADDR_T | 104 | static unsigned char **io_tlb_orig_addr; |
| 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; | ||
| 115 | 105 | ||
| 116 | /* | 106 | /* |
| 117 | * Protect the above data structures in the map and unmap calls | 107 | * Protect the above data structures in the map and unmap calls |
| 118 | */ | 108 | */ |
| 119 | static DEFINE_SPINLOCK(io_tlb_lock); | 109 | static DEFINE_SPINLOCK(io_tlb_lock); |
| 120 | 110 | ||
| 121 | #ifdef SWIOTLB_EXTRA_VARIABLES | ||
| 122 | SWIOTLB_EXTRA_VARIABLES; | ||
| 123 | #endif | ||
| 124 | |||
| 125 | #ifndef SWIOTLB_ARCH_HAS_SETUP_IO_TLB_NPAGES | ||
| 126 | static int __init | 111 | static int __init |
| 127 | setup_io_tlb_npages(char *str) | 112 | setup_io_tlb_npages(char *str) |
| 128 | { | 113 | { |
| @@ -137,25 +122,9 @@ setup_io_tlb_npages(char *str) | |||
| 137 | swiotlb_force = 1; | 122 | swiotlb_force = 1; |
| 138 | return 1; | 123 | return 1; |
| 139 | } | 124 | } |
| 140 | #endif | ||
| 141 | __setup("swiotlb=", setup_io_tlb_npages); | 125 | __setup("swiotlb=", setup_io_tlb_npages); |
| 142 | /* make io_tlb_overflow tunable too? */ | 126 | /* make io_tlb_overflow tunable too? */ |
| 143 | 127 | ||
| 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 | |||
| 159 | /* | 128 | /* |
| 160 | * Statically reserve bounce buffer space and initialize bounce buffer data | 129 | * Statically reserve bounce buffer space and initialize bounce buffer data |
| 161 | * structures for the software IO TLB used to implement the DMA API. | 130 | * structures for the software IO TLB used to implement the DMA API. |
| @@ -169,8 +138,6 @@ swiotlb_init_with_default_size(size_t default_size) | |||
| 169 | io_tlb_nslabs = (default_size >> IO_TLB_SHIFT); | 138 | io_tlb_nslabs = (default_size >> IO_TLB_SHIFT); |
| 170 | io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE); | 139 | io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE); |
| 171 | } | 140 | } |
| 172 | swiotlb_adjust_size(io_tlb_nslabs); | ||
| 173 | swiotlb_adjust_size(io_tlb_overflow); | ||
| 174 | 141 | ||
| 175 | bytes = io_tlb_nslabs << IO_TLB_SHIFT; | 142 | bytes = io_tlb_nslabs << IO_TLB_SHIFT; |
| 176 | 143 | ||
| @@ -188,14 +155,10 @@ swiotlb_init_with_default_size(size_t default_size) | |||
| 188 | * between io_tlb_start and io_tlb_end. | 155 | * between io_tlb_start and io_tlb_end. |
| 189 | */ | 156 | */ |
| 190 | io_tlb_list = alloc_bootmem(io_tlb_nslabs * sizeof(int)); | 157 | io_tlb_list = alloc_bootmem(io_tlb_nslabs * sizeof(int)); |
| 191 | for (i = 0; i < io_tlb_nslabs; i++) { | 158 | 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); | ||
| 195 | io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); | 159 | io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); |
| 196 | } | ||
| 197 | io_tlb_index = 0; | 160 | io_tlb_index = 0; |
| 198 | io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(io_tlb_addr_t)); | 161 | io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(char *)); |
| 199 | 162 | ||
| 200 | /* | 163 | /* |
| 201 | * Get the overflow emergency buffer | 164 | * Get the overflow emergency buffer |
| @@ -203,21 +166,17 @@ swiotlb_init_with_default_size(size_t default_size) | |||
| 203 | io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow); | 166 | io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow); |
| 204 | if (!io_tlb_overflow_buffer) | 167 | if (!io_tlb_overflow_buffer) |
| 205 | panic("Cannot allocate SWIOTLB overflow buffer!\n"); | 168 | panic("Cannot allocate SWIOTLB overflow buffer!\n"); |
| 206 | swiotlb_adjust_seg(io_tlb_overflow_buffer, io_tlb_overflow); | ||
| 207 | 169 | ||
| 208 | swiotlb_print_info(bytes); | 170 | printk(KERN_INFO "Placing software IO TLB between 0x%lx - 0x%lx\n", |
| 171 | virt_to_bus(io_tlb_start), virt_to_bus(io_tlb_end)); | ||
| 209 | } | 172 | } |
| 210 | #ifndef __swiotlb_init_with_default_size | ||
| 211 | #define __swiotlb_init_with_default_size swiotlb_init_with_default_size | ||
| 212 | #endif | ||
| 213 | 173 | ||
| 214 | void __init | 174 | void __init |
| 215 | swiotlb_init(void) | 175 | swiotlb_init(void) |
| 216 | { | 176 | { |
| 217 | __swiotlb_init_with_default_size(64 * (1<<20)); /* default to 64MB */ | 177 | swiotlb_init_with_default_size(64 * (1<<20)); /* default to 64MB */ |
| 218 | } | 178 | } |
| 219 | 179 | ||
| 220 | #ifdef SWIOTLB_ARCH_NEED_LATE_INIT | ||
| 221 | /* | 180 | /* |
| 222 | * Systems with larger DMA zones (those that don't support ISA) can | 181 | * Systems with larger DMA zones (those that don't support ISA) can |
| 223 | * initialize the swiotlb later using the slab allocator if needed. | 182 | * initialize the swiotlb later using the slab allocator if needed. |
| @@ -275,12 +234,12 @@ swiotlb_late_init_with_default_size(size_t default_size) | |||
| 275 | io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); | 234 | io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); |
| 276 | io_tlb_index = 0; | 235 | io_tlb_index = 0; |
| 277 | 236 | ||
| 278 | io_tlb_orig_addr = (io_tlb_addr_t *)__get_free_pages(GFP_KERNEL, | 237 | io_tlb_orig_addr = (unsigned char **)__get_free_pages(GFP_KERNEL, |
| 279 | get_order(io_tlb_nslabs * sizeof(io_tlb_addr_t))); | 238 | get_order(io_tlb_nslabs * sizeof(char *))); |
| 280 | if (!io_tlb_orig_addr) | 239 | if (!io_tlb_orig_addr) |
| 281 | goto cleanup3; | 240 | goto cleanup3; |
| 282 | 241 | ||
| 283 | memset(io_tlb_orig_addr, 0, io_tlb_nslabs * sizeof(io_tlb_addr_t)); | 242 | memset(io_tlb_orig_addr, 0, io_tlb_nslabs * sizeof(char *)); |
| 284 | 243 | ||
| 285 | /* | 244 | /* |
| 286 | * Get the overflow emergency buffer | 245 | * Get the overflow emergency buffer |
| @@ -290,17 +249,19 @@ swiotlb_late_init_with_default_size(size_t default_size) | |||
| 290 | if (!io_tlb_overflow_buffer) | 249 | if (!io_tlb_overflow_buffer) |
| 291 | goto cleanup4; | 250 | goto cleanup4; |
| 292 | 251 | ||
| 293 | swiotlb_print_info(bytes); | 252 | printk(KERN_INFO "Placing %luMB software IO TLB between 0x%lx - " |
| 253 | "0x%lx\n", bytes >> 20, | ||
| 254 | virt_to_bus(io_tlb_start), virt_to_bus(io_tlb_end)); | ||
| 294 | 255 | ||
| 295 | return 0; | 256 | return 0; |
| 296 | 257 | ||
| 297 | cleanup4: | 258 | cleanup4: |
| 298 | free_pages((unsigned long)io_tlb_orig_addr, | 259 | free_pages((unsigned long)io_tlb_orig_addr, get_order(io_tlb_nslabs * |
| 299 | get_order(io_tlb_nslabs * sizeof(io_tlb_addr_t))); | 260 | sizeof(char *))); |
| 300 | io_tlb_orig_addr = NULL; | 261 | io_tlb_orig_addr = NULL; |
| 301 | cleanup3: | 262 | cleanup3: |
| 302 | free_pages((unsigned long)io_tlb_list, | 263 | free_pages((unsigned long)io_tlb_list, get_order(io_tlb_nslabs * |
| 303 | get_order(io_tlb_nslabs * sizeof(int))); | 264 | sizeof(int))); |
| 304 | io_tlb_list = NULL; | 265 | io_tlb_list = NULL; |
| 305 | cleanup2: | 266 | cleanup2: |
| 306 | io_tlb_end = NULL; | 267 | io_tlb_end = NULL; |
| @@ -310,9 +271,7 @@ cleanup1: | |||
| 310 | io_tlb_nslabs = req_nslabs; | 271 | io_tlb_nslabs = req_nslabs; |
| 311 | return -ENOMEM; | 272 | return -ENOMEM; |
| 312 | } | 273 | } |
| 313 | #endif | ||
| 314 | 274 | ||
| 315 | #ifndef SWIOTLB_ARCH_HAS_NEEDS_MAPPING | ||
| 316 | static int | 275 | static int |
| 317 | address_needs_mapping(struct device *hwdev, dma_addr_t addr) | 276 | address_needs_mapping(struct device *hwdev, dma_addr_t addr) |
| 318 | { | 277 | { |
| @@ -323,35 +282,11 @@ address_needs_mapping(struct device *hwdev, dma_addr_t addr) | |||
| 323 | return (addr & ~mask) != 0; | 282 | return (addr & ~mask) != 0; |
| 324 | } | 283 | } |
| 325 | 284 | ||
| 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 | |||
| 350 | /* | 285 | /* |
| 351 | * Allocates bounce buffer and returns its kernel virtual address. | 286 | * Allocates bounce buffer and returns its kernel virtual address. |
| 352 | */ | 287 | */ |
| 353 | static void * | 288 | static void * |
| 354 | map_single(struct device *hwdev, io_tlb_addr_t buffer, size_t size, int dir) | 289 | map_single(struct device *hwdev, char *buffer, size_t size, int dir) |
| 355 | { | 290 | { |
| 356 | unsigned long flags; | 291 | unsigned long flags; |
| 357 | char *dma_addr; | 292 | char *dma_addr; |
| @@ -424,7 +359,7 @@ map_single(struct device *hwdev, io_tlb_addr_t buffer, size_t size, int dir) | |||
| 424 | */ | 359 | */ |
| 425 | io_tlb_orig_addr[index] = buffer; | 360 | io_tlb_orig_addr[index] = buffer; |
| 426 | if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) | 361 | if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) |
| 427 | __sync_single(buffer, dma_addr, size, DMA_TO_DEVICE); | 362 | memcpy(dma_addr, buffer, size); |
| 428 | 363 | ||
| 429 | return dma_addr; | 364 | return dma_addr; |
| 430 | } | 365 | } |
| @@ -438,18 +373,17 @@ unmap_single(struct device *hwdev, char *dma_addr, size_t size, int dir) | |||
| 438 | unsigned long flags; | 373 | unsigned long flags; |
| 439 | int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; | 374 | int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; |
| 440 | int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; | 375 | int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; |
| 441 | io_tlb_addr_t buffer = io_tlb_orig_addr[index]; | 376 | char *buffer = io_tlb_orig_addr[index]; |
| 442 | 377 | ||
| 443 | /* | 378 | /* |
| 444 | * First, sync the memory before unmapping the entry | 379 | * First, sync the memory before unmapping the entry |
| 445 | */ | 380 | */ |
| 446 | if (!swiotlb_orig_addr_null(buffer) | 381 | if (buffer && ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL))) |
| 447 | && ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL))) | ||
| 448 | /* | 382 | /* |
| 449 | * bounce... copy the data back into the original buffer * and | 383 | * bounce... copy the data back into the original buffer * and |
| 450 | * delete the bounce buffer. | 384 | * delete the bounce buffer. |
| 451 | */ | 385 | */ |
| 452 | __sync_single(buffer, dma_addr, size, DMA_FROM_DEVICE); | 386 | memcpy(buffer, dma_addr, size); |
| 453 | 387 | ||
| 454 | /* | 388 | /* |
| 455 | * Return the buffer to the free list by setting the corresponding | 389 | * Return the buffer to the free list by setting the corresponding |
| @@ -482,18 +416,18 @@ sync_single(struct device *hwdev, char *dma_addr, size_t size, | |||
| 482 | int dir, int target) | 416 | int dir, int target) |
| 483 | { | 417 | { |
| 484 | int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; | 418 | int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; |
| 485 | io_tlb_addr_t buffer = io_tlb_orig_addr[index]; | 419 | char *buffer = io_tlb_orig_addr[index]; |
| 486 | 420 | ||
| 487 | switch (target) { | 421 | switch (target) { |
| 488 | case SYNC_FOR_CPU: | 422 | case SYNC_FOR_CPU: |
| 489 | if (likely(dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)) | 423 | if (likely(dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)) |
| 490 | __sync_single(buffer, dma_addr, size, DMA_FROM_DEVICE); | 424 | memcpy(buffer, dma_addr, size); |
| 491 | else | 425 | else |
| 492 | BUG_ON(dir != DMA_TO_DEVICE); | 426 | BUG_ON(dir != DMA_TO_DEVICE); |
| 493 | break; | 427 | break; |
| 494 | case SYNC_FOR_DEVICE: | 428 | case SYNC_FOR_DEVICE: |
| 495 | if (likely(dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)) | 429 | if (likely(dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)) |
| 496 | __sync_single(buffer, dma_addr, size, DMA_TO_DEVICE); | 430 | memcpy(dma_addr, buffer, size); |
| 497 | else | 431 | else |
| 498 | BUG_ON(dir != DMA_FROM_DEVICE); | 432 | BUG_ON(dir != DMA_FROM_DEVICE); |
| 499 | break; | 433 | break; |
| @@ -502,8 +436,6 @@ sync_single(struct device *hwdev, char *dma_addr, size_t size, | |||
| 502 | } | 436 | } |
| 503 | } | 437 | } |
| 504 | 438 | ||
| 505 | #ifdef SWIOTLB_ARCH_NEED_ALLOC | ||
| 506 | |||
| 507 | void * | 439 | void * |
| 508 | swiotlb_alloc_coherent(struct device *hwdev, size_t size, | 440 | swiotlb_alloc_coherent(struct device *hwdev, size_t size, |
| 509 | dma_addr_t *dma_handle, gfp_t flags) | 441 | dma_addr_t *dma_handle, gfp_t flags) |
| @@ -519,10 +451,7 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size, | |||
| 519 | */ | 451 | */ |
| 520 | flags |= GFP_DMA; | 452 | flags |= GFP_DMA; |
| 521 | 453 | ||
| 522 | if (!order_needs_mapping(order)) | 454 | ret = (void *)__get_free_pages(flags, order); |
| 523 | ret = (void *)__get_free_pages(flags, order); | ||
| 524 | else | ||
| 525 | ret = NULL; | ||
| 526 | if (ret && address_needs_mapping(hwdev, virt_to_bus(ret))) { | 455 | if (ret && address_needs_mapping(hwdev, virt_to_bus(ret))) { |
| 527 | /* | 456 | /* |
| 528 | * The allocated memory isn't reachable by the device. | 457 | * The allocated memory isn't reachable by the device. |
| @@ -560,7 +489,6 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size, | |||
| 560 | *dma_handle = dev_addr; | 489 | *dma_handle = dev_addr; |
| 561 | return ret; | 490 | return ret; |
| 562 | } | 491 | } |
| 563 | EXPORT_SYMBOL(swiotlb_alloc_coherent); | ||
| 564 | 492 | ||
| 565 | void | 493 | void |
| 566 | swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, | 494 | swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, |
| @@ -573,9 +501,6 @@ swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, | |||
| 573 | /* DMA_TO_DEVICE to avoid memcpy in unmap_single */ | 501 | /* DMA_TO_DEVICE to avoid memcpy in unmap_single */ |
| 574 | swiotlb_unmap_single (hwdev, dma_handle, size, DMA_TO_DEVICE); | 502 | swiotlb_unmap_single (hwdev, dma_handle, size, DMA_TO_DEVICE); |
| 575 | } | 503 | } |
| 576 | EXPORT_SYMBOL(swiotlb_free_coherent); | ||
| 577 | |||
| 578 | #endif | ||
| 579 | 504 | ||
| 580 | static void | 505 | static void |
| 581 | swiotlb_full(struct device *dev, size_t size, int dir, int do_panic) | 506 | swiotlb_full(struct device *dev, size_t size, int dir, int do_panic) |
| @@ -617,14 +542,13 @@ swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, int dir) | |||
| 617 | * we can safely return the device addr and not worry about bounce | 542 | * we can safely return the device addr and not worry about bounce |
| 618 | * buffering it. | 543 | * buffering it. |
| 619 | */ | 544 | */ |
| 620 | if (!range_needs_mapping(ptr, size) | 545 | if (!address_needs_mapping(hwdev, dev_addr) && !swiotlb_force) |
| 621 | && !address_needs_mapping(hwdev, dev_addr)) | ||
| 622 | return dev_addr; | 546 | return dev_addr; |
| 623 | 547 | ||
| 624 | /* | 548 | /* |
| 625 | * Oh well, have to allocate and map a bounce buffer. | 549 | * Oh well, have to allocate and map a bounce buffer. |
| 626 | */ | 550 | */ |
| 627 | map = map_single(hwdev, ptr_to_io_tlb_addr(ptr), size, dir); | 551 | map = map_single(hwdev, ptr, size, dir); |
| 628 | if (!map) { | 552 | if (!map) { |
| 629 | swiotlb_full(hwdev, size, dir, 1); | 553 | swiotlb_full(hwdev, size, dir, 1); |
| 630 | map = io_tlb_overflow_buffer; | 554 | map = io_tlb_overflow_buffer; |
| @@ -752,16 +676,17 @@ int | |||
| 752 | swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nelems, | 676 | swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nelems, |
| 753 | int dir) | 677 | int dir) |
| 754 | { | 678 | { |
| 679 | void *addr; | ||
| 755 | dma_addr_t dev_addr; | 680 | dma_addr_t dev_addr; |
| 756 | int i; | 681 | int i; |
| 757 | 682 | ||
| 758 | BUG_ON(dir == DMA_NONE); | 683 | BUG_ON(dir == DMA_NONE); |
| 759 | 684 | ||
| 760 | for (i = 0; i < nelems; i++, sg++) { | 685 | for (i = 0; i < nelems; i++, sg++) { |
| 761 | dev_addr = SG_ENT_PHYS_ADDRESS(sg); | 686 | addr = SG_ENT_VIRT_ADDRESS(sg); |
| 762 | if (range_needs_mapping(SG_ENT_VIRT_ADDRESS(sg), sg->length) | 687 | dev_addr = virt_to_bus(addr); |
| 763 | || address_needs_mapping(hwdev, dev_addr)) { | 688 | if (swiotlb_force || address_needs_mapping(hwdev, dev_addr)) { |
| 764 | void *map = map_single(hwdev, sg_to_io_tlb_addr(sg), sg->length, dir); | 689 | void *map = map_single(hwdev, addr, sg->length, dir); |
| 765 | if (!map) { | 690 | if (!map) { |
| 766 | /* Don't panic here, we expect map_sg users | 691 | /* Don't panic here, we expect map_sg users |
| 767 | to do proper error handling. */ | 692 | to do proper error handling. */ |
| @@ -835,44 +760,6 @@ swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, | |||
| 835 | swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_DEVICE); | 760 | swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_DEVICE); |
| 836 | } | 761 | } |
| 837 | 762 | ||
| 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 | |||
| 876 | int | 763 | int |
| 877 | swiotlb_dma_mapping_error(dma_addr_t dma_addr) | 764 | swiotlb_dma_mapping_error(dma_addr_t dma_addr) |
| 878 | { | 765 | { |
| @@ -885,13 +772,10 @@ swiotlb_dma_mapping_error(dma_addr_t dma_addr) | |||
| 885 | * during bus mastering, then you would pass 0x00ffffff as the mask to | 772 | * during bus mastering, then you would pass 0x00ffffff as the mask to |
| 886 | * this function. | 773 | * this function. |
| 887 | */ | 774 | */ |
| 888 | #ifndef __swiotlb_dma_supported | ||
| 889 | #define __swiotlb_dma_supported(hwdev, mask) (virt_to_bus(io_tlb_end - 1) <= (mask)) | ||
| 890 | #endif | ||
| 891 | int | 775 | int |
| 892 | swiotlb_dma_supported(struct device *hwdev, u64 mask) | 776 | swiotlb_dma_supported(struct device *hwdev, u64 mask) |
| 893 | { | 777 | { |
| 894 | return __swiotlb_dma_supported(hwdev, mask); | 778 | return virt_to_bus(io_tlb_end - 1) <= mask; |
| 895 | } | 779 | } |
| 896 | 780 | ||
| 897 | EXPORT_SYMBOL(swiotlb_init); | 781 | EXPORT_SYMBOL(swiotlb_init); |
| @@ -906,4 +790,6 @@ EXPORT_SYMBOL_GPL(swiotlb_sync_single_range_for_device); | |||
| 906 | EXPORT_SYMBOL(swiotlb_sync_sg_for_cpu); | 790 | EXPORT_SYMBOL(swiotlb_sync_sg_for_cpu); |
| 907 | EXPORT_SYMBOL(swiotlb_sync_sg_for_device); | 791 | EXPORT_SYMBOL(swiotlb_sync_sg_for_device); |
| 908 | EXPORT_SYMBOL(swiotlb_dma_mapping_error); | 792 | EXPORT_SYMBOL(swiotlb_dma_mapping_error); |
| 793 | EXPORT_SYMBOL(swiotlb_alloc_coherent); | ||
| 794 | EXPORT_SYMBOL(swiotlb_free_coherent); | ||
| 909 | EXPORT_SYMBOL(swiotlb_dma_supported); | 795 | EXPORT_SYMBOL(swiotlb_dma_supported); |
