@@ -652,7 +652,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 = 0;
+ int ret = -EFAULT;
if (WARN_ON(!buf->db_attach)) {
printk(KERN_ERR "trying to pin a non attached buffer\n");
@@ -671,12 +671,20 @@ 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 of dmabuf is too small\n");
- ret = -EFAULT;
- goto fail_map;
+ printk(KERN_ERR "contiguous chunk is too small %lu/%lu b\n",
+ contig_size, buf->size);
+ goto fail_map_sg;
}
buf->dma_addr = sg_dma_address(sgt->sgl);
@@ -684,7 +692,10 @@ static int vb2_dc_map_dmabuf(void *mem_priv)
return 0;
-fail_map:
+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;
@@ -705,6 +716,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;