diff options
| author | Jens Axboe <jens.axboe@oracle.com> | 2007-05-11 08:56:18 -0400 |
|---|---|---|
| committer | Jens Axboe <jens.axboe@oracle.com> | 2007-10-16 05:26:01 -0400 |
| commit | dbfd49fe9dd7d234a4e195c6ed422cafa25813f2 (patch) | |
| tree | 56e393bc6df0e7f7f660be50d9c60183fde5e689 | |
| parent | 38d375561f0f89e76f28ed9e69706bb2c980200f (diff) | |
swiotlb: sg chaining support
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
| -rw-r--r-- | lib/swiotlb.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/lib/swiotlb.c b/lib/swiotlb.c index 30c1400e749e..c419ecf334c3 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c | |||
| @@ -677,16 +677,17 @@ swiotlb_sync_single_range_for_device(struct device *hwdev, dma_addr_t dev_addr, | |||
| 677 | * same here. | 677 | * same here. |
| 678 | */ | 678 | */ |
| 679 | int | 679 | int |
| 680 | swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nelems, | 680 | swiotlb_map_sg(struct device *hwdev, struct scatterlist *sgl, int nelems, |
| 681 | int dir) | 681 | int dir) |
| 682 | { | 682 | { |
| 683 | struct scatterlist *sg; | ||
| 683 | void *addr; | 684 | void *addr; |
| 684 | dma_addr_t dev_addr; | 685 | dma_addr_t dev_addr; |
| 685 | int i; | 686 | int i; |
| 686 | 687 | ||
| 687 | BUG_ON(dir == DMA_NONE); | 688 | BUG_ON(dir == DMA_NONE); |
| 688 | 689 | ||
| 689 | for (i = 0; i < nelems; i++, sg++) { | 690 | for_each_sg(sgl, sg, nelems, i) { |
| 690 | addr = SG_ENT_VIRT_ADDRESS(sg); | 691 | addr = SG_ENT_VIRT_ADDRESS(sg); |
| 691 | dev_addr = virt_to_bus(addr); | 692 | dev_addr = virt_to_bus(addr); |
| 692 | if (swiotlb_force || address_needs_mapping(hwdev, dev_addr)) { | 693 | if (swiotlb_force || address_needs_mapping(hwdev, dev_addr)) { |
| @@ -696,7 +697,7 @@ swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nelems, | |||
| 696 | to do proper error handling. */ | 697 | to do proper error handling. */ |
| 697 | swiotlb_full(hwdev, sg->length, dir, 0); | 698 | swiotlb_full(hwdev, sg->length, dir, 0); |
| 698 | swiotlb_unmap_sg(hwdev, sg - i, i, dir); | 699 | swiotlb_unmap_sg(hwdev, sg - i, i, dir); |
| 699 | sg[0].dma_length = 0; | 700 | sgl[0].dma_length = 0; |
| 700 | return 0; | 701 | return 0; |
| 701 | } | 702 | } |
| 702 | sg->dma_address = virt_to_bus(map); | 703 | sg->dma_address = virt_to_bus(map); |
| @@ -712,19 +713,21 @@ swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nelems, | |||
| 712 | * concerning calls here are the same as for swiotlb_unmap_single() above. | 713 | * concerning calls here are the same as for swiotlb_unmap_single() above. |
| 713 | */ | 714 | */ |
| 714 | void | 715 | void |
| 715 | swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nelems, | 716 | swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sgl, int nelems, |
| 716 | int dir) | 717 | int dir) |
| 717 | { | 718 | { |
| 719 | struct scatterlist *sg; | ||
| 718 | int i; | 720 | int i; |
| 719 | 721 | ||
| 720 | BUG_ON(dir == DMA_NONE); | 722 | BUG_ON(dir == DMA_NONE); |
| 721 | 723 | ||
| 722 | for (i = 0; i < nelems; i++, sg++) | 724 | for_each_sg(sgl, sg, nelems, i) { |
| 723 | if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) | 725 | if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) |
| 724 | unmap_single(hwdev, bus_to_virt(sg->dma_address), | 726 | unmap_single(hwdev, bus_to_virt(sg->dma_address), |
| 725 | sg->dma_length, dir); | 727 | sg->dma_length, dir); |
| 726 | else if (dir == DMA_FROM_DEVICE) | 728 | else if (dir == DMA_FROM_DEVICE) |
| 727 | dma_mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length); | 729 | dma_mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length); |
| 730 | } | ||
| 728 | } | 731 | } |
| 729 | 732 | ||
| 730 | /* | 733 | /* |
| @@ -735,19 +738,21 @@ swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nelems, | |||
| 735 | * and usage. | 738 | * and usage. |
| 736 | */ | 739 | */ |
| 737 | static void | 740 | static void |
| 738 | swiotlb_sync_sg(struct device *hwdev, struct scatterlist *sg, | 741 | swiotlb_sync_sg(struct device *hwdev, struct scatterlist *sgl, |
| 739 | int nelems, int dir, int target) | 742 | int nelems, int dir, int target) |
| 740 | { | 743 | { |
| 744 | struct scatterlist *sg; | ||
| 741 | int i; | 745 | int i; |
| 742 | 746 | ||
| 743 | BUG_ON(dir == DMA_NONE); | 747 | BUG_ON(dir == DMA_NONE); |
| 744 | 748 | ||
| 745 | for (i = 0; i < nelems; i++, sg++) | 749 | for_each_sg(sgl, sg, nelems, i) { |
| 746 | if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) | 750 | if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) |
| 747 | sync_single(hwdev, bus_to_virt(sg->dma_address), | 751 | sync_single(hwdev, bus_to_virt(sg->dma_address), |
| 748 | sg->dma_length, dir, target); | 752 | sg->dma_length, dir, target); |
| 749 | else if (dir == DMA_FROM_DEVICE) | 753 | else if (dir == DMA_FROM_DEVICE) |
| 750 | dma_mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length); | 754 | dma_mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length); |
| 755 | } | ||
| 751 | } | 756 | } |
| 752 | 757 | ||
| 753 | void | 758 | void |
