diff mbox

[12/12] v4l: vb2-dma-contig: Move allocation of dbuf attachment to attach cb

Message ID 1337778455-27912-13-git-send-email-t.stanislaws@samsung.com
State Under Review
Headers show

Commit Message

Tomasz Stanislawski May 23, 2012, 1:07 p.m. UTC
The allocation of dma_buf_attachment is moved to attach callback.
The initialization is left in map callback.

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 |   39 ++++++++++++++++++----------
 1 file changed, 26 insertions(+), 13 deletions(-)
diff mbox

Patch

diff --git a/drivers/media/video/videobuf2-dma-contig.c b/drivers/media/video/videobuf2-dma-contig.c
index b5caf1d..3bf7c45 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -285,7 +285,15 @@  struct vb2_dc_attachment {
 static int vb2_dc_dmabuf_ops_attach(struct dma_buf *dbuf, struct device *dev,
 	struct dma_buf_attachment *dbuf_attach)
 {
-	/* nothing to be done */
+	struct vb2_dc_attachment *attach;
+
+	attach = kzalloc(sizeof *attach, GFP_KERNEL);
+	if (!attach)
+		return -ENOMEM;
+
+	attach->dir = DMA_NONE;
+	dbuf_attach->priv = attach;
+
 	return 0;
 }
 
@@ -300,7 +308,9 @@  static void vb2_dc_dmabuf_ops_detach(struct dma_buf *dbuf,
 
 	sgt = &attach->sgt;
 
-	dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->nents, attach->dir);
+	/* checking if scaterlist was ever mapped */
+	if (attach->dir != DMA_NONE)
+		dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->nents, attach->dir);
 	sg_free_table(sgt);
 	kfree(attach);
 	db_attach->priv = NULL;
@@ -314,25 +324,28 @@  static struct sg_table *vb2_dc_dmabuf_ops_map(
 	struct vb2_dc_attachment *attach = db_attach->priv;
 	struct sg_table *sgt;
 	struct scatterlist *rd, *wr;
-	int i, ret;
+	int ret;
+	unsigned int i;
+
+	if (WARN_ON(dir == DMA_NONE))
+		return ERR_PTR(-EINVAL);
 
 	/* return previously mapped sg table */
-	if (attach)
+	if (attach->dir == dir)
 		return &attach->sgt;
 
-	attach = kzalloc(sizeof *attach, GFP_KERNEL);
-	if (!attach)
-		return ERR_PTR(-ENOMEM);
+	/* reattaching is not allowed */
+	if (WARN_ON(attach->dir != DMA_NONE))
+		return ERR_PTR(-EBUSY);
 
 	sgt = &attach->sgt;
-	attach->dir = dir;
 
-	/* copying the buf->base_sgt to attachment */
+	/* Copy the buf->base_sgt scatter list to the attachment, as we can't
+	 * map the same scatter list to multiple attachments at the same time.
+	 */
 	ret = sg_alloc_table(sgt, buf->sgt_base.orig_nents, GFP_KERNEL);
-	if (ret) {
-		kfree(attach);
+	if (ret)
 		return ERR_PTR(-ENOMEM);
-	}
 
 	rd = buf->sgt_base.sgl;
 	wr = sgt->sgl;
@@ -347,10 +360,10 @@  static struct sg_table *vb2_dc_dmabuf_ops_map(
 	if (ret <= 0) {
 		printk(KERN_ERR "failed to map scatterlist\n");
 		sg_free_table(sgt);
-		kfree(attach);
 		return ERR_PTR(-EIO);
 	}
 
+	attach->dir = dir;
 	db_attach->priv = attach;
 
 	return sgt;