Loading arch/arm/mm/dma-mapping.c +34 −2 Original line number Original line Diff line number Diff line Loading @@ -1651,7 +1651,31 @@ int arm_coherent_iommu_map_sg(struct device *dev, struct scatterlist *sg, int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg, int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, struct dma_attrs *attrs) int nents, enum dma_data_direction dir, struct dma_attrs *attrs) { { return __iommu_map_sg(dev, sg, nents, dir, attrs, false); struct scatterlist *s; int i; size_t ret; struct dma_iommu_mapping *mapping = dev->archdata.mapping; unsigned int total_length = 0, current_offset = 0; dma_addr_t iova; int prot = __dma_direction_to_prot(dir); for_each_sg(sg, s, nents, i) total_length += s->length; iova = __alloc_iova(mapping, total_length); ret = iommu_map_sg(mapping->domain, iova, sg, nents, prot); if (ret != total_length) { __free_iova(mapping, iova, total_length); return 0; } for_each_sg(sg, s, nents, i) { s->dma_address = iova + current_offset; s->dma_length = total_length - current_offset; current_offset += s->length; } return nents; } } static void __iommu_unmap_sg(struct device *dev, struct scatterlist *sg, static void __iommu_unmap_sg(struct device *dev, struct scatterlist *sg, Loading Loading @@ -1701,7 +1725,15 @@ void arm_coherent_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, void arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, void arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, struct dma_attrs *attrs) enum dma_data_direction dir, struct dma_attrs *attrs) { { __iommu_unmap_sg(dev, sg, nents, dir, attrs, false); struct dma_iommu_mapping *mapping = dev->archdata.mapping; unsigned int total_length = sg_dma_len(sg); dma_addr_t iova = sg_dma_address(sg); total_length = PAGE_ALIGN((iova & ~PAGE_MASK) + total_length); iova &= PAGE_MASK; iommu_unmap_range(mapping->domain, iova, total_length); __free_iova(mapping, iova, total_length); } } /** /** Loading Loading
arch/arm/mm/dma-mapping.c +34 −2 Original line number Original line Diff line number Diff line Loading @@ -1651,7 +1651,31 @@ int arm_coherent_iommu_map_sg(struct device *dev, struct scatterlist *sg, int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg, int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, struct dma_attrs *attrs) int nents, enum dma_data_direction dir, struct dma_attrs *attrs) { { return __iommu_map_sg(dev, sg, nents, dir, attrs, false); struct scatterlist *s; int i; size_t ret; struct dma_iommu_mapping *mapping = dev->archdata.mapping; unsigned int total_length = 0, current_offset = 0; dma_addr_t iova; int prot = __dma_direction_to_prot(dir); for_each_sg(sg, s, nents, i) total_length += s->length; iova = __alloc_iova(mapping, total_length); ret = iommu_map_sg(mapping->domain, iova, sg, nents, prot); if (ret != total_length) { __free_iova(mapping, iova, total_length); return 0; } for_each_sg(sg, s, nents, i) { s->dma_address = iova + current_offset; s->dma_length = total_length - current_offset; current_offset += s->length; } return nents; } } static void __iommu_unmap_sg(struct device *dev, struct scatterlist *sg, static void __iommu_unmap_sg(struct device *dev, struct scatterlist *sg, Loading Loading @@ -1701,7 +1725,15 @@ void arm_coherent_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, void arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, void arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, struct dma_attrs *attrs) enum dma_data_direction dir, struct dma_attrs *attrs) { { __iommu_unmap_sg(dev, sg, nents, dir, attrs, false); struct dma_iommu_mapping *mapping = dev->archdata.mapping; unsigned int total_length = sg_dma_len(sg); dma_addr_t iova = sg_dma_address(sg); total_length = PAGE_ALIGN((iova & ~PAGE_MASK) + total_length); iova &= PAGE_MASK; iommu_unmap_range(mapping->domain, iova, total_length); __free_iova(mapping, iova, total_length); } } /** /** Loading