diff mbox

[v4,12/14] v4l: vb2-dma-contig: change map/unmap behaviour for importers

Message ID 1334332076-28489-13-git-send-email-t.stanislaws@samsung.com
State Superseded, archived
Headers show

Commit Message

Tomasz Stanislawski April 13, 2012, 3:47 p.m. UTC
The DMABUF documentation says that the map_dma_buf callback should return
scatterlist that is mapped into a caller's address space. In practice, almost
none of existing implementations of DMABUF exporter does it.  This patch breaks
the DMABUF specification in order to allow exchange DMABUF buffers between
other APIs like DRM.

Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 drivers/media/video/videobuf2-dma-contig.c |   21 +++++++++++++++++++--
 1 files changed, 19 insertions(+), 2 deletions(-)

Comments

Laurent Pinchart April 17, 2012, 1:03 a.m. UTC | #1
Hi Tomasz,

Thanks for the patch.

On Friday 13 April 2012 17:47:54 Tomasz Stanislawski wrote:
> The DMABUF documentation says that the map_dma_buf callback should return
> scatterlist that is mapped into a caller's address space. In practice,
> almost none of existing implementations of DMABUF exporter does it.  This
> patch breaks the DMABUF specification in order to allow exchange DMABUF
> buffers between other APIs like DRM.

Once again, this means that it's time to either fix the documentation or fix 
the non-compliant drivers.

Could you please read the mail I've sent on 27/03/2012 in the "Minutes from 
V4L2 update call" thread and reply there to avoid scattering the discussion ?
diff mbox

Patch

diff --git a/drivers/media/video/videobuf2-dma-contig.c b/drivers/media/video/videobuf2-dma-contig.c
index a829e7d..0ea3fcd 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -442,6 +442,7 @@  static int vb2_dc_map_dmabuf(void *mem_priv)
 	struct vb2_dc_buf *buf = mem_priv;
 	struct sg_table *sgt;
 	unsigned long contig_size;
+	int ret = -EFAULT;
 
 	if (WARN_ON(!buf->db_attach)) {
 		printk(KERN_ERR "trying to pin a non attached buffer\n");
@@ -460,19 +461,34 @@  static int vb2_dc_map_dmabuf(void *mem_priv)
 		return -EINVAL;
 	}
 
+	/* mapping new sglist to the client */
+	sgt->nents = dma_map_sg(buf->dev, sgt->sgl, sgt->orig_nents,
+		buf->dma_dir);
+	if (sgt->nents <= 0) {
+		printk(KERN_ERR "failed to map scatterlist\n");
+		goto fail_map_attachment;
+	}
+
 	/* checking if dmabuf is big enough to store contiguous chunk */
 	contig_size = vb2_dc_get_contiguous_size(sgt);
 	if (contig_size < buf->size) {
 		printk(KERN_ERR "contiguous chunk is too small %lu/%lu b\n",
 			contig_size, buf->size);
-		dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
-		return -EFAULT;
+		goto fail_map_sg;
 	}
 
 	buf->dma_addr = sg_dma_address(sgt->sgl);
 	buf->dma_sgt = sgt;
 
 	return 0;
+
+fail_map_sg:
+	dma_unmap_sg(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
+
+fail_map_attachment:
+	dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
+
+	return ret;
 }
 
 static void vb2_dc_unmap_dmabuf(void *mem_priv)
@@ -490,6 +506,7 @@  static void vb2_dc_unmap_dmabuf(void *mem_priv)
 		return;
 	}
 
+	dma_unmap_sg(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
 	dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
 
 	buf->dma_addr = 0;