summaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/iommu_common.h
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2008-03-28 15:55:41 -0700
committerDavid S. Miller <davem@davemloft.net>2008-03-28 15:55:41 -0700
commitf08802572965873af97e74337d5740bfa2542941 (patch)
treea28f31926b4f548d662cea2d6b2b1882b0214e24 /arch/sparc64/kernel/iommu_common.h
parent76cc86ee6b3c261b96ea3ee2f4c6dfd127335881 (diff)
sparc64: add the segment boundary checking to IOMMUs while merging SG entries
Some IOMMUs allocate memory areas spanning LLD's segment boundary limit. It forces low level drivers to have a workaround to adjust scatter lists that the IOMMU builds. We are in the process of making all the IOMMUs respect the segment boundary limits to remove such work around in LLDs. SPARC64 IOMMUs were rewritten to use the IOMMU helper functions and the commit 89c94f2f70d093f59b55d3ea8042d13889169346 made the IOMMUs not allocate memory areas spanning the segment boundary limit. However, SPARC64 IOMMUs allocate memory areas first then try to merge them (while some IOMMUs walk through all the sg entries to see how they can be merged first and allocate memory areas). So SPARC64 IOMMUs also need the boundary limit checking when they try to merge sg entries. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/iommu_common.h')
-rw-r--r--arch/sparc64/kernel/iommu_common.h13
1 files changed, 13 insertions, 0 deletions
diff --git a/arch/sparc64/kernel/iommu_common.h b/arch/sparc64/kernel/iommu_common.h
index 0713bd58499..87ace495d45 100644
--- a/arch/sparc64/kernel/iommu_common.h
+++ b/arch/sparc64/kernel/iommu_common.h
@@ -12,6 +12,7 @@
#include <linux/mm.h>
#include <linux/scatterlist.h>
#include <linux/device.h>
+#include <linux/iommu-helper.h>
#include <asm/iommu.h>
#include <asm/scatterlist.h>
@@ -58,6 +59,18 @@ static inline unsigned long calc_npages(struct scatterlist *sglist, int nelems)
return npages;
}
+static inline int is_span_boundary(unsigned long entry,
+ unsigned long shift,
+ unsigned long boundary_size,
+ struct scatterlist *outs,
+ struct scatterlist *sg)
+{
+ unsigned long paddr = SG_ENT_PHYS_ADDRESS(outs);
+ int nr = iommu_num_pages(paddr, outs->dma_length + sg->length);
+
+ return iommu_is_span_boundary(entry, nr, shift, boundary_size);
+}
+
extern unsigned long iommu_range_alloc(struct device *dev,
struct iommu *iommu,
unsigned long npages,