return;
if (p->dbuf_mapped)
- call_void_memop(vb, unmap_dmabuf, p->mem_priv);
+ call_void_memop(vb, unmap_dmabuf,
+ p->mem_priv, 0);
call_void_memop(vb, detach_dmabuf, p->mem_priv);
dma_buf_put(p->dbuf);
state != VB2_BUF_STATE_REQUEUEING) {
/* sync buffers */
for (plane = 0; plane < vb->num_planes; ++plane)
- call_void_memop(vb, finish, vb->planes[plane].mem_priv);
+ call_void_memop(vb, finish, vb->planes[plane].mem_priv,
+ vb->planes[plane].bytesused);
}
spin_lock_irqsave(&q->done_lock, flags);
* userspace knows sooner rather than later if the dma-buf map fails.
*/
for (plane = 0; plane < vb->num_planes; ++plane) {
- ret = call_memop(vb, map_dmabuf, vb->planes[plane].mem_priv);
+ ret = call_memop(vb, map_dmabuf, vb->planes[plane].mem_priv,
+ planes[plane].bytesused);
+
if (ret) {
dprintk(1, "failed to map dmabuf for plane %d\n",
plane);
/* sync buffers */
for (plane = 0; plane < vb->num_planes; ++plane)
- call_void_memop(vb, prepare, vb->planes[plane].mem_priv);
+ call_void_memop(vb, prepare, vb->planes[plane].mem_priv,
+ vb->planes[plane].bytesused);
vb->state = VB2_BUF_STATE_PREPARED;
for (i = 0; i < vb->num_planes; ++i) {
if (!vb->planes[i].dbuf_mapped)
continue;
- call_void_memop(vb, unmap_dmabuf, vb->planes[i].mem_priv);
+
+ call_void_memop(vb, unmap_dmabuf,
+ vb->planes[i].mem_priv,
+ vb->planes[i].bytesused);
+
vb->planes[i].dbuf_mapped = 0;
}
}
for (plane = 0; plane < vb->num_planes; ++plane)
call_void_memop(vb, finish,
- vb->planes[plane].mem_priv);
+ vb->planes[plane].mem_priv,
+ 0);
}
if (vb->state != VB2_BUF_STATE_DEQUEUED) {
}
}
-static void vb2_dma_sg_prepare(void *buf_priv)
+static void vb2_dma_sg_prepare(void *buf_priv, size_t size)
{
struct vb2_dma_sg_buf *buf = buf_priv;
struct sg_table *sgt = buf->dma_sgt;
+ struct scatterlist *sg;
+ int i;
/* DMABUF exporter will flush the cache for us */
if (buf->db_attach)
return;
- dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->orig_nents,
- buf->dma_dir);
+ if (size == 0)
+ size = buf->size;
+
+ for_each_sg(sgt->sgl, sg, sgt->nents, i) {
+ size_t sg_len = min_t(size_t, size, sg->length);
+
+ dma_sync_single_for_device(buf->dev, sg->dma_address,
+ sg_len, buf->dma_dir);
+
+ size -= sg_len;
+
+ if (!size)
+ break;
+ }
}
-static void vb2_dma_sg_finish(void *buf_priv)
+static void vb2_dma_sg_finish(void *buf_priv, size_t size)
{
struct vb2_dma_sg_buf *buf = buf_priv;
struct sg_table *sgt = buf->dma_sgt;
+ struct scatterlist *sg;
+ int i;
/* DMABUF exporter will flush the cache for us */
if (buf->db_attach)
return;
- dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir);
+ if (size == 0)
+ size = buf->size;
+
+ for_each_sg(sgt->sgl, sg, sgt->nents, i) {
+ size_t sg_len = min_t(size_t, size, sg->length);
+
+ dma_sync_single_for_cpu(buf->dev, sg->dma_address,
+ sg_len, buf->dma_dir);
+
+ size -= sg_len;
+
+ if (!size)
+ break;
+ }
}
static void *vb2_dma_sg_get_userptr(struct device *dev, unsigned long vaddr,
/* callbacks for DMABUF buffers */
/*********************************************/
-static int vb2_dma_sg_map_dmabuf(void *mem_priv)
+static int vb2_dma_sg_map_dmabuf(void *mem_priv, size_t size)
{
struct vb2_dma_sg_buf *buf = mem_priv;
struct sg_table *sgt;
}
/* get the associated scatterlist for this buffer */
- sgt = dma_buf_map_attachment(buf->db_attach, buf->dma_dir);
+ sgt = (size == 0) ?
+ dma_buf_map_attachment(buf->db_attach, buf->dma_dir) :
+ dma_buf_map_attachment_area(buf->db_attach,
+ buf->dma_dir, size);
+
if (IS_ERR(sgt)) {
pr_err("Error getting dmabuf scatterlist\n");
return -EINVAL;
return 0;
}
-static void vb2_dma_sg_unmap_dmabuf(void *mem_priv)
+static void vb2_dma_sg_unmap_dmabuf(void *mem_priv, size_t size)
{
struct vb2_dma_sg_buf *buf = mem_priv;
struct sg_table *sgt = buf->dma_sgt;
dma_buf_vunmap(buf->db_attach->dmabuf, buf->vaddr);
buf->vaddr = NULL;
}
- dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
+
+ if (size == 0)
+ dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
+ else
+ dma_buf_unmap_attachment_area(buf->db_attach, sgt,
+ buf->dma_dir, size);
buf->dma_sgt = NULL;
}
/* if vb2 works correctly you should never detach mapped buffer */
if (WARN_ON(buf->dma_sgt))
- vb2_dma_sg_unmap_dmabuf(buf);
+ vb2_dma_sg_unmap_dmabuf(buf, 0);
ion_iovmm_unmap(buf->db_attach, buf->iova);
enum dma_data_direction dma_dir);
void (*put_userptr)(void *buf_priv);
- void (*prepare)(void *buf_priv);
- void (*finish)(void *buf_priv);
+ void (*prepare)(void *buf_priv, size_t size);
+ void (*finish)(void *buf_priv, size_t size);
void *(*attach_dmabuf)(struct device *dev,
struct dma_buf *dbuf,
unsigned long size,
enum dma_data_direction dma_dir);
void (*detach_dmabuf)(void *buf_priv);
- int (*map_dmabuf)(void *buf_priv);
- void (*unmap_dmabuf)(void *buf_priv);
+ int (*map_dmabuf)(void *buf_priv, size_t size);
+ void (*unmap_dmabuf)(void *buf_priv, size_t size);
void *(*vaddr)(void *buf_priv);
void *(*cookie)(void *buf_priv);