arm: dma-mapping: map sg lists into the SMMU as virtually contiguous
Following commit implements mapping of sg virtually contiguously. "arm64: dma-mapping: map sg lists into the SMMU as virtually contiguous" a03f74ef16cc73531795176d3ea8b82b66ed0146 This has been left for ARM (32-bit). Implement the same for ARM. Change-Id: Ibf67f29a60b8d19e526c4719590f2f473ea9dca5 Signed-off-by: Chintan Pandya <cpandya@codeaurora.org>
This commit is contained in:
parent
cc077f64d2
commit
81e4499b1e
1 changed files with 34 additions and 2 deletions
|
@ -1689,7 +1689,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 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,
|
||||
|
@ -1739,7 +1763,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,
|
||||
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…
Add table
Reference in a new issue