/* * ispmmu_vmap - Wrapper for Virtual memory mapping of a scatter gather list * @dev: Device pointer specific to the OMAP3 ISP. * @sglist: Pointer to source Scatter gather list to allocate. * @sglen: Number of elements of the scatter-gatter list. * * Returns a resulting mapped device address by the ISP MMU, or -ENOMEM if * we ran out of memory. */ static dma_addr_t ispmmu_vmap(struct isp_device *isp, const struct scatterlist *sglist, int sglen) { struct sg_table *sgt; u32 da; sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); if (sgt == NULL) return -ENOMEM; sgt->sgl = (struct scatterlist *)sglist; sgt->nents = sglen; sgt->orig_nents = sglen; da = iommu_vmap(isp->iommu, 0, sgt, IOMMU_FLAG); if (IS_ERR_VALUE(da)) kfree(sgt); return da; }
dma_addr_t ispmmu_vmap(const struct scatterlist *sglist, int sglen) { int err; void *da; struct sg_table *sgt; unsigned int i; struct scatterlist *sg, *src = (struct scatterlist *)sglist; /* * convert isp sglist to iommu sgt * FIXME: should be fixed in the upper layer? */ sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); if (!sgt) return -ENOMEM; err = sg_alloc_table(sgt, sglen, GFP_KERNEL); if (err) goto err_sg_alloc; for_each_sg(sgt->sgl, sg, sgt->nents, i) sg_set_buf(sg, phys_to_virt(sg_dma_address(src + i)), sg_dma_len(src + i)); da = (void *)iommu_vmap(isp_iommu, 0, sgt, IOMMU_FLAG); if (IS_ERR(da)) goto err_vmap; return (dma_addr_t)da; err_vmap: sg_free_table(sgt); err_sg_alloc: kfree(sgt); return -ENOMEM; }