The allocation of dma_buf_attachment is moved to attach callback.
The initialization is left in map callback.

Signed-off-by: Tomasz Stanislawski <t.stanisl...@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.p...@samsung.com>
---
 drivers/media/video/videobuf2-dma-contig.c |   39 ++++++++++++++++++----------
 1 file changed, 26 insertions(+), 13 deletions(-)

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;
-- 
1.7.9.5

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to