diff options
Diffstat (limited to 'lib/swiotlb.c')
-rw-r--r-- | lib/swiotlb.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/lib/swiotlb.c b/lib/swiotlb.c index d8b09051c455..a0b4039e2880 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c | |||
@@ -312,6 +312,15 @@ static int is_swiotlb_buffer(char *addr) | |||
312 | return addr >= io_tlb_start && addr < io_tlb_end; | 312 | return addr >= io_tlb_start && addr < io_tlb_end; |
313 | } | 313 | } |
314 | 314 | ||
315 | static void | ||
316 | __sync_single(char *buffer, char *dma_addr, size_t size, int dir) | ||
317 | { | ||
318 | if (dir == DMA_TO_DEVICE) | ||
319 | memcpy(dma_addr, buffer, size); | ||
320 | else | ||
321 | memcpy(buffer, dma_addr, size); | ||
322 | } | ||
323 | |||
315 | /* | 324 | /* |
316 | * Allocates bounce buffer and returns its kernel virtual address. | 325 | * Allocates bounce buffer and returns its kernel virtual address. |
317 | */ | 326 | */ |
@@ -413,7 +422,7 @@ found: | |||
413 | for (i = 0; i < nslots; i++) | 422 | for (i = 0; i < nslots; i++) |
414 | io_tlb_orig_addr[index+i] = buffer + (i << IO_TLB_SHIFT); | 423 | io_tlb_orig_addr[index+i] = buffer + (i << IO_TLB_SHIFT); |
415 | if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) | 424 | if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) |
416 | memcpy(dma_addr, buffer, size); | 425 | __sync_single(buffer, dma_addr, size, DMA_TO_DEVICE); |
417 | 426 | ||
418 | return dma_addr; | 427 | return dma_addr; |
419 | } | 428 | } |
@@ -437,7 +446,7 @@ unmap_single(struct device *hwdev, char *dma_addr, size_t size, int dir) | |||
437 | * bounce... copy the data back into the original buffer * and | 446 | * bounce... copy the data back into the original buffer * and |
438 | * delete the bounce buffer. | 447 | * delete the bounce buffer. |
439 | */ | 448 | */ |
440 | memcpy(buffer, dma_addr, size); | 449 | __sync_single(buffer, dma_addr, size, DMA_FROM_DEVICE); |
441 | 450 | ||
442 | /* | 451 | /* |
443 | * Return the buffer to the free list by setting the corresponding | 452 | * Return the buffer to the free list by setting the corresponding |
@@ -477,13 +486,13 @@ sync_single(struct device *hwdev, char *dma_addr, size_t size, | |||
477 | switch (target) { | 486 | switch (target) { |
478 | case SYNC_FOR_CPU: | 487 | case SYNC_FOR_CPU: |
479 | if (likely(dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)) | 488 | if (likely(dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)) |
480 | memcpy(buffer, dma_addr, size); | 489 | __sync_single(buffer, dma_addr, size, DMA_FROM_DEVICE); |
481 | else | 490 | else |
482 | BUG_ON(dir != DMA_TO_DEVICE); | 491 | BUG_ON(dir != DMA_TO_DEVICE); |
483 | break; | 492 | break; |
484 | case SYNC_FOR_DEVICE: | 493 | case SYNC_FOR_DEVICE: |
485 | if (likely(dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)) | 494 | if (likely(dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)) |
486 | memcpy(dma_addr, buffer, size); | 495 | __sync_single(buffer, dma_addr, size, DMA_TO_DEVICE); |
487 | else | 496 | else |
488 | BUG_ON(dir != DMA_FROM_DEVICE); | 497 | BUG_ON(dir != DMA_FROM_DEVICE); |
489 | break; | 498 | break; |