CHROMIUM: v4l2: dmabuf: update VIDIOC_EXPBUF interface to upstream
authorJohn Sheu <sheu@chromium.org>
Thu, 31 Jan 2013 02:39:36 +0000 (18:39 -0800)
committerChromeBot <chrome-bot@google.com>
Wed, 6 Feb 2013 20:16:59 +0000 (12:16 -0800)
<UPSTREAM MERGE NOT REQUIRED>

Backport the VIDIOC_EXPBUF interface from upstream kernels.

Signed-off-by: John Sheu <sheu@google.com>
BUG=chromium-os:38376
BUG=chromium:167417
TEST=local build, run on snow
Change-Id: Ia5cae1636b85d2c716188ff510a83a04b9cd8bc9
Reviewed-on: https://gerrit.chromium.org/gerrit/42374
Tested-by: John Sheu <sheu@chromium.org>
Reviewed-by: Pawel Osciak <posciak@chromium.org>
Commit-Queue: John Sheu <sheu@chromium.org>

drivers/media/video/s5p-mfc/s5p_mfc_dec.c
drivers/media/video/s5p-mfc/s5p_mfc_enc.c
drivers/media/video/v4l2-mem2mem.c
drivers/media/video/videobuf2-core.c
include/linux/videodev2.h

index d7bf206..d1c014c 100644 (file)
@@ -668,16 +668,12 @@ static int vidioc_expbuf(struct file *file, void *priv,
        struct v4l2_exportbuffer *eb)
 {
        struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
-       int ret;
 
-       if (eb->mem_offset < DST_QUEUE_OFF_BASE)
+       if (eb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
                return vb2_expbuf(&ctx->vq_src, eb);
-
-       eb->mem_offset -= DST_QUEUE_OFF_BASE;
-       ret = vb2_expbuf(&ctx->vq_dst, eb);
-       eb->mem_offset += DST_QUEUE_OFF_BASE;
-
-       return ret;
+       else if (eb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+               return vb2_expbuf(&ctx->vq_dst, eb);
+       return -EINVAL;
 }
 
 /* Stream on */
index 8ce1636..61de649 100644 (file)
@@ -1286,16 +1286,12 @@ static int vidioc_expbuf(struct file *file, void *priv,
        struct v4l2_exportbuffer *eb)
 {
        struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
-       int ret;
 
-       if (eb->mem_offset < DST_QUEUE_OFF_BASE)
+       if (eb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
                return vb2_expbuf(&ctx->vq_src, eb);
-
-       eb->mem_offset -= DST_QUEUE_OFF_BASE;
-       ret = vb2_expbuf(&ctx->vq_dst, eb);
-       eb->mem_offset += DST_QUEUE_OFF_BASE;
-
-       return ret;
+       else if (eb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+               return vb2_expbuf(&ctx->vq_dst, eb);
+       return -EINVAL;
 }
 
 /* Stream on */
index a8f3cda..0b10557 100644 (file)
@@ -340,12 +340,10 @@ int v4l2_m2m_expbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
                                                struct v4l2_exportbuffer *eb)
 {
        struct vb2_queue *vq;
-       if (eb->mem_offset < DST_QUEUE_OFF_BASE) {
+       if (V4L2_TYPE_IS_OUTPUT(eb->type))
                vq = v4l2_m2m_get_vq(m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
-       } else {
+       else
                vq = v4l2_m2m_get_vq(m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
-               eb->mem_offset -= DST_QUEUE_OFF_BASE;
-       }
        return vb2_expbuf(vq, eb);
 }
 EXPORT_SYMBOL_GPL(v4l2_m2m_expbuf);
index 982e256..ecab4a3 100644 (file)
@@ -1697,35 +1697,6 @@ int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type)
 }
 EXPORT_SYMBOL_GPL(vb2_streamoff);
 
-/**
- * __find_plane_by_offset() - find plane associated with the given offset off
- */
-static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off,
-                       unsigned int *_buffer, unsigned int *_plane)
-{
-       struct vb2_buffer *vb;
-       unsigned int buffer, plane;
-
-       /*
-        * Go over all buffers and their planes, comparing the given offset
-        * with an offset assigned to each plane. If a match is found,
-        * return its buffer and plane numbers.
-        */
-       for (buffer = 0; buffer < q->num_buffers; ++buffer) {
-               vb = q->bufs[buffer];
-
-               for (plane = 0; plane < vb->num_planes; ++plane) {
-                       if (vb->v4l2_planes[plane].m.mem_offset == off) {
-                               *_buffer = buffer;
-                               *_plane = plane;
-                               return 0;
-                       }
-               }
-       }
-
-       return -EINVAL;
-}
-
 /**
  * vb2_expbuf() - Export a buffer as a file descriptor
  * @q:         videobuf2 queue
@@ -1739,7 +1710,6 @@ int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
 {
        struct vb2_buffer *vb = NULL;
        struct vb2_plane *vb_plane;
-       unsigned int buffer, plane;
        int ret;
        struct dma_buf *dbuf;
 
@@ -1761,38 +1731,73 @@ int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
        /*
         * Find the plane corresponding to the offset passed by userspace.
         */
-       ret = __find_plane_by_offset(q, eb->mem_offset, &buffer, &plane);
-       if (ret) {
-               dprintk(1, "invalid offset %u\n", eb->mem_offset);
-               return ret;
+       if (eb->type != q->type) {
+               dprintk(1, "invalid type %u\n", eb->type);
+               return -EINVAL;
        }
-
-       vb = q->bufs[buffer];
-       vb_plane = &vb->planes[plane];
+       if (eb->index >= q->num_buffers) {
+               dprintk(1, "invalid buffer %u\n", eb->index);
+               return -EINVAL;
+       }
+       vb = q->bufs[eb->index];
+       if (eb->plane >= vb->num_planes) {
+               dprintk(1, "invalid plane %u\n", eb->plane);
+               return -EINVAL;
+       }
+       vb_plane = &vb->planes[eb->plane];
 
        dbuf = call_memop(q, get_dmabuf, vb_plane->mem_priv);
        if (IS_ERR_OR_NULL(dbuf)) {
                dprintk(1, "Failed to export buffer %d, plane %d\n",
-                       buffer, plane);
+                       eb->index, eb->plane);
                return -EINVAL;
        }
 
        ret = dma_buf_fd(dbuf, eb->flags);
        if (ret < 0) {
                dprintk(3, "buffer %d, plane %d failed to export (%d)\n",
-                       buffer, plane, ret);
+                       eb->index, eb->plane, ret);
                dma_buf_put(dbuf);
                return ret;
        }
 
        dprintk(3, "buffer %d, plane %d exported as %d descriptor\n",
-               buffer, plane, ret);
+               eb->index, eb->plane, ret);
        eb->fd = ret;
 
        return 0;
 }
 EXPORT_SYMBOL_GPL(vb2_expbuf);
 
