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