diff options
author | Christoph Hellwig <hch@lst.de> | 2019-04-11 03:19:58 -0400 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2019-05-02 19:51:29 -0400 |
commit | 8b35d9feed8e4e66dc4048f776c356e26e2a8216 (patch) | |
tree | 6d32ab8bafd97690a83d22e944ac6bac46e93994 /drivers/xen | |
parent | aca351cc4c034b4880f0a0dc3602ed3761ef6f01 (diff) |
swiotlb-xen: use ->map_page to implement ->map_sg
We can simply loop over the segments and map them, removing lots of
duplicate code.
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'drivers/xen')
-rw-r--r-- | drivers/xen/swiotlb-xen.c | 68 |
1 files changed, 10 insertions, 58 deletions
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c index 272e4aef2a86..e40bf1b707e3 100644 --- a/drivers/xen/swiotlb-xen.c +++ b/drivers/xen/swiotlb-xen.c | |||
@@ -514,24 +514,8 @@ xen_swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sgl, int nelems, | |||
514 | 514 | ||
515 | } | 515 | } |
516 | 516 | ||
517 | /* | ||
518 | * Map a set of buffers described by scatterlist in streaming mode for DMA. | ||
519 | * This is the scatter-gather version of the above xen_swiotlb_map_page | ||
520 | * interface. Here the scatter gather list elements are each tagged with the | ||
521 | * appropriate dma address and length. They are obtained via | ||
522 | * sg_dma_{address,length}(SG). | ||
523 | * | ||
524 | * NOTE: An implementation may be able to use a smaller number of | ||
525 | * DMA address/length pairs than there are SG table elements. | ||
526 | * (for example via virtual mapping capabilities) | ||
527 | * The routine returns the number of addr/length pairs actually | ||
528 | * used, at most nents. | ||
529 | * | ||
530 | * Device ownership issues as mentioned above for xen_swiotlb_map_page are the | ||
531 | * same here. | ||
532 | */ | ||
533 | static int | 517 | static int |
534 | xen_swiotlb_map_sg(struct device *hwdev, struct scatterlist *sgl, int nelems, | 518 | xen_swiotlb_map_sg(struct device *dev, struct scatterlist *sgl, int nelems, |
535 | enum dma_data_direction dir, unsigned long attrs) | 519 | enum dma_data_direction dir, unsigned long attrs) |
536 | { | 520 | { |
537 | struct scatterlist *sg; | 521 | struct scatterlist *sg; |
@@ -540,50 +524,18 @@ xen_swiotlb_map_sg(struct device *hwdev, struct scatterlist *sgl, int nelems, | |||
540 | BUG_ON(dir == DMA_NONE); | 524 | BUG_ON(dir == DMA_NONE); |
541 | 525 | ||
542 | for_each_sg(sgl, sg, nelems, i) { | 526 | for_each_sg(sgl, sg, nelems, i) { |
543 | phys_addr_t paddr = sg_phys(sg); | 527 | sg->dma_address = xen_swiotlb_map_page(dev, sg_page(sg), |
544 | dma_addr_t dev_addr = xen_phys_to_bus(paddr); | 528 | sg->offset, sg->length, dir, attrs); |
545 | 529 | if (sg->dma_address == DMA_MAPPING_ERROR) | |
546 | if (swiotlb_force == SWIOTLB_FORCE || | 530 | goto out_unmap; |
547 | xen_arch_need_swiotlb(hwdev, paddr, dev_addr) || | ||
548 | !dma_capable(hwdev, dev_addr, sg->length) || | ||
549 | range_straddles_page_boundary(paddr, sg->length)) { | ||
550 | phys_addr_t map = swiotlb_tbl_map_single(hwdev, | ||
551 | start_dma_addr, | ||
552 | sg_phys(sg), | ||
553 | sg->length, | ||
554 | dir, attrs); | ||
555 | if (map == DMA_MAPPING_ERROR) { | ||
556 | dev_warn(hwdev, "swiotlb buffer is full\n"); | ||
557 | /* Don't panic here, we expect map_sg users | ||
558 | to do proper error handling. */ | ||
559 | attrs |= DMA_ATTR_SKIP_CPU_SYNC; | ||
560 | xen_swiotlb_unmap_sg(hwdev, sgl, i, dir, attrs); | ||
561 | sg_dma_len(sgl) = 0; | ||
562 | return 0; | ||
563 | } | ||
564 | dev_addr = xen_phys_to_bus(map); | ||
565 | xen_dma_map_page(hwdev, pfn_to_page(map >> PAGE_SHIFT), | ||
566 | dev_addr, | ||
567 | map & ~PAGE_MASK, | ||
568 | sg->length, | ||
569 | dir, | ||
570 | attrs); | ||
571 | sg->dma_address = dev_addr; | ||
572 | } else { | ||
573 | /* we are not interested in the dma_addr returned by | ||
574 | * xen_dma_map_page, only in the potential cache flushes executed | ||
575 | * by the function. */ | ||
576 | xen_dma_map_page(hwdev, pfn_to_page(paddr >> PAGE_SHIFT), | ||
577 | dev_addr, | ||
578 | paddr & ~PAGE_MASK, | ||
579 | sg->length, | ||
580 | dir, | ||
581 | attrs); | ||
582 | sg->dma_address = dev_addr; | ||
583 | } | ||
584 | sg_dma_len(sg) = sg->length; | 531 | sg_dma_len(sg) = sg->length; |
585 | } | 532 | } |
533 | |||
586 | return nelems; | 534 | return nelems; |
535 | out_unmap: | ||
536 | xen_swiotlb_unmap_sg(dev, sgl, i, dir, attrs | DMA_ATTR_SKIP_CPU_SYNC); | ||
537 | sg_dma_len(sgl) = 0; | ||
538 | return 0; | ||
587 | } | 539 | } |
588 | 540 | ||
589 | /* | 541 | /* |