+/**
+ * __find_plane_by_offset() - find plane associated with the given offset off
+ */
+static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off,
+                       unsigned int *_buffer, unsigned int *_plane)
+{
+       struct vb2_buffer *vb;
+       unsigned int buffer, plane;
+
+       /*
+        * Go over all buffers and their planes, comparing the given offset
+        * with an offset assigned to each plane. If a match is found,
+        * return its buffer and plane numbers.
+        */
+       for (buffer = 0; buffer < q->num_buffers; ++buffer) {
+               vb = q->bufs[buffer];
+
+               for (plane = 0; plane < vb->num_planes; ++plane) {
+                       if (vb->v4l2_planes[plane].m.mem_offset == off) {
+                               *_buffer = buffer;
+                               *_plane = plane;
+                               return 0;
+                       }
+               }
+       }
+
+       return -EINVAL;
+}
+
 /**
  * vb2_mmap() - map video buffers into application address space
  * @q:         videobuf2 queue
index 405313f..aa129fb 100644 (file)
@@ -695,12 +695,13 @@ struct v4l2_buffer {
 /**
  * struct v4l2_exportbuffer - export of video buffer as DMABUF file descriptor
  *
- * @fd:                file descriptor associated with DMABUF (set by driver)
- * @mem_offset:        buffer memory offset as returned by VIDIOC_QUERYBUF in struct
- *             v4l2_buffer::m.offset (for single-plane formats) or
- *             v4l2_plane::m.offset (for multi-planar formats)
+ * @index:     id number of the buffer
+ * @type:      enum v4l2_buf_type; buffer type (type == *_MPLANE for
+ *             multiplanar buffers);
+ * @plane:     index of the plane to be exported, 0 for single plane queues
  * @flags:     flags for newly created file, currently only O_CLOEXEC is
  *             supported, refer to manual of open syscall for more details
+ * @fd:                file descriptor associated with DMABUF (set by driver)
  *
  * Contains data used for exporting a video buffer as DMABUF file descriptor.
  * The buffer is identified by a 'cookie' returned by VIDIOC_QUERYBUF
@@ -710,11 +711,12 @@ struct v4l2_buffer {
  * content. Therefore this field should not be used for any other extensions.
  */
 struct v4l2_exportbuffer {
-       __u32           fd;
-       __u32           reserved0;
-       __u32           mem_offset;
+       __u32           type; /* enum v4l2_buf_type */
+       __u32           index;
+       __u32           plane;
        __u32           flags;
-       __u32           reserved[12];
+       __s32           fd;
+       __u32           reserved[11];
 };
 
 /*