Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ea3aba84 authored by Philipp Zabel's avatar Philipp Zabel Committed by Mauro Carvalho Chehab
Browse files

[media] videobuf2: Add support for file access mode flags for DMABUF exporting



Currently it is not possible for userspace to map a DMABUF exported buffer
with write permissions. This patch allows to also pass O_RDONLY/O_RDWR when
exporting the buffer, so that userspace may map it with write permissions.

Signed-off-by: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: default avatarSylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent d8eec74a
Loading
Loading
Loading
Loading
+5 −3
Original line number Original line Diff line number Diff line
@@ -73,7 +73,8 @@ range from zero to the maximal number of valid planes for the currently active
format. For the single-planar API, applications must set <structfield> plane
format. For the single-planar API, applications must set <structfield> plane
</structfield> to zero.  Additional flags may be posted in the <structfield>
</structfield> to zero.  Additional flags may be posted in the <structfield>
flags </structfield> field.  Refer to a manual for open() for details.
flags </structfield> field.  Refer to a manual for open() for details.
Currently only O_CLOEXEC is supported.  All other fields must be set to zero.
Currently only O_CLOEXEC, O_RDONLY, O_WRONLY, and O_RDWR are supported.  All
other fields must be set to zero.
In the case of multi-planar API, every plane is exported separately using
In the case of multi-planar API, every plane is exported separately using
multiple <constant> VIDIOC_EXPBUF </constant> calls. </para>
multiple <constant> VIDIOC_EXPBUF </constant> calls. </para>


@@ -170,8 +171,9 @@ multi-planar API. Otherwise this value must be set to zero. </entry>
	    <entry>__u32</entry>
	    <entry>__u32</entry>
	    <entry><structfield>flags</structfield></entry>
	    <entry><structfield>flags</structfield></entry>
	    <entry>Flags for the newly created file, currently only <constant>
	    <entry>Flags for the newly created file, currently only <constant>
O_CLOEXEC </constant> is supported, refer to the manual of open() for more
O_CLOEXEC </constant>, <constant>O_RDONLY</constant>, <constant>O_WRONLY
details.</entry>
</constant>, and <constant>O_RDWR</constant> are supported, refer to the manual
of open() for more details.</entry>
	  </row>
	  </row>
	  <row>
	  <row>
	    <entry>__s32</entry>
	    <entry>__s32</entry>
+4 −4
Original line number Original line Diff line number Diff line
@@ -1824,8 +1824,8 @@ int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
		return -EINVAL;
		return -EINVAL;
	}
	}


	if (eb->flags & ~O_CLOEXEC) {
	if (eb->flags & ~(O_CLOEXEC | O_ACCMODE)) {
		dprintk(1, "Queue does support only O_CLOEXEC flag\n");
		dprintk(1, "Queue does support only O_CLOEXEC and access mode flags\n");
		return -EINVAL;
		return -EINVAL;
	}
	}


@@ -1848,14 +1848,14 @@ int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)


	vb_plane = &vb->planes[eb->plane];
	vb_plane = &vb->planes[eb->plane];


	dbuf = call_memop(q, get_dmabuf, vb_plane->mem_priv);
	dbuf = call_memop(q, get_dmabuf, vb_plane->mem_priv, eb->flags & O_ACCMODE);
	if (IS_ERR_OR_NULL(dbuf)) {
	if (IS_ERR_OR_NULL(dbuf)) {
		dprintk(1, "Failed to export buffer %d, plane %d\n",
		dprintk(1, "Failed to export buffer %d, plane %d\n",
			eb->index, eb->plane);
			eb->index, eb->plane);
		return -EINVAL;
		return -EINVAL;
	}
	}


	ret = dma_buf_fd(dbuf, eb->flags);
	ret = dma_buf_fd(dbuf, eb->flags & ~O_ACCMODE);
	if (ret < 0) {
	if (ret < 0) {
		dprintk(3, "buffer %d, plane %d failed to export (%d)\n",
		dprintk(3, "buffer %d, plane %d failed to export (%d)\n",
			eb->index, eb->plane, ret);
			eb->index, eb->plane, ret);
+2 −2
Original line number Original line Diff line number Diff line
@@ -393,7 +393,7 @@ static struct sg_table *vb2_dc_get_base_sgt(struct vb2_dc_buf *buf)
	return sgt;
	return sgt;
}
}


static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv)
static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv, unsigned long flags)
{
{
	struct vb2_dc_buf *buf = buf_priv;
	struct vb2_dc_buf *buf = buf_priv;
	struct dma_buf *dbuf;
	struct dma_buf *dbuf;
@@ -404,7 +404,7 @@ static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv)
	if (WARN_ON(!buf->sgt_base))
	if (WARN_ON(!buf->sgt_base))
		return NULL;
		return NULL;


	dbuf = dma_buf_export(buf, &vb2_dc_dmabuf_ops, buf->size, 0);
	dbuf = dma_buf_export(buf, &vb2_dc_dmabuf_ops, buf->size, flags);
	if (IS_ERR(dbuf))
	if (IS_ERR(dbuf))
		return NULL;
		return NULL;


+1 −1
Original line number Original line Diff line number Diff line
@@ -83,7 +83,7 @@ struct vb2_fileio_data;
struct vb2_mem_ops {
struct vb2_mem_ops {
	void		*(*alloc)(void *alloc_ctx, unsigned long size, gfp_t gfp_flags);
	void		*(*alloc)(void *alloc_ctx, unsigned long size, gfp_t gfp_flags);
	void		(*put)(void *buf_priv);
	void		(*put)(void *buf_priv);
	struct dma_buf *(*get_dmabuf)(void *buf_priv);
	struct dma_buf *(*get_dmabuf)(void *buf_priv, unsigned long flags);


	void		*(*get_userptr)(void *alloc_ctx, unsigned long vaddr,
	void		*(*get_userptr)(void *alloc_ctx, unsigned long vaddr,
					unsigned long size, int write);
					unsigned long size, int write);