1 --- a/arch/arm/plat-omap/iovmm.c 2011-11-15 06:09:03.909034496 -0500
2 +++ b/arch/arm/plat-omap/iovmm.c 2011-12-21 14:03:23.673780000 -0500
5 static struct kmem_cache *iovm_area_cachep;
7 +/* return the offset of the first scatterlist entry in a sg table */
8 +static unsigned int sgtable_offset(const struct sg_table *sgt)
10 + if (!sgt || !sgt->nents)
13 + return sgt->sgl->offset;
16 /* return total bytes of sg buffers */
17 static size_t sgtable_len(const struct sg_table *sgt)
20 for_each_sg(sgt->sgl, sg, sgt->nents, i) {
23 - bytes = sg_dma_len(sg);
24 + bytes = sg_dma_len(sg) + sg->offset;
26 if (!iopgsz_ok(bytes)) {
27 - pr_err("%s: sg[%d] not iommu pagesize(%x)\n",
28 - __func__, i, bytes);
29 + pr_err("%s: sg[%d] not iommu pagesize(%u %u)\n",
30 + __func__, i, bytes, sg->offset);
34 + if (i && sg->offset) {
35 + pr_err("%s: sg[%d] offset not allowed in internal "
36 + "entries\n", __func__, i);
44 +static struct scatterlist *sg_alloc(unsigned int nents, gfp_t gfp_mask)
46 + return kmalloc(nents * sizeof(struct scatterlist), gfp_mask);
49 +static void sg_free(struct scatterlist *sg, unsigned int nents)
55 /* allocate and initialize sg_table header(a kind of 'superblock') */
56 static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags)
59 return ERR_PTR(-ENOMEM);
61 - err = sg_alloc_table(sgt, nr_entries, GFP_KERNEL);
62 + err = __sg_alloc_table(sgt, nr_entries, -1, GFP_KERNEL, sg_alloc);
71 + __sg_free_table(sgt, -1, sg_free);
74 pr_debug("%s: sgt:%p\n", __func__, sgt);
80 - bytes = sg_dma_len(sg);
81 + pa = sg_phys(sg) - sg->offset;
82 + bytes = sg_dma_len(sg) + sg->offset;
84 BUG_ON(bytes != PAGE_SIZE);
91 - bytes = sg_dma_len(sg);
92 + pa = sg_phys(sg) - sg->offset;
93 + bytes = sg_dma_len(sg) + sg->offset;
95 flags &= ~IOVMF_PGSZ_MASK;
96 pgsz = bytes_to_iopgsz(bytes);
102 + return da + sgtable_offset(sgt);
104 EXPORT_SYMBOL_GPL(iommu_vmap);
107 * 'sgt' is allocated before 'iommu_vmalloc()' is called.
108 * Just returns 'sgt' to the caller to free
111 sgt = unmap_vm_area(obj, da, vunmap_sg, IOVMF_DISCONT | IOVMF_MMIO);
113 dev_dbg(obj->dev, "%s: No sgt\n", __func__);