All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9 v6] new ioctl()s and soc-camera implementation
@ 2011-08-31 18:02 Guennadi Liakhovetski
  2011-08-31 18:02 ` [PATCH 1/9 v6] V4L: add a new videobuf2 buffer state VB2_BUF_STATE_PREPARED Guennadi Liakhovetski
                   ` (8 more replies)
  0 siblings, 9 replies; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-08-31 18:02 UTC (permalink / raw)
  To: Linux Media Mailing List
  Cc: Hans Verkuil, Laurent Pinchart, Pawel Osciak, Sakari Ailus,
	Mauro Carvalho Chehab, Marek Szyprowski

Here goes the next round, addressing Pawel's review of the vb2 
implementation - thanks!

Guennadi Liakhovetski (9):
  V4L: add a new videobuf2 buffer state VB2_BUF_STATE_PREPARED
  V4L: add two new ioctl()s for multi-size videobuffer management
  V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF
    ioctl()s
  V4L: vb2: prepare to support multi-size buffers
  V4L: vb2: add support for buffers of different sizes on a single
    queue
  V4L: sh-mobile-ceu-camera: prepare to support multi-size buffers
  dmaengine: ipu-idmac: add support for the DMA_PAUSE control
  V4L: mx3-camera: prepare to support multi-size buffers
  V4L: soc-camera: add 2 new ioctl() handlers

 Documentation/DocBook/media/v4l/io.xml             |   17 +
 Documentation/DocBook/media/v4l/v4l2.xml           |    2 +
 .../DocBook/media/v4l/vidioc-create-bufs.xml       |  147 ++++++++
 .../DocBook/media/v4l/vidioc-prepare-buf.xml       |   96 ++++++
 drivers/dma/ipu/ipu_idmac.c                        |   65 +++--
 drivers/media/video/atmel-isi.c                    |    6 +-
 drivers/media/video/marvell-ccic/mcam-core.c       |    3 +-
 drivers/media/video/mem2mem_testdev.c              |    7 +-
 drivers/media/video/mx3_camera.c                   |  160 +++++-----
 drivers/media/video/pwc/pwc-if.c                   |    6 +-
 drivers/media/video/s5p-fimc/fimc-capture.c        |    6 +-
 drivers/media/video/s5p-fimc/fimc-core.c           |    6 +-
 drivers/media/video/s5p-mfc/s5p_mfc_dec.c          |    7 +-
 drivers/media/video/s5p-mfc/s5p_mfc_enc.c          |    5 +-
 drivers/media/video/s5p-tv/mixer_video.c           |    4 +-
 drivers/media/video/sh_mobile_ceu_camera.c         |  123 +++++---
 drivers/media/video/soc_camera.c                   |   33 ++-
 drivers/media/video/v4l2-compat-ioctl32.c          |   67 ++++-
 drivers/media/video/v4l2-ioctl.c                   |   29 ++
 drivers/media/video/videobuf2-core.c               |  348 ++++++++++++++++----
 drivers/media/video/vivi.c                         |    6 +-
 include/linux/videodev2.h                          |   15 +
 include/media/v4l2-ioctl.h                         |    2 +
 include/media/videobuf2-core.h                     |   43 ++-
 24 files changed, 939 insertions(+), 264 deletions(-)
 create mode 100644 Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
 create mode 100644 Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml

-- 
1.7.2.5

Enjoy
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH 1/9 v6] V4L: add a new videobuf2 buffer state VB2_BUF_STATE_PREPARED
  2011-08-31 18:02 [PATCH 0/9 v6] new ioctl()s and soc-camera implementation Guennadi Liakhovetski
@ 2011-08-31 18:02 ` Guennadi Liakhovetski
  2011-08-31 18:02 ` [PATCH 2/9 v6] V4L: add two new ioctl()s for multi-size videobuffer management Guennadi Liakhovetski
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-08-31 18:02 UTC (permalink / raw)
  To: Linux Media Mailing List
  Cc: Hans Verkuil, Laurent Pinchart, Pawel Osciak, Sakari Ailus,
	Mauro Carvalho Chehab, Marek Szyprowski

This patch prepares for a better separation of the buffer preparation
stage.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Cc: Hans Verkuil <hverkuil@xs4all.nl>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: Mauro Carvalho Chehab <mchehab@infradead.org>
Cc: Pawel Osciak <pawel@osciak.com>
Cc: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
---

v6: as reported by Pawel: the VB2_BUF_STATE_PREPARED state has to actually be
    set

 drivers/media/video/videobuf2-core.c |   61 +++++++++++++++++++++------------
 include/media/videobuf2-core.h       |    2 +
 2 files changed, 41 insertions(+), 22 deletions(-)

diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/video/videobuf2-core.c
index 3015e60..4153da2 100644
--- a/drivers/media/video/videobuf2-core.c
+++ b/drivers/media/video/videobuf2-core.c
@@ -333,6 +333,7 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
 		b->flags |= V4L2_BUF_FLAG_DONE;
 		break;
 	case VB2_BUF_STATE_DEQUEUED:
+	case VB2_BUF_STATE_PREPARED:
 		/* nothing */
 		break;
 	}
@@ -817,6 +818,33 @@ static void __enqueue_in_driver(struct vb2_buffer *vb)
 	q->ops->buf_queue(vb);
 }
 
+static int __buf_prepare(struct vb2_buffer *vb, struct v4l2_buffer *b)
+{
+	struct vb2_queue *q = vb->vb2_queue;
+	int ret;
+
+	switch (q->memory) {
+	case V4L2_MEMORY_MMAP:
+		ret = __qbuf_mmap(vb, b);
+		break;
+	case V4L2_MEMORY_USERPTR:
+		ret = __qbuf_userptr(vb, b);
+		break;
+	default:
+		WARN(1, "Invalid queue type\n");
+		ret = -EINVAL;
+	}
+
+	if (!ret)
+		ret = call_qop(q, buf_prepare, vb);
+	if (ret)
+		dprintk(1, "qbuf: buffer preparation failed: %d\n", ret);
+	else
+		vb->state = VB2_BUF_STATE_PREPARED;
+
+	return ret;
+}
+
 /**
  * vb2_qbuf() - Queue a buffer from userspace
  * @q:		videobuf2 queue
@@ -826,8 +854,8 @@ static void __enqueue_in_driver(struct vb2_buffer *vb)
  * Should be called from vidioc_qbuf ioctl handler of a driver.
  * This function:
  * 1) verifies the passed buffer,
- * 2) calls buf_prepare callback in the driver (if provided), in which
- *    driver-specific buffer initialization can be performed,
+ * 2) if necessary, calls buf_prepare callback in the driver (if provided), in
+ *    which driver-specific buffer initialization can be performed,
  * 3) if streaming is on, queues the buffer in driver by the means of buf_queue
  *    callback for processing.
  *
@@ -837,7 +865,7 @@ static void __enqueue_in_driver(struct vb2_buffer *vb)
 int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
 {
 	struct vb2_buffer *vb;
-	int ret = 0;
+	int ret;
 
 	if (q->fileio) {
 		dprintk(1, "qbuf: file io in progress\n");
@@ -866,29 +894,18 @@ int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
 		return -EINVAL;
 	}
 
-	if (vb->state != VB2_BUF_STATE_DEQUEUED) {
+	switch (vb->state) {
+	case VB2_BUF_STATE_DEQUEUED:
+		ret = __buf_prepare(vb, b);
+		if (ret)
+			return ret;
+	case VB2_BUF_STATE_PREPARED:
+		break;
+	default:
 		dprintk(1, "qbuf: buffer already in use\n");
 		return -EINVAL;
 	}
 
-	if (q->memory == V4L2_MEMORY_MMAP)
-		ret = __qbuf_mmap(vb, b);
-	else if (q->memory == V4L2_MEMORY_USERPTR)
-		ret = __qbuf_userptr(vb, b);
-	else {
-		WARN(1, "Invalid queue type\n");
-		return -EINVAL;
-	}
-
-	if (ret)
-		return ret;
-
-	ret = call_qop(q, buf_prepare, vb);
-	if (ret) {
-		dprintk(1, "qbuf: buffer preparation failed\n");
-		return ret;
-	}
-
 	/*
 	 * Add to the queued buffers list, a buffer will stay on it until
 	 * dequeued in dqbuf.
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index f87472a..65946c5 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -106,6 +106,7 @@ enum vb2_fileio_flags {
 /**
  * enum vb2_buffer_state - current video buffer state
  * @VB2_BUF_STATE_DEQUEUED:	buffer under userspace control
+ * @VB2_BUF_STATE_PREPARED:	buffer prepared in videobuf and by the driver
  * @VB2_BUF_STATE_QUEUED:	buffer queued in videobuf, but not in driver
  * @VB2_BUF_STATE_ACTIVE:	buffer queued in driver and possibly used
  *				in a hardware operation
@@ -117,6 +118,7 @@ enum vb2_fileio_flags {
  */
 enum vb2_buffer_state {
 	VB2_BUF_STATE_DEQUEUED,
+	VB2_BUF_STATE_PREPARED,
 	VB2_BUF_STATE_QUEUED,
 	VB2_BUF_STATE_ACTIVE,
 	VB2_BUF_STATE_DONE,
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 2/9 v6] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-08-31 18:02 [PATCH 0/9 v6] new ioctl()s and soc-camera implementation Guennadi Liakhovetski
  2011-08-31 18:02 ` [PATCH 1/9 v6] V4L: add a new videobuf2 buffer state VB2_BUF_STATE_PREPARED Guennadi Liakhovetski
@ 2011-08-31 18:02 ` Guennadi Liakhovetski
  2011-08-31 21:06   ` Sakari Ailus
  2011-08-31 18:02 ` [PATCH 3/9 v6] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s Guennadi Liakhovetski
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-08-31 18:02 UTC (permalink / raw)
  To: Linux Media Mailing List
  Cc: Hans Verkuil, Laurent Pinchart, Pawel Osciak, Sakari Ailus,
	Mauro Carvalho Chehab, Marek Szyprowski

A possibility to preallocate and initialise buffers of different sizes
in V4L2 is required for an efficient implementation of a snapshot
mode. This patch adds two new ioctl()s: VIDIOC_CREATE_BUFS and
VIDIOC_PREPARE_BUF and defines respective data structures.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Cc: Hans Verkuil <hverkuil@xs4all.nl>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: Mauro Carvalho Chehab <mchehab@infradead.org>
Cc: Pawel Osciak <pawel@osciak.com>
Cc: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
---
 drivers/media/video/v4l2-compat-ioctl32.c |   67 +++++++++++++++++++++++++---
 drivers/media/video/v4l2-ioctl.c          |   29 ++++++++++++
 include/linux/videodev2.h                 |   15 ++++++
 include/media/v4l2-ioctl.h                |    2 +
 4 files changed, 105 insertions(+), 8 deletions(-)

diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
index 61979b7..85758d2 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -159,11 +159,16 @@ struct v4l2_format32 {
 	} fmt;
 };
 
-static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+struct v4l2_create_buffers32 {
+	__u32			index;		/* output: buffers index...index + count - 1 have been created */
+	__u32			count;
+	enum v4l2_memory        memory;
+	struct v4l2_format32	format;		/* filled in by the user, plane sizes calculated by the driver */
+	__u32			reserved[8];
+};
+
+static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
 {
-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
-			get_user(kp->type, &up->type))
-			return -EFAULT;
 	switch (kp->type) {
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
@@ -192,11 +197,24 @@ static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
 	}
 }
 
-static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+{
+	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
+			get_user(kp->type, &up->type))
+			return -EFAULT;
+	return __get_v4l2_format32(kp, up);
+}
+
+static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
+{
+	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)) ||
+	    copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format.fmt)))
+			return -EFAULT;
+	return __get_v4l2_format32(&kp->format, &up->format);
+}
+
+static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
 {
-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
-		put_user(kp->type, &up->type))
-		return -EFAULT;
 	switch (kp->type) {
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
@@ -225,6 +243,22 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
 	}
 }
 
+static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+{
+	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
+		put_user(kp->type, &up->type))
+		return -EFAULT;
+	return __put_v4l2_format32(kp, up);
+}
+
+static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
+{
+	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_create_buffers32)) ||
+	    copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format.fmt)))
+			return -EFAULT;
+	return __put_v4l2_format32(&kp->format, &up->format);
+}
+
 struct v4l2_standard32 {
 	__u32		     index;
 	__u32		     id[2]; /* __u64 would get the alignment wrong */
@@ -702,6 +736,8 @@ static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *u
 #define VIDIOC_S_EXT_CTRLS32    _IOWR('V', 72, struct v4l2_ext_controls32)
 #define VIDIOC_TRY_EXT_CTRLS32  _IOWR('V', 73, struct v4l2_ext_controls32)
 #define	VIDIOC_DQEVENT32	_IOR ('V', 89, struct v4l2_event32)
+#define VIDIOC_CREATE_BUFS32	_IOWR('V', 92, struct v4l2_create_buffers32)
+#define VIDIOC_PREPARE_BUF32	_IOW ('V', 93, struct v4l2_buffer32)
 
 #define VIDIOC_OVERLAY32	_IOW ('V', 14, s32)
 #define VIDIOC_STREAMON32	_IOW ('V', 18, s32)
@@ -721,6 +757,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
 		struct v4l2_standard v2s;
 		struct v4l2_ext_controls v2ecs;
 		struct v4l2_event v2ev;
+		struct v4l2_create_buffers v2crt;
 		unsigned long vx;
 		int vi;
 	} karg;
@@ -751,6 +788,8 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
 	case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break;
 	case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break;
 	case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break;
+	case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break;
+	case VIDIOC_PREPARE_BUF32: cmd = VIDIOC_PREPARE_BUF; break;
 	}
 
 	switch (cmd) {
@@ -775,6 +814,12 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
 		compatible_arg = 0;
 		break;
 
+	case VIDIOC_CREATE_BUFS:
+		err = get_v4l2_create32(&karg.v2crt, up);
+		compatible_arg = 0;
+		break;
+
+	case VIDIOC_PREPARE_BUF:
 	case VIDIOC_QUERYBUF:
 	case VIDIOC_QBUF:
 	case VIDIOC_DQBUF:
@@ -860,6 +905,10 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
 		err = put_v4l2_format32(&karg.v2f, up);
 		break;
 
+	case VIDIOC_CREATE_BUFS:
+		err = put_v4l2_create32(&karg.v2crt, up);
+		break;
+
 	case VIDIOC_QUERYBUF:
 	case VIDIOC_QBUF:
 	case VIDIOC_DQBUF:
@@ -959,6 +1008,8 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
 	case VIDIOC_DQEVENT32:
 	case VIDIOC_SUBSCRIBE_EVENT:
 	case VIDIOC_UNSUBSCRIBE_EVENT:
+	case VIDIOC_CREATE_BUFS32:
+	case VIDIOC_PREPARE_BUF32:
 		ret = do_video_ioctl(file, cmd, arg);
 		break;
 
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 002ce13..6fa8e04 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -260,6 +260,8 @@ static const char *v4l2_ioctls[] = {
 	[_IOC_NR(VIDIOC_DQEVENT)]	   = "VIDIOC_DQEVENT",
 	[_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)]  = "VIDIOC_SUBSCRIBE_EVENT",
 	[_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT",
+	[_IOC_NR(VIDIOC_CREATE_BUFS)]      = "VIDIOC_CREATE_BUFS",
+	[_IOC_NR(VIDIOC_PREPARE_BUF)]      = "VIDIOC_PREPARE_BUF",
 };
 #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
 
@@ -2216,6 +2218,33 @@ static long __video_do_ioctl(struct file *file,
 		dbgarg(cmd, "type=0x%8.8x", sub->type);
 		break;
 	}
+	case VIDIOC_CREATE_BUFS:
+	{
+		struct v4l2_create_buffers *create = arg;
+
+		if (!ops->vidioc_create_bufs)
+			break;
+		ret = check_fmt(ops, create->format.type);
+		if (ret)
+			break;
+
+		ret = ops->vidioc_create_bufs(file, fh, create);
+
+		dbgarg(cmd, "count=%d @ %d\n", create->count, create->index);
+		break;
+	}
+	case VIDIOC_PREPARE_BUF:
+	{
+		struct v4l2_buffer *b = arg;
+
+		if (!ops->vidioc_prepare_buf)
+			break;
+
+		ret = ops->vidioc_prepare_buf(file, fh, b);
+
+		dbgarg(cmd, "index=%d", b->index);
+		break;
+	}
 	default:
 	{
 		bool valid_prio = true;
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index fca24cc..988e1be 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -653,6 +653,9 @@ struct v4l2_buffer {
 #define V4L2_BUF_FLAG_ERROR	0x0040
 #define V4L2_BUF_FLAG_TIMECODE	0x0100	/* timecode field is valid */
 #define V4L2_BUF_FLAG_INPUT     0x0200  /* input field is valid */
+/* Cache handling flags */
+#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE	0x0400
+#define V4L2_BUF_FLAG_NO_CACHE_CLEAN		0x0800
 
 /*
  *	O V E R L A Y   P R E V I E W
@@ -2092,6 +2095,15 @@ struct v4l2_dbg_chip_ident {
 	__u32 revision;    /* chip revision, chip specific */
 } __attribute__ ((packed));
 
+/* VIDIOC_CREATE_BUFS */
+struct v4l2_create_buffers {
+	__u32			index;		/* output: buffers index...index + count - 1 have been created */
+	__u32			count;
+	enum v4l2_memory        memory;
+	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
+	__u32			reserved[8];
+};
+
 /*
  *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
  *
@@ -2182,6 +2194,9 @@ struct v4l2_dbg_chip_ident {
 #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct v4l2_event_subscription)
 #define	VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
 
+#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct v4l2_create_buffers)
+#define VIDIOC_PREPARE_BUF	 _IOW('V', 93, struct v4l2_buffer)
+
 /* Reminder: when adding new ioctls please add support for them to
    drivers/media/video/v4l2-compat-ioctl32.c as well! */
 
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index dd9f1e7..55cf8ae 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -122,6 +122,8 @@ struct v4l2_ioctl_ops {
 	int (*vidioc_qbuf)    (struct file *file, void *fh, struct v4l2_buffer *b);
 	int (*vidioc_dqbuf)   (struct file *file, void *fh, struct v4l2_buffer *b);
 
+	int (*vidioc_create_bufs)(struct file *file, void *fh, struct v4l2_create_buffers *b);
+	int (*vidioc_prepare_buf)(struct file *file, void *fh, const struct v4l2_buffer *b);
 
 	int (*vidioc_overlay) (struct file *file, void *fh, unsigned int i);
 	int (*vidioc_g_fbuf)   (struct file *file, void *fh,
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 3/9 v6] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s
  2011-08-31 18:02 [PATCH 0/9 v6] new ioctl()s and soc-camera implementation Guennadi Liakhovetski
  2011-08-31 18:02 ` [PATCH 1/9 v6] V4L: add a new videobuf2 buffer state VB2_BUF_STATE_PREPARED Guennadi Liakhovetski
  2011-08-31 18:02 ` [PATCH 2/9 v6] V4L: add two new ioctl()s for multi-size videobuffer management Guennadi Liakhovetski
@ 2011-08-31 18:02 ` Guennadi Liakhovetski
  2011-08-31 21:11   ` Sakari Ailus
  2011-11-03 12:13   ` [PATCH 3/9 v6] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s Mauro Carvalho Chehab
  2011-08-31 18:02 ` [PATCH 4/9 v6] V4L: vb2: prepare to support multi-size buffers Guennadi Liakhovetski
                   ` (5 subsequent siblings)
  8 siblings, 2 replies; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-08-31 18:02 UTC (permalink / raw)
  To: Linux Media Mailing List
  Cc: Hans Verkuil, Laurent Pinchart, Pawel Osciak, Sakari Ailus,
	Mauro Carvalho Chehab, Marek Szyprowski

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Cc: Hans Verkuil <hverkuil@xs4all.nl>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: Mauro Carvalho Chehab <mchehab@infradead.org>
Cc: Pawel Osciak <pawel@osciak.com>
Cc: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
---
 Documentation/DocBook/media/v4l/io.xml             |   17 +++
 Documentation/DocBook/media/v4l/v4l2.xml           |    2 +
 .../DocBook/media/v4l/vidioc-create-bufs.xml       |  147 ++++++++++++++++++++
 .../DocBook/media/v4l/vidioc-prepare-buf.xml       |   96 +++++++++++++
 4 files changed, 262 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
 create mode 100644 Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml

diff --git a/Documentation/DocBook/media/v4l/io.xml b/Documentation/DocBook/media/v4l/io.xml
index 227e7ac..ff03dd2 100644
--- a/Documentation/DocBook/media/v4l/io.xml
+++ b/Documentation/DocBook/media/v4l/io.xml
@@ -927,6 +927,23 @@ ioctl is called.</entry>
 Applications set or clear this flag before calling the
 <constant>VIDIOC_QBUF</constant> ioctl.</entry>
 	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant></entry>
+	    <entry>0x0400</entry>
+	    <entry>Caches do not have to be invalidated for this buffer.
+Typically applications shall use this flag if the data captured in the buffer
+is not going to be touched by the CPU, instead the buffer will, probably, be
+passed on to a DMA-capable hardware unit for further processing or output.
+</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant></entry>
+	    <entry>0x0800</entry>
+	    <entry>Caches do not have to be cleaned for this buffer.
+Typically applications shall use this flag for output buffers if the data
+in this buffer has not been created by the CPU but by some DMA-capable unit,
+in which case caches have not been used.</entry>
+	  </row>
 	</tbody>
       </tgroup>
     </table>
diff --git a/Documentation/DocBook/media/v4l/v4l2.xml b/Documentation/DocBook/media/v4l/v4l2.xml
index 0d05e87..06bb179 100644
--- a/Documentation/DocBook/media/v4l/v4l2.xml
+++ b/Documentation/DocBook/media/v4l/v4l2.xml
@@ -462,6 +462,7 @@ and discussions on the V4L mailing list.</revremark>
     &sub-close;
     &sub-ioctl;
     <!-- All ioctls go here. -->
+    &sub-create-bufs;
     &sub-cropcap;
     &sub-dbg-g-chip-ident;
     &sub-dbg-g-register;
@@ -504,6 +505,7 @@ and discussions on the V4L mailing list.</revremark>
     &sub-queryctrl;
     &sub-query-dv-preset;
     &sub-querystd;
+    &sub-prepare-buf;
     &sub-reqbufs;
     &sub-s-hw-freq-seek;
     &sub-streamon;
diff --git a/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
new file mode 100644
index 0000000..eb99604
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
@@ -0,0 +1,147 @@
+<refentry id="vidioc-create-bufs">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_CREATE_BUFS</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_CREATE_BUFS</refname>
+    <refpurpose>Create buffers for Memory Mapped or User Pointer I/O</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_create_buffers *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_CREATE_BUFS</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>This ioctl is used to create buffers for <link linkend="mmap">memory
+mapped</link> or <link linkend="userp">user pointer</link>
+I/O. It can be used as an alternative or in addition to the
+<constant>VIDIOC_REQBUFS</constant> ioctl, when a tighter control over buffers
+is required. This ioctl can be called multiple times to create buffers of
+different sizes.</para>
+
+    <para>To allocate device buffers applications initialize relevant fields of
+the <structname>v4l2_create_buffers</structname> structure. They set the
+<structfield>type</structfield> field in the
+<structname>v4l2_format</structname> structure, embedded in this
+structure, to the respective stream or buffer type.
+<structfield>count</structfield> must be set to the number of required buffers.
+<structfield>memory</structfield> specifies the required I/O method. The
+<structfield>format</structfield> field shall typically be filled in using
+either the <constant>VIDIOC_TRY_FMT</constant> or
+<constant>VIDIOC_G_FMT</constant> ioctl(). Additionally, applications can adjust
+<structfield>sizeimage</structfield> fields to fit their specific needs. The
+<structfield>reserved</structfield> array must be zeroed.</para>
+
+    <para>When the ioctl is called with a pointer to this structure the driver
+will attempt to allocate up to the requested number of buffers and store the
+actual number allocated and the starting index in the
+<structfield>count</structfield> and the <structfield>index</structfield> fields
+respectively. On return <structfield>count</structfield> can be smaller than
+the number requested. The driver may also adjust buffer sizes as it sees fit,
+however, it will not update <structfield>sizeimage</structfield> fields, the
+user has to use <constant>VIDIOC_QUERYBUF</constant> to retrieve that
+information.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-create-buffers">
+      <title>struct <structname>v4l2_create_buffers</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>index</structfield></entry>
+	    <entry>The starting buffer index, returned by the driver.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>count</structfield></entry>
+	    <entry>The number of buffers requested or granted.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-memory;</entry>
+	    <entry><structfield>memory</structfield></entry>
+	    <entry>Applications set this field to
+<constant>V4L2_MEMORY_MMAP</constant> or
+<constant>V4L2_MEMORY_USERPTR</constant>.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-format;</entry>
+	    <entry><structfield>format</structfield></entry>
+	    <entry>Filled in by the application, preserved by the driver.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[8]</entry>
+	    <entry>A place holder for future extensions.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>ENOMEM</errorcode></term>
+	<listitem>
+	  <para>No memory to allocate buffers for <link linkend="mmap">memory
+mapped</link> I/O.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The buffer type (<structfield>type</structfield> field) or the
+requested I/O method (<structfield>memory</structfield>) is not
+supported.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
new file mode 100644
index 0000000..509e752
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
@@ -0,0 +1,96 @@
+<refentry id="vidioc-prepare-buf">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_PREPARE_BUF</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_PREPARE_BUF</refname>
+    <refpurpose>Prepare a buffer for I/O</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_buffer *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_PREPARE_BUF</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>Applications can optionally call the
+<constant>VIDIOC_PREPARE_BUF</constant> ioctl to pass ownership of the buffer
+to the driver before actually enqueuing it, using the
+<constant>VIDIOC_QBUF</constant> ioctl, and to prepare it for future I/O.
+Such preparations may include cache invalidation or cleaning. Performing them
+in advance saves time during the actual I/O. In case such cache operations are
+not required, the application can use one of
+<constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant> and
+<constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant> flags to skip the respective
+step.</para>
+
+    <para>The <structname>v4l2_buffer</structname> structure is
+specified in <xref linkend="buffer" />.</para>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>File I/O is in progress.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The buffer <structfield>type</structfield> is not
+supported, or the <structfield>index</structfield> is out of bounds,
+or no buffers have been allocated yet, or the
+<structfield>userptr</structfield> or
+<structfield>length</structfield> are invalid.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 4/9 v6] V4L: vb2: prepare to support multi-size buffers
  2011-08-31 18:02 [PATCH 0/9 v6] new ioctl()s and soc-camera implementation Guennadi Liakhovetski
                   ` (2 preceding siblings ...)
  2011-08-31 18:02 ` [PATCH 3/9 v6] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s Guennadi Liakhovetski
@ 2011-08-31 18:02 ` Guennadi Liakhovetski
  2011-08-31 18:02 ` [PATCH 5/9 v6] V4L: vb2: add support for buffers of different sizes on a single queue Guennadi Liakhovetski
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-08-31 18:02 UTC (permalink / raw)
  To: Linux Media Mailing List
  Cc: Hans Verkuil, Laurent Pinchart, Pawel Osciak, Sakari Ailus,
	Mauro Carvalho Chehab, Marek Szyprowski

In preparation for the forthcoming VIDIOC_CREATE_BUFS ioctl add a
"const struct v4l2_format *" argument to the .queue_setup() vb2
operation.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Cc: Hans Verkuil <hverkuil@xs4all.nl>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: Mauro Carvalho Chehab <mchehab@infradead.org>
Cc: Pawel Osciak <pawel@osciak.com>
Cc: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
---
 drivers/media/video/atmel-isi.c              |    6 +++---
 drivers/media/video/marvell-ccic/mcam-core.c |    3 ++-
 drivers/media/video/mem2mem_testdev.c        |    7 ++++---
 drivers/media/video/mx3_camera.c             |    1 +
 drivers/media/video/pwc/pwc-if.c             |    6 +++---
 drivers/media/video/s5p-fimc/fimc-capture.c  |    6 +++---
 drivers/media/video/s5p-fimc/fimc-core.c     |    6 +++---
 drivers/media/video/s5p-mfc/s5p_mfc_dec.c    |    7 ++++---
 drivers/media/video/s5p-mfc/s5p_mfc_enc.c    |    5 +++--
 drivers/media/video/s5p-tv/mixer_video.c     |    4 ++--
 drivers/media/video/sh_mobile_ceu_camera.c   |    1 +
 drivers/media/video/videobuf2-core.c         |    6 +++---
 drivers/media/video/vivi.c                   |    6 +++---
 include/media/videobuf2-core.h               |    6 +++---
 14 files changed, 38 insertions(+), 32 deletions(-)

diff --git a/drivers/media/video/atmel-isi.c b/drivers/media/video/atmel-isi.c
index 3e3d4cc..7c41a87 100644
--- a/drivers/media/video/atmel-isi.c
+++ b/drivers/media/video/atmel-isi.c
@@ -249,9 +249,9 @@ static int atmel_isi_wait_status(struct atmel_isi *isi, int wait_reset)
 /* ------------------------------------------------------------------
 	Videobuf operations
    ------------------------------------------------------------------*/
-static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
-				unsigned int *nplanes, unsigned long sizes[],
-				void *alloc_ctxs[])
+static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+				unsigned int *nbuffers, unsigned int *nplanes,
+				unsigned long sizes[], void *alloc_ctxs[])
 {
 	struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
 	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
diff --git a/drivers/media/video/marvell-ccic/mcam-core.c b/drivers/media/video/marvell-ccic/mcam-core.c
index 83c1451..65517c8 100644
--- a/drivers/media/video/marvell-ccic/mcam-core.c
+++ b/drivers/media/video/marvell-ccic/mcam-core.c
@@ -883,7 +883,8 @@ static int mcam_read_setup(struct mcam_camera *cam)
  * Videobuf2 interface code.
  */
 
-static int mcam_vb_queue_setup(struct vb2_queue *vq, unsigned int *nbufs,
+static int mcam_vb_queue_setup(struct vb2_queue *vq,
+		const struct v4l2_format *fmt, unsigned int *nbufs,
 		unsigned int *num_planes, unsigned long sizes[],
 		void *alloc_ctxs[])
 {
diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c
index 166bf93..c0e633f 100644
--- a/drivers/media/video/mem2mem_testdev.c
+++ b/drivers/media/video/mem2mem_testdev.c
@@ -738,9 +738,10 @@ static const struct v4l2_ioctl_ops m2mtest_ioctl_ops = {
  * Queue operations
  */
 
-static int m2mtest_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
-				unsigned int *nplanes, unsigned long sizes[],
-				void *alloc_ctxs[])
+static int m2mtest_queue_setup(struct vb2_queue *vq,
+				const struct v4l2_format *fmt,
+				unsigned int *nbuffers, unsigned int *nplanes,
+				unsigned long sizes[], void *alloc_ctxs[])
 {
 	struct m2mtest_ctx *ctx = vb2_get_drv_priv(vq);
 	struct m2mtest_q_data *q_data;
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index 3f37522f..6bfbce9 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -191,6 +191,7 @@ static void mx3_cam_dma_done(void *arg)
  * Calculate the __buffer__ (not data) size and number of buffers.
  */
 static int mx3_videobuf_setup(struct vb2_queue *vq,
+			const struct v4l2_format *fmt,
 			unsigned int *count, unsigned int *num_planes,
 			unsigned long sizes[], void *alloc_ctxs[])
 {
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 51ca358..d6ff2c9 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -744,9 +744,9 @@ static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma)
 /***************************************************************************/
 /* Videobuf2 operations */
 
-static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
-				unsigned int *nplanes, unsigned long sizes[],
-				void *alloc_ctxs[])
+static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+				unsigned int *nbuffers, unsigned int *nplanes,
+				unsigned long sizes[], void *alloc_ctxs[])
 {
 	struct pwc_device *pdev = vb2_get_drv_priv(vq);
 
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c
index 0d730e5..36d71a1 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -264,9 +264,9 @@ static unsigned int get_plane_size(struct fimc_frame *fr, unsigned int plane)
 	return fr->f_width * fr->f_height * fr->fmt->depth[plane] / 8;
 }
 
-static int queue_setup(struct vb2_queue *vq, unsigned int *num_buffers,
-		       unsigned int *num_planes, unsigned long sizes[],
-		       void *allocators[])
+static int queue_setup(struct vb2_queue *vq,  const struct v4l2_format *pfmt,
+		       unsigned int *num_buffers, unsigned int *num_planes,
+		       unsigned long sizes[], void *allocators[])
 {
 	struct fimc_ctx *ctx = vq->drv_priv;
 	struct fimc_fmt *fmt = ctx->d_frame.fmt;
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c
index aa55066..26348e2 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.c
+++ b/drivers/media/video/s5p-fimc/fimc-core.c
@@ -691,9 +691,9 @@ static void fimc_job_abort(void *priv)
 	fimc_m2m_shutdown(priv);
 }
 
-static int fimc_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers,
-			    unsigned int *num_planes, unsigned long sizes[],
-			    void *allocators[])
+static int fimc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+			    unsigned int *num_buffers, unsigned int *num_planes,
+			    unsigned long sizes[], void *allocators[])
 {
 	struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
 	struct fimc_frame *f;
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
index b2c5052..06f317c 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
+++ b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
@@ -744,9 +744,10 @@ static const struct v4l2_ioctl_ops s5p_mfc_dec_ioctl_ops = {
 	.vidioc_g_crop = vidioc_g_crop,
 };
 
-static int s5p_mfc_queue_setup(struct vb2_queue *vq, unsigned int *buf_count,
-			       unsigned int *plane_count, unsigned long psize[],
-			       void *allocators[])
+static int s5p_mfc_queue_setup(struct vb2_queue *vq,
+			const struct v4l2_format *fmt, unsigned int *buf_count,
+			unsigned int *plane_count, unsigned long psize[],
+			void *allocators[])
 {
 	struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
 
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
index fee094a..0c1a22f 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
@@ -1513,8 +1513,9 @@ static int check_vb_with_fmt(struct s5p_mfc_fmt *fmt, struct vb2_buffer *vb)
 }
 
 static int s5p_mfc_queue_setup(struct vb2_queue *vq,
-		       unsigned int *buf_count, unsigned int *plane_count,
-		       unsigned long psize[], void *allocators[])
+			const struct v4l2_format *fmt,
+			unsigned int *buf_count, unsigned int *plane_count,
+			unsigned long psize[], void *allocators[])
 {
 	struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
 
diff --git a/drivers/media/video/s5p-tv/mixer_video.c b/drivers/media/video/s5p-tv/mixer_video.c
index 43ac22f..74b86aa 100644
--- a/drivers/media/video/s5p-tv/mixer_video.c
+++ b/drivers/media/video/s5p-tv/mixer_video.c
@@ -727,8 +727,8 @@ static const struct v4l2_file_operations mxr_fops = {
 	.unlocked_ioctl = video_ioctl2,
 };
 
-static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
-	unsigned int *nplanes, unsigned long sizes[],
+static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
+	unsigned int *nbuffers, unsigned int *nplanes, unsigned long sizes[],
 	void *alloc_ctxs[])
 {
 	struct mxr_layer *layer = vb2_get_drv_priv(vq);
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 8b344d4..db3a24d 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -193,6 +193,7 @@ static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev)
  *  Videobuf operations
  */
 static int sh_mobile_ceu_videobuf_setup(struct vb2_queue *vq,
+			const struct v4l2_format *fmt,
 			unsigned int *count, unsigned int *num_planes,
 			unsigned long sizes[], void *alloc_ctxs[])
 {
diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/video/videobuf2-core.c
index 4153da2..7a9ac8a 100644
--- a/drivers/media/video/videobuf2-core.c
+++ b/drivers/media/video/videobuf2-core.c
@@ -525,7 +525,7 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
 	 * Ask the driver how many buffers and planes per buffer it requires.
 	 * Driver also sets the size and allocator context for each plane.
 	 */
-	ret = call_qop(q, queue_setup, q, &num_buffers, &num_planes,
+	ret = call_qop(q, queue_setup, q, NULL, &num_buffers, &num_planes,
 		       plane_sizes, q->alloc_ctx);
 	if (ret)
 		return ret;
@@ -545,8 +545,8 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
 		unsigned int orig_num_buffers;
 
 		orig_num_buffers = num_buffers = ret;
-		ret = call_qop(q, queue_setup, q, &num_buffers, &num_planes,
-			       plane_sizes, q->alloc_ctx);
+		ret = call_qop(q, queue_setup, q, NULL, &num_buffers,
+			       &num_planes, plane_sizes, q->alloc_ctx);
 		if (ret)
 			goto free_mem;
 
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index a848bd2..0b24508 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -650,9 +650,9 @@ static void vivi_stop_generating(struct vivi_dev *dev)
 /* ------------------------------------------------------------------
 	Videobuf operations
    ------------------------------------------------------------------*/
-static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
-				unsigned int *nplanes, unsigned long sizes[],
-				void *alloc_ctxs[])
+static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+				unsigned int *nbuffers, unsigned int *nplanes,
+				unsigned long sizes[], void *alloc_ctxs[])
 {
 	struct vivi_dev *dev = vb2_get_drv_priv(vq);
 	unsigned long size;
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 65946c5..d043132 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -212,9 +212,9 @@ struct vb2_buffer {
  *			the buffer back by calling vb2_buffer_done() function
  */
 struct vb2_ops {
-	int (*queue_setup)(struct vb2_queue *q, unsigned int *num_buffers,
-			   unsigned int *num_planes, unsigned long sizes[],
-			   void *alloc_ctxs[]);
+	int (*queue_setup)(struct vb2_queue *q, const struct v4l2_format *fmt,
+			   unsigned int *num_buffers, unsigned int *num_planes,
+			   unsigned long sizes[], void *alloc_ctxs[]);
 
 	void (*wait_prepare)(struct vb2_queue *q);
 	void (*wait_finish)(struct vb2_queue *q);
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 5/9 v6] V4L: vb2: add support for buffers of different sizes on a single queue
  2011-08-31 18:02 [PATCH 0/9 v6] new ioctl()s and soc-camera implementation Guennadi Liakhovetski
                   ` (3 preceding siblings ...)
  2011-08-31 18:02 ` [PATCH 4/9 v6] V4L: vb2: prepare to support multi-size buffers Guennadi Liakhovetski
@ 2011-08-31 18:02 ` Guennadi Liakhovetski
  2011-08-31 18:02 ` [PATCH 6/9 v6] V4L: sh-mobile-ceu-camera: prepare to support multi-size buffers Guennadi Liakhovetski
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-08-31 18:02 UTC (permalink / raw)
  To: Linux Media Mailing List
  Cc: Hans Verkuil, Laurent Pinchart, Pawel Osciak, Sakari Ailus,
	Mauro Carvalho Chehab, Marek Szyprowski

The two recently added ioctl()s VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF
allow user-space applications to allocate video buffers of different
sizes and hand them over to the driver for fast switching between
different frame formats. This patch adds support for buffers of different
sizes on the same buffer-queue to vb2.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Cc: Hans Verkuil <hverkuil@xs4all.nl>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: Mauro Carvalho Chehab <mchehab@infradead.org>
Cc: Pawel Osciak <pawel@osciak.com>
Cc: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
---

v6: fix issues, pointed out by Pawel

 drivers/media/video/videobuf2-core.c |  283 ++++++++++++++++++++++++++++------
 include/media/videobuf2-core.h       |   35 +++--
 2 files changed, 259 insertions(+), 59 deletions(-)

diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/video/videobuf2-core.c
index 7a9ac8a..6243de1 100644
--- a/drivers/media/video/videobuf2-core.c
+++ b/drivers/media/video/videobuf2-core.c
@@ -44,7 +44,7 @@ module_param(debug, int, 0644);
  * __vb2_buf_mem_alloc() - allocate video memory for the given buffer
  */
 static int __vb2_buf_mem_alloc(struct vb2_buffer *vb,
-				unsigned long *plane_sizes)
+			       const unsigned long *plane_sizes)
 {
 	struct vb2_queue *q = vb->vb2_queue;
 	void *mem_priv;
@@ -110,13 +110,22 @@ static void __vb2_buf_userptr_put(struct vb2_buffer *vb)
  * __setup_offsets() - setup unique offsets ("cookies") for every plane in
  * every buffer on the queue
  */
-static void __setup_offsets(struct vb2_queue *q)
+static void __setup_offsets(struct vb2_queue *q, unsigned int n)
 {
 	unsigned int buffer, plane;
 	struct vb2_buffer *vb;
-	unsigned long off = 0;
+	unsigned long off;
 
-	for (buffer = 0; buffer < q->num_buffers; ++buffer) {
+	if (q->num_buffers) {
+		struct v4l2_plane *p;
+		vb = q->bufs[q->num_buffers - 1];
+		p = &vb->v4l2_planes[vb->num_planes - 1];
+		off = PAGE_ALIGN(p->m.mem_offset + p->length);
+	} else {
+		off = 0;
+	}
+
+	for (buffer = q->num_buffers; buffer < q->num_buffers + n; ++buffer) {
 		vb = q->bufs[buffer];
 		if (!vb)
 			continue;
@@ -142,7 +151,7 @@ static void __setup_offsets(struct vb2_queue *q)
  */
 static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory,
 			     unsigned int num_buffers, unsigned int num_planes,
-			     unsigned long plane_sizes[])
+			     const unsigned long *plane_sizes)
 {
 	unsigned int buffer;
 	struct vb2_buffer *vb;
@@ -163,7 +172,7 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory,
 		vb->state = VB2_BUF_STATE_DEQUEUED;
 		vb->vb2_queue = q;
 		vb->num_planes = num_planes;
-		vb->v4l2_buf.index = buffer;
+		vb->v4l2_buf.index = q->num_buffers + buffer;
 		vb->v4l2_buf.type = q->type;
 		vb->v4l2_buf.memory = memory;
 
@@ -191,15 +200,13 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory,
 			}
 		}
 
-		q->bufs[buffer] = vb;
+		q->bufs[q->num_buffers + buffer] = vb;
 	}
 
-	q->num_buffers = buffer;
-
-	__setup_offsets(q);
+	__setup_offsets(q, buffer);
 
 	dprintk(1, "Allocated %d buffers, %d plane(s) each\n",
-			q->num_buffers, num_planes);
+			buffer, num_planes);
 
 	return buffer;
 }
@@ -207,12 +214,13 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory,
 /**
  * __vb2_free_mem() - release all video buffer memory for a given queue
  */
-static void __vb2_free_mem(struct vb2_queue *q)
+static void __vb2_free_mem(struct vb2_queue *q, unsigned int buffers)
 {
 	unsigned int buffer;
 	struct vb2_buffer *vb;
 
-	for (buffer = 0; buffer < q->num_buffers; ++buffer) {
+	for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
+	     ++buffer) {
 		vb = q->bufs[buffer];
 		if (!vb)
 			continue;
@@ -226,17 +234,18 @@ static void __vb2_free_mem(struct vb2_queue *q)
 }
 
 /**
- * __vb2_queue_free() - free the queue - video memory and related information
- * and return the queue to an uninitialized state. Might be called even if the
- * queue has already been freed.
+ * __vb2_queue_free() - free buffers at the end of the queue - video memory and
+ * related information, if no buffers are left return the queue to an
+ * uninitialized state. Might be called even if the queue has already been freed.
  */
-static void __vb2_queue_free(struct vb2_queue *q)
+static void __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
 {
 	unsigned int buffer;
 
 	/* Call driver-provided cleanup function for each buffer, if provided */
 	if (q->ops->buf_cleanup) {
-		for (buffer = 0; buffer < q->num_buffers; ++buffer) {
+		for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
+		     ++buffer) {
 			if (NULL == q->bufs[buffer])
 				continue;
 			q->ops->buf_cleanup(q->bufs[buffer]);
@@ -244,23 +253,25 @@ static void __vb2_queue_free(struct vb2_queue *q)
 	}
 
 	/* Release video buffer memory */
-	__vb2_free_mem(q);
+	__vb2_free_mem(q, buffers);
 
 	/* Free videobuf buffers */
-	for (buffer = 0; buffer < q->num_buffers; ++buffer) {
+	for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
+	     ++buffer) {
 		kfree(q->bufs[buffer]);
 		q->bufs[buffer] = NULL;
 	}
 
-	q->num_buffers = 0;
-	q->memory = 0;
+	q->num_buffers -= buffers;
+	if (!q->num_buffers)
+		q->memory = 0;
 }
 
 /**
  * __verify_planes_array() - verify that the planes array passed in struct
  * v4l2_buffer from userspace can be safely used
  */
-static int __verify_planes_array(struct vb2_buffer *vb, struct v4l2_buffer *b)
+static int __verify_planes_array(struct vb2_buffer *vb, const struct v4l2_buffer *b)
 {
 	/* Is memory for copying plane information present? */
 	if (NULL == b->m.planes) {
@@ -454,8 +465,8 @@ static bool __buffers_in_use(struct vb2_queue *q)
  */
 int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
 {
-	unsigned int num_buffers, num_planes;
-	unsigned long plane_sizes[VIDEO_MAX_PLANES];
+	unsigned int num_buffers, allocated_buffers, num_planes = 0;
+	unsigned long plane_sizes[VIDEO_MAX_PLANES] = {};
 	int ret = 0;
 
 	if (q->fileio) {
@@ -503,7 +514,7 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
 			return -EBUSY;
 		}
 
-		__vb2_queue_free(q);
+		__vb2_queue_free(q, q->num_buffers);
 
 		/*
 		 * In case of REQBUFS(0) return immediately without calling
@@ -517,7 +528,6 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
 	 * Make sure the requested values and current defaults are sane.
 	 */
 	num_buffers = min_t(unsigned int, req->count, VIDEO_MAX_FRAME);
-	memset(plane_sizes, 0, sizeof(plane_sizes));
 	memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx));
 	q->memory = req->memory;
 
@@ -538,44 +548,168 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
 		return -ENOMEM;
 	}
 
+	allocated_buffers = ret;
+
 	/*
 	 * Check if driver can handle the allocated number of buffers.
 	 */
-	if (ret < num_buffers) {
-		unsigned int orig_num_buffers;
+	if (allocated_buffers < num_buffers) {
+		num_buffers = allocated_buffers;
 
-		orig_num_buffers = num_buffers = ret;
 		ret = call_qop(q, queue_setup, q, NULL, &num_buffers,
 			       &num_planes, plane_sizes, q->alloc_ctx);
-		if (ret)
-			goto free_mem;
 
-		if (orig_num_buffers < num_buffers) {
+		if (!ret && allocated_buffers < num_buffers)
 			ret = -ENOMEM;
-			goto free_mem;
-		}
 
 		/*
-		 * Ok, driver accepted smaller number of buffers.
+		 * Either the driver has accepted a smaller number of buffers,
+		 * or .queue_setup() returned an error
 		 */
-		ret = num_buffers;
+	}
+
+	q->num_buffers = allocated_buffers;
+
+	if (ret < 0) {
+		__vb2_queue_free(q, allocated_buffers);
+		return ret;
 	}
 
 	/*
 	 * Return the number of successfully allocated buffers
 	 * to the userspace.
 	 */
-	req->count = ret;
+	req->count = allocated_buffers;
 
 	return 0;
-
-free_mem:
-	__vb2_queue_free(q);
-	return ret;
 }
 EXPORT_SYMBOL_GPL(vb2_reqbufs);
 
 /**
+ * vb2_create_bufs() - Allocate buffers and any required auxiliary structs
+ * @q:		videobuf2 queue
+ * @create:	creation parameters, passed from userspace to vidioc_create_bufs
+ *		handler in driver
+ *
+ * Should be called from vidioc_create_bufs ioctl handler of a driver.
+ * This function:
+ * 1) verifies parameter sanity
+ * 2) calls the .queue_setup() queue operation
+ * 3) performs any necessary memory allocations
+ *
+ * The return values from this function are intended to be directly returned
+ * from vidioc_create_bufs handler in driver.
+ */
+int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create)
+{
+	unsigned int num_planes = 0, num_buffers, allocated_buffers;
+	unsigned long plane_sizes[VIDEO_MAX_PLANES] = {};
+	int ret = 0;
+
+	if (q->fileio) {
+		dprintk(1, "%s(): file io in progress\n", __func__);
+		return -EBUSY;
+	}
+
+	if (create->memory != V4L2_MEMORY_MMAP
+			&& create->memory != V4L2_MEMORY_USERPTR) {
+		dprintk(1, "%s(): unsupported memory type\n", __func__);
+		return -EINVAL;
+	}
+
+	if (create->format.type != q->type) {
+		dprintk(1, "%s(): requested type is incorrect\n", __func__);
+		return -EINVAL;
+	}
+
+	/*
+	 * Make sure all the required memory ops for given memory type
+	 * are available.
+	 */
+	if (create->memory == V4L2_MEMORY_MMAP && __verify_mmap_ops(q)) {
+		dprintk(1, "%s(): MMAP for current setup unsupported\n", __func__);
+		return -EINVAL;
+	}
+
+	if (create->memory == V4L2_MEMORY_USERPTR && __verify_userptr_ops(q)) {
+		dprintk(1, "%s(): USERPTR for current setup unsupported\n", __func__);
+		return -EINVAL;
+	}
+
+	if (q->num_buffers == VIDEO_MAX_FRAME) {
+		dprintk(1, "%s(): maximum number of buffers already allocated\n",
+			__func__);
+		return -ENOBUFS;
+	}
+
+	create->index = q->num_buffers;
+
+	if (!q->num_buffers) {
+		memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx));
+		q->memory = create->memory;
+	}
+
+	num_buffers = min(create->count, VIDEO_MAX_FRAME - q->num_buffers);
+
+	/*
+	 * Ask the driver, whether the requested number of buffers, planes per
+	 * buffer and their sizes are acceptable
+	 */
+	ret = call_qop(q, queue_setup, q, &create->format, &num_buffers,
+		       &num_planes, plane_sizes, q->alloc_ctx);
+	if (ret)
+		return ret;
+
+	/* Finally, allocate buffers and video memory */
+	ret = __vb2_queue_alloc(q, create->memory, num_buffers,
+				num_planes, plane_sizes);
+	if (ret < 0) {
+		dprintk(1, "Memory allocation failed with error: %d\n", ret);
+		return ret;
+	}
+
+	allocated_buffers = ret;
+
+	/*
+	 * Check if driver can handle the so far allocated number of buffers.
+	 */
+	if (ret < num_buffers) {
+		num_buffers = ret;
+
+		/*
+		 * q->num_buffers contains the total number of buffers, that the
+		 * queue driver has set up
+		 */
+		ret = call_qop(q, queue_setup, q, &create->format, &num_buffers,
+			       &num_planes, plane_sizes, q->alloc_ctx);
+
+		if (!ret && allocated_buffers < num_buffers)
+			ret = -ENOMEM;
+
+		/*
+		 * Either the driver has accepted a smaller number of buffers,
+		 * or .queue_setup() returned an error
+		 */
+	}
+
+	q->num_buffers += allocated_buffers;
+
+	if (ret < 0) {
+		__vb2_queue_free(q, allocated_buffers);
+		return ret;
+	}
+
+	/*
+	 * Return the number of successfully allocated buffers
+	 * to the userspace.
+	 */
+	create->count = allocated_buffers;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(vb2_create_bufs);
+
+/**
  * vb2_plane_vaddr() - Return a kernel virtual address of a given plane
  * @vb:		vb2_buffer to which the plane in question belongs to
  * @plane_no:	plane number for which the address is to be returned
@@ -659,7 +793,7 @@ EXPORT_SYMBOL_GPL(vb2_buffer_done);
  * __fill_vb2_buffer() - fill a vb2_buffer with information provided in
  * a v4l2_buffer by the userspace
  */
-static int __fill_vb2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b,
+static int __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b,
 				struct v4l2_plane *v4l2_planes)
 {
 	unsigned int plane;
@@ -723,7 +857,7 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b,
 /**
  * __qbuf_userptr() - handle qbuf of a USERPTR buffer
  */
-static int __qbuf_userptr(struct vb2_buffer *vb, struct v4l2_buffer *b)
+static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b)
 {
 	struct v4l2_plane planes[VIDEO_MAX_PLANES];
 	struct vb2_queue *q = vb->vb2_queue;
@@ -801,7 +935,7 @@ err:
 /**
  * __qbuf_mmap() - handle qbuf of an MMAP buffer
  */
-static int __qbuf_mmap(struct vb2_buffer *vb, struct v4l2_buffer *b)
+static int __qbuf_mmap(struct vb2_buffer *vb, const struct v4l2_buffer *b)
 {
 	return __fill_vb2_buffer(vb, b, vb->v4l2_planes);
 }
@@ -818,7 +952,7 @@ static void __enqueue_in_driver(struct vb2_buffer *vb)
 	q->ops->buf_queue(vb);
 }
 
-static int __buf_prepare(struct vb2_buffer *vb, struct v4l2_buffer *b)
+static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b)
 {
 	struct vb2_queue *q = vb->vb2_queue;
 	int ret;
@@ -846,6 +980,61 @@ static int __buf_prepare(struct vb2_buffer *vb, struct v4l2_buffer *b)
 }
 
 /**
+ * vb2_prepare_buf() - Pass ownership of a buffer from userspace to the kernel
+ * @q:		videobuf2 queue
+ * @b:		buffer structure passed from userspace to vidioc_prepare_buf
+ *		handler in driver
+ *
+ * Should be called from vidioc_prepare_buf ioctl handler of a driver.
+ * This function:
+ * 1) verifies the passed buffer,
+ * 2) calls buf_prepare callback in the driver (if provided), in which
+ *    driver-specific buffer initialization can be performed,
+ *
+ * The return values from this function are intended to be directly returned
+ * from vidioc_prepare_buf handler in driver.
+ */
+int vb2_prepare_buf(struct vb2_queue *q, const struct v4l2_buffer *b)
+{
+	struct vb2_buffer *vb;
+
+	if (q->fileio) {
+		dprintk(1, "%s(): file io in progress\n", __func__);
+		return -EBUSY;
+	}
+
+	if (b->type != q->type) {
+		dprintk(1, "%s(): invalid buffer type\n", __func__);
+		return -EINVAL;
+	}
+
+	if (b->index >= q->num_buffers) {
+		dprintk(1, "%s(): buffer index out of range\n", __func__);
+		return -EINVAL;
+	}
+
+	vb = q->bufs[b->index];
+	if (NULL == vb) {
+		/* Should never happen */
+		dprintk(1, "%s(): buffer is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	if (b->memory != q->memory) {
+		dprintk(1, "%s(): invalid memory type\n", __func__);
+		return -EINVAL;
+	}
+
+	if (vb->state != VB2_BUF_STATE_DEQUEUED) {
+		dprintk(1, "%s(): invalid buffer state %d\n", __func__, vb->state);
+		return -EINVAL;
+	}
+
+	return __buf_prepare(vb, b);
+}
+EXPORT_SYMBOL_GPL(vb2_prepare_buf);
+
+/**
  * vb2_qbuf() - Queue a buffer from userspace
  * @q:		videobuf2 queue
  * @b:		buffer structure passed from userspace to vidioc_qbuf handler
@@ -1478,7 +1667,7 @@ void vb2_queue_release(struct vb2_queue *q)
 {
 	__vb2_cleanup_fileio(q);
 	__vb2_queue_cancel(q);
-	__vb2_queue_free(q);
+	__vb2_queue_free(q, q->num_buffers);
 }
 EXPORT_SYMBOL_GPL(vb2_queue_release);
 
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index d043132..177a9e2 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -172,13 +172,21 @@ struct vb2_buffer {
 /**
  * struct vb2_ops - driver-specific callbacks
  *
- * @queue_setup:	called from a VIDIOC_REQBUFS handler, before
- *			memory allocation; driver should return the required
- *			number of buffers in num_buffers, the required number
- *			of planes per buffer in num_planes; the size of each
- *			plane should be set in the sizes[] array and optional
- *			per-plane allocator specific context in alloc_ctxs[]
- *			array
+ * @queue_setup:	called from VIDIOC_REQBUFS and VIDIOC_CREATE_BUFS
+ *			handlers before memory allocation, or, if
+ *			*num_planes != 0, after the allocation to verify a
+ *			smaller number of buffers. Driver should return
+ *			the required number of buffers in *num_buffers, the
+ *			required number of planes per buffer in *num_planes; the
+ *			size of each plane should be set in the sizes[] array
+ *			and optional per-plane allocator specific context in the
+ *			alloc_ctxs[] array. When called from VIDIOC_REQBUFS,
+ *			fmt == NULL, the driver has to use the currently
+ *			configured format and *num_buffers is the total number
+ *			of buffers, that are being allocated. When called from
+ *			VIDIOC_CREATE_BUFS, fmt != NULL and it describes the
+ *			target frame format. In this case *num_buffers are being
+ *			allocated additionally to q->num_buffers.
  * @wait_prepare:	release any locks taken while calling vb2 functions;
  *			it is called before an ioctl needs to wait for a new
  *			buffer to arrive; required to avoid a deadlock in
@@ -191,11 +199,11 @@ struct vb2_buffer {
  *			perform additional buffer-related initialization;
  *			initialization failure (return != 0) will prevent
  *			queue setup from completing successfully; optional
- * @buf_prepare:	called every time the buffer is queued from userspace;
- *			drivers may perform any initialization required before
- *			each hardware operation in this callback;
- *			if an error is returned, the buffer will not be queued
- *			in driver; optional
+ * @buf_prepare:	called every time the buffer is queued from userspace
+ *			and from the VIDIOC_PREPARE_BUF ioctl; drivers may
+ *			perform any initialization required before each hardware
+ *			operation in this callback; if an error is returned, the
+ *			buffer will not be queued in driver; optional
  * @buf_finish:		called before every dequeue of the buffer back to
  *			userspace; drivers may perform any operations required
  *			before userspace accesses the buffer; optional
@@ -293,6 +301,9 @@ int vb2_wait_for_all_buffers(struct vb2_queue *q);
 int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b);
 int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req);
 
+int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create);
+int vb2_prepare_buf(struct vb2_queue *q, const struct v4l2_buffer *b);
+
 int vb2_queue_init(struct vb2_queue *q);
 
 void vb2_queue_release(struct vb2_queue *q);
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 6/9 v6] V4L: sh-mobile-ceu-camera: prepare to support multi-size buffers
  2011-08-31 18:02 [PATCH 0/9 v6] new ioctl()s and soc-camera implementation Guennadi Liakhovetski
                   ` (4 preceding siblings ...)
  2011-08-31 18:02 ` [PATCH 5/9 v6] V4L: vb2: add support for buffers of different sizes on a single queue Guennadi Liakhovetski
@ 2011-08-31 18:02 ` Guennadi Liakhovetski
  2011-08-31 18:02 ` [PATCH 7/9 v6] dmaengine: ipu-idmac: add support for the DMA_PAUSE control Guennadi Liakhovetski
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-08-31 18:02 UTC (permalink / raw)
  To: Linux Media Mailing List
  Cc: Hans Verkuil, Laurent Pinchart, Pawel Osciak, Sakari Ailus,
	Mauro Carvalho Chehab, Marek Szyprowski

Prepare the sh_mobile_ceu_camera friver to support the new
VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s. The .queue_setup()
vb2 operation must be able to handle buffer sizes, provided by the
caller, and the .buf_prepare() operation must not use the currently
configured frame format for its operation.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Cc: Hans Verkuil <hverkuil@xs4all.nl>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: Mauro Carvalho Chehab <mchehab@infradead.org>
Cc: Pawel Osciak <pawel@osciak.com>
Cc: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
---

v6: Handle the case of VIDIOC_CREATE_BUFS, when vb2 creates fewer buffers, than
    requested by the user, correctly

 drivers/media/video/sh_mobile_ceu_camera.c |  122 ++++++++++++++++++----------
 1 files changed, 79 insertions(+), 43 deletions(-)

diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index db3a24d..56bb82d 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -90,7 +90,6 @@
 struct sh_mobile_ceu_buffer {
 	struct vb2_buffer vb; /* v4l buffer must be first */
 	struct list_head queue;
-	enum v4l2_mbus_pixelcode code;
 };
 
 struct sh_mobile_ceu_dev {
@@ -100,7 +99,8 @@ struct sh_mobile_ceu_dev {
 
 	unsigned int irq;
 	void __iomem *base;
-	unsigned long video_limit;
+	size_t video_limit;
+	size_t buf_total;
 
 	spinlock_t lock;		/* Protects video buffer lists */
 	struct list_head capture;
@@ -192,6 +192,12 @@ static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev)
 /*
  *  Videobuf operations
  */
+
+/*
+ * .queue_setup() is called to check, whether the driver can accept the
+ *		  requested number of buffers and to fill in plane sizes
+ *		  for the current frame format if required
+ */
 static int sh_mobile_ceu_videobuf_setup(struct vb2_queue *vq,
 			const struct v4l2_format *fmt,
 			unsigned int *count, unsigned int *num_planes,
@@ -200,26 +206,45 @@ static int sh_mobile_ceu_videobuf_setup(struct vb2_queue *vq,
 	struct soc_camera_device *icd = container_of(vq, struct soc_camera_device, vb2_vidq);
 	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct sh_mobile_ceu_dev *pcdev = ici->priv;
-	int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
-						icd->current_fmt->host_fmt);
+	int bytes_per_line;
+	unsigned int height;
 
+	if (fmt) {
+		const struct soc_camera_format_xlate *xlate = soc_camera_xlate_by_fourcc(icd,
+								fmt->fmt.pix.pixelformat);
+		bytes_per_line = soc_mbus_bytes_per_line(fmt->fmt.pix.width,
+							 xlate->host_fmt);
+		height = fmt->fmt.pix.height;
+	} else {
+		/* Called from VIDIOC_REQBUFS or in compatibility mode */
+		bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
+						icd->current_fmt->host_fmt);
+		height = icd->user_height;
+	}
 	if (bytes_per_line < 0)
 		return bytes_per_line;
 
-	*num_planes = 1;
+	sizes[0] = bytes_per_line * height;
 
-	pcdev->sequence = 0;
-	sizes[0] = bytes_per_line * icd->user_height;
 	alloc_ctxs[0] = pcdev->alloc_ctx;
 
+	if (!vq->num_buffers)
+		pcdev->sequence = 0;
+
 	if (!*count)
 		*count = 2;
 
-	if (pcdev->video_limit) {
-		if (PAGE_ALIGN(sizes[0]) * *count > pcdev->video_limit)
-			*count = pcdev->video_limit / PAGE_ALIGN(sizes[0]);
+	/* If *num_planes != 0, we have already verified *count. */
+	if (pcdev->video_limit && !*num_planes) {
+		size_t size = PAGE_ALIGN(sizes[0]) * *count;
+
+		if (size + pcdev->buf_total > pcdev->video_limit)
+			*count = (pcdev->video_limit - pcdev->buf_total) /
+				PAGE_ALIGN(sizes[0]);
 	}
 
+	*num_planes = 1;
+
 	dev_dbg(icd->parent, "count=%d, size=%lu\n", *count, sizes[0]);
 
 	return 0;
@@ -331,23 +356,40 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
 
 static int sh_mobile_ceu_videobuf_prepare(struct vb2_buffer *vb)
 {
+	struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
+
+	/* Added list head initialization on alloc */
+	WARN(!list_empty(&buf->queue), "Buffer %p on queue!\n", vb);
+
+	return 0;
+}
+
+static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
+{
 	struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
-	struct sh_mobile_ceu_buffer *buf;
+	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+	struct sh_mobile_ceu_dev *pcdev = ici->priv;
+	struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
+	unsigned long size;
 	int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
 						icd->current_fmt->host_fmt);
-	unsigned long size;
 
 	if (bytes_per_line < 0)
-		return bytes_per_line;
+		goto error;
+
+	size = icd->user_height * bytes_per_line;
+
+	if (vb2_plane_size(vb, 0) < size) {
+		dev_err(icd->parent, "Buffer #%d too small (%lu < %lu)\n",
+			vb->v4l2_buf.index, vb2_plane_size(vb, 0), size);
+		goto error;
+	}
 
-	buf = to_ceu_vb(vb);
+	vb2_set_plane_payload(vb, 0, size);
 
 	dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
 		vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
 
-	/* Added list head initialization on alloc */
-	WARN(!list_empty(&buf->queue), "Buffer %p on queue!\n", vb);
-
 #ifdef DEBUG
 	/*
 	 * This can be useful if you want to see if we actually fill
@@ -357,31 +399,6 @@ static int sh_mobile_ceu_videobuf_prepare(struct vb2_buffer *vb)
 		memset(vb2_plane_vaddr(vb, 0), 0xaa, vb2_get_plane_payload(vb, 0));
 #endif
 
-	BUG_ON(NULL == icd->current_fmt);
-
-	size = icd->user_height * bytes_per_line;
-
-	if (vb2_plane_size(vb, 0) < size) {
-		dev_err(icd->parent, "Buffer too small (%lu < %lu)\n",
-			vb2_plane_size(vb, 0), size);
-		return -ENOBUFS;
-	}
-
-	vb2_set_plane_payload(vb, 0, size);
-
-	return 0;
-}
-
-static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
-{
-	struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-	struct sh_mobile_ceu_dev *pcdev = ici->priv;
-	struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
-
-	dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
-		vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
-
 	spin_lock_irq(&pcdev->lock);
 	list_add_tail(&buf->queue, &pcdev->capture);
 
@@ -395,6 +412,11 @@ static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
 		sh_mobile_ceu_capture(pcdev);
 	}
 	spin_unlock_irq(&pcdev->lock);
+
+	return;
+
+error:
+	vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
 }
 
 static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb)
@@ -419,11 +441,23 @@ static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb)
 	if (buf->queue.next)
 		list_del_init(&buf->queue);
 
+	pcdev->buf_total -= PAGE_ALIGN(vb2_plane_size(vb, 0));
+	dev_dbg(icd->parent, "%s() %zu bytes buffers\n", __func__,
+		pcdev->buf_total);
+
 	spin_unlock_irq(&pcdev->lock);
 }
 
 static int sh_mobile_ceu_videobuf_init(struct vb2_buffer *vb)
 {
+	struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
+	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+	struct sh_mobile_ceu_dev *pcdev = ici->priv;
+
+	pcdev->buf_total += PAGE_ALIGN(vb2_plane_size(vb, 0));
+	dev_dbg(icd->parent, "%s() %zu bytes buffers\n", __func__,
+		pcdev->buf_total);
+
 	/* This is for locking debugging only */
 	INIT_LIST_HEAD(&to_ceu_vb(vb)->queue);
 	return 0;
@@ -525,6 +559,8 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
 
 	pm_runtime_get_sync(ici->v4l2_dev.dev);
 
+	pcdev->buf_total = 0;
+
 	ret = sh_mobile_ceu_soft_reset(pcdev);
 
 	csi2_sd = find_csi2(pcdev);
@@ -1674,7 +1710,7 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
 		image_mode = false;
 	}
 
-	dev_info(dev, "S_FMT(pix=0x%x, fld 0x%x, code 0x%x, %ux%u)\n", pixfmt, mf.field, mf.code,
+	dev_geo(dev, "S_FMT(pix=0x%x, fld 0x%x, code 0x%x, %ux%u)\n", pixfmt, mf.field, mf.code,
 		pix->width, pix->height);
 
 	dev_geo(dev, "4: request camera output %ux%u\n", mf.width, mf.height);
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 7/9 v6] dmaengine: ipu-idmac: add support for the DMA_PAUSE control
  2011-08-31 18:02 [PATCH 0/9 v6] new ioctl()s and soc-camera implementation Guennadi Liakhovetski
                   ` (5 preceding siblings ...)
  2011-08-31 18:02 ` [PATCH 6/9 v6] V4L: sh-mobile-ceu-camera: prepare to support multi-size buffers Guennadi Liakhovetski
@ 2011-08-31 18:02 ` Guennadi Liakhovetski
  2011-08-31 18:02 ` [PATCH 8/9 v6] V4L: mx3-camera: prepare to support multi-size buffers Guennadi Liakhovetski
  2011-08-31 18:02 ` [PATCH 9/9 v6] V4L: soc-camera: add 2 new ioctl() handlers Guennadi Liakhovetski
  8 siblings, 0 replies; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-08-31 18:02 UTC (permalink / raw)
  To: Linux Media Mailing List
  Cc: Hans Verkuil, Laurent Pinchart, Pawel Osciak, Sakari Ailus,
	Mauro Carvalho Chehab, Marek Szyprowski

To support multi-size buffers in the mx3_camera V4L2 driver we have to be
able to stop DMA on a channel without releasing descriptors and completely
halting the hardware. Use the DMA_PAUSE control to implement this mode.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Acked-by: Vinod Koul <vinod.koul@linux.intel.com>
Cc: Hans Verkuil <hverkuil@xs4all.nl>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: Mauro Carvalho Chehab <mchehab@infradead.org>
Cc: Pawel Osciak <pawel@osciak.com>
Cc: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
---
 drivers/dma/ipu/ipu_idmac.c |   65 +++++++++++++++++++++++++++---------------
 1 files changed, 42 insertions(+), 23 deletions(-)

diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
index c1a125e..42cdf1c 100644
--- a/drivers/dma/ipu/ipu_idmac.c
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -1306,6 +1306,7 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
 	    ipu_submit_buffer(ichan, descnew, sgnew, ichan->active_buffer) < 0) {
 		callback = descnew->txd.callback;
 		callback_param = descnew->txd.callback_param;
+		list_del_init(&descnew->list);
 		spin_unlock(&ichan->lock);
 		if (callback)
 			callback(callback_param);
@@ -1427,39 +1428,58 @@ static int __idmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
 {
 	struct idmac_channel *ichan = to_idmac_chan(chan);
 	struct idmac *idmac = to_idmac(chan->device);
+	struct ipu *ipu = to_ipu(idmac);
+	struct list_head *list, *tmp;
 	unsigned long flags;
 	int i;
 
-	/* Only supports DMA_TERMINATE_ALL */
-	if (cmd != DMA_TERMINATE_ALL)
-		return -ENXIO;
+	switch (cmd) {
+	case DMA_PAUSE:
+		spin_lock_irqsave(&ipu->lock, flags);
+		ipu_ic_disable_task(ipu, chan->chan_id);
 
-	ipu_disable_channel(idmac, ichan,
-			    ichan->status >= IPU_CHANNEL_ENABLED);
+		/* Return all descriptors into "prepared" state */
+		list_for_each_safe(list, tmp, &ichan->queue)
+			list_del_init(list);
 
-	tasklet_disable(&to_ipu(idmac)->tasklet);
+		ichan->sg[0] = NULL;
+		ichan->sg[1] = NULL;
 
-	/* ichan->queue is modified in ISR, have to spinlock */
-	spin_lock_irqsave(&ichan->lock, flags);
-	list_splice_init(&ichan->queue, &ichan->free_list);
+		spin_unlock_irqrestore(&ipu->lock, flags);
 
-	if (ichan->desc)
-		for (i = 0; i < ichan->n_tx_desc; i++) {
-			struct idmac_tx_desc *desc = ichan->desc + i;
-			if (list_empty(&desc->list))
-				/* Descriptor was prepared, but not submitted */
-				list_add(&desc->list, &ichan->free_list);
+		ichan->status = IPU_CHANNEL_INITIALIZED;
+		break;
+	case DMA_TERMINATE_ALL:
+		ipu_disable_channel(idmac, ichan,
+				    ichan->status >= IPU_CHANNEL_ENABLED);
 
-			async_tx_clear_ack(&desc->txd);
-		}
+		tasklet_disable(&ipu->tasklet);
 
-	ichan->sg[0] = NULL;
-	ichan->sg[1] = NULL;
-	spin_unlock_irqrestore(&ichan->lock, flags);
+		/* ichan->queue is modified in ISR, have to spinlock */
+		spin_lock_irqsave(&ichan->lock, flags);
+		list_splice_init(&ichan->queue, &ichan->free_list);
 
-	tasklet_enable(&to_ipu(idmac)->tasklet);
+		if (ichan->desc)
+			for (i = 0; i < ichan->n_tx_desc; i++) {
+				struct idmac_tx_desc *desc = ichan->desc + i;
+				if (list_empty(&desc->list))
+					/* Descriptor was prepared, but not submitted */
+					list_add(&desc->list, &ichan->free_list);
 
-	ichan->status = IPU_CHANNEL_INITIALIZED;
+				async_tx_clear_ack(&desc->txd);
+			}
+
+		ichan->sg[0] = NULL;
+		ichan->sg[1] = NULL;
+		spin_unlock_irqrestore(&ichan->lock, flags);
+
+		tasklet_enable(&ipu->tasklet);
+
+		ichan->status = IPU_CHANNEL_INITIALIZED;
+		break;
+	default:
+		return -ENOSYS;
+	}
 
 	return 0;
 }
@@ -1662,7 +1682,6 @@ static void __exit ipu_idmac_exit(struct ipu *ipu)
 		struct idmac_channel *ichan = ipu->channel + i;
 
 		idmac_control(&ichan->dma_chan, DMA_TERMINATE_ALL, 0);
-		idmac_prep_slave_sg(&ichan->dma_chan, NULL, 0, DMA_NONE, 0);
 	}
 
 	dma_async_device_unregister(&idmac->dma);
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 8/9 v6] V4L: mx3-camera: prepare to support multi-size buffers
  2011-08-31 18:02 [PATCH 0/9 v6] new ioctl()s and soc-camera implementation Guennadi Liakhovetski
                   ` (6 preceding siblings ...)
  2011-08-31 18:02 ` [PATCH 7/9 v6] dmaengine: ipu-idmac: add support for the DMA_PAUSE control Guennadi Liakhovetski
@ 2011-08-31 18:02 ` Guennadi Liakhovetski
  2011-08-31 18:02 ` [PATCH 9/9 v6] V4L: soc-camera: add 2 new ioctl() handlers Guennadi Liakhovetski
  8 siblings, 0 replies; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-08-31 18:02 UTC (permalink / raw)
  To: Linux Media Mailing List
  Cc: Hans Verkuil, Laurent Pinchart, Pawel Osciak, Sakari Ailus,
	Mauro Carvalho Chehab, Marek Szyprowski

Prepare the mx3_camera driver to support the new VIDIOC_CREATE_BUFS and
VIDIOC_PREPARE_BUF ioctl()s. The .queue_setup() vb2 operation must be
able to handle buffer sizes, provided by the caller, and the
.buf_prepare() operation must not use the currently configured frame
format for its operation, which makes it superfluous for this driver.
Its functionality is moved into .buf_queue().

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Cc: Hans Verkuil <hverkuil@xs4all.nl>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: Mauro Carvalho Chehab <mchehab@infradead.org>
Cc: Pawel Osciak <pawel@osciak.com>
Cc: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
---

v6: Handle the case of VIDIOC_CREATE_BUFS, when vb2 creates fewer buffers, than
    requested by the user, correctly

 drivers/media/video/mx3_camera.c |  159 ++++++++++++++++++++------------------
 1 files changed, 83 insertions(+), 76 deletions(-)

diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index 6bfbce9..a85283a 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -114,6 +114,7 @@ struct mx3_camera_dev {
 	struct list_head	capture;
 	spinlock_t		lock;		/* Protects video buffer lists */
 	struct mx3_camera_buffer *active;
+	size_t			buf_total;
 	struct vb2_alloc_ctx	*alloc_ctx;
 	enum v4l2_field		field;
 	int			sequence;
@@ -198,73 +199,44 @@ static int mx3_videobuf_setup(struct vb2_queue *vq,
 	struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
 	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct mx3_camera_dev *mx3_cam = ici->priv;
-	int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
-						icd->current_fmt->host_fmt);
-
-	if (bytes_per_line < 0)
-		return bytes_per_line;
+	int bytes_per_line;
+	unsigned int height;
 
 	if (!mx3_cam->idmac_channel[0])
 		return -EINVAL;
 
-	*num_planes = 1;
-
-	mx3_cam->sequence = 0;
-	sizes[0] = bytes_per_line * icd->user_height;
-	alloc_ctxs[0] = mx3_cam->alloc_ctx;
-
-	if (!*count)
-		*count = 32;
-
-	if (sizes[0] * *count > MAX_VIDEO_MEM * 1024 * 1024)
-		*count = MAX_VIDEO_MEM * 1024 * 1024 / sizes[0];
-
-	return 0;
-}
-
-static int mx3_videobuf_prepare(struct vb2_buffer *vb)
-{
-	struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-	struct mx3_camera_dev *mx3_cam = ici->priv;
-	struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
-	struct scatterlist *sg;
-	struct mx3_camera_buffer *buf;
-	size_t new_size;
-	int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
+	if (fmt) {
+		const struct soc_camera_format_xlate *xlate = soc_camera_xlate_by_fourcc(icd,
+								fmt->fmt.pix.pixelformat);
+		bytes_per_line = soc_mbus_bytes_per_line(fmt->fmt.pix.width,
+							 xlate->host_fmt);
+		height = fmt->fmt.pix.height;
+	} else {
+		/* Called from VIDIOC_REQBUFS or in compatibility mode */
+		bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
 						icd->current_fmt->host_fmt);
-
+		height = icd->user_height;
+	}
 	if (bytes_per_line < 0)
 		return bytes_per_line;
 
-	buf = to_mx3_vb(vb);
-	sg = &buf->sg;
-
-	new_size = bytes_per_line * icd->user_height;
-
-	if (vb2_plane_size(vb, 0) < new_size) {
-		dev_err(icd->parent, "Buffer too small (%lu < %zu)\n",
-			vb2_plane_size(vb, 0), new_size);
-		return -ENOBUFS;
-	}
+	sizes[0] = bytes_per_line * height;
 
-	if (buf->state == CSI_BUF_NEEDS_INIT) {
-		sg_dma_address(sg)	= vb2_dma_contig_plane_paddr(vb, 0);
-		sg_dma_len(sg)		= new_size;
+	alloc_ctxs[0] = mx3_cam->alloc_ctx;
 
-		buf->txd = ichan->dma_chan.device->device_prep_slave_sg(
-			&ichan->dma_chan, sg, 1, DMA_FROM_DEVICE,
-			DMA_PREP_INTERRUPT);
-		if (!buf->txd)
-			return -EIO;
+	if (!vq->num_buffers)
+		mx3_cam->sequence = 0;
 
-		buf->txd->callback_param	= buf->txd;
-		buf->txd->callback		= mx3_cam_dma_done;
+	if (!*count)
+		*count = 2;
 
-		buf->state = CSI_BUF_PREPARED;
-	}
+	/* If *num_planes != 0, we have already verified *count. */
+	if (!*num_planes &&
+	    sizes[0] * *count + mx3_cam->buf_total > MAX_VIDEO_MEM * 1024 * 1024)
+		*count = (MAX_VIDEO_MEM * 1024 * 1024 - mx3_cam->buf_total) /
+			sizes[0];
 
-	vb2_set_plane_payload(vb, 0, new_size);
+	*num_planes = 1;
 
 	return 0;
 }
@@ -288,28 +260,58 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb)
 	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct mx3_camera_dev *mx3_cam = ici->priv;
 	struct mx3_camera_buffer *buf = to_mx3_vb(vb);
-	struct dma_async_tx_descriptor *txd = buf->txd;
-	struct idmac_channel *ichan = to_idmac_chan(txd->chan);
+	struct scatterlist *sg = &buf->sg;
+	struct dma_async_tx_descriptor *txd;
+	struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
 	struct idmac_video_param *video = &ichan->params.video;
-	dma_cookie_t cookie;
-	u32 fourcc = icd->current_fmt->host_fmt->fourcc;
+	const struct soc_mbus_pixelfmt *host_fmt = icd->current_fmt->host_fmt;
+	int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, host_fmt);
 	unsigned long flags;
+	dma_cookie_t cookie;
+	size_t new_size;
+
+	BUG_ON(bytes_per_line <= 0);
+
+	new_size = bytes_per_line * icd->user_height;
+
+	if (vb2_plane_size(vb, 0) < new_size) {
+		dev_err(icd->parent, "Buffer #%d too small (%lu < %zu)\n",
+			vb->v4l2_buf.index, vb2_plane_size(vb, 0), new_size);
+		goto error;
+	}
+
+	if (buf->state == CSI_BUF_NEEDS_INIT) {
+		sg_dma_address(sg)	= vb2_dma_contig_plane_paddr(vb, 0);
+		sg_dma_len(sg)		= new_size;
+
+		txd = ichan->dma_chan.device->device_prep_slave_sg(
+			&ichan->dma_chan, sg, 1, DMA_FROM_DEVICE,
+			DMA_PREP_INTERRUPT);
+		if (!txd)
+			goto error;
+
+		txd->callback_param	= txd;
+		txd->callback		= mx3_cam_dma_done;
+
+		buf->state		= CSI_BUF_PREPARED;
+		buf->txd		= txd;
+	} else {
+		txd = buf->txd;
+	}
+
+	vb2_set_plane_payload(vb, 0, new_size);
 
 	/* This is the configuration of one sg-element */
-	video->out_pixel_fmt	= fourcc_to_ipu_pix(fourcc);
+	video->out_pixel_fmt = fourcc_to_ipu_pix(host_fmt->fourcc);
 
 	if (video->out_pixel_fmt == IPU_PIX_FMT_GENERIC) {
 		/*
-		 * If the IPU DMA channel is configured to transport
-		 * generic 8-bit data, we have to set up correctly the
-		 * geometry parameters upon the current pixel format.
-		 * So, since the DMA horizontal parameters are expressed
-		 * in bytes not pixels, convert these in the right unit.
+		 * If the IPU DMA channel is configured to transfer generic
+		 * 8-bit data, we have to set up the geometry parameters
+		 * correctly, according to the current pixel format. The DMA
+		 * horizontal parameters in this case are expressed in bytes,
+		 * not in pixels.
 		 */
-		int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
-						icd->current_fmt->host_fmt);
-		BUG_ON(bytes_per_line <= 0);
-
 		video->out_width	= bytes_per_line;
 		video->out_height	= icd->user_height;
 		video->out_stride	= bytes_per_line;
@@ -353,6 +355,7 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb)
 		mx3_cam->active = NULL;
 
 	spin_unlock_irqrestore(&mx3_cam->lock, flags);
+error:
 	vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
 }
 
@@ -386,17 +389,24 @@ static void mx3_videobuf_release(struct vb2_buffer *vb)
 	}
 
 	spin_unlock_irqrestore(&mx3_cam->lock, flags);
+
+	mx3_cam->buf_total -= vb2_plane_size(vb, 0);
 }
 
 static int mx3_videobuf_init(struct vb2_buffer *vb)
 {
+	struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
+	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+	struct mx3_camera_dev *mx3_cam = ici->priv;
 	struct mx3_camera_buffer *buf = to_mx3_vb(vb);
+
 	/* This is for locking debugging only */
 	INIT_LIST_HEAD(&buf->queue);
 	sg_init_table(&buf->sg, 1);
 
 	buf->state = CSI_BUF_NEEDS_INIT;
-	buf->txd = NULL;
+
+	mx3_cam->buf_total += vb2_plane_size(vb, 0);
 
 	return 0;
 }
@@ -407,13 +417,12 @@ static int mx3_stop_streaming(struct vb2_queue *q)
 	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct mx3_camera_dev *mx3_cam = ici->priv;
 	struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
-	struct dma_chan *chan;
 	struct mx3_camera_buffer *buf, *tmp;
 	unsigned long flags;
 
 	if (ichan) {
-		chan = &ichan->dma_chan;
-		chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
+		struct dma_chan *chan = &ichan->dma_chan;
+		chan->device->device_control(chan, DMA_PAUSE, 0);
 	}
 
 	spin_lock_irqsave(&mx3_cam->lock, flags);
@@ -421,8 +430,8 @@ static int mx3_stop_streaming(struct vb2_queue *q)
 	mx3_cam->active = NULL;
 
 	list_for_each_entry_safe(buf, tmp, &mx3_cam->capture, queue) {
-		buf->state = CSI_BUF_NEEDS_INIT;
 		list_del_init(&buf->queue);
+		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
 	}
 
 	spin_unlock_irqrestore(&mx3_cam->lock, flags);
@@ -432,7 +441,6 @@ static int mx3_stop_streaming(struct vb2_queue *q)
 
 static struct vb2_ops mx3_videobuf_ops = {
 	.queue_setup	= mx3_videobuf_setup,
-	.buf_prepare	= mx3_videobuf_prepare,
 	.buf_queue	= mx3_videobuf_queue,
 	.buf_cleanup	= mx3_videobuf_release,
 	.buf_init	= mx3_videobuf_init,
@@ -516,6 +524,7 @@ static int mx3_camera_add_device(struct soc_camera_device *icd)
 
 	mx3_camera_activate(mx3_cam, icd);
 
+	mx3_cam->buf_total = 0;
 	mx3_cam->icd = icd;
 
 	dev_info(icd->parent, "MX3 Camera driver attached to camera %d\n",
@@ -1263,8 +1272,6 @@ static int __devexit mx3_camera_remove(struct platform_device *pdev)
 
 	dmaengine_put();
 
-	dev_info(&pdev->dev, "i.MX3x Camera driver unloaded\n");
-
 	return 0;
 }
 
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 9/9 v6] V4L: soc-camera: add 2 new ioctl() handlers
  2011-08-31 18:02 [PATCH 0/9 v6] new ioctl()s and soc-camera implementation Guennadi Liakhovetski
                   ` (7 preceding siblings ...)
  2011-08-31 18:02 ` [PATCH 8/9 v6] V4L: mx3-camera: prepare to support multi-size buffers Guennadi Liakhovetski
@ 2011-08-31 18:02 ` Guennadi Liakhovetski
  8 siblings, 0 replies; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-08-31 18:02 UTC (permalink / raw)
  To: Linux Media Mailing List
  Cc: Hans Verkuil, Laurent Pinchart, Pawel Osciak, Sakari Ailus,
	Mauro Carvalho Chehab, Marek Szyprowski

This patch adds two new ioctl() handlers: .vidioc_create_bufs() and
.vidioc_prepare_buf() for compliant vb2 soc-camera hosts.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Cc: Hans Verkuil <hverkuil@xs4all.nl>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: Mauro Carvalho Chehab <mchehab@infradead.org>
Cc: Pawel Osciak <pawel@osciak.com>
Cc: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
---
 drivers/media/video/soc_camera.c |   33 +++++++++++++++++++++++++++++++--
 1 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index ac23916..5943235 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -318,6 +318,32 @@ static int soc_camera_dqbuf(struct file *file, void *priv,
 		return vb2_dqbuf(&icd->vb2_vidq, p, file->f_flags & O_NONBLOCK);
 }
 
+static int soc_camera_create_bufs(struct file *file, void *priv,
+			    struct v4l2_create_buffers *create)
+{
+	struct soc_camera_device *icd = file->private_data;
+	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+
+	/* videobuf2 only */
+	if (ici->ops->init_videobuf)
+		return -EINVAL;
+	else
+		return vb2_create_bufs(&icd->vb2_vidq, create);
+}
+
+static int soc_camera_prepare_buf(struct file *file, void *priv,
+				  const struct v4l2_buffer *b)
+{
+	struct soc_camera_device *icd = file->private_data;
+	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+
+	/* videobuf2 only */
+	if (ici->ops->init_videobuf)
+		return -EINVAL;
+	else
+		return vb2_prepare_buf(&icd->vb2_vidq, b);
+}
+
 /* Always entered with .video_lock held */
 static int soc_camera_init_user_formats(struct soc_camera_device *icd)
 {
@@ -1101,6 +1127,7 @@ static int soc_camera_probe(struct soc_camera_device *icd)
 		if (!control || !control->driver || !dev_get_drvdata(control) ||
 		    !try_module_get(control->driver->owner)) {
 			icl->del_device(icd);
+			ret = -ENODEV;
 			goto enodrv;
 		}
 	}
@@ -1366,19 +1393,21 @@ static int soc_camera_device_register(struct soc_camera_device *icd)
 
 static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
 	.vidioc_querycap	 = soc_camera_querycap,
+	.vidioc_try_fmt_vid_cap  = soc_camera_try_fmt_vid_cap,
 	.vidioc_g_fmt_vid_cap    = soc_camera_g_fmt_vid_cap,
-	.vidioc_enum_fmt_vid_cap = soc_camera_enum_fmt_vid_cap,
 	.vidioc_s_fmt_vid_cap    = soc_camera_s_fmt_vid_cap,
+	.vidioc_enum_fmt_vid_cap = soc_camera_enum_fmt_vid_cap,
 	.vidioc_enum_input	 = soc_camera_enum_input,
 	.vidioc_g_input		 = soc_camera_g_input,
 	.vidioc_s_input		 = soc_camera_s_input,
 	.vidioc_s_std		 = soc_camera_s_std,
 	.vidioc_enum_framesizes  = soc_camera_enum_fsizes,
 	.vidioc_reqbufs		 = soc_camera_reqbufs,
-	.vidioc_try_fmt_vid_cap  = soc_camera_try_fmt_vid_cap,
 	.vidioc_querybuf	 = soc_camera_querybuf,
 	.vidioc_qbuf		 = soc_camera_qbuf,
 	.vidioc_dqbuf		 = soc_camera_dqbuf,
+	.vidioc_create_bufs	 = soc_camera_create_bufs,
+	.vidioc_prepare_buf	 = soc_camera_prepare_buf,
 	.vidioc_streamon	 = soc_camera_streamon,
 	.vidioc_streamoff	 = soc_camera_streamoff,
 	.vidioc_queryctrl	 = soc_camera_queryctrl,
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v6] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-08-31 18:02 ` [PATCH 2/9 v6] V4L: add two new ioctl()s for multi-size videobuffer management Guennadi Liakhovetski
@ 2011-08-31 21:06   ` Sakari Ailus
  2011-09-01  7:03     ` Guennadi Liakhovetski
  0 siblings, 1 reply; 59+ messages in thread
From: Sakari Ailus @ 2011-08-31 21:06 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Linux Media Mailing List, Hans Verkuil, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

Hi Guennadi,

Thanks for the patch!!

On Wed, Aug 31, 2011 at 08:02:41PM +0200, Guennadi Liakhovetski wrote:
> A possibility to preallocate and initialise buffers of different sizes
> in V4L2 is required for an efficient implementation of a snapshot
> mode. This patch adds two new ioctl()s: VIDIOC_CREATE_BUFS and
> VIDIOC_PREPARE_BUF and defines respective data structures.
> 
> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> Cc: Hans Verkuil <hverkuil@xs4all.nl>
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Cc: Marek Szyprowski <m.szyprowski@samsung.com>
> Cc: Mauro Carvalho Chehab <mchehab@infradead.org>
> Cc: Pawel Osciak <pawel@osciak.com>
> Cc: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
> ---
>  drivers/media/video/v4l2-compat-ioctl32.c |   67 +++++++++++++++++++++++++---
>  drivers/media/video/v4l2-ioctl.c          |   29 ++++++++++++
>  include/linux/videodev2.h                 |   15 ++++++
>  include/media/v4l2-ioctl.h                |    2 +
>  4 files changed, 105 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
> index 61979b7..85758d2 100644
> --- a/drivers/media/video/v4l2-compat-ioctl32.c
> +++ b/drivers/media/video/v4l2-compat-ioctl32.c
> @@ -159,11 +159,16 @@ struct v4l2_format32 {
>  	} fmt;
>  };
>  
> -static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
> +struct v4l2_create_buffers32 {
> +	__u32			index;		/* output: buffers index...index + count - 1 have been created */
> +	__u32			count;
> +	enum v4l2_memory        memory;
> +	struct v4l2_format32	format;		/* filled in by the user, plane sizes calculated by the driver */
> +	__u32			reserved[8];
> +};
> +
> +static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
>  {
> -	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
> -			get_user(kp->type, &up->type))
> -			return -EFAULT;
>  	switch (kp->type) {
>  	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
>  	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
> @@ -192,11 +197,24 @@ static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
>  	}
>  }
>  
> -static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
> +static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
> +{
> +	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
> +			get_user(kp->type, &up->type))
> +			return -EFAULT;
> +	return __get_v4l2_format32(kp, up);
> +}
> +
> +static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
> +{
> +	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)) ||
> +	    copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format.fmt)))
> +			return -EFAULT;
> +	return __get_v4l2_format32(&kp->format, &up->format);
> +}
> +
> +static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
>  {
> -	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
> -		put_user(kp->type, &up->type))
> -		return -EFAULT;
>  	switch (kp->type) {
>  	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
>  	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
> @@ -225,6 +243,22 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
>  	}
>  }
>  
> +static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
> +{
> +	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
> +		put_user(kp->type, &up->type))
> +		return -EFAULT;
> +	return __put_v4l2_format32(kp, up);
> +}
> +
> +static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
> +{
> +	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_create_buffers32)) ||
> +	    copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format.fmt)))
> +			return -EFAULT;
> +	return __put_v4l2_format32(&kp->format, &up->format);
> +}
> +
>  struct v4l2_standard32 {
>  	__u32		     index;
>  	__u32		     id[2]; /* __u64 would get the alignment wrong */
> @@ -702,6 +736,8 @@ static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *u
>  #define VIDIOC_S_EXT_CTRLS32    _IOWR('V', 72, struct v4l2_ext_controls32)
>  #define VIDIOC_TRY_EXT_CTRLS32  _IOWR('V', 73, struct v4l2_ext_controls32)
>  #define	VIDIOC_DQEVENT32	_IOR ('V', 89, struct v4l2_event32)
> +#define VIDIOC_CREATE_BUFS32	_IOWR('V', 92, struct v4l2_create_buffers32)
> +#define VIDIOC_PREPARE_BUF32	_IOW ('V', 93, struct v4l2_buffer32)
>  
>  #define VIDIOC_OVERLAY32	_IOW ('V', 14, s32)
>  #define VIDIOC_STREAMON32	_IOW ('V', 18, s32)
> @@ -721,6 +757,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
>  		struct v4l2_standard v2s;
>  		struct v4l2_ext_controls v2ecs;
>  		struct v4l2_event v2ev;
> +		struct v4l2_create_buffers v2crt;
>  		unsigned long vx;
>  		int vi;
>  	} karg;
> @@ -751,6 +788,8 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
>  	case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break;
>  	case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break;
>  	case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break;
> +	case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break;
> +	case VIDIOC_PREPARE_BUF32: cmd = VIDIOC_PREPARE_BUF; break;
>  	}
>  
>  	switch (cmd) {
> @@ -775,6 +814,12 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
>  		compatible_arg = 0;
>  		break;
>  
> +	case VIDIOC_CREATE_BUFS:
> +		err = get_v4l2_create32(&karg.v2crt, up);
> +		compatible_arg = 0;
> +		break;
> +
> +	case VIDIOC_PREPARE_BUF:
>  	case VIDIOC_QUERYBUF:
>  	case VIDIOC_QBUF:
>  	case VIDIOC_DQBUF:
> @@ -860,6 +905,10 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
>  		err = put_v4l2_format32(&karg.v2f, up);
>  		break;
>  
> +	case VIDIOC_CREATE_BUFS:
> +		err = put_v4l2_create32(&karg.v2crt, up);
> +		break;
> +
>  	case VIDIOC_QUERYBUF:
>  	case VIDIOC_QBUF:
>  	case VIDIOC_DQBUF:
> @@ -959,6 +1008,8 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
>  	case VIDIOC_DQEVENT32:
>  	case VIDIOC_SUBSCRIBE_EVENT:
>  	case VIDIOC_UNSUBSCRIBE_EVENT:
> +	case VIDIOC_CREATE_BUFS32:
> +	case VIDIOC_PREPARE_BUF32:
>  		ret = do_video_ioctl(file, cmd, arg);
>  		break;
>  
> diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
> index 002ce13..6fa8e04 100644
> --- a/drivers/media/video/v4l2-ioctl.c
> +++ b/drivers/media/video/v4l2-ioctl.c
> @@ -260,6 +260,8 @@ static const char *v4l2_ioctls[] = {
>  	[_IOC_NR(VIDIOC_DQEVENT)]	   = "VIDIOC_DQEVENT",
>  	[_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)]  = "VIDIOC_SUBSCRIBE_EVENT",
>  	[_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT",
> +	[_IOC_NR(VIDIOC_CREATE_BUFS)]      = "VIDIOC_CREATE_BUFS",
> +	[_IOC_NR(VIDIOC_PREPARE_BUF)]      = "VIDIOC_PREPARE_BUF",
>  };
>  #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
>  
> @@ -2216,6 +2218,33 @@ static long __video_do_ioctl(struct file *file,
>  		dbgarg(cmd, "type=0x%8.8x", sub->type);
>  		break;
>  	}
> +	case VIDIOC_CREATE_BUFS:
> +	{
> +		struct v4l2_create_buffers *create = arg;
> +
> +		if (!ops->vidioc_create_bufs)
> +			break;
> +		ret = check_fmt(ops, create->format.type);
> +		if (ret)
> +			break;
> +
> +		ret = ops->vidioc_create_bufs(file, fh, create);
> +
> +		dbgarg(cmd, "count=%d @ %d\n", create->count, create->index);
> +		break;
> +	}
> +	case VIDIOC_PREPARE_BUF:
> +	{
> +		struct v4l2_buffer *b = arg;
> +
> +		if (!ops->vidioc_prepare_buf)
> +			break;
> +
> +		ret = ops->vidioc_prepare_buf(file, fh, b);
> +
> +		dbgarg(cmd, "index=%d", b->index);
> +		break;
> +	}
>  	default:
>  	{
>  		bool valid_prio = true;
> diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
> index fca24cc..988e1be 100644
> --- a/include/linux/videodev2.h
> +++ b/include/linux/videodev2.h
> @@ -653,6 +653,9 @@ struct v4l2_buffer {
>  #define V4L2_BUF_FLAG_ERROR	0x0040
>  #define V4L2_BUF_FLAG_TIMECODE	0x0100	/* timecode field is valid */
>  #define V4L2_BUF_FLAG_INPUT     0x0200  /* input field is valid */
> +/* Cache handling flags */
> +#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE	0x0400
> +#define V4L2_BUF_FLAG_NO_CACHE_CLEAN		0x0800
>  
>  /*
>   *	O V E R L A Y   P R E V I E W
> @@ -2092,6 +2095,15 @@ struct v4l2_dbg_chip_ident {
>  	__u32 revision;    /* chip revision, chip specific */
>  } __attribute__ ((packed));
>  
> +/* VIDIOC_CREATE_BUFS */
> +struct v4l2_create_buffers {
> +	__u32			index;		/* output: buffers index...index + count - 1 have been created */
> +	__u32			count;
> +	enum v4l2_memory        memory;
> +	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
> +	__u32			reserved[8];
> +};

How about splitting the above comments? These lines are really long.
Kerneldoc could also be used, I think.

> +
>  /*
>   *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
>   *
> @@ -2182,6 +2194,9 @@ struct v4l2_dbg_chip_ident {
>  #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct v4l2_event_subscription)
>  #define	VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
>  
> +#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct v4l2_create_buffers)
> +#define VIDIOC_PREPARE_BUF	 _IOW('V', 93, struct v4l2_buffer)

Does prepare_buf ever do anything that would need to return anything to the
user? I guess the answer is "no"?

This patch looks very good to me in general.

> +
>  /* Reminder: when adding new ioctls please add support for them to
>     drivers/media/video/v4l2-compat-ioctl32.c as well! */
>  
> diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
> index dd9f1e7..55cf8ae 100644
> --- a/include/media/v4l2-ioctl.h
> +++ b/include/media/v4l2-ioctl.h
> @@ -122,6 +122,8 @@ struct v4l2_ioctl_ops {
>  	int (*vidioc_qbuf)    (struct file *file, void *fh, struct v4l2_buffer *b);
>  	int (*vidioc_dqbuf)   (struct file *file, void *fh, struct v4l2_buffer *b);
>  
> +	int (*vidioc_create_bufs)(struct file *file, void *fh, struct v4l2_create_buffers *b);
> +	int (*vidioc_prepare_buf)(struct file *file, void *fh, const struct v4l2_buffer *b);
>  
>  	int (*vidioc_overlay) (struct file *file, void *fh, unsigned int i);
>  	int (*vidioc_g_fbuf)   (struct file *file, void *fh,
> -- 
> 1.7.2.5
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Sakari Ailus
sakari.ailus@iki.fi

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 3/9 v6] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s
  2011-08-31 18:02 ` [PATCH 3/9 v6] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s Guennadi Liakhovetski
@ 2011-08-31 21:11   ` Sakari Ailus
  2011-09-01  7:10     ` Guennadi Liakhovetski
  2011-11-03 12:13   ` [PATCH 3/9 v6] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s Mauro Carvalho Chehab
  1 sibling, 1 reply; 59+ messages in thread
From: Sakari Ailus @ 2011-08-31 21:11 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Linux Media Mailing List, Hans Verkuil, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

Hi Guennadi,

On Wed, Aug 31, 2011 at 08:02:42PM +0200, Guennadi Liakhovetski wrote:
> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> Cc: Hans Verkuil <hverkuil@xs4all.nl>
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Cc: Marek Szyprowski <m.szyprowski@samsung.com>
> Cc: Mauro Carvalho Chehab <mchehab@infradead.org>
> Cc: Pawel Osciak <pawel@osciak.com>
> Cc: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
> ---
>  Documentation/DocBook/media/v4l/io.xml             |   17 +++
>  Documentation/DocBook/media/v4l/v4l2.xml           |    2 +
>  .../DocBook/media/v4l/vidioc-create-bufs.xml       |  147 ++++++++++++++++++++
>  .../DocBook/media/v4l/vidioc-prepare-buf.xml       |   96 +++++++++++++
>  4 files changed, 262 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
>  create mode 100644 Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
> 
> diff --git a/Documentation/DocBook/media/v4l/io.xml b/Documentation/DocBook/media/v4l/io.xml
> index 227e7ac..ff03dd2 100644
> --- a/Documentation/DocBook/media/v4l/io.xml
> +++ b/Documentation/DocBook/media/v4l/io.xml
> @@ -927,6 +927,23 @@ ioctl is called.</entry>
>  Applications set or clear this flag before calling the
>  <constant>VIDIOC_QBUF</constant> ioctl.</entry>
>  	  </row>
> +	  <row>
> +	    <entry><constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant></entry>
> +	    <entry>0x0400</entry>
> +	    <entry>Caches do not have to be invalidated for this buffer.
> +Typically applications shall use this flag if the data captured in the buffer
> +is not going to be touched by the CPU, instead the buffer will, probably, be
> +passed on to a DMA-capable hardware unit for further processing or output.
> +</entry>
> +	  </row>
> +	  <row>
> +	    <entry><constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant></entry>
> +	    <entry>0x0800</entry>
> +	    <entry>Caches do not have to be cleaned for this buffer.
> +Typically applications shall use this flag for output buffers if the data
> +in this buffer has not been created by the CPU but by some DMA-capable unit,
> +in which case caches have not been used.</entry>
> +	  </row>
>  	</tbody>
>        </tgroup>
>      </table>
> diff --git a/Documentation/DocBook/media/v4l/v4l2.xml b/Documentation/DocBook/media/v4l/v4l2.xml
> index 0d05e87..06bb179 100644
> --- a/Documentation/DocBook/media/v4l/v4l2.xml
> +++ b/Documentation/DocBook/media/v4l/v4l2.xml
> @@ -462,6 +462,7 @@ and discussions on the V4L mailing list.</revremark>
>      &sub-close;
>      &sub-ioctl;
>      <!-- All ioctls go here. -->
> +    &sub-create-bufs;
>      &sub-cropcap;
>      &sub-dbg-g-chip-ident;
>      &sub-dbg-g-register;
> @@ -504,6 +505,7 @@ and discussions on the V4L mailing list.</revremark>
>      &sub-queryctrl;
>      &sub-query-dv-preset;
>      &sub-querystd;
> +    &sub-prepare-buf;
>      &sub-reqbufs;
>      &sub-s-hw-freq-seek;
>      &sub-streamon;
> diff --git a/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
> new file mode 100644
> index 0000000..eb99604
> --- /dev/null
> +++ b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
> @@ -0,0 +1,147 @@
> +<refentry id="vidioc-create-bufs">
> +  <refmeta>
> +    <refentrytitle>ioctl VIDIOC_CREATE_BUFS</refentrytitle>
> +    &manvol;
> +  </refmeta>
> +
> +  <refnamediv>
> +    <refname>VIDIOC_CREATE_BUFS</refname>
> +    <refpurpose>Create buffers for Memory Mapped or User Pointer I/O</refpurpose>
> +  </refnamediv>
> +
> +  <refsynopsisdiv>
> +    <funcsynopsis>
> +      <funcprototype>
> +	<funcdef>int <function>ioctl</function></funcdef>
> +	<paramdef>int <parameter>fd</parameter></paramdef>
> +	<paramdef>int <parameter>request</parameter></paramdef>
> +	<paramdef>struct v4l2_create_buffers *<parameter>argp</parameter></paramdef>
> +      </funcprototype>
> +    </funcsynopsis>
> +  </refsynopsisdiv>
> +
> +  <refsect1>
> +    <title>Arguments</title>
> +
> +    <variablelist>
> +      <varlistentry>
> +	<term><parameter>fd</parameter></term>
> +	<listitem>
> +	  <para>&fd;</para>
> +	</listitem>
> +      </varlistentry>
> +      <varlistentry>
> +	<term><parameter>request</parameter></term>
> +	<listitem>
> +	  <para>VIDIOC_CREATE_BUFS</para>
> +	</listitem>
> +      </varlistentry>
> +      <varlistentry>
> +	<term><parameter>argp</parameter></term>
> +	<listitem>
> +	  <para></para>
> +	</listitem>
> +      </varlistentry>
> +    </variablelist>
> +  </refsect1>
> +
> +  <refsect1>
> +    <title>Description</title>
> +
> +    <para>This ioctl is used to create buffers for <link linkend="mmap">memory
> +mapped</link> or <link linkend="userp">user pointer</link>
> +I/O. It can be used as an alternative or in addition to the
> +<constant>VIDIOC_REQBUFS</constant> ioctl, when a tighter control over buffers
> +is required. This ioctl can be called multiple times to create buffers of
> +different sizes.</para>
> +
> +    <para>To allocate device buffers applications initialize relevant fields of
> +the <structname>v4l2_create_buffers</structname> structure. They set the
> +<structfield>type</structfield> field in the
> +<structname>v4l2_format</structname> structure, embedded in this
> +structure, to the respective stream or buffer type.
> +<structfield>count</structfield> must be set to the number of required buffers.
> +<structfield>memory</structfield> specifies the required I/O method. The
> +<structfield>format</structfield> field shall typically be filled in using
> +either the <constant>VIDIOC_TRY_FMT</constant> or
> +<constant>VIDIOC_G_FMT</constant> ioctl(). Additionally, applications can adjust
> +<structfield>sizeimage</structfield> fields to fit their specific needs. The
> +<structfield>reserved</structfield> array must be zeroed.</para>
> +
> +    <para>When the ioctl is called with a pointer to this structure the driver
> +will attempt to allocate up to the requested number of buffers and store the
> +actual number allocated and the starting index in the
> +<structfield>count</structfield> and the <structfield>index</structfield> fields
> +respectively. On return <structfield>count</structfield> can be smaller than
> +the number requested. The driver may also adjust buffer sizes as it sees fit,
> +however, it will not update <structfield>sizeimage</structfield> fields, the
> +user has to use <constant>VIDIOC_QUERYBUF</constant> to retrieve that
> +information.</para>
> +
> +    <table pgwide="1" frame="none" id="v4l2-create-buffers">
> +      <title>struct <structname>v4l2_create_buffers</structname></title>
> +      <tgroup cols="3">
> +	&cs-str;
> +	<tbody valign="top">
> +	  <row>
> +	    <entry>__u32</entry>
> +	    <entry><structfield>index</structfield></entry>
> +	    <entry>The starting buffer index, returned by the driver.</entry>
> +	  </row>
> +	  <row>
> +	    <entry>__u32</entry>
> +	    <entry><structfield>count</structfield></entry>
> +	    <entry>The number of buffers requested or granted.</entry>
> +	  </row>
> +	  <row>
> +	    <entry>&v4l2-memory;</entry>
> +	    <entry><structfield>memory</structfield></entry>
> +	    <entry>Applications set this field to
> +<constant>V4L2_MEMORY_MMAP</constant> or
> +<constant>V4L2_MEMORY_USERPTR</constant>.</entry>
> +	  </row>
> +	  <row>
> +	    <entry>&v4l2-format;</entry>
> +	    <entry><structfield>format</structfield></entry>
> +	    <entry>Filled in by the application, preserved by the driver.</entry>
> +	  </row>
> +	  <row>
> +	    <entry>__u32</entry>
> +	    <entry><structfield>reserved</structfield>[8]</entry>
> +	    <entry>A place holder for future extensions.</entry>
> +	  </row>
> +	</tbody>
> +      </tgroup>
> +    </table>
> +  </refsect1>
> +
> +  <refsect1>
> +    &return-value;
> +
> +    <variablelist>
> +      <varlistentry>
> +	<term><errorcode>ENOMEM</errorcode></term>
> +	<listitem>
> +	  <para>No memory to allocate buffers for <link linkend="mmap">memory
> +mapped</link> I/O.</para>
> +	</listitem>
> +      </varlistentry>
> +      <varlistentry>
> +	<term><errorcode>EINVAL</errorcode></term>
> +	<listitem>
> +	  <para>The buffer type (<structfield>type</structfield> field) or the
> +requested I/O method (<structfield>memory</structfield>) is not
> +supported.</para>
> +	</listitem>
> +      </varlistentry>
> +    </variablelist>
> +  </refsect1>
> +</refentry>
> +
> +<!--
> +Local Variables:
> +mode: sgml
> +sgml-parent-document: "v4l2.sgml"
> +indent-tabs-mode: nil
> +End:
> +-->
> diff --git a/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
> new file mode 100644
> index 0000000..509e752
> --- /dev/null
> +++ b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
> @@ -0,0 +1,96 @@
> +<refentry id="vidioc-prepare-buf">
> +  <refmeta>
> +    <refentrytitle>ioctl VIDIOC_PREPARE_BUF</refentrytitle>
> +    &manvol;
> +  </refmeta>
> +
> +  <refnamediv>
> +    <refname>VIDIOC_PREPARE_BUF</refname>
> +    <refpurpose>Prepare a buffer for I/O</refpurpose>
> +  </refnamediv>
> +
> +  <refsynopsisdiv>
> +    <funcsynopsis>
> +      <funcprototype>
> +	<funcdef>int <function>ioctl</function></funcdef>
> +	<paramdef>int <parameter>fd</parameter></paramdef>
> +	<paramdef>int <parameter>request</parameter></paramdef>
> +	<paramdef>struct v4l2_buffer *<parameter>argp</parameter></paramdef>
> +      </funcprototype>
> +    </funcsynopsis>
> +  </refsynopsisdiv>
> +
> +  <refsect1>
> +    <title>Arguments</title>
> +
> +    <variablelist>
> +      <varlistentry>
> +	<term><parameter>fd</parameter></term>
> +	<listitem>
> +	  <para>&fd;</para>
> +	</listitem>
> +      </varlistentry>
> +      <varlistentry>
> +	<term><parameter>request</parameter></term>
> +	<listitem>
> +	  <para>VIDIOC_PREPARE_BUF</para>
> +	</listitem>
> +      </varlistentry>
> +      <varlistentry>
> +	<term><parameter>argp</parameter></term>
> +	<listitem>
> +	  <para></para>
> +	</listitem>
> +      </varlistentry>
> +    </variablelist>
> +  </refsect1>
> +
> +  <refsect1>
> +    <title>Description</title>
> +
> +    <para>Applications can optionally call the
> +<constant>VIDIOC_PREPARE_BUF</constant> ioctl to pass ownership of the buffer
> +to the driver before actually enqueuing it, using the
> +<constant>VIDIOC_QBUF</constant> ioctl, and to prepare it for future I/O.
> +Such preparations may include cache invalidation or cleaning. Performing them

I think it could be added that the first time when the buffer is prepared,
the preparation may include very time consuming tasks such as memory
allocation and iommu mapping of that memory.

> +in advance saves time during the actual I/O. In case such cache operations are
> +not required, the application can use one of
> +<constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant> and
> +<constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant> flags to skip the respective
> +step.</para>
> +
> +    <para>The <structname>v4l2_buffer</structname> structure is
> +specified in <xref linkend="buffer" />.</para>
> +  </refsect1>
> +
> +  <refsect1>
> +    &return-value;
> +
> +    <variablelist>
> +      <varlistentry>
> +	<term><errorcode>EBUSY</errorcode></term>
> +	<listitem>
> +	  <para>File I/O is in progress.</para>
> +	</listitem>
> +      </varlistentry>
> +      <varlistentry>
> +	<term><errorcode>EINVAL</errorcode></term>
> +	<listitem>
> +	  <para>The buffer <structfield>type</structfield> is not
> +supported, or the <structfield>index</structfield> is out of bounds,
> +or no buffers have been allocated yet, or the
> +<structfield>userptr</structfield> or
> +<structfield>length</structfield> are invalid.</para>
> +	</listitem>
> +      </varlistentry>
> +    </variablelist>
> +  </refsect1>
> +</refentry>
> +
> +<!--
> +Local Variables:
> +mode: sgml
> +sgml-parent-document: "v4l2.sgml"
> +indent-tabs-mode: nil
> +End:
> +-->
> -- 
> 1.7.2.5
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Sakari Ailus
sakari.ailus@iki.fi

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v6] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-08-31 21:06   ` Sakari Ailus
@ 2011-09-01  7:03     ` Guennadi Liakhovetski
  2011-09-01  8:35       ` Laurent Pinchart
  2011-09-01  8:42       ` Sakari Ailus
  0 siblings, 2 replies; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-09-01  7:03 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Linux Media Mailing List, Hans Verkuil, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

Hi Sakari

On Thu, 1 Sep 2011, Sakari Ailus wrote:

> Hi Guennadi,
> 
> Thanks for the patch!!
> 
> On Wed, Aug 31, 2011 at 08:02:41PM +0200, Guennadi Liakhovetski wrote:
> > A possibility to preallocate and initialise buffers of different sizes
> > in V4L2 is required for an efficient implementation of a snapshot
> > mode. This patch adds two new ioctl()s: VIDIOC_CREATE_BUFS and
> > VIDIOC_PREPARE_BUF and defines respective data structures.
> > 
> > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > Cc: Hans Verkuil <hverkuil@xs4all.nl>
> > Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > Cc: Marek Szyprowski <m.szyprowski@samsung.com>
> > Cc: Mauro Carvalho Chehab <mchehab@infradead.org>
> > Cc: Pawel Osciak <pawel@osciak.com>
> > Cc: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
> > ---
> >  drivers/media/video/v4l2-compat-ioctl32.c |   67 +++++++++++++++++++++++++---
> >  drivers/media/video/v4l2-ioctl.c          |   29 ++++++++++++
> >  include/linux/videodev2.h                 |   15 ++++++
> >  include/media/v4l2-ioctl.h                |    2 +
> >  4 files changed, 105 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
> > index 61979b7..85758d2 100644
> > --- a/drivers/media/video/v4l2-compat-ioctl32.c
> > +++ b/drivers/media/video/v4l2-compat-ioctl32.c
> > @@ -159,11 +159,16 @@ struct v4l2_format32 {
> >  	} fmt;
> >  };
> >  
> > -static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
> > +struct v4l2_create_buffers32 {
> > +	__u32			index;		/* output: buffers index...index + count - 1 have been created */
> > +	__u32			count;
> > +	enum v4l2_memory        memory;
> > +	struct v4l2_format32	format;		/* filled in by the user, plane sizes calculated by the driver */
> > +	__u32			reserved[8];
> > +};
> > +
> > +static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
> >  {
> > -	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
> > -			get_user(kp->type, &up->type))
> > -			return -EFAULT;
> >  	switch (kp->type) {
> >  	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
> >  	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
> > @@ -192,11 +197,24 @@ static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
> >  	}
> >  }
> >  
> > -static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
> > +static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
> > +{
> > +	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
> > +			get_user(kp->type, &up->type))
> > +			return -EFAULT;
> > +	return __get_v4l2_format32(kp, up);
> > +}
> > +
> > +static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
> > +{
> > +	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)) ||
> > +	    copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format.fmt)))
> > +			return -EFAULT;
> > +	return __get_v4l2_format32(&kp->format, &up->format);
> > +}
> > +
> > +static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
> >  {
> > -	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
> > -		put_user(kp->type, &up->type))
> > -		return -EFAULT;
> >  	switch (kp->type) {
> >  	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
> >  	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
> > @@ -225,6 +243,22 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
> >  	}
> >  }
> >  
> > +static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
> > +{
> > +	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
> > +		put_user(kp->type, &up->type))
> > +		return -EFAULT;
> > +	return __put_v4l2_format32(kp, up);
> > +}
> > +
> > +static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
> > +{
> > +	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_create_buffers32)) ||
> > +	    copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format.fmt)))
> > +			return -EFAULT;
> > +	return __put_v4l2_format32(&kp->format, &up->format);
> > +}
> > +
> >  struct v4l2_standard32 {
> >  	__u32		     index;
> >  	__u32		     id[2]; /* __u64 would get the alignment wrong */
> > @@ -702,6 +736,8 @@ static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *u
> >  #define VIDIOC_S_EXT_CTRLS32    _IOWR('V', 72, struct v4l2_ext_controls32)
> >  #define VIDIOC_TRY_EXT_CTRLS32  _IOWR('V', 73, struct v4l2_ext_controls32)
> >  #define	VIDIOC_DQEVENT32	_IOR ('V', 89, struct v4l2_event32)
> > +#define VIDIOC_CREATE_BUFS32	_IOWR('V', 92, struct v4l2_create_buffers32)
> > +#define VIDIOC_PREPARE_BUF32	_IOW ('V', 93, struct v4l2_buffer32)
> >  
> >  #define VIDIOC_OVERLAY32	_IOW ('V', 14, s32)
> >  #define VIDIOC_STREAMON32	_IOW ('V', 18, s32)
> > @@ -721,6 +757,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
> >  		struct v4l2_standard v2s;
> >  		struct v4l2_ext_controls v2ecs;
> >  		struct v4l2_event v2ev;
> > +		struct v4l2_create_buffers v2crt;
> >  		unsigned long vx;
> >  		int vi;
> >  	} karg;
> > @@ -751,6 +788,8 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
> >  	case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break;
> >  	case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break;
> >  	case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break;
> > +	case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break;
> > +	case VIDIOC_PREPARE_BUF32: cmd = VIDIOC_PREPARE_BUF; break;
> >  	}
> >  
> >  	switch (cmd) {
> > @@ -775,6 +814,12 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
> >  		compatible_arg = 0;
> >  		break;
> >  
> > +	case VIDIOC_CREATE_BUFS:
> > +		err = get_v4l2_create32(&karg.v2crt, up);
> > +		compatible_arg = 0;
> > +		break;
> > +
> > +	case VIDIOC_PREPARE_BUF:
> >  	case VIDIOC_QUERYBUF:
> >  	case VIDIOC_QBUF:
> >  	case VIDIOC_DQBUF:
> > @@ -860,6 +905,10 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
> >  		err = put_v4l2_format32(&karg.v2f, up);
> >  		break;
> >  
> > +	case VIDIOC_CREATE_BUFS:
> > +		err = put_v4l2_create32(&karg.v2crt, up);
> > +		break;
> > +
> >  	case VIDIOC_QUERYBUF:
> >  	case VIDIOC_QBUF:
> >  	case VIDIOC_DQBUF:
> > @@ -959,6 +1008,8 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
> >  	case VIDIOC_DQEVENT32:
> >  	case VIDIOC_SUBSCRIBE_EVENT:
> >  	case VIDIOC_UNSUBSCRIBE_EVENT:
> > +	case VIDIOC_CREATE_BUFS32:
> > +	case VIDIOC_PREPARE_BUF32:
> >  		ret = do_video_ioctl(file, cmd, arg);
> >  		break;
> >  
> > diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
> > index 002ce13..6fa8e04 100644
> > --- a/drivers/media/video/v4l2-ioctl.c
> > +++ b/drivers/media/video/v4l2-ioctl.c
> > @@ -260,6 +260,8 @@ static const char *v4l2_ioctls[] = {
> >  	[_IOC_NR(VIDIOC_DQEVENT)]	   = "VIDIOC_DQEVENT",
> >  	[_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)]  = "VIDIOC_SUBSCRIBE_EVENT",
> >  	[_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT",
> > +	[_IOC_NR(VIDIOC_CREATE_BUFS)]      = "VIDIOC_CREATE_BUFS",
> > +	[_IOC_NR(VIDIOC_PREPARE_BUF)]      = "VIDIOC_PREPARE_BUF",
> >  };
> >  #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
> >  
> > @@ -2216,6 +2218,33 @@ static long __video_do_ioctl(struct file *file,
> >  		dbgarg(cmd, "type=0x%8.8x", sub->type);
> >  		break;
> >  	}
> > +	case VIDIOC_CREATE_BUFS:
> > +	{
> > +		struct v4l2_create_buffers *create = arg;
> > +
> > +		if (!ops->vidioc_create_bufs)
> > +			break;
> > +		ret = check_fmt(ops, create->format.type);
> > +		if (ret)
> > +			break;
> > +
> > +		ret = ops->vidioc_create_bufs(file, fh, create);
> > +
> > +		dbgarg(cmd, "count=%d @ %d\n", create->count, create->index);
> > +		break;
> > +	}
> > +	case VIDIOC_PREPARE_BUF:
> > +	{
> > +		struct v4l2_buffer *b = arg;
> > +
> > +		if (!ops->vidioc_prepare_buf)
> > +			break;
> > +
> > +		ret = ops->vidioc_prepare_buf(file, fh, b);
> > +
> > +		dbgarg(cmd, "index=%d", b->index);
> > +		break;
> > +	}
> >  	default:
> >  	{
> >  		bool valid_prio = true;
> > diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
> > index fca24cc..988e1be 100644
> > --- a/include/linux/videodev2.h
> > +++ b/include/linux/videodev2.h
> > @@ -653,6 +653,9 @@ struct v4l2_buffer {
> >  #define V4L2_BUF_FLAG_ERROR	0x0040
> >  #define V4L2_BUF_FLAG_TIMECODE	0x0100	/* timecode field is valid */
> >  #define V4L2_BUF_FLAG_INPUT     0x0200  /* input field is valid */
> > +/* Cache handling flags */
> > +#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE	0x0400
> > +#define V4L2_BUF_FLAG_NO_CACHE_CLEAN		0x0800
> >  
> >  /*
> >   *	O V E R L A Y   P R E V I E W
> > @@ -2092,6 +2095,15 @@ struct v4l2_dbg_chip_ident {
> >  	__u32 revision;    /* chip revision, chip specific */
> >  } __attribute__ ((packed));
> >  
> > +/* VIDIOC_CREATE_BUFS */
> > +struct v4l2_create_buffers {
> > +	__u32			index;		/* output: buffers index...index + count - 1 have been created */
> > +	__u32			count;
> > +	enum v4l2_memory        memory;
> > +	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
> > +	__u32			reserved[8];
> > +};
> 
> How about splitting the above comments? These lines are really long.
> Kerneldoc could also be used, I think.

Sure, how about this incremental patch:

From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Subject: V4L: improve struct v4l2_create_buffers documentation

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 988e1be..64e0bf2 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -2095,12 +2095,20 @@ struct v4l2_dbg_chip_ident {
 	__u32 revision;    /* chip revision, chip specific */
 } __attribute__ ((packed));
 
-/* VIDIOC_CREATE_BUFS */
+/**
+ * struct v4l2_create_buffers - VIDIOC_CREATE_BUFS argument
+ * @index:	on return, index of the first created buffer
+ * @count:	entry: number of requested buffers,
+ *		return: number of created buffers
+ * @memory:	buffer memory type
+ * @format:	frame format, for which buffers are requested
+ * @reserved:	future extensions
+ */
 struct v4l2_create_buffers {
-	__u32			index;		/* output: buffers index...index + count - 1 have been created */
+	__u32			index;
 	__u32			count;
 	enum v4l2_memory        memory;
-	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
+	struct v4l2_format	format;
 	__u32			reserved[8];
 };
 

> > +
> >  /*
> >   *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
> >   *
> > @@ -2182,6 +2194,9 @@ struct v4l2_dbg_chip_ident {
> >  #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct v4l2_event_subscription)
> >  #define	VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
> >  
> > +#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct v4l2_create_buffers)
> > +#define VIDIOC_PREPARE_BUF	 _IOW('V', 93, struct v4l2_buffer)
> 
> Does prepare_buf ever do anything that would need to return anything to the
> user? I guess the answer is "no"?

Exactly, that's why it's an "_IOW" ioctl(), not an "_IOWR", or have I 
misunderstood you?

Thanks
Guennadi

> 
> This patch looks very good to me in general.
> 
> > +
> >  /* Reminder: when adding new ioctls please add support for them to
> >     drivers/media/video/v4l2-compat-ioctl32.c as well! */
> >  
> > diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
> > index dd9f1e7..55cf8ae 100644
> > --- a/include/media/v4l2-ioctl.h
> > +++ b/include/media/v4l2-ioctl.h
> > @@ -122,6 +122,8 @@ struct v4l2_ioctl_ops {
> >  	int (*vidioc_qbuf)    (struct file *file, void *fh, struct v4l2_buffer *b);
> >  	int (*vidioc_dqbuf)   (struct file *file, void *fh, struct v4l2_buffer *b);
> >  
> > +	int (*vidioc_create_bufs)(struct file *file, void *fh, struct v4l2_create_buffers *b);
> > +	int (*vidioc_prepare_buf)(struct file *file, void *fh, const struct v4l2_buffer *b);
> >  
> >  	int (*vidioc_overlay) (struct file *file, void *fh, unsigned int i);
> >  	int (*vidioc_g_fbuf)   (struct file *file, void *fh,
> > -- 
> > 1.7.2.5
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-media" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> -- 
> Sakari Ailus
> sakari.ailus@iki.fi
> 

---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply related	[flat|nested] 59+ messages in thread

* Re: [PATCH 3/9 v6] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s
  2011-08-31 21:11   ` Sakari Ailus
@ 2011-09-01  7:10     ` Guennadi Liakhovetski
  2011-09-01 11:08       ` [PATCH 1/1] v4l: Add note on buffer locking to memory and DMA mapping to PREPARE_BUF Sakari Ailus
  0 siblings, 1 reply; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-09-01  7:10 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Linux Media Mailing List, Hans Verkuil, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

On Thu, 1 Sep 2011, Sakari Ailus wrote:

> Hi Guennadi,
> 
> On Wed, Aug 31, 2011 at 08:02:42PM +0200, Guennadi Liakhovetski wrote:
> > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > Cc: Hans Verkuil <hverkuil@xs4all.nl>
> > Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > Cc: Marek Szyprowski <m.szyprowski@samsung.com>
> > Cc: Mauro Carvalho Chehab <mchehab@infradead.org>
> > Cc: Pawel Osciak <pawel@osciak.com>
> > Cc: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
> > ---
> >  Documentation/DocBook/media/v4l/io.xml             |   17 +++
> >  Documentation/DocBook/media/v4l/v4l2.xml           |    2 +
> >  .../DocBook/media/v4l/vidioc-create-bufs.xml       |  147 ++++++++++++++++++++
> >  .../DocBook/media/v4l/vidioc-prepare-buf.xml       |   96 +++++++++++++
> >  4 files changed, 262 insertions(+), 0 deletions(-)
> >  create mode 100644 Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
> >  create mode 100644 Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml

[snip]

> > +  <refsect1>
> > +    <title>Description</title>
> > +
> > +    <para>Applications can optionally call the
> > +<constant>VIDIOC_PREPARE_BUF</constant> ioctl to pass ownership of the buffer
> > +to the driver before actually enqueuing it, using the
> > +<constant>VIDIOC_QBUF</constant> ioctl, and to prepare it for future I/O.
> > +Such preparations may include cache invalidation or cleaning. Performing them
> 
> I think it could be added that the first time when the buffer is prepared,
> the preparation may include very time consuming tasks such as memory
> allocation and iommu mapping of that memory.

Sure, looking forward to your incremental patch.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v6] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-01  7:03     ` Guennadi Liakhovetski
@ 2011-09-01  8:35       ` Laurent Pinchart
  2011-09-01  8:53         ` Guennadi Liakhovetski
  2011-09-01  8:42       ` Sakari Ailus
  1 sibling, 1 reply; 59+ messages in thread
From: Laurent Pinchart @ 2011-09-01  8:35 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Sakari Ailus, Linux Media Mailing List, Hans Verkuil,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

Hi Guennadi,

On Thursday 01 September 2011 09:03:52 Guennadi Liakhovetski wrote:
> On Thu, 1 Sep 2011, Sakari Ailus wrote:
> > On Wed, Aug 31, 2011 at 08:02:41PM +0200, Guennadi Liakhovetski wrote:

[snip]

> > > +
> > > 
> > >  /*
> > >  
> > >   *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
> > >   *
> > > 
> > > @@ -2182,6 +2194,9 @@ struct v4l2_dbg_chip_ident {
> > > 
> > >  #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct
> > >  v4l2_event_subscription) #define	VIDIOC_UNSUBSCRIBE_EVENT _IOW('V',
> > >  91, struct v4l2_event_subscription)
> > > 
> > > +#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct v4l2_create_buffers)
> > > +#define VIDIOC_PREPARE_BUF	 _IOW('V', 93, struct v4l2_buffer)
> > 
> > Does prepare_buf ever do anything that would need to return anything to
> > the user? I guess the answer is "no"?
> 
> Exactly, that's why it's an "_IOW" ioctl(), not an "_IOWR", or have I
> misunderstood you?

This caught my eyes as well. Do you think VIDIOC_PREPARE_BUF could need to 
return information to userspace in the future ?

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v6] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-01  7:03     ` Guennadi Liakhovetski
  2011-09-01  8:35       ` Laurent Pinchart
@ 2011-09-01  8:42       ` Sakari Ailus
  2011-09-01  9:24         ` Guennadi Liakhovetski
  2011-09-08  7:45         ` [PATCH 2/9 v7] " Guennadi Liakhovetski
  1 sibling, 2 replies; 59+ messages in thread
From: Sakari Ailus @ 2011-09-01  8:42 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Linux Media Mailing List, Hans Verkuil, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

On Thu, Sep 01, 2011 at 09:03:52AM +0200, Guennadi Liakhovetski wrote:
> Hi Sakari

Hi Guennadi,

> On Thu, 1 Sep 2011, Sakari Ailus wrote:
[clip]
> > > diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
> > > index fca24cc..988e1be 100644
> > > --- a/include/linux/videodev2.h
> > > +++ b/include/linux/videodev2.h
> > > @@ -653,6 +653,9 @@ struct v4l2_buffer {
> > >  #define V4L2_BUF_FLAG_ERROR	0x0040
> > >  #define V4L2_BUF_FLAG_TIMECODE	0x0100	/* timecode field is valid */
> > >  #define V4L2_BUF_FLAG_INPUT     0x0200  /* input field is valid */
> > > +/* Cache handling flags */
> > > +#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE	0x0400
> > > +#define V4L2_BUF_FLAG_NO_CACHE_CLEAN		0x0800
> > >  
> > >  /*
> > >   *	O V E R L A Y   P R E V I E W
> > > @@ -2092,6 +2095,15 @@ struct v4l2_dbg_chip_ident {
> > >  	__u32 revision;    /* chip revision, chip specific */
> > >  } __attribute__ ((packed));
> > >  
> > > +/* VIDIOC_CREATE_BUFS */
> > > +struct v4l2_create_buffers {
> > > +	__u32			index;		/* output: buffers index...index + count - 1 have been created */
> > > +	__u32			count;
> > > +	enum v4l2_memory        memory;
> > > +	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
> > > +	__u32			reserved[8];
> > > +};
> > 
> > How about splitting the above comments? These lines are really long.
> > Kerneldoc could also be used, I think.
> 
> Sure, how about this incremental patch:
> 
> From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> Subject: V4L: improve struct v4l2_create_buffers documentation
> 
> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> ---
> diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
> index 988e1be..64e0bf2 100644
> --- a/include/linux/videodev2.h
> +++ b/include/linux/videodev2.h
> @@ -2095,12 +2095,20 @@ struct v4l2_dbg_chip_ident {
>  	__u32 revision;    /* chip revision, chip specific */
>  } __attribute__ ((packed));
>  
> -/* VIDIOC_CREATE_BUFS */
> +/**
> + * struct v4l2_create_buffers - VIDIOC_CREATE_BUFS argument
> + * @index:	on return, index of the first created buffer
> + * @count:	entry: number of requested buffers,
> + *		return: number of created buffers
> + * @memory:	buffer memory type
> + * @format:	frame format, for which buffers are requested
> + * @reserved:	future extensions
> + */
>  struct v4l2_create_buffers {
> -	__u32			index;		/* output: buffers index...index + count - 1 have been created */
> +	__u32			index;
>  	__u32			count;
>  	enum v4l2_memory        memory;
> -	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
> +	struct v4l2_format	format;
>  	__u32			reserved[8];
>  };

Thanks! This looks good to me. Could you do a similar change to the
compat-IOCTL version of this struct (v4l2_create_buffers32)?

> > > +
> > >  /*
> > >   *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
> > >   *
> > > @@ -2182,6 +2194,9 @@ struct v4l2_dbg_chip_ident {
> > >  #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct v4l2_event_subscription)
> > >  #define	VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
> > >  
> > > +#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct v4l2_create_buffers)
> > > +#define VIDIOC_PREPARE_BUF	 _IOW('V', 93, struct v4l2_buffer)
> > 
> > Does prepare_buf ever do anything that would need to return anything to the
> > user? I guess the answer is "no"?
> 
> Exactly, that's why it's an "_IOW" ioctl(), not an "_IOWR", or have I 
> misunderstood you?

I was thinking if this will be the case now and in the foreseeable future as
this can't be changed after once defined. I just wanted to bring this up
even though I don't see myself that any of the fields would need to be
returned to the user. But there are reserved fields...

So unless someone comes up with something quick, I think this should stay
as-is.

-- 
Sakari Ailus
sakari.ailus@iki.fi

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v6] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-01  8:35       ` Laurent Pinchart
@ 2011-09-01  8:53         ` Guennadi Liakhovetski
  0 siblings, 0 replies; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-09-01  8:53 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Sakari Ailus, Linux Media Mailing List, Hans Verkuil,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

On Thu, 1 Sep 2011, Laurent Pinchart wrote:

> Hi Guennadi,
> 
> On Thursday 01 September 2011 09:03:52 Guennadi Liakhovetski wrote:
> > On Thu, 1 Sep 2011, Sakari Ailus wrote:
> > > On Wed, Aug 31, 2011 at 08:02:41PM +0200, Guennadi Liakhovetski wrote:
> 
> [snip]
> 
> > > > +
> > > > 
> > > >  /*
> > > >  
> > > >   *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
> > > >   *
> > > > 
> > > > @@ -2182,6 +2194,9 @@ struct v4l2_dbg_chip_ident {
> > > > 
> > > >  #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct
> > > >  v4l2_event_subscription) #define	VIDIOC_UNSUBSCRIBE_EVENT _IOW('V',
> > > >  91, struct v4l2_event_subscription)
> > > > 
> > > > +#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct v4l2_create_buffers)
> > > > +#define VIDIOC_PREPARE_BUF	 _IOW('V', 93, struct v4l2_buffer)
> > > 
> > > Does prepare_buf ever do anything that would need to return anything to
> > > the user? I guess the answer is "no"?
> > 
> > Exactly, that's why it's an "_IOW" ioctl(), not an "_IOWR", or have I
> > misunderstood you?
> 
> This caught my eyes as well. Do you think VIDIOC_PREPARE_BUF could need to 
> return information to userspace in the future ?

Let's see: "[PATCH 2/9 v6]," it has been an "_IOW" since v1, posted on 
01.04 - exactly 5 months ago, when it was still called SUBMIT_BUF. So, 
IIRC, since then noone has come up with even a doubt, that this might need 
to change in the future (until today), let alone an example, what might 
need to be given back.

But sure, I cannot look into the future, so, I'm all ears.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v6] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-01  8:42       ` Sakari Ailus
@ 2011-09-01  9:24         ` Guennadi Liakhovetski
  2011-09-01 10:19           ` Sakari Ailus
  2011-09-08  7:45         ` [PATCH 2/9 v7] " Guennadi Liakhovetski
  1 sibling, 1 reply; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-09-01  9:24 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Linux Media Mailing List, Hans Verkuil, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

On Thu, 1 Sep 2011, Sakari Ailus wrote:

> On Thu, Sep 01, 2011 at 09:03:52AM +0200, Guennadi Liakhovetski wrote:
> > Hi Sakari
> 
> Hi Guennadi,
> 
> > On Thu, 1 Sep 2011, Sakari Ailus wrote:
> [clip]
> > > > diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
> > > > index fca24cc..988e1be 100644
> > > > --- a/include/linux/videodev2.h
> > > > +++ b/include/linux/videodev2.h
> > > > @@ -653,6 +653,9 @@ struct v4l2_buffer {
> > > >  #define V4L2_BUF_FLAG_ERROR	0x0040
> > > >  #define V4L2_BUF_FLAG_TIMECODE	0x0100	/* timecode field is valid */
> > > >  #define V4L2_BUF_FLAG_INPUT     0x0200  /* input field is valid */
> > > > +/* Cache handling flags */
> > > > +#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE	0x0400
> > > > +#define V4L2_BUF_FLAG_NO_CACHE_CLEAN		0x0800
> > > >  
> > > >  /*
> > > >   *	O V E R L A Y   P R E V I E W
> > > > @@ -2092,6 +2095,15 @@ struct v4l2_dbg_chip_ident {
> > > >  	__u32 revision;    /* chip revision, chip specific */
> > > >  } __attribute__ ((packed));
> > > >  
> > > > +/* VIDIOC_CREATE_BUFS */
> > > > +struct v4l2_create_buffers {
> > > > +	__u32			index;		/* output: buffers index...index + count - 1 have been created */
> > > > +	__u32			count;
> > > > +	enum v4l2_memory        memory;
> > > > +	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
> > > > +	__u32			reserved[8];
> > > > +};
> > > 
> > > How about splitting the above comments? These lines are really long.
> > > Kerneldoc could also be used, I think.
> > 
> > Sure, how about this incremental patch:
> > 
> > From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > Subject: V4L: improve struct v4l2_create_buffers documentation
> > 
> > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > ---
> > diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
> > index 988e1be..64e0bf2 100644
> > --- a/include/linux/videodev2.h
> > +++ b/include/linux/videodev2.h
> > @@ -2095,12 +2095,20 @@ struct v4l2_dbg_chip_ident {
> >  	__u32 revision;    /* chip revision, chip specific */
> >  } __attribute__ ((packed));
> >  
> > -/* VIDIOC_CREATE_BUFS */
> > +/**
> > + * struct v4l2_create_buffers - VIDIOC_CREATE_BUFS argument
> > + * @index:	on return, index of the first created buffer
> > + * @count:	entry: number of requested buffers,
> > + *		return: number of created buffers
> > + * @memory:	buffer memory type
> > + * @format:	frame format, for which buffers are requested
> > + * @reserved:	future extensions
> > + */
> >  struct v4l2_create_buffers {
> > -	__u32			index;		/* output: buffers index...index + count - 1 have been created */
> > +	__u32			index;
> >  	__u32			count;
> >  	enum v4l2_memory        memory;
> > -	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
> > +	struct v4l2_format	format;
> >  	__u32			reserved[8];
> >  };
> 
> Thanks! This looks good to me. Could you do a similar change to the
> compat-IOCTL version of this struct (v4l2_create_buffers32)?

Of course, I'll submit an incremental patch as soon as this is accepted 
for upstream, unless there are other important changes to this patch and a 
new revision is anyway unavoidable.

> 
> > > > +
> > > >  /*
> > > >   *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
> > > >   *
> > > > @@ -2182,6 +2194,9 @@ struct v4l2_dbg_chip_ident {
> > > >  #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct v4l2_event_subscription)
> > > >  #define	VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
> > > >  
> > > > +#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct v4l2_create_buffers)
> > > > +#define VIDIOC_PREPARE_BUF	 _IOW('V', 93, struct v4l2_buffer)
> > > 
> > > Does prepare_buf ever do anything that would need to return anything to the
> > > user? I guess the answer is "no"?
> > 
> > Exactly, that's why it's an "_IOW" ioctl(), not an "_IOWR", or have I 
> > misunderstood you?
> 
> I was thinking if this will be the case now and in the foreseeable future as
> this can't be changed after once defined. I just wanted to bring this up
> even though I don't see myself that any of the fields would need to be
> returned to the user. But there are reserved fields...
> 
> So unless someone comes up with something quick, I think this should stay
> as-is.

Agree. I understand, it is important to try to design the user-space API 
as clever as possible, so, I'm relying on our combined wisdom for it. But 
even that is probably limited, so, mistakes are still possible. Therefore, 
unless someone comes up with a realistic reason, why this has to be _IOWR, 
we shall keep it _IOW and be prepared to delight our user-space colleagues 
with more shiny new ioctl()s in the somewhat near future;-)

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v6] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-01  9:24         ` Guennadi Liakhovetski
@ 2011-09-01 10:19           ` Sakari Ailus
  2011-09-01 10:51             ` Guennadi Liakhovetski
  0 siblings, 1 reply; 59+ messages in thread
From: Sakari Ailus @ 2011-09-01 10:19 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Sakari Ailus, Linux Media Mailing List, Hans Verkuil,
	Laurent Pinchart, Pawel Osciak, Mauro Carvalho Chehab,
	Marek Szyprowski

Guennadi Liakhovetski wrote:
> On Thu, 1 Sep 2011, Sakari Ailus wrote:
> 
>> On Thu, Sep 01, 2011 at 09:03:52AM +0200, Guennadi Liakhovetski wrote:
>>> Hi Sakari
>>
>> Hi Guennadi,
>>
>>> On Thu, 1 Sep 2011, Sakari Ailus wrote:
>> [clip]
>>>>> diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
>>>>> index fca24cc..988e1be 100644
>>>>> --- a/include/linux/videodev2.h
>>>>> +++ b/include/linux/videodev2.h
>>>>> @@ -653,6 +653,9 @@ struct v4l2_buffer {
>>>>>  #define V4L2_BUF_FLAG_ERROR	0x0040
>>>>>  #define V4L2_BUF_FLAG_TIMECODE	0x0100	/* timecode field is valid */
>>>>>  #define V4L2_BUF_FLAG_INPUT     0x0200  /* input field is valid */
>>>>> +/* Cache handling flags */
>>>>> +#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE	0x0400
>>>>> +#define V4L2_BUF_FLAG_NO_CACHE_CLEAN		0x0800
>>>>>  
>>>>>  /*
>>>>>   *	O V E R L A Y   P R E V I E W
>>>>> @@ -2092,6 +2095,15 @@ struct v4l2_dbg_chip_ident {
>>>>>  	__u32 revision;    /* chip revision, chip specific */
>>>>>  } __attribute__ ((packed));
>>>>>  
>>>>> +/* VIDIOC_CREATE_BUFS */
>>>>> +struct v4l2_create_buffers {
>>>>> +	__u32			index;		/* output: buffers index...index + count - 1 have been created */
>>>>> +	__u32			count;
>>>>> +	enum v4l2_memory        memory;
>>>>> +	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
>>>>> +	__u32			reserved[8];
>>>>> +};
>>>>
>>>> How about splitting the above comments? These lines are really long.
>>>> Kerneldoc could also be used, I think.
>>>
>>> Sure, how about this incremental patch:
>>>
>>> From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
>>> Subject: V4L: improve struct v4l2_create_buffers documentation
>>>
>>> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
>>> ---
>>> diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
>>> index 988e1be..64e0bf2 100644
>>> --- a/include/linux/videodev2.h
>>> +++ b/include/linux/videodev2.h
>>> @@ -2095,12 +2095,20 @@ struct v4l2_dbg_chip_ident {
>>>  	__u32 revision;    /* chip revision, chip specific */
>>>  } __attribute__ ((packed));
>>>  
>>> -/* VIDIOC_CREATE_BUFS */
>>> +/**
>>> + * struct v4l2_create_buffers - VIDIOC_CREATE_BUFS argument
>>> + * @index:	on return, index of the first created buffer
>>> + * @count:	entry: number of requested buffers,
>>> + *		return: number of created buffers
>>> + * @memory:	buffer memory type
>>> + * @format:	frame format, for which buffers are requested
>>> + * @reserved:	future extensions
>>> + */
>>>  struct v4l2_create_buffers {
>>> -	__u32			index;		/* output: buffers index...index + count - 1 have been created */
>>> +	__u32			index;
>>>  	__u32			count;
>>>  	enum v4l2_memory        memory;
>>> -	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
>>> +	struct v4l2_format	format;
>>>  	__u32			reserved[8];
>>>  };
>>
>> Thanks! This looks good to me. Could you do a similar change to the
>> compat-IOCTL version of this struct (v4l2_create_buffers32)?
> 
> Of course, I'll submit an incremental patch as soon as this is accepted 
> for upstream, unless there are other important changes to this patch and a 
> new revision is anyway unavoidable.

Ok. I'll send a small patch to the documentation as well then.

>>>>> +
>>>>>  /*
>>>>>   *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
>>>>>   *
>>>>> @@ -2182,6 +2194,9 @@ struct v4l2_dbg_chip_ident {
>>>>>  #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct v4l2_event_subscription)
>>>>>  #define	VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
>>>>>  
>>>>> +#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct v4l2_create_buffers)
>>>>> +#define VIDIOC_PREPARE_BUF	 _IOW('V', 93, struct v4l2_buffer)
>>>>
>>>> Does prepare_buf ever do anything that would need to return anything to the
>>>> user? I guess the answer is "no"?
>>>
>>> Exactly, that's why it's an "_IOW" ioctl(), not an "_IOWR", or have I 
>>> misunderstood you?
>>
>> I was thinking if this will be the case now and in the foreseeable future as
>> this can't be changed after once defined. I just wanted to bring this up
>> even though I don't see myself that any of the fields would need to be
>> returned to the user. But there are reserved fields...
>>
>> So unless someone comes up with something quick, I think this should stay
>> as-is.
> 
> Agree. I understand, it is important to try to design the user-space API 
> as clever as possible, so, I'm relying on our combined wisdom for it. But 
> even that is probably limited, so, mistakes are still possible. Therefore, 
> unless someone comes up with a realistic reason, why this has to be _IOWR, 
> we shall keep it _IOW and be prepared to delight our user-space colleagues 
> with more shiny new ioctl()s in the somewhat near future;-)

What we could also do is to mark the new IOCTLs experimental, and remove
the note after one or two more kernel releases. This would allow
postponing the decision.

We also don't have anyone using these ioctls from user space as far as I
understand, so we might get important input later on as well.

Cheers,

-- 
Sakari Ailus
sakari.ailus@maxwell.research.nokia.com

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v6] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-01 10:19           ` Sakari Ailus
@ 2011-09-01 10:51             ` Guennadi Liakhovetski
  2011-09-01 11:06               ` Sakari Ailus
  0 siblings, 1 reply; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-09-01 10:51 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Sakari Ailus, Linux Media Mailing List, Hans Verkuil,
	Laurent Pinchart, Pawel Osciak, Mauro Carvalho Chehab,
	Marek Szyprowski

On Thu, 1 Sep 2011, Sakari Ailus wrote:

> Guennadi Liakhovetski wrote:
> > On Thu, 1 Sep 2011, Sakari Ailus wrote:
> > 
> >> On Thu, Sep 01, 2011 at 09:03:52AM +0200, Guennadi Liakhovetski wrote:
> >>> Hi Sakari
> >>
> >> Hi Guennadi,
> >>
> >>> On Thu, 1 Sep 2011, Sakari Ailus wrote:
> >> [clip]
> >>>>> diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
> >>>>> index fca24cc..988e1be 100644
> >>>>> --- a/include/linux/videodev2.h
> >>>>> +++ b/include/linux/videodev2.h
> >>>>> @@ -653,6 +653,9 @@ struct v4l2_buffer {
> >>>>>  #define V4L2_BUF_FLAG_ERROR	0x0040
> >>>>>  #define V4L2_BUF_FLAG_TIMECODE	0x0100	/* timecode field is valid */
> >>>>>  #define V4L2_BUF_FLAG_INPUT     0x0200  /* input field is valid */
> >>>>> +/* Cache handling flags */
> >>>>> +#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE	0x0400
> >>>>> +#define V4L2_BUF_FLAG_NO_CACHE_CLEAN		0x0800
> >>>>>  
> >>>>>  /*
> >>>>>   *	O V E R L A Y   P R E V I E W
> >>>>> @@ -2092,6 +2095,15 @@ struct v4l2_dbg_chip_ident {
> >>>>>  	__u32 revision;    /* chip revision, chip specific */
> >>>>>  } __attribute__ ((packed));
> >>>>>  
> >>>>> +/* VIDIOC_CREATE_BUFS */
> >>>>> +struct v4l2_create_buffers {
> >>>>> +	__u32			index;		/* output: buffers index...index + count - 1 have been created */
> >>>>> +	__u32			count;
> >>>>> +	enum v4l2_memory        memory;
> >>>>> +	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
> >>>>> +	__u32			reserved[8];
> >>>>> +};
> >>>>
> >>>> How about splitting the above comments? These lines are really long.
> >>>> Kerneldoc could also be used, I think.
> >>>
> >>> Sure, how about this incremental patch:
> >>>
> >>> From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> >>> Subject: V4L: improve struct v4l2_create_buffers documentation
> >>>
> >>> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> >>> ---
> >>> diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
> >>> index 988e1be..64e0bf2 100644
> >>> --- a/include/linux/videodev2.h
> >>> +++ b/include/linux/videodev2.h
> >>> @@ -2095,12 +2095,20 @@ struct v4l2_dbg_chip_ident {
> >>>  	__u32 revision;    /* chip revision, chip specific */
> >>>  } __attribute__ ((packed));
> >>>  
> >>> -/* VIDIOC_CREATE_BUFS */
> >>> +/**
> >>> + * struct v4l2_create_buffers - VIDIOC_CREATE_BUFS argument
> >>> + * @index:	on return, index of the first created buffer
> >>> + * @count:	entry: number of requested buffers,
> >>> + *		return: number of created buffers
> >>> + * @memory:	buffer memory type
> >>> + * @format:	frame format, for which buffers are requested
> >>> + * @reserved:	future extensions
> >>> + */
> >>>  struct v4l2_create_buffers {
> >>> -	__u32			index;		/* output: buffers index...index + count - 1 have been created */
> >>> +	__u32			index;
> >>>  	__u32			count;
> >>>  	enum v4l2_memory        memory;
> >>> -	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
> >>> +	struct v4l2_format	format;
> >>>  	__u32			reserved[8];
> >>>  };
> >>
> >> Thanks! This looks good to me. Could you do a similar change to the
> >> compat-IOCTL version of this struct (v4l2_create_buffers32)?
> > 
> > Of course, I'll submit an incremental patch as soon as this is accepted 
> > for upstream, unless there are other important changes to this patch and a 
> > new revision is anyway unavoidable.
> 
> Ok. I'll send a small patch to the documentation as well then.

Good, thanks!

> >>>>> +
> >>>>>  /*
> >>>>>   *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
> >>>>>   *
> >>>>> @@ -2182,6 +2194,9 @@ struct v4l2_dbg_chip_ident {
> >>>>>  #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct v4l2_event_subscription)
> >>>>>  #define	VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
> >>>>>  
> >>>>> +#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct v4l2_create_buffers)
> >>>>> +#define VIDIOC_PREPARE_BUF	 _IOW('V', 93, struct v4l2_buffer)
> >>>>
> >>>> Does prepare_buf ever do anything that would need to return anything to the
> >>>> user? I guess the answer is "no"?
> >>>
> >>> Exactly, that's why it's an "_IOW" ioctl(), not an "_IOWR", or have I 
> >>> misunderstood you?
> >>
> >> I was thinking if this will be the case now and in the foreseeable future as
> >> this can't be changed after once defined. I just wanted to bring this up
> >> even though I don't see myself that any of the fields would need to be
> >> returned to the user. But there are reserved fields...
> >>
> >> So unless someone comes up with something quick, I think this should stay
> >> as-is.
> > 
> > Agree. I understand, it is important to try to design the user-space API 
> > as clever as possible, so, I'm relying on our combined wisdom for it. But 
> > even that is probably limited, so, mistakes are still possible. Therefore, 
> > unless someone comes up with a realistic reason, why this has to be _IOWR, 
> > we shall keep it _IOW and be prepared to delight our user-space colleagues 
> > with more shiny new ioctl()s in the somewhat near future;-)
> 
> What we could also do is to mark the new IOCTLs experimental, and remove
> the note after one or two more kernel releases. This would allow
> postponing the decision.

Is there a standard way to do this, or is it just a free-form note in the 
documentation / in the header?

> We also don't have anyone using these ioctls from user space as far as I
> understand, so we might get important input later on as well.

Does either of these allow us to actually _change_ ioctl()s after their 
appearance in the mainline?

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v6] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-01 10:51             ` Guennadi Liakhovetski
@ 2011-09-01 11:06               ` Sakari Ailus
  2011-09-01 13:35                 ` Laurent Pinchart
  0 siblings, 1 reply; 59+ messages in thread
From: Sakari Ailus @ 2011-09-01 11:06 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Sakari Ailus, Linux Media Mailing List, Hans Verkuil,
	Laurent Pinchart, Pawel Osciak, Mauro Carvalho Chehab,
	Marek Szyprowski

On Thu, Sep 01, 2011 at 12:51:58PM +0200, Guennadi Liakhovetski wrote:
> On Thu, 1 Sep 2011, Sakari Ailus wrote:
> 
> > Guennadi Liakhovetski wrote:
> > > On Thu, 1 Sep 2011, Sakari Ailus wrote:
> > > 
> > >> On Thu, Sep 01, 2011 at 09:03:52AM +0200, Guennadi Liakhovetski wrote:
> > >>> Hi Sakari
> > >>
> > >> Hi Guennadi,
> > >>
> > >>> On Thu, 1 Sep 2011, Sakari Ailus wrote:
> > >> [clip]
> > >>>>> diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
> > >>>>> index fca24cc..988e1be 100644
> > >>>>> --- a/include/linux/videodev2.h
> > >>>>> +++ b/include/linux/videodev2.h
> > >>>>> @@ -653,6 +653,9 @@ struct v4l2_buffer {
> > >>>>>  #define V4L2_BUF_FLAG_ERROR	0x0040
> > >>>>>  #define V4L2_BUF_FLAG_TIMECODE	0x0100	/* timecode field is valid */
> > >>>>>  #define V4L2_BUF_FLAG_INPUT     0x0200  /* input field is valid */
> > >>>>> +/* Cache handling flags */
> > >>>>> +#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE	0x0400
> > >>>>> +#define V4L2_BUF_FLAG_NO_CACHE_CLEAN		0x0800
> > >>>>>  
> > >>>>>  /*
> > >>>>>   *	O V E R L A Y   P R E V I E W
> > >>>>> @@ -2092,6 +2095,15 @@ struct v4l2_dbg_chip_ident {
> > >>>>>  	__u32 revision;    /* chip revision, chip specific */
> > >>>>>  } __attribute__ ((packed));
> > >>>>>  
> > >>>>> +/* VIDIOC_CREATE_BUFS */
> > >>>>> +struct v4l2_create_buffers {
> > >>>>> +	__u32			index;		/* output: buffers index...index + count - 1 have been created */
> > >>>>> +	__u32			count;
> > >>>>> +	enum v4l2_memory        memory;
> > >>>>> +	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
> > >>>>> +	__u32			reserved[8];
> > >>>>> +};
> > >>>>
> > >>>> How about splitting the above comments? These lines are really long.
> > >>>> Kerneldoc could also be used, I think.
> > >>>
> > >>> Sure, how about this incremental patch:
> > >>>
> > >>> From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > >>> Subject: V4L: improve struct v4l2_create_buffers documentation
> > >>>
> > >>> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > >>> ---
> > >>> diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
> > >>> index 988e1be..64e0bf2 100644
> > >>> --- a/include/linux/videodev2.h
> > >>> +++ b/include/linux/videodev2.h
> > >>> @@ -2095,12 +2095,20 @@ struct v4l2_dbg_chip_ident {
> > >>>  	__u32 revision;    /* chip revision, chip specific */
> > >>>  } __attribute__ ((packed));
> > >>>  
> > >>> -/* VIDIOC_CREATE_BUFS */
> > >>> +/**
> > >>> + * struct v4l2_create_buffers - VIDIOC_CREATE_BUFS argument
> > >>> + * @index:	on return, index of the first created buffer
> > >>> + * @count:	entry: number of requested buffers,
> > >>> + *		return: number of created buffers
> > >>> + * @memory:	buffer memory type
> > >>> + * @format:	frame format, for which buffers are requested
> > >>> + * @reserved:	future extensions
> > >>> + */
> > >>>  struct v4l2_create_buffers {
> > >>> -	__u32			index;		/* output: buffers index...index + count - 1 have been created */
> > >>> +	__u32			index;
> > >>>  	__u32			count;
> > >>>  	enum v4l2_memory        memory;
> > >>> -	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
> > >>> +	struct v4l2_format	format;
> > >>>  	__u32			reserved[8];
> > >>>  };
> > >>
> > >> Thanks! This looks good to me. Could you do a similar change to the
> > >> compat-IOCTL version of this struct (v4l2_create_buffers32)?
> > > 
> > > Of course, I'll submit an incremental patch as soon as this is accepted 
> > > for upstream, unless there are other important changes to this patch and a 
> > > new revision is anyway unavoidable.
> > 
> > Ok. I'll send a small patch to the documentation as well then.
> 
> Good, thanks!
> 
> > >>>>> +
> > >>>>>  /*
> > >>>>>   *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
> > >>>>>   *
> > >>>>> @@ -2182,6 +2194,9 @@ struct v4l2_dbg_chip_ident {
> > >>>>>  #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct v4l2_event_subscription)
> > >>>>>  #define	VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
> > >>>>>  
> > >>>>> +#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct v4l2_create_buffers)
> > >>>>> +#define VIDIOC_PREPARE_BUF	 _IOW('V', 93, struct v4l2_buffer)
> > >>>>
> > >>>> Does prepare_buf ever do anything that would need to return anything to the
> > >>>> user? I guess the answer is "no"?
> > >>>
> > >>> Exactly, that's why it's an "_IOW" ioctl(), not an "_IOWR", or have I 
> > >>> misunderstood you?
> > >>
> > >> I was thinking if this will be the case now and in the foreseeable future as
> > >> this can't be changed after once defined. I just wanted to bring this up
> > >> even though I don't see myself that any of the fields would need to be
> > >> returned to the user. But there are reserved fields...
> > >>
> > >> So unless someone comes up with something quick, I think this should stay
> > >> as-is.
> > > 
> > > Agree. I understand, it is important to try to design the user-space API 
> > > as clever as possible, so, I'm relying on our combined wisdom for it. But 
> > > even that is probably limited, so, mistakes are still possible. Therefore, 
> > > unless someone comes up with a realistic reason, why this has to be _IOWR, 
> > > we shall keep it _IOW and be prepared to delight our user-space colleagues 
> > > with more shiny new ioctl()s in the somewhat near future;-)
> > 
> > What we could also do is to mark the new IOCTLs experimental, and remove
> > the note after one or two more kernel releases. This would allow
> > postponing the decision.
> 
> Is there a standard way to do this, or is it just a free-form note in the 
> documentation / in the header?

I think a free form note saying this out loud in a visible place should be
enough. A note should also be added to
Documentation/DocBook/media/v4l/compat.xml to the section "Experimental API
Elements".

Speaking of this, we seem to have quite a few of these that probably
shouldn't be experimental anymore, such as VIDIOC_ENUM_FRAMESIZES.
Interestingly enough, VIDIOC_ENUM_FRAMEINTERVALS no longer is experimental.
I think I'll send a patch for this.

<URL:http://hverkuil.home.xs4all.nl/spec/media.html#vidioc-enum-framesizes>

> > We also don't have anyone using these ioctls from user space as far as I
> > understand, so we might get important input later on as well.
> 
> Does either of these allow us to actually _change_ ioctl()s after their 
> appearance in the mainline?

That's my understanding, but of course someone could just say "no" when we
try to do that. I think that if something is marked experimental at least
the argument that it can't be changed is a little bit moot since the users
have been notified of this beforehand.

There are a few examples of this. At least the V4L2 subdev and MC interfaces
are marked experimental. However, we haven't actually tried to use that to
make changes which might break user space since we haven't got a need to.

Hans, Laurent: do you have an opinion on this?

-- 
Sakari Ailus
sakari.ailus@iki.fi

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH 1/1] v4l: Add note on buffer locking to memory and DMA mapping to PREPARE_BUF
  2011-09-01  7:10     ` Guennadi Liakhovetski
@ 2011-09-01 11:08       ` Sakari Ailus
  2011-09-28 20:20         ` Sakari Ailus
  0 siblings, 1 reply; 59+ messages in thread
From: Sakari Ailus @ 2011-09-01 11:08 UTC (permalink / raw)
  To: g.liakhovetski
  Cc: linux-media, hverkuil, laurent.pinchart, pawel, mchehab, m.szyprowski

Add note to documentation of VIDIOC_PREPARE_BUF that the preparation done by
the IOCTL may include locking buffers to system memory and creating DMA
mappings for them.

Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
---
 .../DocBook/media/v4l/vidioc-prepare-buf.xml       |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
index 509e752..7177c2f 100644
--- a/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
@@ -52,9 +52,11 @@
 <constant>VIDIOC_PREPARE_BUF</constant> ioctl to pass ownership of the buffer
 to the driver before actually enqueuing it, using the
 <constant>VIDIOC_QBUF</constant> ioctl, and to prepare it for future I/O.
-Such preparations may include cache invalidation or cleaning. Performing them
-in advance saves time during the actual I/O. In case such cache operations are
-not required, the application can use one of
+Such preparations may include locking the buffer to system memory and
+creating DMA mapping for it (on the first time
+<constant>VIDIOC_PREPARE_BUF</constant> is called), cache invalidation or
+cleaning. Performing them in advance saves time during the actual I/O. In
+case such cache operations are not required, the application can use one of
 <constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant> and
 <constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant> flags to skip the respective
 step.</para>
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v6] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-01 11:06               ` Sakari Ailus
@ 2011-09-01 13:35                 ` Laurent Pinchart
  2011-09-01 13:45                   ` Guennadi Liakhovetski
  0 siblings, 1 reply; 59+ messages in thread
From: Laurent Pinchart @ 2011-09-01 13:35 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Guennadi Liakhovetski, Sakari Ailus, Linux Media Mailing List,
	Hans Verkuil, Pawel Osciak, Mauro Carvalho Chehab,
	Marek Szyprowski

Hi Sakari,

On Thursday 01 September 2011 13:06:12 Sakari Ailus wrote:
> On Thu, Sep 01, 2011 at 12:51:58PM +0200, Guennadi Liakhovetski wrote:
> > On Thu, 1 Sep 2011, Sakari Ailus wrote:
> > > Guennadi Liakhovetski wrote:
> > > > On Thu, 1 Sep 2011, Sakari Ailus wrote:
> > > >> On Thu, Sep 01, 2011 at 09:03:52AM +0200, Guennadi Liakhovetski 
wrote:
> > > >>> Hi Sakari
> > > >> 
> > > >> Hi Guennadi,
> > > >> 
> > > >>> On Thu, 1 Sep 2011, Sakari Ailus wrote:
> > > >> [clip]
> > > >> 
> > > >>>>> diff --git a/include/linux/videodev2.h
> > > >>>>> b/include/linux/videodev2.h index fca24cc..988e1be 100644
> > > >>>>> --- a/include/linux/videodev2.h
> > > >>>>> +++ b/include/linux/videodev2.h
> > > >>>>> @@ -653,6 +653,9 @@ struct v4l2_buffer {
> > > >>>>> 
> > > >>>>>  #define V4L2_BUF_FLAG_ERROR	0x0040
> > > >>>>>  #define V4L2_BUF_FLAG_TIMECODE	0x0100	/* timecode field is valid
> > > >>>>>  */ #define V4L2_BUF_FLAG_INPUT     0x0200  /* input field is
> > > >>>>>  valid */
> > > >>>>> 
> > > >>>>> +/* Cache handling flags */
> > > >>>>> +#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE	0x0400
> > > >>>>> +#define V4L2_BUF_FLAG_NO_CACHE_CLEAN		0x0800
> > > >>>>> 
> > > >>>>>  /*
> > > >>>>>  
> > > >>>>>   *	O V E R L A Y   P R E V I E W
> > > >>>>> 
> > > >>>>> @@ -2092,6 +2095,15 @@ struct v4l2_dbg_chip_ident {
> > > >>>>> 
> > > >>>>>  	__u32 revision;    /* chip revision, chip specific */
> > > >>>>>  
> > > >>>>>  } __attribute__ ((packed));
> > > >>>>> 
> > > >>>>> +/* VIDIOC_CREATE_BUFS */
> > > >>>>> +struct v4l2_create_buffers {
> > > >>>>> +	__u32			index;		/* output: buffers index...index + count 
- 1
> > > >>>>> have been created */ +	__u32			count;
> > > >>>>> +	enum v4l2_memory        memory;
> > > >>>>> +	struct v4l2_format	format;		/* "type" is used always, the 
rest
> > > >>>>> if sizeimage == 0 */ +	__u32			reserved[8];
> > > >>>>> +};
> > > >>>> 
> > > >>>> How about splitting the above comments? These lines are really
> > > >>>> long. Kerneldoc could also be used, I think.
> > > >>> 
> > > >>> Sure, how about this incremental patch:
> > > >>> 
> > > >>> From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > > >>> Subject: V4L: improve struct v4l2_create_buffers documentation
> > > >>> 
> > > >>> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > > >>> ---
> > > >>> diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
> > > >>> index 988e1be..64e0bf2 100644
> > > >>> --- a/include/linux/videodev2.h
> > > >>> +++ b/include/linux/videodev2.h
> > > >>> @@ -2095,12 +2095,20 @@ struct v4l2_dbg_chip_ident {
> > > >>> 
> > > >>>  	__u32 revision;    /* chip revision, chip specific */
> > > >>>  
> > > >>>  } __attribute__ ((packed));
> > > >>> 
> > > >>> -/* VIDIOC_CREATE_BUFS */
> > > >>> +/**
> > > >>> + * struct v4l2_create_buffers - VIDIOC_CREATE_BUFS argument
> > > >>> + * @index:	on return, index of the first created buffer
> > > >>> + * @count:	entry: number of requested buffers,
> > > >>> + *		return: number of created buffers
> > > >>> + * @memory:	buffer memory type
> > > >>> + * @format:	frame format, for which buffers are requested
> > > >>> + * @reserved:	future extensions
> > > >>> + */
> > > >>> 
> > > >>>  struct v4l2_create_buffers {
> > > >>> 
> > > >>> -	__u32			index;		/* output: buffers index...index + count - 1 
have
> > > >>> been created */ +	__u32			index;
> > > >>> 
> > > >>>  	__u32			count;
> > > >>>  	enum v4l2_memory        memory;
> > > >>> 
> > > >>> -	struct v4l2_format	format;		/* "type" is used always, the 
rest if
> > > >>> sizeimage == 0 */ +	struct v4l2_format	format;
> > > >>> 
> > > >>>  	__u32			reserved[8];
> > > >>>  
> > > >>>  };
> > > >> 
> > > >> Thanks! This looks good to me. Could you do a similar change to the
> > > >> compat-IOCTL version of this struct (v4l2_create_buffers32)?
> > > > 
> > > > Of course, I'll submit an incremental patch as soon as this is
> > > > accepted for upstream, unless there are other important changes to
> > > > this patch and a new revision is anyway unavoidable.
> > > 
> > > Ok. I'll send a small patch to the documentation as well then.
> > 
> > Good, thanks!
> > 
> > > >>>>> +
> > > >>>>> 
> > > >>>>>  /*
> > > >>>>>  
> > > >>>>>   *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
> > > >>>>>   *
> > > >>>>> 
> > > >>>>> @@ -2182,6 +2194,9 @@ struct v4l2_dbg_chip_ident {
> > > >>>>> 
> > > >>>>>  #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct
> > > >>>>>  v4l2_event_subscription) #define	VIDIOC_UNSUBSCRIBE_EVENT
> > > >>>>>  _IOW('V', 91, struct v4l2_event_subscription)
> > > >>>>> 
> > > >>>>> +#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct
> > > >>>>> v4l2_create_buffers) +#define VIDIOC_PREPARE_BUF	 _IOW('V', 93,
> > > >>>>> struct v4l2_buffer)
> > > >>>> 
> > > >>>> Does prepare_buf ever do anything that would need to return
> > > >>>> anything to the user? I guess the answer is "no"?
> > > >>> 
> > > >>> Exactly, that's why it's an "_IOW" ioctl(), not an "_IOWR", or have
> > > >>> I misunderstood you?
> > > >> 
> > > >> I was thinking if this will be the case now and in the foreseeable
> > > >> future as this can't be changed after once defined. I just wanted
> > > >> to bring this up even though I don't see myself that any of the
> > > >> fields would need to be returned to the user. But there are
> > > >> reserved fields...
> > > >> 
> > > >> So unless someone comes up with something quick, I think this should
> > > >> stay as-is.
> > > > 
> > > > Agree. I understand, it is important to try to design the user-space
> > > > API as clever as possible, so, I'm relying on our combined wisdom
> > > > for it. But even that is probably limited, so, mistakes are still
> > > > possible. Therefore, unless someone comes up with a realistic
> > > > reason, why this has to be _IOWR, we shall keep it _IOW and be
> > > > prepared to delight our user-space colleagues with more shiny new
> > > > ioctl()s in the somewhat near future;-)
> > > 
> > > What we could also do is to mark the new IOCTLs experimental, and
> > > remove the note after one or two more kernel releases. This would
> > > allow postponing the decision.
> > 
> > Is there a standard way to do this, or is it just a free-form note in the
> > documentation / in the header?
> 
> I think a free form note saying this out loud in a visible place should be
> enough. A note should also be added to
> Documentation/DocBook/media/v4l/compat.xml to the section "Experimental API
> Elements".
> 
> Speaking of this, we seem to have quite a few of these that probably
> shouldn't be experimental anymore, such as VIDIOC_ENUM_FRAMESIZES.
> Interestingly enough, VIDIOC_ENUM_FRAMEINTERVALS no longer is experimental.
> I think I'll send a patch for this.
> 
> <URL:http://hverkuil.home.xs4all.nl/spec/media.html#vidioc-enum-framesizes>
> 
> > > We also don't have anyone using these ioctls from user space as far as
> > > I understand, so we might get important input later on as well.
> > 
> > Does either of these allow us to actually _change_ ioctl()s after their
> > appearance in the mainline?
> 
> That's my understanding, but of course someone could just say "no" when we
> try to do that. I think that if something is marked experimental at least
> the argument that it can't be changed is a little bit moot since the users
> have been notified of this beforehand.
> 
> There are a few examples of this. At least the V4L2 subdev and MC
> interfaces are marked experimental. However, we haven't actually tried to
> use that to make changes which might break user space since we haven't got
> a need to.
> 
> Hans, Laurent: do you have an opinion on this?

We should of course try to keep the API and ABI compatible across kernel 
versions, but experimental APIs can be changed. It also depends on how widely 
the API has been picked up by userspace and how much the changes would break 
it. Being experimental isn't an excuse for making userspace's life a 
nightmare.

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v6] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-01 13:35                 ` Laurent Pinchart
@ 2011-09-01 13:45                   ` Guennadi Liakhovetski
  0 siblings, 0 replies; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-09-01 13:45 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Sakari Ailus, Sakari Ailus, Linux Media Mailing List,
	Hans Verkuil, Pawel Osciak, Mauro Carvalho Chehab,
	Marek Szyprowski

On Thu, 1 Sep 2011, Laurent Pinchart wrote:

> Hi Sakari,
> 
> On Thursday 01 September 2011 13:06:12 Sakari Ailus wrote:

[snip]

> > That's my understanding, but of course someone could just say "no" when we
> > try to do that. I think that if something is marked experimental at least
> > the argument that it can't be changed is a little bit moot since the users
> > have been notified of this beforehand.
> > 
> > There are a few examples of this. At least the V4L2 subdev and MC
> > interfaces are marked experimental. However, we haven't actually tried to
> > use that to make changes which might break user space since we haven't got
> > a need to.
> > 
> > Hans, Laurent: do you have an opinion on this?
> 
> We should of course try to keep the API and ABI compatible across kernel 
> versions, but experimental APIs can be changed. It also depends on how widely 
> the API has been picked up by userspace and how much the changes would break 
> it. Being experimental isn't an excuse for making userspace's life a 
> nightmare.

Right, they deserve it regardless;-)

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH 2/9 v7] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-01  8:42       ` Sakari Ailus
  2011-09-01  9:24         ` Guennadi Liakhovetski
@ 2011-09-08  7:45         ` Guennadi Liakhovetski
  2011-09-08  7:46           ` [PATCH 3/9 v7] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s Guennadi Liakhovetski
                             ` (3 more replies)
  1 sibling, 4 replies; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-09-08  7:45 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Linux Media Mailing List, Hans Verkuil, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

A possibility to preallocate and initialise buffers of different sizes
in V4L2 is required for an efficient implementation of a snapshot
mode. This patch adds two new ioctl()s: VIDIOC_CREATE_BUFS and
VIDIOC_PREPARE_BUF and defines respective data structures.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v7: added the "experimental" comment, as suggested by Sakari - thanks.

 drivers/media/video/v4l2-compat-ioctl32.c |   67 +++++++++++++++++++++++++---
 drivers/media/video/v4l2-ioctl.c          |   29 ++++++++++++
 include/linux/videodev2.h                 |   17 +++++++
 include/media/v4l2-ioctl.h                |    2 +
 4 files changed, 107 insertions(+), 8 deletions(-)

diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
index 61979b7..85758d2 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -159,11 +159,16 @@ struct v4l2_format32 {
 	} fmt;
 };
 
-static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+struct v4l2_create_buffers32 {
+	__u32			index;		/* output: buffers index...index + count - 1 have been created */
+	__u32			count;
+	enum v4l2_memory        memory;
+	struct v4l2_format32	format;		/* filled in by the user, plane sizes calculated by the driver */
+	__u32			reserved[8];
+};
+
+static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
 {
-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
-			get_user(kp->type, &up->type))
-			return -EFAULT;
 	switch (kp->type) {
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
@@ -192,11 +197,24 @@ static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
 	}
 }
 
-static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+{
+	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
+			get_user(kp->type, &up->type))
+			return -EFAULT;
+	return __get_v4l2_format32(kp, up);
+}
+
+static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
+{
+	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)) ||
+	    copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format.fmt)))
+			return -EFAULT;
+	return __get_v4l2_format32(&kp->format, &up->format);
+}
+
+static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
 {
-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
-		put_user(kp->type, &up->type))
-		return -EFAULT;
 	switch (kp->type) {
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
@@ -225,6 +243,22 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
 	}
 }
 
+static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+{
+	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
+		put_user(kp->type, &up->type))
+		return -EFAULT;
+	return __put_v4l2_format32(kp, up);
+}
+
+static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
+{
+	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_create_buffers32)) ||
+	    copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format.fmt)))
+			return -EFAULT;
+	return __put_v4l2_format32(&kp->format, &up->format);
+}
+
 struct v4l2_standard32 {
 	__u32		     index;
 	__u32		     id[2]; /* __u64 would get the alignment wrong */
@@ -702,6 +736,8 @@ static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *u
 #define VIDIOC_S_EXT_CTRLS32    _IOWR('V', 72, struct v4l2_ext_controls32)
 #define VIDIOC_TRY_EXT_CTRLS32  _IOWR('V', 73, struct v4l2_ext_controls32)
 #define	VIDIOC_DQEVENT32	_IOR ('V', 89, struct v4l2_event32)
+#define VIDIOC_CREATE_BUFS32	_IOWR('V', 92, struct v4l2_create_buffers32)
+#define VIDIOC_PREPARE_BUF32	_IOW ('V', 93, struct v4l2_buffer32)
 
 #define VIDIOC_OVERLAY32	_IOW ('V', 14, s32)
 #define VIDIOC_STREAMON32	_IOW ('V', 18, s32)
@@ -721,6 +757,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
 		struct v4l2_standard v2s;
 		struct v4l2_ext_controls v2ecs;
 		struct v4l2_event v2ev;
+		struct v4l2_create_buffers v2crt;
 		unsigned long vx;
 		int vi;
 	} karg;
@@ -751,6 +788,8 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
 	case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break;
 	case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break;
 	case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break;
+	case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break;
+	case VIDIOC_PREPARE_BUF32: cmd = VIDIOC_PREPARE_BUF; break;
 	}
 
 	switch (cmd) {
@@ -775,6 +814,12 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
 		compatible_arg = 0;
 		break;
 
+	case VIDIOC_CREATE_BUFS:
+		err = get_v4l2_create32(&karg.v2crt, up);
+		compatible_arg = 0;
+		break;
+
+	case VIDIOC_PREPARE_BUF:
 	case VIDIOC_QUERYBUF:
 	case VIDIOC_QBUF:
 	case VIDIOC_DQBUF:
@@ -860,6 +905,10 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
 		err = put_v4l2_format32(&karg.v2f, up);
 		break;
 
+	case VIDIOC_CREATE_BUFS:
+		err = put_v4l2_create32(&karg.v2crt, up);
+		break;
+
 	case VIDIOC_QUERYBUF:
 	case VIDIOC_QBUF:
 	case VIDIOC_DQBUF:
@@ -959,6 +1008,8 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
 	case VIDIOC_DQEVENT32:
 	case VIDIOC_SUBSCRIBE_EVENT:
 	case VIDIOC_UNSUBSCRIBE_EVENT:
+	case VIDIOC_CREATE_BUFS32:
+	case VIDIOC_PREPARE_BUF32:
 		ret = do_video_ioctl(file, cmd, arg);
 		break;
 
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 21c49dc..3c2295b 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -273,6 +273,8 @@ static const char *v4l2_ioctls[] = {
 	[_IOC_NR(VIDIOC_DQEVENT)]	   = "VIDIOC_DQEVENT",
 	[_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)]  = "VIDIOC_SUBSCRIBE_EVENT",
 	[_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT",
+	[_IOC_NR(VIDIOC_CREATE_BUFS)]      = "VIDIOC_CREATE_BUFS",
+	[_IOC_NR(VIDIOC_PREPARE_BUF)]      = "VIDIOC_PREPARE_BUF",
 };
 #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
 
@@ -2096,6 +2098,33 @@ static long __video_do_ioctl(struct file *file,
 		dbgarg(cmd, "type=0x%8.8x", sub->type);
 		break;
 	}
+	case VIDIOC_CREATE_BUFS:
+	{
+		struct v4l2_create_buffers *create = arg;
+
+		if (!ops->vidioc_create_bufs)
+			break;
+		ret = check_fmt(ops, create->format.type);
+		if (ret)
+			break;
+
+		ret = ops->vidioc_create_bufs(file, fh, create);
+
+		dbgarg(cmd, "count=%d @ %d\n", create->count, create->index);
+		break;
+	}
+	case VIDIOC_PREPARE_BUF:
+	{
+		struct v4l2_buffer *b = arg;
+
+		if (!ops->vidioc_prepare_buf)
+			break;
+
+		ret = ops->vidioc_prepare_buf(file, fh, b);
+
+		dbgarg(cmd, "index=%d", b->index);
+		break;
+	}
 	default:
 		if (!ops->vidioc_default)
 			break;
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index a5359c6..6e87ea9 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -653,6 +653,9 @@ struct v4l2_buffer {
 #define V4L2_BUF_FLAG_ERROR	0x0040
 #define V4L2_BUF_FLAG_TIMECODE	0x0100	/* timecode field is valid */
 #define V4L2_BUF_FLAG_INPUT     0x0200  /* input field is valid */
+/* Cache handling flags */
+#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE	0x0400
+#define V4L2_BUF_FLAG_NO_CACHE_CLEAN		0x0800
 
 /*
  *	O V E R L A Y   P R E V I E W
@@ -2098,6 +2101,15 @@ struct v4l2_dbg_chip_ident {
 	__u32 revision;    /* chip revision, chip specific */
 } __attribute__ ((packed));
 
+/* VIDIOC_CREATE_BUFS */
+struct v4l2_create_buffers {
+	__u32			index;		/* output: buffers index...index + count - 1 have been created */
+	__u32			count;
+	enum v4l2_memory        memory;
+	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
+	__u32			reserved[8];
+};
+
 /*
  *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
  *
@@ -2188,6 +2200,11 @@ struct v4l2_dbg_chip_ident {
 #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct v4l2_event_subscription)
 #define	VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
 
+/* Experimental, the below two ioctls may change over the next couple of kernel
+   versions */
+#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct v4l2_create_buffers)
+#define VIDIOC_PREPARE_BUF	 _IOW('V', 93, struct v4l2_buffer)
+
 /* Reminder: when adding new ioctls please add support for them to
    drivers/media/video/v4l2-compat-ioctl32.c as well! */
 
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index dd9f1e7..55cf8ae 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -122,6 +122,8 @@ struct v4l2_ioctl_ops {
 	int (*vidioc_qbuf)    (struct file *file, void *fh, struct v4l2_buffer *b);
 	int (*vidioc_dqbuf)   (struct file *file, void *fh, struct v4l2_buffer *b);
 
+	int (*vidioc_create_bufs)(struct file *file, void *fh, struct v4l2_create_buffers *b);
+	int (*vidioc_prepare_buf)(struct file *file, void *fh, const struct v4l2_buffer *b);
 
 	int (*vidioc_overlay) (struct file *file, void *fh, unsigned int i);
 	int (*vidioc_g_fbuf)   (struct file *file, void *fh,
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 3/9 v7] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s
  2011-09-08  7:45         ` [PATCH 2/9 v7] " Guennadi Liakhovetski
@ 2011-09-08  7:46           ` Guennadi Liakhovetski
  2011-09-09 13:24             ` Laurent Pinchart
  2011-09-27 10:51             ` Hans Verkuil
  2011-09-08  7:48           ` [PATCH] V4L: docbook documentation for struct v4l2_create_buffers Guennadi Liakhovetski
                             ` (2 subsequent siblings)
  3 siblings, 2 replies; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-09-08  7:46 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Linux Media Mailing List, Hans Verkuil, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v7: added to the experimental list in compat.xml

 Documentation/DocBook/media/v4l/compat.xml         |    3 +
 Documentation/DocBook/media/v4l/io.xml             |   17 +++
 Documentation/DocBook/media/v4l/v4l2.xml           |    2 +
 .../DocBook/media/v4l/vidioc-create-bufs.xml       |  147 ++++++++++++++++++++
 .../DocBook/media/v4l/vidioc-prepare-buf.xml       |   96 +++++++++++++
 5 files changed, 265 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
 create mode 100644 Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml

diff --git a/Documentation/DocBook/media/v4l/compat.xml b/Documentation/DocBook/media/v4l/compat.xml
index ce1004a..91f8977 100644
--- a/Documentation/DocBook/media/v4l/compat.xml
+++ b/Documentation/DocBook/media/v4l/compat.xml
@@ -2478,6 +2478,9 @@ ioctls.</para>
         <listitem>
 	  <para>Flash API. <xref linkend="flash-controls" /></para>
         </listitem>
+        <listitem>
+	  <para>&VIDIOC-CREATE-BUFS; and &VIDIOC-PREPARE-BUF; ioctls.</para>
+        </listitem>
       </itemizedlist>
     </section>
 
diff --git a/Documentation/DocBook/media/v4l/io.xml b/Documentation/DocBook/media/v4l/io.xml
index c57d1ec..74ead1e 100644
--- a/Documentation/DocBook/media/v4l/io.xml
+++ b/Documentation/DocBook/media/v4l/io.xml
@@ -927,6 +927,23 @@ ioctl is called.</entry>
 Applications set or clear this flag before calling the
 <constant>VIDIOC_QBUF</constant> ioctl.</entry>
 	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant></entry>
+	    <entry>0x0400</entry>
+	    <entry>Caches do not have to be invalidated for this buffer.
+Typically applications shall use this flag if the data captured in the buffer
+is not going to be touched by the CPU, instead the buffer will, probably, be
+passed on to a DMA-capable hardware unit for further processing or output.
+</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant></entry>
+	    <entry>0x0800</entry>
+	    <entry>Caches do not have to be cleaned for this buffer.
+Typically applications shall use this flag for output buffers if the data
+in this buffer has not been created by the CPU but by some DMA-capable unit,
+in which case caches have not been used.</entry>
+	  </row>
 	</tbody>
       </tgroup>
     </table>
diff --git a/Documentation/DocBook/media/v4l/v4l2.xml b/Documentation/DocBook/media/v4l/v4l2.xml
index 0d05e87..06bb179 100644
--- a/Documentation/DocBook/media/v4l/v4l2.xml
+++ b/Documentation/DocBook/media/v4l/v4l2.xml
@@ -462,6 +462,7 @@ and discussions on the V4L mailing list.</revremark>
     &sub-close;
     &sub-ioctl;
     <!-- All ioctls go here. -->
+    &sub-create-bufs;
     &sub-cropcap;
     &sub-dbg-g-chip-ident;
     &sub-dbg-g-register;
@@ -504,6 +505,7 @@ and discussions on the V4L mailing list.</revremark>
     &sub-queryctrl;
     &sub-query-dv-preset;
     &sub-querystd;
+    &sub-prepare-buf;
     &sub-reqbufs;
     &sub-s-hw-freq-seek;
     &sub-streamon;
diff --git a/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
new file mode 100644
index 0000000..eb99604
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
@@ -0,0 +1,147 @@
+<refentry id="vidioc-create-bufs">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_CREATE_BUFS</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_CREATE_BUFS</refname>
+    <refpurpose>Create buffers for Memory Mapped or User Pointer I/O</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_create_buffers *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_CREATE_BUFS</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>This ioctl is used to create buffers for <link linkend="mmap">memory
+mapped</link> or <link linkend="userp">user pointer</link>
+I/O. It can be used as an alternative or in addition to the
+<constant>VIDIOC_REQBUFS</constant> ioctl, when a tighter control over buffers
+is required. This ioctl can be called multiple times to create buffers of
+different sizes.</para>
+
+    <para>To allocate device buffers applications initialize relevant fields of
+the <structname>v4l2_create_buffers</structname> structure. They set the
+<structfield>type</structfield> field in the
+<structname>v4l2_format</structname> structure, embedded in this
+structure, to the respective stream or buffer type.
+<structfield>count</structfield> must be set to the number of required buffers.
+<structfield>memory</structfield> specifies the required I/O method. The
+<structfield>format</structfield> field shall typically be filled in using
+either the <constant>VIDIOC_TRY_FMT</constant> or
+<constant>VIDIOC_G_FMT</constant> ioctl(). Additionally, applications can adjust
+<structfield>sizeimage</structfield> fields to fit their specific needs. The
+<structfield>reserved</structfield> array must be zeroed.</para>
+
+    <para>When the ioctl is called with a pointer to this structure the driver
+will attempt to allocate up to the requested number of buffers and store the
+actual number allocated and the starting index in the
+<structfield>count</structfield> and the <structfield>index</structfield> fields
+respectively. On return <structfield>count</structfield> can be smaller than
+the number requested. The driver may also adjust buffer sizes as it sees fit,
+however, it will not update <structfield>sizeimage</structfield> fields, the
+user has to use <constant>VIDIOC_QUERYBUF</constant> to retrieve that
+information.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-create-buffers">
+      <title>struct <structname>v4l2_create_buffers</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>index</structfield></entry>
+	    <entry>The starting buffer index, returned by the driver.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>count</structfield></entry>
+	    <entry>The number of buffers requested or granted.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-memory;</entry>
+	    <entry><structfield>memory</structfield></entry>
+	    <entry>Applications set this field to
+<constant>V4L2_MEMORY_MMAP</constant> or
+<constant>V4L2_MEMORY_USERPTR</constant>.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-format;</entry>
+	    <entry><structfield>format</structfield></entry>
+	    <entry>Filled in by the application, preserved by the driver.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[8]</entry>
+	    <entry>A place holder for future extensions.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>ENOMEM</errorcode></term>
+	<listitem>
+	  <para>No memory to allocate buffers for <link linkend="mmap">memory
+mapped</link> I/O.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The buffer type (<structfield>type</structfield> field) or the
+requested I/O method (<structfield>memory</structfield>) is not
+supported.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
new file mode 100644
index 0000000..509e752
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
@@ -0,0 +1,96 @@
+<refentry id="vidioc-prepare-buf">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_PREPARE_BUF</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_PREPARE_BUF</refname>
+    <refpurpose>Prepare a buffer for I/O</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_buffer *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_PREPARE_BUF</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>Applications can optionally call the
+<constant>VIDIOC_PREPARE_BUF</constant> ioctl to pass ownership of the buffer
+to the driver before actually enqueuing it, using the
+<constant>VIDIOC_QBUF</constant> ioctl, and to prepare it for future I/O.
+Such preparations may include cache invalidation or cleaning. Performing them
+in advance saves time during the actual I/O. In case such cache operations are
+not required, the application can use one of
+<constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant> and
+<constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant> flags to skip the respective
+step.</para>
+
+    <para>The <structname>v4l2_buffer</structname> structure is
+specified in <xref linkend="buffer" />.</para>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>File I/O is in progress.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The buffer <structfield>type</structfield> is not
+supported, or the <structfield>index</structfield> is out of bounds,
+or no buffers have been allocated yet, or the
+<structfield>userptr</structfield> or
+<structfield>length</structfield> are invalid.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH] V4L: docbook documentation for struct v4l2_create_buffers
  2011-09-08  7:45         ` [PATCH 2/9 v7] " Guennadi Liakhovetski
  2011-09-08  7:46           ` [PATCH 3/9 v7] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s Guennadi Liakhovetski
@ 2011-09-08  7:48           ` Guennadi Liakhovetski
  2011-09-08  8:10           ` [PATCH 1/1] v4l: Mark VIDIOC_PREPARE_BUFS and VIDIOC_CREATE_BUFS experimental Sakari Ailus
  2011-09-27 10:34           ` [PATCH 2/9 v7] V4L: add two new ioctl()s for multi-size videobuffer management Hans Verkuil
  3 siblings, 0 replies; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-09-08  7:48 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Linux Media Mailing List, Hans Verkuil, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

Obviously, this goes on top of the "multi-size buffers" patch series. 
Thanks again to Sakari for the idea.

 drivers/media/video/v4l2-compat-ioctl32.c |   13 +++++++++++--
 include/linux/videodev2.h                 |   14 +++++++++++---
 2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
index 85758d2..b1064a1 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -159,11 +159,20 @@ struct v4l2_format32 {
 	} fmt;
 };
 
+/**
+ * struct v4l2_create_buffers32 - VIDIOC_CREATE_BUFS32 argument
+ * @index:	on return, index of the first created buffer
+ * @count:	entry: number of requested buffers,
+ *		return: number of created buffers
+ * @memory:	buffer memory type
+ * @format:	frame format, for which buffers are requested
+ * @reserved:	future extensions
+ */
 struct v4l2_create_buffers32 {
-	__u32			index;		/* output: buffers index...index + count - 1 have been created */
+	__u32			index;
 	__u32			count;
 	enum v4l2_memory        memory;
-	struct v4l2_format32	format;		/* filled in by the user, plane sizes calculated by the driver */
+	struct v4l2_format32	format;
 	__u32			reserved[8];
 };
 
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 66a9e53..84852c1 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -2102,12 +2102,20 @@ struct v4l2_dbg_chip_ident {
 	__u32 revision;    /* chip revision, chip specific */
 } __attribute__ ((packed));
 
-/* VIDIOC_CREATE_BUFS */
+/**
+ * struct v4l2_create_buffers - VIDIOC_CREATE_BUFS argument
+ * @index:	on return, index of the first created buffer
+ * @count:	entry: number of requested buffers,
+ *		return: number of created buffers
+ * @memory:	buffer memory type
+ * @format:	frame format, for which buffers are requested
+ * @reserved:	future extensions
+ */
 struct v4l2_create_buffers {
-	__u32			index;		/* output: buffers index...index + count - 1 have been created */
+	__u32			index;
 	__u32			count;
 	enum v4l2_memory        memory;
-	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
+	struct v4l2_format	format;
 	__u32			reserved[8];
 };
 
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 1/1] v4l: Mark VIDIOC_PREPARE_BUFS and VIDIOC_CREATE_BUFS experimental.
  2011-09-08  7:45         ` [PATCH 2/9 v7] " Guennadi Liakhovetski
  2011-09-08  7:46           ` [PATCH 3/9 v7] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s Guennadi Liakhovetski
  2011-09-08  7:48           ` [PATCH] V4L: docbook documentation for struct v4l2_create_buffers Guennadi Liakhovetski
@ 2011-09-08  8:10           ` Sakari Ailus
  2011-09-27 10:34           ` [PATCH 2/9 v7] V4L: add two new ioctl()s for multi-size videobuffer management Hans Verkuil
  3 siblings, 0 replies; 59+ messages in thread
From: Sakari Ailus @ 2011-09-08  8:10 UTC (permalink / raw)
  To: linux-media
  Cc: g.liakhovetski, hverkuil, laurent.pinchart, pawel, mchehab, m.szyprowski

Add a note to documentation of both VIDIOC_PREPARE_BUFS and
VIDIOC_CREATE_BUFS that these ioctls are experimental.

Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
---

I think it would be even better to add the note to the ioctls themselves.
The users are not going to be looking at the list of experimental features
when then want to implement something.

 .../DocBook/media/v4l/vidioc-create-bufs.xml       |    9 +++++++++
 .../DocBook/media/v4l/vidioc-prepare-buf.xml       |    9 +++++++++
 2 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
index eb99604..d43e24a 100644
--- a/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
@@ -48,6 +48,15 @@
   <refsect1>
     <title>Description</title>
 
+    <note>
+      <title>Experimental</title>
+
+      <para>
+	This is an <link linkend="experimental">experimental</link>
+	interface and may change in the future.
+      </para>
+    </note>
+
     <para>This ioctl is used to create buffers for <link linkend="mmap">memory
 mapped</link> or <link linkend="userp">user pointer</link>
 I/O. It can be used as an alternative or in addition to the
diff --git a/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
index 509e752..8889c6d 100644
--- a/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
@@ -48,6 +48,15 @@
   <refsect1>
     <title>Description</title>
 
+    <note>
+      <title>Experimental</title>
+
+      <para>
+	This is an <link linkend="experimental">experimental</link>
+	interface and may change in the future.
+      </para>
+    </note>
+
     <para>Applications can optionally call the
 <constant>VIDIOC_PREPARE_BUF</constant> ioctl to pass ownership of the buffer
 to the driver before actually enqueuing it, using the
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* Re: [PATCH 3/9 v7] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s
  2011-09-08  7:46           ` [PATCH 3/9 v7] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s Guennadi Liakhovetski
@ 2011-09-09 13:24             ` Laurent Pinchart
  2011-09-27 10:51             ` Hans Verkuil
  1 sibling, 0 replies; 59+ messages in thread
From: Laurent Pinchart @ 2011-09-09 13:24 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Sakari Ailus, Linux Media Mailing List, Hans Verkuil,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

Hi Guennadi,

Thank you for the patch.

As discussed over jabber, we're suffering from an AB-BA deadlock that this 
patch could make worse.

The mmap code path takes mm->mmap_sem in the kernel' mmap handler before 
calling the driver's mmap handler. The driver will then lock the queue mutex 
before calling vb2_mmap (or let the core lock the vdev mutex).

In the VIDIOC_QBUF code path, the driver will first lock the queue mutex (or 
let the core lock the vdev mutex) and call vb2_qbuf. This will then take mm-
>mmap_sem to call get_user_pages for USERPTR buffers. The two locks are taken 
in different orders depending on the code paths, resulting in a possible AB-BA 
deadlock.

mmap'ing USERPTR buffers doesn't make sense, so application will likely not 
experience any deadlock. However, if VIDIOC_CREATE_BUFS allows mixing MMAP and 
USERPTR buffers, we could suddenly see a rise of deadlock issues resulting 
from valid use cases.

This problem needs to be fixed anyway, as a rogue application can currently 
produce a kernel deadlock. The fix can probably be pretty simple if we decide 
not to support mixing MMAP and USERPTR buffers, but it might become more 
complex if we need to support that.

I'm interested in hearing what others think about this.

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v7] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-08  7:45         ` [PATCH 2/9 v7] " Guennadi Liakhovetski
                             ` (2 preceding siblings ...)
  2011-09-08  8:10           ` [PATCH 1/1] v4l: Mark VIDIOC_PREPARE_BUFS and VIDIOC_CREATE_BUFS experimental Sakari Ailus
@ 2011-09-27 10:34           ` Hans Verkuil
  2011-09-27 11:00             ` Guennadi Liakhovetski
  2011-09-27 17:08             ` [PATCH 2/9 v7] " Laurent Pinchart
  3 siblings, 2 replies; 59+ messages in thread
From: Hans Verkuil @ 2011-09-27 10:34 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Sakari Ailus, Linux Media Mailing List, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

On Thursday, September 08, 2011 09:45:15 Guennadi Liakhovetski wrote:
> A possibility to preallocate and initialise buffers of different sizes
> in V4L2 is required for an efficient implementation of a snapshot
> mode. This patch adds two new ioctl()s: VIDIOC_CREATE_BUFS and
> VIDIOC_PREPARE_BUF and defines respective data structures.
> 
> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> ---
> 
> v7: added the "experimental" comment, as suggested by Sakari - thanks.
> 
>  drivers/media/video/v4l2-compat-ioctl32.c |   67 +++++++++++++++++++++++++---
>  drivers/media/video/v4l2-ioctl.c          |   29 ++++++++++++
>  include/linux/videodev2.h                 |   17 +++++++
>  include/media/v4l2-ioctl.h                |    2 +
>  4 files changed, 107 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
> index 61979b7..85758d2 100644
> --- a/drivers/media/video/v4l2-compat-ioctl32.c
> +++ b/drivers/media/video/v4l2-compat-ioctl32.c
> @@ -159,11 +159,16 @@ struct v4l2_format32 {
>  	} fmt;
>  };
>  
> -static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
> +struct v4l2_create_buffers32 {
> +	__u32			index;		/* output: buffers index...index + count - 1 have been created */
> +	__u32			count;
> +	enum v4l2_memory        memory;
> +	struct v4l2_format32	format;		/* filled in by the user, plane sizes calculated by the driver */
> +	__u32			reserved[8];
> +};
> +
> +static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
>  {
> -	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
> -			get_user(kp->type, &up->type))
> -			return -EFAULT;
>  	switch (kp->type) {
>  	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
>  	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
> @@ -192,11 +197,24 @@ static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
>  	}
>  }
>  
> -static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
> +static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
> +{
> +	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
> +			get_user(kp->type, &up->type))
> +			return -EFAULT;
> +	return __get_v4l2_format32(kp, up);
> +}
> +
> +static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
> +{
> +	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)) ||
> +	    copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format.fmt)))
> +			return -EFAULT;
> +	return __get_v4l2_format32(&kp->format, &up->format);
> +}
> +
> +static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
>  {
> -	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
> -		put_user(kp->type, &up->type))
> -		return -EFAULT;
>  	switch (kp->type) {
>  	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
>  	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
> @@ -225,6 +243,22 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
>  	}
>  }
>  
> +static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
> +{
> +	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
> +		put_user(kp->type, &up->type))
> +		return -EFAULT;
> +	return __put_v4l2_format32(kp, up);
> +}
> +
> +static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
> +{
> +	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_create_buffers32)) ||
> +	    copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format.fmt)))
> +			return -EFAULT;
> +	return __put_v4l2_format32(&kp->format, &up->format);
> +}
> +
>  struct v4l2_standard32 {
>  	__u32		     index;
>  	__u32		     id[2]; /* __u64 would get the alignment wrong */
> @@ -702,6 +736,8 @@ static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *u
>  #define VIDIOC_S_EXT_CTRLS32    _IOWR('V', 72, struct v4l2_ext_controls32)
>  #define VIDIOC_TRY_EXT_CTRLS32  _IOWR('V', 73, struct v4l2_ext_controls32)
>  #define	VIDIOC_DQEVENT32	_IOR ('V', 89, struct v4l2_event32)
> +#define VIDIOC_CREATE_BUFS32	_IOWR('V', 92, struct v4l2_create_buffers32)
> +#define VIDIOC_PREPARE_BUF32	_IOW ('V', 93, struct v4l2_buffer32)
>  
>  #define VIDIOC_OVERLAY32	_IOW ('V', 14, s32)
>  #define VIDIOC_STREAMON32	_IOW ('V', 18, s32)
> @@ -721,6 +757,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
>  		struct v4l2_standard v2s;
>  		struct v4l2_ext_controls v2ecs;
>  		struct v4l2_event v2ev;
> +		struct v4l2_create_buffers v2crt;
>  		unsigned long vx;
>  		int vi;
>  	} karg;
> @@ -751,6 +788,8 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
>  	case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break;
>  	case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break;
>  	case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break;
> +	case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break;
> +	case VIDIOC_PREPARE_BUF32: cmd = VIDIOC_PREPARE_BUF; break;
>  	}
>  
>  	switch (cmd) {
> @@ -775,6 +814,12 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
>  		compatible_arg = 0;
>  		break;
>  
> +	case VIDIOC_CREATE_BUFS:
> +		err = get_v4l2_create32(&karg.v2crt, up);
> +		compatible_arg = 0;
> +		break;
> +
> +	case VIDIOC_PREPARE_BUF:
>  	case VIDIOC_QUERYBUF:
>  	case VIDIOC_QBUF:
>  	case VIDIOC_DQBUF:
> @@ -860,6 +905,10 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
>  		err = put_v4l2_format32(&karg.v2f, up);
>  		break;
>  
> +	case VIDIOC_CREATE_BUFS:
> +		err = put_v4l2_create32(&karg.v2crt, up);
> +		break;
> +
>  	case VIDIOC_QUERYBUF:
>  	case VIDIOC_QBUF:
>  	case VIDIOC_DQBUF:
> @@ -959,6 +1008,8 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
>  	case VIDIOC_DQEVENT32:
>  	case VIDIOC_SUBSCRIBE_EVENT:
>  	case VIDIOC_UNSUBSCRIBE_EVENT:
> +	case VIDIOC_CREATE_BUFS32:
> +	case VIDIOC_PREPARE_BUF32:
>  		ret = do_video_ioctl(file, cmd, arg);
>  		break;
>  
> diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
> index 21c49dc..3c2295b 100644
> --- a/drivers/media/video/v4l2-ioctl.c
> +++ b/drivers/media/video/v4l2-ioctl.c
> @@ -273,6 +273,8 @@ static const char *v4l2_ioctls[] = {
>  	[_IOC_NR(VIDIOC_DQEVENT)]	   = "VIDIOC_DQEVENT",
>  	[_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)]  = "VIDIOC_SUBSCRIBE_EVENT",
>  	[_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT",
> +	[_IOC_NR(VIDIOC_CREATE_BUFS)]      = "VIDIOC_CREATE_BUFS",
> +	[_IOC_NR(VIDIOC_PREPARE_BUF)]      = "VIDIOC_PREPARE_BUF",
>  };
>  #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
>  
> @@ -2096,6 +2098,33 @@ static long __video_do_ioctl(struct file *file,
>  		dbgarg(cmd, "type=0x%8.8x", sub->type);
>  		break;
>  	}
> +	case VIDIOC_CREATE_BUFS:
> +	{
> +		struct v4l2_create_buffers *create = arg;
> +
> +		if (!ops->vidioc_create_bufs)
> +			break;

Just as with REQBUFS you need to add code here to handle priority checking:

		if (ret_prio) {
			ret = ret_prio;
			break;
		}

> +		ret = check_fmt(ops, create->format.type);
> +		if (ret)
> +			break;
> +
> +		ret = ops->vidioc_create_bufs(file, fh, create);
> +
> +		dbgarg(cmd, "count=%d @ %d\n", create->count, create->index);
> +		break;
> +	}
> +	case VIDIOC_PREPARE_BUF:
> +	{
> +		struct v4l2_buffer *b = arg;
> +
> +		if (!ops->vidioc_prepare_buf)
> +			break;

You need a check_fmt call here as well (just as in QBUF et al).

> +		ret = ops->vidioc_prepare_buf(file, fh, b);
> +
> +		dbgarg(cmd, "index=%d", b->index);
> +		break;
> +	}
>  	default:
>  		if (!ops->vidioc_default)
>  			break;
> diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
> index a5359c6..6e87ea9 100644
> --- a/include/linux/videodev2.h
> +++ b/include/linux/videodev2.h
> @@ -653,6 +653,9 @@ struct v4l2_buffer {
>  #define V4L2_BUF_FLAG_ERROR	0x0040
>  #define V4L2_BUF_FLAG_TIMECODE	0x0100	/* timecode field is valid */
>  #define V4L2_BUF_FLAG_INPUT     0x0200  /* input field is valid */
> +/* Cache handling flags */
> +#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE	0x0400
> +#define V4L2_BUF_FLAG_NO_CACHE_CLEAN		0x0800
>  
>  /*
>   *	O V E R L A Y   P R E V I E W
> @@ -2098,6 +2101,15 @@ struct v4l2_dbg_chip_ident {
>  	__u32 revision;    /* chip revision, chip specific */
>  } __attribute__ ((packed));
>  
> +/* VIDIOC_CREATE_BUFS */
> +struct v4l2_create_buffers {
> +	__u32			index;		/* output: buffers index...index + count - 1 have been created */
> +	__u32			count;
> +	enum v4l2_memory        memory;
> +	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
> +	__u32			reserved[8];
> +};
> +
>  /*
>   *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
>   *
> @@ -2188,6 +2200,11 @@ struct v4l2_dbg_chip_ident {
>  #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct v4l2_event_subscription)
>  #define	VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
>  
> +/* Experimental, the below two ioctls may change over the next couple of kernel
> +   versions */
> +#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct v4l2_create_buffers)
> +#define VIDIOC_PREPARE_BUF	 _IOW('V', 93, struct v4l2_buffer)

I think I would prefer _IOWR here. QBUF etc. also use IOWR and you never know
what you might return in the future. At the very least using IOWR allows us
to update the state field, which would be a perfectly reasonable thing to do.

> +
>  /* Reminder: when adding new ioctls please add support for them to
>     drivers/media/video/v4l2-compat-ioctl32.c as well! */
>  
> diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
> index dd9f1e7..55cf8ae 100644
> --- a/include/media/v4l2-ioctl.h
> +++ b/include/media/v4l2-ioctl.h
> @@ -122,6 +122,8 @@ struct v4l2_ioctl_ops {
>  	int (*vidioc_qbuf)    (struct file *file, void *fh, struct v4l2_buffer *b);
>  	int (*vidioc_dqbuf)   (struct file *file, void *fh, struct v4l2_buffer *b);
>  
> +	int (*vidioc_create_bufs)(struct file *file, void *fh, struct v4l2_create_buffers *b);
> +	int (*vidioc_prepare_buf)(struct file *file, void *fh, const struct v4l2_buffer *b);
>  
>  	int (*vidioc_overlay) (struct file *file, void *fh, unsigned int i);
>  	int (*vidioc_g_fbuf)   (struct file *file, void *fh,
> 

Regards,

	Hans

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 3/9 v7] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s
  2011-09-08  7:46           ` [PATCH 3/9 v7] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s Guennadi Liakhovetski
  2011-09-09 13:24             ` Laurent Pinchart
@ 2011-09-27 10:51             ` Hans Verkuil
  2011-09-27 15:49               ` Guennadi Liakhovetski
  2011-09-27 17:01               ` [PATCH 3/9 v8] " Guennadi Liakhovetski
  1 sibling, 2 replies; 59+ messages in thread
From: Hans Verkuil @ 2011-09-27 10:51 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Sakari Ailus, Linux Media Mailing List, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

On Thursday, September 08, 2011 09:46:26 Guennadi Liakhovetski wrote:
> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> ---
> 
> v7: added to the experimental list in compat.xml
> 
>  Documentation/DocBook/media/v4l/compat.xml         |    3 +
>  Documentation/DocBook/media/v4l/io.xml             |   17 +++
>  Documentation/DocBook/media/v4l/v4l2.xml           |    2 +
>  .../DocBook/media/v4l/vidioc-create-bufs.xml       |  147 ++++++++++++++++++++
>  .../DocBook/media/v4l/vidioc-prepare-buf.xml       |   96 +++++++++++++
>  5 files changed, 265 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
>  create mode 100644 Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
> 
> diff --git a/Documentation/DocBook/media/v4l/compat.xml b/Documentation/DocBook/media/v4l/compat.xml
> index ce1004a..91f8977 100644
> --- a/Documentation/DocBook/media/v4l/compat.xml
> +++ b/Documentation/DocBook/media/v4l/compat.xml
> @@ -2478,6 +2478,9 @@ ioctls.</para>
>          <listitem>
>  	  <para>Flash API. <xref linkend="flash-controls" /></para>
>          </listitem>
> +        <listitem>
> +	  <para>&VIDIOC-CREATE-BUFS; and &VIDIOC-PREPARE-BUF; ioctls.</para>
> +        </listitem>
>        </itemizedlist>
>      </section>
>  
> diff --git a/Documentation/DocBook/media/v4l/io.xml b/Documentation/DocBook/media/v4l/io.xml
> index c57d1ec..74ead1e 100644
> --- a/Documentation/DocBook/media/v4l/io.xml
> +++ b/Documentation/DocBook/media/v4l/io.xml
> @@ -927,6 +927,23 @@ ioctl is called.</entry>
>  Applications set or clear this flag before calling the
>  <constant>VIDIOC_QBUF</constant> ioctl.</entry>
>  	  </row>
> +	  <row>
> +	    <entry><constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant></entry>
> +	    <entry>0x0400</entry>
> +	    <entry>Caches do not have to be invalidated for this buffer.
> +Typically applications shall use this flag if the data captured in the buffer
> +is not going to be touched by the CPU, instead the buffer will, probably, be
> +passed on to a DMA-capable hardware unit for further processing or output.
> +</entry>
> +	  </row>
> +	  <row>
> +	    <entry><constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant></entry>
> +	    <entry>0x0800</entry>
> +	    <entry>Caches do not have to be cleaned for this buffer.
> +Typically applications shall use this flag for output buffers if the data
> +in this buffer has not been created by the CPU but by some DMA-capable unit,
> +in which case caches have not been used.</entry>
> +	  </row>
>  	</tbody>
>        </tgroup>
>      </table>
> diff --git a/Documentation/DocBook/media/v4l/v4l2.xml b/Documentation/DocBook/media/v4l/v4l2.xml
> index 0d05e87..06bb179 100644
> --- a/Documentation/DocBook/media/v4l/v4l2.xml
> +++ b/Documentation/DocBook/media/v4l/v4l2.xml
> @@ -462,6 +462,7 @@ and discussions on the V4L mailing list.</revremark>
>      &sub-close;
>      &sub-ioctl;
>      <!-- All ioctls go here. -->
> +    &sub-create-bufs;
>      &sub-cropcap;
>      &sub-dbg-g-chip-ident;
>      &sub-dbg-g-register;
> @@ -504,6 +505,7 @@ and discussions on the V4L mailing list.</revremark>
>      &sub-queryctrl;
>      &sub-query-dv-preset;
>      &sub-querystd;
> +    &sub-prepare-buf;
>      &sub-reqbufs;
>      &sub-s-hw-freq-seek;
>      &sub-streamon;
> diff --git a/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
> new file mode 100644
> index 0000000..eb99604
> --- /dev/null
> +++ b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
> @@ -0,0 +1,147 @@
> +<refentry id="vidioc-create-bufs">
> +  <refmeta>
> +    <refentrytitle>ioctl VIDIOC_CREATE_BUFS</refentrytitle>
> +    &manvol;
> +  </refmeta>
> +
> +  <refnamediv>
> +    <refname>VIDIOC_CREATE_BUFS</refname>
> +    <refpurpose>Create buffers for Memory Mapped or User Pointer I/O</refpurpose>
> +  </refnamediv>
> +
> +  <refsynopsisdiv>
> +    <funcsynopsis>
> +      <funcprototype>
> +	<funcdef>int <function>ioctl</function></funcdef>
> +	<paramdef>int <parameter>fd</parameter></paramdef>
> +	<paramdef>int <parameter>request</parameter></paramdef>
> +	<paramdef>struct v4l2_create_buffers *<parameter>argp</parameter></paramdef>
> +      </funcprototype>
> +    </funcsynopsis>
> +  </refsynopsisdiv>
> +
> +  <refsect1>
> +    <title>Arguments</title>
> +
> +    <variablelist>
> +      <varlistentry>
> +	<term><parameter>fd</parameter></term>
> +	<listitem>
> +	  <para>&fd;</para>
> +	</listitem>
> +      </varlistentry>
> +      <varlistentry>
> +	<term><parameter>request</parameter></term>
> +	<listitem>
> +	  <para>VIDIOC_CREATE_BUFS</para>
> +	</listitem>
> +      </varlistentry>
> +      <varlistentry>
> +	<term><parameter>argp</parameter></term>
> +	<listitem>
> +	  <para></para>
> +	</listitem>
> +      </varlistentry>
> +    </variablelist>
> +  </refsect1>
> +
> +  <refsect1>
> +    <title>Description</title>
> +
> +    <para>This ioctl is used to create buffers for <link linkend="mmap">memory
> +mapped</link> or <link linkend="userp">user pointer</link>
> +I/O. It can be used as an alternative or in addition to the
> +<constant>VIDIOC_REQBUFS</constant> ioctl, when a tighter control over buffers
> +is required. This ioctl can be called multiple times to create buffers of
> +different sizes.</para>
> +
> +    <para>To allocate device buffers applications initialize relevant fields of
> +the <structname>v4l2_create_buffers</structname> structure. They set the
> +<structfield>type</structfield> field in the
> +<structname>v4l2_format</structname> structure, embedded in this
> +structure, to the respective stream or buffer type.
> +<structfield>count</structfield> must be set to the number of required buffers.
> +<structfield>memory</structfield> specifies the required I/O method. The
> +<structfield>format</structfield> field shall typically be filled in using
> +either the <constant>VIDIOC_TRY_FMT</constant> or
> +<constant>VIDIOC_G_FMT</constant> ioctl(). Additionally, applications can adjust
> +<structfield>sizeimage</structfield> fields to fit their specific needs. The
> +<structfield>reserved</structfield> array must be zeroed.</para>
> +
> +    <para>When the ioctl is called with a pointer to this structure the driver
> +will attempt to allocate up to the requested number of buffers and store the
> +actual number allocated and the starting index in the
> +<structfield>count</structfield> and the <structfield>index</structfield> fields
> +respectively. On return <structfield>count</structfield> can be smaller than
> +the number requested. The driver may also adjust buffer sizes as it sees fit,

Add: 'provided the size is greater than or equal to sizeimage'.

That's very important!

Otherwise everything looks fine to me.

Regards,

	Hans

> +however, it will not update <structfield>sizeimage</structfield> fields, the
> +user has to use <constant>VIDIOC_QUERYBUF</constant> to retrieve that
> +information.</para>
> +
> +    <table pgwide="1" frame="none" id="v4l2-create-buffers">
> +      <title>struct <structname>v4l2_create_buffers</structname></title>
> +      <tgroup cols="3">
> +	&cs-str;
> +	<tbody valign="top">
> +	  <row>
> +	    <entry>__u32</entry>
> +	    <entry><structfield>index</structfield></entry>
> +	    <entry>The starting buffer index, returned by the driver.</entry>
> +	  </row>
> +	  <row>
> +	    <entry>__u32</entry>
> +	    <entry><structfield>count</structfield></entry>
> +	    <entry>The number of buffers requested or granted.</entry>
> +	  </row>
> +	  <row>
> +	    <entry>&v4l2-memory;</entry>
> +	    <entry><structfield>memory</structfield></entry>
> +	    <entry>Applications set this field to
> +<constant>V4L2_MEMORY_MMAP</constant> or
> +<constant>V4L2_MEMORY_USERPTR</constant>.</entry>
> +	  </row>
> +	  <row>
> +	    <entry>&v4l2-format;</entry>
> +	    <entry><structfield>format</structfield></entry>
> +	    <entry>Filled in by the application, preserved by the driver.</entry>
> +	  </row>
> +	  <row>
> +	    <entry>__u32</entry>
> +	    <entry><structfield>reserved</structfield>[8]</entry>
> +	    <entry>A place holder for future extensions.</entry>
> +	  </row>
> +	</tbody>
> +      </tgroup>
> +    </table>
> +  </refsect1>
> +
> +  <refsect1>
> +    &return-value;
> +
> +    <variablelist>
> +      <varlistentry>
> +	<term><errorcode>ENOMEM</errorcode></term>
> +	<listitem>
> +	  <para>No memory to allocate buffers for <link linkend="mmap">memory
> +mapped</link> I/O.</para>
> +	</listitem>
> +      </varlistentry>
> +      <varlistentry>
> +	<term><errorcode>EINVAL</errorcode></term>
> +	<listitem>
> +	  <para>The buffer type (<structfield>type</structfield> field) or the
> +requested I/O method (<structfield>memory</structfield>) is not
> +supported.</para>
> +	</listitem>
> +      </varlistentry>
> +    </variablelist>
> +  </refsect1>
> +</refentry>
> +
> +<!--
> +Local Variables:
> +mode: sgml
> +sgml-parent-document: "v4l2.sgml"
> +indent-tabs-mode: nil
> +End:
> +-->
> diff --git a/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
> new file mode 100644
> index 0000000..509e752
> --- /dev/null
> +++ b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
> @@ -0,0 +1,96 @@
> +<refentry id="vidioc-prepare-buf">
> +  <refmeta>
> +    <refentrytitle>ioctl VIDIOC_PREPARE_BUF</refentrytitle>
> +    &manvol;
> +  </refmeta>
> +
> +  <refnamediv>
> +    <refname>VIDIOC_PREPARE_BUF</refname>
> +    <refpurpose>Prepare a buffer for I/O</refpurpose>
> +  </refnamediv>
> +
> +  <refsynopsisdiv>
> +    <funcsynopsis>
> +      <funcprototype>
> +	<funcdef>int <function>ioctl</function></funcdef>
> +	<paramdef>int <parameter>fd</parameter></paramdef>
> +	<paramdef>int <parameter>request</parameter></paramdef>
> +	<paramdef>struct v4l2_buffer *<parameter>argp</parameter></paramdef>
> +      </funcprototype>
> +    </funcsynopsis>
> +  </refsynopsisdiv>
> +
> +  <refsect1>
> +    <title>Arguments</title>
> +
> +    <variablelist>
> +      <varlistentry>
> +	<term><parameter>fd</parameter></term>
> +	<listitem>
> +	  <para>&fd;</para>
> +	</listitem>
> +      </varlistentry>
> +      <varlistentry>
> +	<term><parameter>request</parameter></term>
> +	<listitem>
> +	  <para>VIDIOC_PREPARE_BUF</para>
> +	</listitem>
> +      </varlistentry>
> +      <varlistentry>
> +	<term><parameter>argp</parameter></term>
> +	<listitem>
> +	  <para></para>
> +	</listitem>
> +      </varlistentry>
> +    </variablelist>
> +  </refsect1>
> +
> +  <refsect1>
> +    <title>Description</title>
> +
> +    <para>Applications can optionally call the
> +<constant>VIDIOC_PREPARE_BUF</constant> ioctl to pass ownership of the buffer
> +to the driver before actually enqueuing it, using the
> +<constant>VIDIOC_QBUF</constant> ioctl, and to prepare it for future I/O.
> +Such preparations may include cache invalidation or cleaning. Performing them
> +in advance saves time during the actual I/O. In case such cache operations are
> +not required, the application can use one of
> +<constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant> and
> +<constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant> flags to skip the respective
> +step.</para>
> +
> +    <para>The <structname>v4l2_buffer</structname> structure is
> +specified in <xref linkend="buffer" />.</para>
> +  </refsect1>
> +
> +  <refsect1>
> +    &return-value;
> +
> +    <variablelist>
> +      <varlistentry>
> +	<term><errorcode>EBUSY</errorcode></term>
> +	<listitem>
> +	  <para>File I/O is in progress.</para>
> +	</listitem>
> +      </varlistentry>
> +      <varlistentry>
> +	<term><errorcode>EINVAL</errorcode></term>
> +	<listitem>
> +	  <para>The buffer <structfield>type</structfield> is not
> +supported, or the <structfield>index</structfield> is out of bounds,
> +or no buffers have been allocated yet, or the
> +<structfield>userptr</structfield> or
> +<structfield>length</structfield> are invalid.</para>
> +	</listitem>
> +      </varlistentry>
> +    </variablelist>
> +  </refsect1>
> +</refentry>
> +
> +<!--
> +Local Variables:
> +mode: sgml
> +sgml-parent-document: "v4l2.sgml"
> +indent-tabs-mode: nil
> +End:
> +-->
> 

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v7] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-27 10:34           ` [PATCH 2/9 v7] V4L: add two new ioctl()s for multi-size videobuffer management Hans Verkuil
@ 2011-09-27 11:00             ` Guennadi Liakhovetski
  2011-09-27 11:06               ` Hans Verkuil
  2011-09-27 17:08             ` [PATCH 2/9 v7] " Laurent Pinchart
  1 sibling, 1 reply; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-09-27 11:00 UTC (permalink / raw)
  To: Hans Verkuil
  Cc: Sakari Ailus, Linux Media Mailing List, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

Hi Hans

On Tue, 27 Sep 2011, Hans Verkuil wrote:

> On Thursday, September 08, 2011 09:45:15 Guennadi Liakhovetski wrote:
> > A possibility to preallocate and initialise buffers of different sizes
> > in V4L2 is required for an efficient implementation of a snapshot
> > mode. This patch adds two new ioctl()s: VIDIOC_CREATE_BUFS and
> > VIDIOC_PREPARE_BUF and defines respective data structures.
> > 
> > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > ---
> > 
> > v7: added the "experimental" comment, as suggested by Sakari - thanks.
> > 
> >  drivers/media/video/v4l2-compat-ioctl32.c |   67 +++++++++++++++++++++++++---
> >  drivers/media/video/v4l2-ioctl.c          |   29 ++++++++++++
> >  include/linux/videodev2.h                 |   17 +++++++
> >  include/media/v4l2-ioctl.h                |    2 +
> >  4 files changed, 107 insertions(+), 8 deletions(-)

[snip]

> > diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
> > index a5359c6..6e87ea9 100644
> > --- a/include/linux/videodev2.h
> > +++ b/include/linux/videodev2.h
> > @@ -653,6 +653,9 @@ struct v4l2_buffer {
> >  #define V4L2_BUF_FLAG_ERROR	0x0040
> >  #define V4L2_BUF_FLAG_TIMECODE	0x0100	/* timecode field is valid */
> >  #define V4L2_BUF_FLAG_INPUT     0x0200  /* input field is valid */
> > +/* Cache handling flags */
> > +#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE	0x0400
> > +#define V4L2_BUF_FLAG_NO_CACHE_CLEAN		0x0800
> >  
> >  /*
> >   *	O V E R L A Y   P R E V I E W
> > @@ -2098,6 +2101,15 @@ struct v4l2_dbg_chip_ident {
> >  	__u32 revision;    /* chip revision, chip specific */
> >  } __attribute__ ((packed));
> >  
> > +/* VIDIOC_CREATE_BUFS */
> > +struct v4l2_create_buffers {
> > +	__u32			index;		/* output: buffers index...index + count - 1 have been created */
> > +	__u32			count;
> > +	enum v4l2_memory        memory;
> > +	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
> > +	__u32			reserved[8];
> > +};
> > +
> >  /*
> >   *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
> >   *
> > @@ -2188,6 +2200,11 @@ struct v4l2_dbg_chip_ident {
> >  #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct v4l2_event_subscription)
> >  #define	VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
> >  
> > +/* Experimental, the below two ioctls may change over the next couple of kernel
> > +   versions */
> > +#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct v4l2_create_buffers)
> > +#define VIDIOC_PREPARE_BUF	 _IOW('V', 93, struct v4l2_buffer)
> 
> I think I would prefer _IOWR here. QBUF etc. also use IOWR and you never know
> what you might return in the future. At the very least using IOWR allows us
> to update the state field, which would be a perfectly reasonable thing to do.

Sorry, which state field do you mean? We have already marked these ioctl() 
as experimental, isn't this enough?

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v7] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-27 11:00             ` Guennadi Liakhovetski
@ 2011-09-27 11:06               ` Hans Verkuil
  2011-09-27 12:19                 ` Guennadi Liakhovetski
  0 siblings, 1 reply; 59+ messages in thread
From: Hans Verkuil @ 2011-09-27 11:06 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Sakari Ailus, Linux Media Mailing List, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

On Tuesday, September 27, 2011 13:00:24 Guennadi Liakhovetski wrote:
> Hi Hans
> 
> On Tue, 27 Sep 2011, Hans Verkuil wrote:
> 
> > On Thursday, September 08, 2011 09:45:15 Guennadi Liakhovetski wrote:
> > > A possibility to preallocate and initialise buffers of different sizes
> > > in V4L2 is required for an efficient implementation of a snapshot
> > > mode. This patch adds two new ioctl()s: VIDIOC_CREATE_BUFS and
> > > VIDIOC_PREPARE_BUF and defines respective data structures.
> > > 
> > > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > > ---
> > > 
> > > v7: added the "experimental" comment, as suggested by Sakari - thanks.
> > > 
> > >  drivers/media/video/v4l2-compat-ioctl32.c |   67 +++++++++++++++++++++++++---
> > >  drivers/media/video/v4l2-ioctl.c          |   29 ++++++++++++
> > >  include/linux/videodev2.h                 |   17 +++++++
> > >  include/media/v4l2-ioctl.h                |    2 +
> > >  4 files changed, 107 insertions(+), 8 deletions(-)
> 
> [snip]
> 
> > > diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
> > > index a5359c6..6e87ea9 100644
> > > --- a/include/linux/videodev2.h
> > > +++ b/include/linux/videodev2.h
> > > @@ -653,6 +653,9 @@ struct v4l2_buffer {
> > >  #define V4L2_BUF_FLAG_ERROR	0x0040
> > >  #define V4L2_BUF_FLAG_TIMECODE	0x0100	/* timecode field is valid */
> > >  #define V4L2_BUF_FLAG_INPUT     0x0200  /* input field is valid */
> > > +/* Cache handling flags */
> > > +#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE	0x0400
> > > +#define V4L2_BUF_FLAG_NO_CACHE_CLEAN		0x0800
> > >  
> > >  /*
> > >   *	O V E R L A Y   P R E V I E W
> > > @@ -2098,6 +2101,15 @@ struct v4l2_dbg_chip_ident {
> > >  	__u32 revision;    /* chip revision, chip specific */
> > >  } __attribute__ ((packed));
> > >  
> > > +/* VIDIOC_CREATE_BUFS */
> > > +struct v4l2_create_buffers {
> > > +	__u32			index;		/* output: buffers index...index + count - 1 have been created */
> > > +	__u32			count;
> > > +	enum v4l2_memory        memory;
> > > +	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
> > > +	__u32			reserved[8];
> > > +};
> > > +
> > >  /*
> > >   *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
> > >   *
> > > @@ -2188,6 +2200,11 @@ struct v4l2_dbg_chip_ident {
> > >  #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct v4l2_event_subscription)
> > >  #define	VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
> > >  
> > > +/* Experimental, the below two ioctls may change over the next couple of kernel
> > > +   versions */
> > > +#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct v4l2_create_buffers)
> > > +#define VIDIOC_PREPARE_BUF	 _IOW('V', 93, struct v4l2_buffer)
> > 
> > I think I would prefer _IOWR here. QBUF etc. also use IOWR and you never know
> > what you might return in the future. At the very least using IOWR allows us
> > to update the state field, which would be a perfectly reasonable thing to do.
> 
> Sorry, which state field do you mean? We have already marked these ioctl() 
> as experimental, isn't this enough?

The state field in the v4l2_buffer argument.

The experimental tag allows for changes, that's true. So this is my proposed
change :-)

Regards,

	Hans

> 
> Thanks
> Guennadi
> ---
> Guennadi Liakhovetski, Ph.D.
> Freelance Open-Source Software Developer
> http://www.open-technology.de/
> 

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v7] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-27 11:06               ` Hans Verkuil
@ 2011-09-27 12:19                 ` Guennadi Liakhovetski
  2011-09-27 13:40                   ` Hans Verkuil
  0 siblings, 1 reply; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-09-27 12:19 UTC (permalink / raw)
  To: Hans Verkuil
  Cc: Sakari Ailus, Linux Media Mailing List, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

On Tue, 27 Sep 2011, Hans Verkuil wrote:

> On Tuesday, September 27, 2011 13:00:24 Guennadi Liakhovetski wrote:
> > Hi Hans
> > 
> > On Tue, 27 Sep 2011, Hans Verkuil wrote:
> > 
> > > On Thursday, September 08, 2011 09:45:15 Guennadi Liakhovetski wrote:
> > > > A possibility to preallocate and initialise buffers of different sizes
> > > > in V4L2 is required for an efficient implementation of a snapshot
> > > > mode. This patch adds two new ioctl()s: VIDIOC_CREATE_BUFS and
> > > > VIDIOC_PREPARE_BUF and defines respective data structures.
> > > > 
> > > > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > > > ---
> > > > 
> > > > v7: added the "experimental" comment, as suggested by Sakari - thanks.
> > > > 
> > > >  drivers/media/video/v4l2-compat-ioctl32.c |   67 +++++++++++++++++++++++++---
> > > >  drivers/media/video/v4l2-ioctl.c          |   29 ++++++++++++
> > > >  include/linux/videodev2.h                 |   17 +++++++
> > > >  include/media/v4l2-ioctl.h                |    2 +
> > > >  4 files changed, 107 insertions(+), 8 deletions(-)
> > 
> > [snip]
> > 
> > > > diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
> > > > index a5359c6..6e87ea9 100644
> > > > --- a/include/linux/videodev2.h
> > > > +++ b/include/linux/videodev2.h
> > > > @@ -653,6 +653,9 @@ struct v4l2_buffer {
> > > >  #define V4L2_BUF_FLAG_ERROR	0x0040
> > > >  #define V4L2_BUF_FLAG_TIMECODE	0x0100	/* timecode field is valid */
> > > >  #define V4L2_BUF_FLAG_INPUT     0x0200  /* input field is valid */
> > > > +/* Cache handling flags */
> > > > +#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE	0x0400
> > > > +#define V4L2_BUF_FLAG_NO_CACHE_CLEAN		0x0800
> > > >  
> > > >  /*
> > > >   *	O V E R L A Y   P R E V I E W
> > > > @@ -2098,6 +2101,15 @@ struct v4l2_dbg_chip_ident {
> > > >  	__u32 revision;    /* chip revision, chip specific */
> > > >  } __attribute__ ((packed));
> > > >  
> > > > +/* VIDIOC_CREATE_BUFS */
> > > > +struct v4l2_create_buffers {
> > > > +	__u32			index;		/* output: buffers index...index + count - 1 have been created */
> > > > +	__u32			count;
> > > > +	enum v4l2_memory        memory;
> > > > +	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
> > > > +	__u32			reserved[8];
> > > > +};
> > > > +
> > > >  /*
> > > >   *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
> > > >   *
> > > > @@ -2188,6 +2200,11 @@ struct v4l2_dbg_chip_ident {
> > > >  #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct v4l2_event_subscription)
> > > >  #define	VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
> > > >  
> > > > +/* Experimental, the below two ioctls may change over the next couple of kernel
> > > > +   versions */
> > > > +#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct v4l2_create_buffers)
> > > > +#define VIDIOC_PREPARE_BUF	 _IOW('V', 93, struct v4l2_buffer)
> > > 
> > > I think I would prefer _IOWR here. QBUF etc. also use IOWR and you never know
> > > what you might return in the future. At the very least using IOWR allows us
> > > to update the state field, which would be a perfectly reasonable thing to do.
> > 
> > Sorry, which state field do you mean? We have already marked these ioctl() 
> > as experimental, isn't this enough?
> 
> The state field in the v4l2_buffer argument.

Is this a new field? I seem to remember some discussion to replace one of 
existing unused fields in a user-exposed struct (ioctl() argument) with a 
different one. Is this what you're referring to? Can you point me out to 
the patch?

> The experimental tag allows for changes, that's true. So this is my proposed
> change :-)

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v7] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-27 12:19                 ` Guennadi Liakhovetski
@ 2011-09-27 13:40                   ` Hans Verkuil
  2011-09-27 16:54                     ` [PATCH 2/9 v8] " Guennadi Liakhovetski
  0 siblings, 1 reply; 59+ messages in thread
From: Hans Verkuil @ 2011-09-27 13:40 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Sakari Ailus, Linux Media Mailing List, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

On Tuesday, September 27, 2011 14:19:54 Guennadi Liakhovetski wrote:
> On Tue, 27 Sep 2011, Hans Verkuil wrote:
> 
> > On Tuesday, September 27, 2011 13:00:24 Guennadi Liakhovetski wrote:
> > > Hi Hans
> > > 
> > > On Tue, 27 Sep 2011, Hans Verkuil wrote:
> > > 
> > > > On Thursday, September 08, 2011 09:45:15 Guennadi Liakhovetski wrote:
> > > > > A possibility to preallocate and initialise buffers of different sizes
> > > > > in V4L2 is required for an efficient implementation of a snapshot
> > > > > mode. This patch adds two new ioctl()s: VIDIOC_CREATE_BUFS and
> > > > > VIDIOC_PREPARE_BUF and defines respective data structures.
> > > > > 
> > > > > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > > > > ---
> > > > > 
> > > > > v7: added the "experimental" comment, as suggested by Sakari - thanks.
> > > > > 
> > > > >  drivers/media/video/v4l2-compat-ioctl32.c |   67 +++++++++++++++++++++++++---
> > > > >  drivers/media/video/v4l2-ioctl.c          |   29 ++++++++++++
> > > > >  include/linux/videodev2.h                 |   17 +++++++
> > > > >  include/media/v4l2-ioctl.h                |    2 +
> > > > >  4 files changed, 107 insertions(+), 8 deletions(-)
> > > 
> > > [snip]
> > > 
> > > > > diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
> > > > > index a5359c6..6e87ea9 100644
> > > > > --- a/include/linux/videodev2.h
> > > > > +++ b/include/linux/videodev2.h
> > > > > @@ -653,6 +653,9 @@ struct v4l2_buffer {
> > > > >  #define V4L2_BUF_FLAG_ERROR	0x0040
> > > > >  #define V4L2_BUF_FLAG_TIMECODE	0x0100	/* timecode field is valid */
> > > > >  #define V4L2_BUF_FLAG_INPUT     0x0200  /* input field is valid */
> > > > > +/* Cache handling flags */
> > > > > +#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE	0x0400
> > > > > +#define V4L2_BUF_FLAG_NO_CACHE_CLEAN		0x0800
> > > > >  
> > > > >  /*
> > > > >   *	O V E R L A Y   P R E V I E W
> > > > > @@ -2098,6 +2101,15 @@ struct v4l2_dbg_chip_ident {
> > > > >  	__u32 revision;    /* chip revision, chip specific */
> > > > >  } __attribute__ ((packed));
> > > > >  
> > > > > +/* VIDIOC_CREATE_BUFS */
> > > > > +struct v4l2_create_buffers {
> > > > > +	__u32			index;		/* output: buffers index...index + count - 1 have been created */
> > > > > +	__u32			count;
> > > > > +	enum v4l2_memory        memory;
> > > > > +	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
> > > > > +	__u32			reserved[8];
> > > > > +};
> > > > > +
> > > > >  /*
> > > > >   *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
> > > > >   *
> > > > > @@ -2188,6 +2200,11 @@ struct v4l2_dbg_chip_ident {
> > > > >  #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct v4l2_event_subscription)
> > > > >  #define	VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
> > > > >  
> > > > > +/* Experimental, the below two ioctls may change over the next couple of kernel
> > > > > +   versions */
> > > > > +#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct v4l2_create_buffers)
> > > > > +#define VIDIOC_PREPARE_BUF	 _IOW('V', 93, struct v4l2_buffer)
> > > > 
> > > > I think I would prefer _IOWR here. QBUF etc. also use IOWR and you never know
> > > > what you might return in the future. At the very least using IOWR allows us
> > > > to update the state field, which would be a perfectly reasonable thing to do.
> > > 
> > > Sorry, which state field do you mean? We have already marked these ioctl() 
> > > as experimental, isn't this enough?
> > 
> > The state field in the v4l2_buffer argument.
> 
> Is this a new field? I seem to remember some discussion to replace one of 
> existing unused fields in a user-exposed struct (ioctl() argument) with a 
> different one. Is this what you're referring to? Can you point me out to 
> the patch?

Sorry, my fault. I confused vb2_buffer 'state' with v4l2_buffer 'flags'.
What happens in the case of QBUF is that v4l2_buffer is returned and the flags
field is set to FLAG_QUEUED. Something similar can be done if you have a IOWR
PREPARE_BUF: let it set FLAG_QUEUED. That makes it consistent with the QBUF
behavior as well (I always like consistent APIs).

I'm not sure whether we want to add a FLAG_PREPARED as well. I don't think it
has much value, although it would be a trivial addition.

Regards,

	Hans

> 
> > The experimental tag allows for changes, that's true. So this is my proposed
> > change :-)
> 
> Thanks
> Guennadi
> ---
> Guennadi Liakhovetski, Ph.D.
> Freelance Open-Source Software Developer
> http://www.open-technology.de/
> 

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 3/9 v7] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s
  2011-09-27 10:51             ` Hans Verkuil
@ 2011-09-27 15:49               ` Guennadi Liakhovetski
  2011-09-27 19:50                 ` Sakari Ailus
  2011-09-28  7:34                 ` Hans Verkuil
  2011-09-27 17:01               ` [PATCH 3/9 v8] " Guennadi Liakhovetski
  1 sibling, 2 replies; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-09-27 15:49 UTC (permalink / raw)
  To: Hans Verkuil
  Cc: Sakari Ailus, Linux Media Mailing List, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

On Tue, 27 Sep 2011, Hans Verkuil wrote:

> On Thursday, September 08, 2011 09:46:26 Guennadi Liakhovetski wrote:
> > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > ---

[snip]

> > +    <para>When the ioctl is called with a pointer to this structure the driver
> > +will attempt to allocate up to the requested number of buffers and store the
> > +actual number allocated and the starting index in the
> > +<structfield>count</structfield> and the <structfield>index</structfield> fields
> > +respectively. On return <structfield>count</structfield> can be smaller than
> > +the number requested. The driver may also adjust buffer sizes as it sees fit,
> 
> Add: 'provided the size is greater than or equal to sizeimage'.

How about:

The driver may also increase buffer sizes if required, however, it will 
not update <structfield>sizeimage</structfield> field values. The
user has to use <constant>VIDIOC_QUERYBUF</constant> to retrieve that
information.</para>

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH 2/9 v8] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-27 13:40                   ` Hans Verkuil
@ 2011-09-27 16:54                     ` Guennadi Liakhovetski
  2011-09-28  8:06                       ` Hans Verkuil
  2011-09-28 13:19                       ` [PATCH 2/9 v9] " Guennadi Liakhovetski
  0 siblings, 2 replies; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-09-27 16:54 UTC (permalink / raw)
  To: Hans Verkuil
  Cc: Sakari Ailus, Linux Media Mailing List, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

A possibility to preallocate and initialise buffers of different sizes
in V4L2 is required for an efficient implementation of a snapshot
mode. This patch adds two new ioctl()s: VIDIOC_CREATE_BUFS and
VIDIOC_PREPARE_BUF and defines respective data structures.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v8: addressed comments from Hans - thanks:

    1. added checks in ioctl() preprocessing
    2. changed VIDIOC_PREPARE_BUF to _IOWR

 drivers/media/video/v4l2-compat-ioctl32.c |   67 +++++++++++++++++++++++++---
 drivers/media/video/v4l2-ioctl.c          |   36 +++++++++++++++
 include/linux/videodev2.h                 |   17 +++++++
 include/media/v4l2-ioctl.h                |    2 +
 4 files changed, 114 insertions(+), 8 deletions(-)

diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
index 61979b7..85758d2 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -159,11 +159,16 @@ struct v4l2_format32 {
 	} fmt;
 };
 
-static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+struct v4l2_create_buffers32 {
+	__u32			index;		/* output: buffers index...index + count - 1 have been created */
+	__u32			count;
+	enum v4l2_memory        memory;
+	struct v4l2_format32	format;		/* filled in by the user, plane sizes calculated by the driver */
+	__u32			reserved[8];
+};
+
+static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
 {
-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
-			get_user(kp->type, &up->type))
-			return -EFAULT;
 	switch (kp->type) {
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
@@ -192,11 +197,24 @@ static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
 	}
 }
 
-static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+{
+	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
+			get_user(kp->type, &up->type))
+			return -EFAULT;
+	return __get_v4l2_format32(kp, up);
+}
+
+static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
+{
+	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)) ||
+	    copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format.fmt)))
+			return -EFAULT;
+	return __get_v4l2_format32(&kp->format, &up->format);
+}
+
+static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
 {
-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
-		put_user(kp->type, &up->type))
-		return -EFAULT;
 	switch (kp->type) {
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
@@ -225,6 +243,22 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
 	}
 }
 
+static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+{
+	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
+		put_user(kp->type, &up->type))
+		return -EFAULT;
+	return __put_v4l2_format32(kp, up);
+}
+
+static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
+{
+	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_create_buffers32)) ||
+	    copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format.fmt)))
+			return -EFAULT;
+	return __put_v4l2_format32(&kp->format, &up->format);
+}
+
 struct v4l2_standard32 {
 	__u32		     index;
 	__u32		     id[2]; /* __u64 would get the alignment wrong */
@@ -702,6 +736,8 @@ static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *u
 #define VIDIOC_S_EXT_CTRLS32    _IOWR('V', 72, struct v4l2_ext_controls32)
 #define VIDIOC_TRY_EXT_CTRLS32  _IOWR('V', 73, struct v4l2_ext_controls32)
 #define	VIDIOC_DQEVENT32	_IOR ('V', 89, struct v4l2_event32)
+#define VIDIOC_CREATE_BUFS32	_IOWR('V', 92, struct v4l2_create_buffers32)
+#define VIDIOC_PREPARE_BUF32	_IOWR('V', 93, struct v4l2_buffer32)
 
 #define VIDIOC_OVERLAY32	_IOW ('V', 14, s32)
 #define VIDIOC_STREAMON32	_IOW ('V', 18, s32)
@@ -721,6 +757,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
 		struct v4l2_standard v2s;
 		struct v4l2_ext_controls v2ecs;
 		struct v4l2_event v2ev;
+		struct v4l2_create_buffers v2crt;
 		unsigned long vx;
 		int vi;
 	} karg;
@@ -751,6 +788,8 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
 	case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break;
 	case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break;
 	case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break;
+	case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break;
+	case VIDIOC_PREPARE_BUF32: cmd = VIDIOC_PREPARE_BUF; break;
 	}
 
 	switch (cmd) {
@@ -775,6 +814,12 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
 		compatible_arg = 0;
 		break;
 
+	case VIDIOC_CREATE_BUFS:
+		err = get_v4l2_create32(&karg.v2crt, up);
+		compatible_arg = 0;
+		break;
+
+	case VIDIOC_PREPARE_BUF:
 	case VIDIOC_QUERYBUF:
 	case VIDIOC_QBUF:
 	case VIDIOC_DQBUF:
@@ -860,6 +905,10 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
 		err = put_v4l2_format32(&karg.v2f, up);
 		break;
 
+	case VIDIOC_CREATE_BUFS:
+		err = put_v4l2_create32(&karg.v2crt, up);
+		break;
+
 	case VIDIOC_QUERYBUF:
 	case VIDIOC_QBUF:
 	case VIDIOC_DQBUF:
@@ -959,6 +1008,8 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
 	case VIDIOC_DQEVENT32:
 	case VIDIOC_SUBSCRIBE_EVENT:
 	case VIDIOC_UNSUBSCRIBE_EVENT:
+	case VIDIOC_CREATE_BUFS32:
+	case VIDIOC_PREPARE_BUF32:
 		ret = do_video_ioctl(file, cmd, arg);
 		break;
 
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 21c49dc..ff378eb 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -273,6 +273,8 @@ static const char *v4l2_ioctls[] = {
 	[_IOC_NR(VIDIOC_DQEVENT)]	   = "VIDIOC_DQEVENT",
 	[_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)]  = "VIDIOC_SUBSCRIBE_EVENT",
 	[_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT",
+	[_IOC_NR(VIDIOC_CREATE_BUFS)]      = "VIDIOC_CREATE_BUFS",
+	[_IOC_NR(VIDIOC_PREPARE_BUF)]      = "VIDIOC_PREPARE_BUF",
 };
 #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
 
@@ -2096,6 +2098,40 @@ static long __video_do_ioctl(struct file *file,
 		dbgarg(cmd, "type=0x%8.8x", sub->type);
 		break;
 	}
+	case VIDIOC_CREATE_BUFS:
+	{
+		struct v4l2_create_buffers *create = arg;
+
+		if (!ops->vidioc_create_bufs)
+			break;
+		if (ret_prio) {
+			ret = ret_prio;
+			break;
+		}
+		ret = check_fmt(ops, create->format.type);
+		if (ret)
+			break;
+
+		ret = ops->vidioc_create_bufs(file, fh, create);
+
+		dbgarg(cmd, "count=%d @ %d\n", create->count, create->index);
+		break;
+	}
+	case VIDIOC_PREPARE_BUF:
+	{
+		struct v4l2_buffer *b = arg;
+
+		if (!ops->vidioc_prepare_buf)
+			break;
+		ret = check_fmt(ops, b->type);
+		if (ret)
+			break;
+
+		ret = ops->vidioc_prepare_buf(file, fh, b);
+
+		dbgarg(cmd, "index=%d", b->index);
+		break;
+	}
 	default:
 		if (!ops->vidioc_default)
 			break;
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 9d14523..7d75dd1 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -653,6 +653,9 @@ struct v4l2_buffer {
 #define V4L2_BUF_FLAG_ERROR	0x0040
 #define V4L2_BUF_FLAG_TIMECODE	0x0100	/* timecode field is valid */
 #define V4L2_BUF_FLAG_INPUT     0x0200  /* input field is valid */
+/* Cache handling flags */
+#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE	0x0400
+#define V4L2_BUF_FLAG_NO_CACHE_CLEAN		0x0800
 
 /*
  *	O V E R L A Y   P R E V I E W
@@ -2099,6 +2102,15 @@ struct v4l2_dbg_chip_ident {
 	__u32 revision;    /* chip revision, chip specific */
 } __attribute__ ((packed));
 
+/* VIDIOC_CREATE_BUFS */
+struct v4l2_create_buffers {
+	__u32			index;		/* output: buffers index...index + count - 1 have been created */
+	__u32			count;
+	enum v4l2_memory        memory;
+	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
+	__u32			reserved[8];
+};
+
 /*
  *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
  *
@@ -2189,6 +2201,11 @@ struct v4l2_dbg_chip_ident {
 #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct v4l2_event_subscription)
 #define	VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
 
+/* Experimental, the below two ioctls may change over the next couple of kernel
+   versions */
+#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct v4l2_create_buffers)
+#define VIDIOC_PREPARE_BUF	_IOWR('V', 93, struct v4l2_buffer)
+
 /* Reminder: when adding new ioctls please add support for them to
    drivers/media/video/v4l2-compat-ioctl32.c as well! */
 
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index dd9f1e7..55cf8ae 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -122,6 +122,8 @@ struct v4l2_ioctl_ops {
 	int (*vidioc_qbuf)    (struct file *file, void *fh, struct v4l2_buffer *b);
 	int (*vidioc_dqbuf)   (struct file *file, void *fh, struct v4l2_buffer *b);
 
+	int (*vidioc_create_bufs)(struct file *file, void *fh, struct v4l2_create_buffers *b);
+	int (*vidioc_prepare_buf)(struct file *file, void *fh, const struct v4l2_buffer *b);
 
 	int (*vidioc_overlay) (struct file *file, void *fh, unsigned int i);
 	int (*vidioc_g_fbuf)   (struct file *file, void *fh,
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 3/9 v8] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s
  2011-09-27 10:51             ` Hans Verkuil
  2011-09-27 15:49               ` Guennadi Liakhovetski
@ 2011-09-27 17:01               ` Guennadi Liakhovetski
  2011-09-28 13:20                 ` [PATCH 3/9 v9] " Guennadi Liakhovetski
  1 sibling, 1 reply; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-09-27 17:01 UTC (permalink / raw)
  To: Hans Verkuil
  Cc: Sakari Ailus, Linux Media Mailing List, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v8: specify, that the drivers may only increase buffer sizes, not decrease 
them - thanks to Hans for suggestion

>From e879854cc639ba7c0228109f22415cc44df7edc0 Mon Sep 17 00:00:00 2001
From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Date: Tue, 27 Sep 2011 18:59:32 +0200
Subject: [PATCH 02/36] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 Documentation/DocBook/media/v4l/compat.xml         |    3 +
 Documentation/DocBook/media/v4l/io.xml             |   17 +++
 Documentation/DocBook/media/v4l/v4l2.xml           |    2 +
 .../DocBook/media/v4l/vidioc-create-bufs.xml       |  147 ++++++++++++++++++++
 .../DocBook/media/v4l/vidioc-prepare-buf.xml       |   96 +++++++++++++
 5 files changed, 265 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
 create mode 100644 Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml

diff --git a/Documentation/DocBook/media/v4l/compat.xml b/Documentation/DocBook/media/v4l/compat.xml
index 91410b6..b68698f 100644
--- a/Documentation/DocBook/media/v4l/compat.xml
+++ b/Documentation/DocBook/media/v4l/compat.xml
@@ -2486,6 +2486,9 @@ ioctls.</para>
         <listitem>
 	  <para>Flash API. <xref linkend="flash-controls" /></para>
         </listitem>
+        <listitem>
+	  <para>&VIDIOC-CREATE-BUFS; and &VIDIOC-PREPARE-BUF; ioctls.</para>
+        </listitem>
       </itemizedlist>
     </section>
 
diff --git a/Documentation/DocBook/media/v4l/io.xml b/Documentation/DocBook/media/v4l/io.xml
index c57d1ec..74ead1e 100644
--- a/Documentation/DocBook/media/v4l/io.xml
+++ b/Documentation/DocBook/media/v4l/io.xml
@@ -927,6 +927,23 @@ ioctl is called.</entry>
 Applications set or clear this flag before calling the
 <constant>VIDIOC_QBUF</constant> ioctl.</entry>
 	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant></entry>
+	    <entry>0x0400</entry>
+	    <entry>Caches do not have to be invalidated for this buffer.
+Typically applications shall use this flag if the data captured in the buffer
+is not going to be touched by the CPU, instead the buffer will, probably, be
+passed on to a DMA-capable hardware unit for further processing or output.
+</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant></entry>
+	    <entry>0x0800</entry>
+	    <entry>Caches do not have to be cleaned for this buffer.
+Typically applications shall use this flag for output buffers if the data
+in this buffer has not been created by the CPU but by some DMA-capable unit,
+in which case caches have not been used.</entry>
+	  </row>
 	</tbody>
       </tgroup>
     </table>
diff --git a/Documentation/DocBook/media/v4l/v4l2.xml b/Documentation/DocBook/media/v4l/v4l2.xml
index 40132c2..2ab365c 100644
--- a/Documentation/DocBook/media/v4l/v4l2.xml
+++ b/Documentation/DocBook/media/v4l/v4l2.xml
@@ -469,6 +469,7 @@ and discussions on the V4L mailing list.</revremark>
     &sub-close;
     &sub-ioctl;
     <!-- All ioctls go here. -->
+    &sub-create-bufs;
     &sub-cropcap;
     &sub-dbg-g-chip-ident;
     &sub-dbg-g-register;
@@ -511,6 +512,7 @@ and discussions on the V4L mailing list.</revremark>
     &sub-queryctrl;
     &sub-query-dv-preset;
     &sub-querystd;
+    &sub-prepare-buf;
     &sub-reqbufs;
     &sub-s-hw-freq-seek;
     &sub-streamon;
diff --git a/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
new file mode 100644
index 0000000..27d694d
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
@@ -0,0 +1,147 @@
+<refentry id="vidioc-create-bufs">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_CREATE_BUFS</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_CREATE_BUFS</refname>
+    <refpurpose>Create buffers for Memory Mapped or User Pointer I/O</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_create_buffers *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_CREATE_BUFS</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>This ioctl is used to create buffers for <link linkend="mmap">memory
+mapped</link> or <link linkend="userp">user pointer</link>
+I/O. It can be used as an alternative or in addition to the
+<constant>VIDIOC_REQBUFS</constant> ioctl, when a tighter control over buffers
+is required. This ioctl can be called multiple times to create buffers of
+different sizes.</para>
+
+    <para>To allocate device buffers applications initialize relevant fields of
+the <structname>v4l2_create_buffers</structname> structure. They set the
+<structfield>type</structfield> field in the
+<structname>v4l2_format</structname> structure, embedded in this
+structure, to the respective stream or buffer type.
+<structfield>count</structfield> must be set to the number of required buffers.
+<structfield>memory</structfield> specifies the required I/O method. The
+<structfield>format</structfield> field shall typically be filled in using
+either the <constant>VIDIOC_TRY_FMT</constant> or
+<constant>VIDIOC_G_FMT</constant> ioctl(). Additionally, applications can adjust
+<structfield>sizeimage</structfield> fields to fit their specific needs. The
+<structfield>reserved</structfield> array must be zeroed.</para>
+
+    <para>When the ioctl is called with a pointer to this structure the driver
+will attempt to allocate up to the requested number of buffers and store the
+actual number allocated and the starting index in the
+<structfield>count</structfield> and the <structfield>index</structfield> fields
+respectively. On return <structfield>count</structfield> can be smaller than
+the number requested. The driver may also increase buffer sizes if required,
+however, it will not update <structfield>sizeimage</structfield> field values.
+The user has to use <constant>VIDIOC_QUERYBUF</constant> to retrieve that
+information.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-create-buffers">
+      <title>struct <structname>v4l2_create_buffers</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>index</structfield></entry>
+	    <entry>The starting buffer index, returned by the driver.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>count</structfield></entry>
+	    <entry>The number of buffers requested or granted.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-memory;</entry>
+	    <entry><structfield>memory</structfield></entry>
+	    <entry>Applications set this field to
+<constant>V4L2_MEMORY_MMAP</constant> or
+<constant>V4L2_MEMORY_USERPTR</constant>.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-format;</entry>
+	    <entry><structfield>format</structfield></entry>
+	    <entry>Filled in by the application, preserved by the driver.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[8]</entry>
+	    <entry>A place holder for future extensions.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>ENOMEM</errorcode></term>
+	<listitem>
+	  <para>No memory to allocate buffers for <link linkend="mmap">memory
+mapped</link> I/O.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The buffer type (<structfield>type</structfield> field) or the
+requested I/O method (<structfield>memory</structfield>) is not
+supported.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
new file mode 100644
index 0000000..509e752
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
@@ -0,0 +1,96 @@
+<refentry id="vidioc-prepare-buf">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_PREPARE_BUF</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_PREPARE_BUF</refname>
+    <refpurpose>Prepare a buffer for I/O</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_buffer *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_PREPARE_BUF</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>Applications can optionally call the
+<constant>VIDIOC_PREPARE_BUF</constant> ioctl to pass ownership of the buffer
+to the driver before actually enqueuing it, using the
+<constant>VIDIOC_QBUF</constant> ioctl, and to prepare it for future I/O.
+Such preparations may include cache invalidation or cleaning. Performing them
+in advance saves time during the actual I/O. In case such cache operations are
+not required, the application can use one of
+<constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant> and
+<constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant> flags to skip the respective
+step.</para>
+
+    <para>The <structname>v4l2_buffer</structname> structure is
+specified in <xref linkend="buffer" />.</para>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>File I/O is in progress.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The buffer <structfield>type</structfield> is not
+supported, or the <structfield>index</structfield> is out of bounds,
+or no buffers have been allocated yet, or the
+<structfield>userptr</structfield> or
+<structfield>length</structfield> are invalid.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v7] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-27 10:34           ` [PATCH 2/9 v7] V4L: add two new ioctl()s for multi-size videobuffer management Hans Verkuil
  2011-09-27 11:00             ` Guennadi Liakhovetski
@ 2011-09-27 17:08             ` Laurent Pinchart
  2011-09-28  8:09               ` Hans Verkuil
  1 sibling, 1 reply; 59+ messages in thread
From: Laurent Pinchart @ 2011-09-27 17:08 UTC (permalink / raw)
  To: Hans Verkuil
  Cc: Guennadi Liakhovetski, Sakari Ailus, Linux Media Mailing List,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

Hi Hans,

On Tuesday 27 September 2011 12:34:20 Hans Verkuil wrote:
> On Thursday, September 08, 2011 09:45:15 Guennadi Liakhovetski wrote:
> > A possibility to preallocate and initialise buffers of different sizes
> > in V4L2 is required for an efficient implementation of a snapshot
> > mode. This patch adds two new ioctl()s: VIDIOC_CREATE_BUFS and
> > VIDIOC_PREPARE_BUF and defines respective data structures.
> > 
> > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > ---

[snip]

> > @@ -2096,6 +2098,33 @@ static long __video_do_ioctl(struct file *file,
> > 
> >  		dbgarg(cmd, "type=0x%8.8x", sub->type);
> >  		break;
> >  	
> >  	}
> > 
> > +	case VIDIOC_CREATE_BUFS:
> > +	{
> > +		struct v4l2_create_buffers *create = arg;
> > +
> > +		if (!ops->vidioc_create_bufs)
> > +			break;
> 
> Just as with REQBUFS you need to add code here to handle priority checking:
> 
> 		if (ret_prio) {
> 			ret = ret_prio;
> 			break;
> 		}

Speaking of prio support, how is locking handled here ? Does video_ioctl2() 
require drivers to synchronize all ioctl calls or can it work with fine-grain 
locking ?
 
> > +		ret = check_fmt(ops, create->format.type);
> > +		if (ret)
> > +			break;
> > +
> > +		ret = ops->vidioc_create_bufs(file, fh, create);
> > +
> > +		dbgarg(cmd, "count=%d @ %d\n", create->count, create->index);
> > +		break;
> > +	}

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 3/9 v7] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s
  2011-09-27 15:49               ` Guennadi Liakhovetski
@ 2011-09-27 19:50                 ` Sakari Ailus
  2011-09-28  7:34                 ` Hans Verkuil
  1 sibling, 0 replies; 59+ messages in thread
From: Sakari Ailus @ 2011-09-27 19:50 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Hans Verkuil, Linux Media Mailing List, Laurent Pinchart,
	Pawel Osciak, Mauro Carvalho Chehab, Marek Szyprowski

Hi Guennadi,

On Tue, Sep 27, 2011 at 05:49:52PM +0200, Guennadi Liakhovetski wrote:
> On Tue, 27 Sep 2011, Hans Verkuil wrote:
> 
> > On Thursday, September 08, 2011 09:46:26 Guennadi Liakhovetski wrote:
> > > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > > ---
> 
> [snip]
> 
> > > +    <para>When the ioctl is called with a pointer to this structure the driver
> > > +will attempt to allocate up to the requested number of buffers and store the
> > > +actual number allocated and the starting index in the
> > > +<structfield>count</structfield> and the <structfield>index</structfield> fields
> > > +respectively. On return <structfield>count</structfield> can be smaller than
> > > +the number requested. The driver may also adjust buffer sizes as it sees fit,
> > 
> > Add: 'provided the size is greater than or equal to sizeimage'.
> 
> How about:
> 
> The driver may also increase buffer sizes if required, however, it will 
> not update <structfield>sizeimage</structfield> field values. The
> user has to use <constant>VIDIOC_QUERYBUF</constant> to retrieve that
> information.</para>

This may be a stupid question but would there be adverse effects from
updating it?

-- 
Sakari Ailus
e-mail: sakari.ailus@iki.fi	jabber/XMPP/Gmail: sailus@retiisi.org.uk

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 3/9 v7] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s
  2011-09-27 15:49               ` Guennadi Liakhovetski
  2011-09-27 19:50                 ` Sakari Ailus
@ 2011-09-28  7:34                 ` Hans Verkuil
  1 sibling, 0 replies; 59+ messages in thread
From: Hans Verkuil @ 2011-09-28  7:34 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Sakari Ailus, Linux Media Mailing List, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

On Tuesday, September 27, 2011 17:49:52 Guennadi Liakhovetski wrote:
> On Tue, 27 Sep 2011, Hans Verkuil wrote:
> 
> > On Thursday, September 08, 2011 09:46:26 Guennadi Liakhovetski wrote:
> > > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > > ---
> 
> [snip]
> 
> > > +    <para>When the ioctl is called with a pointer to this structure the driver
> > > +will attempt to allocate up to the requested number of buffers and store the
> > > +actual number allocated and the starting index in the
> > > +<structfield>count</structfield> and the <structfield>index</structfield> fields
> > > +respectively. On return <structfield>count</structfield> can be smaller than
> > > +the number requested. The driver may also adjust buffer sizes as it sees fit,
> > 
> > Add: 'provided the size is greater than or equal to sizeimage'.
> 
> How about:
> 
> The driver may also increase buffer sizes if required, however, it will 
> not update <structfield>sizeimage</structfield> field values. The
> user has to use <constant>VIDIOC_QUERYBUF</constant> to retrieve that
> information.</para>

Looks good.

Regards,

	Hans

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v8] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-27 16:54                     ` [PATCH 2/9 v8] " Guennadi Liakhovetski
@ 2011-09-28  8:06                       ` Hans Verkuil
  2011-09-28  8:34                         ` Guennadi Liakhovetski
  2011-09-28 13:19                       ` [PATCH 2/9 v9] " Guennadi Liakhovetski
  1 sibling, 1 reply; 59+ messages in thread
From: Hans Verkuil @ 2011-09-28  8:06 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Sakari Ailus, Linux Media Mailing List, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

On Tuesday, September 27, 2011 18:54:53 Guennadi Liakhovetski wrote:
> A possibility to preallocate and initialise buffers of different sizes
> in V4L2 is required for an efficient implementation of a snapshot
> mode. This patch adds two new ioctl()s: VIDIOC_CREATE_BUFS and
> VIDIOC_PREPARE_BUF and defines respective data structures.
> 
> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> ---
> 
> v8: addressed comments from Hans - thanks:
> 
>     1. added checks in ioctl() preprocessing
>     2. changed VIDIOC_PREPARE_BUF to _IOWR
> 
>  drivers/media/video/v4l2-compat-ioctl32.c |   67 +++++++++++++++++++++++++---
>  drivers/media/video/v4l2-ioctl.c          |   36 +++++++++++++++
>  include/linux/videodev2.h                 |   17 +++++++
>  include/media/v4l2-ioctl.h                |    2 +
>  4 files changed, 114 insertions(+), 8 deletions(-)
> 

Almost:

> diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
> index 9d14523..7d75dd1 100644
> --- a/include/linux/videodev2.h
> +++ b/include/linux/videodev2.h
> @@ -653,6 +653,9 @@ struct v4l2_buffer {
>  #define V4L2_BUF_FLAG_ERROR	0x0040
>  #define V4L2_BUF_FLAG_TIMECODE	0x0100	/* timecode field is valid */
>  #define V4L2_BUF_FLAG_INPUT     0x0200  /* input field is valid */
> +/* Cache handling flags */
> +#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE	0x0400
> +#define V4L2_BUF_FLAG_NO_CACHE_CLEAN		0x0800
>  
>  /*
>   *	O V E R L A Y   P R E V I E W
> @@ -2099,6 +2102,15 @@ struct v4l2_dbg_chip_ident {
>  	__u32 revision;    /* chip revision, chip specific */
>  } __attribute__ ((packed));
>  
> +/* VIDIOC_CREATE_BUFS */
> +struct v4l2_create_buffers {
> +	__u32			index;		/* output: buffers index...index + count - 1 have been created */
> +	__u32			count;
> +	enum v4l2_memory        memory;
> +	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
> +	__u32			reserved[8];
> +};
> +
>  /*
>   *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
>   *
> @@ -2189,6 +2201,11 @@ struct v4l2_dbg_chip_ident {
>  #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct v4l2_event_subscription)
>  #define	VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
>  
> +/* Experimental, the below two ioctls may change over the next couple of kernel
> +   versions */
> +#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct v4l2_create_buffers)
> +#define VIDIOC_PREPARE_BUF	_IOWR('V', 93, struct v4l2_buffer)
> +
>  /* Reminder: when adding new ioctls please add support for them to
>     drivers/media/video/v4l2-compat-ioctl32.c as well! */
>  
> diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
> index dd9f1e7..55cf8ae 100644
> --- a/include/media/v4l2-ioctl.h
> +++ b/include/media/v4l2-ioctl.h
> @@ -122,6 +122,8 @@ struct v4l2_ioctl_ops {
>  	int (*vidioc_qbuf)    (struct file *file, void *fh, struct v4l2_buffer *b);
>  	int (*vidioc_dqbuf)   (struct file *file, void *fh, struct v4l2_buffer *b);
>  
> +	int (*vidioc_create_bufs)(struct file *file, void *fh, struct v4l2_create_buffers *b);
> +	int (*vidioc_prepare_buf)(struct file *file, void *fh, const struct v4l2_buffer *b);

If this is IOWR, then there shouldn't be a const here.

I have been thinking about this a bit more. Currently we only have a V4L2_BUF_FLAG_QUEUED
flag and no V4L2_BUF_FLAG_PREPARED flag. I do think we need this after all. The QUEUED flag
can't be used here as the buffer isn't queued yet, it's only prepared.

Regards,

	Hans

>  
>  	int (*vidioc_overlay) (struct file *file, void *fh, unsigned int i);
>  	int (*vidioc_g_fbuf)   (struct file *file, void *fh,
> 

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v7] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-27 17:08             ` [PATCH 2/9 v7] " Laurent Pinchart
@ 2011-09-28  8:09               ` Hans Verkuil
  0 siblings, 0 replies; 59+ messages in thread
From: Hans Verkuil @ 2011-09-28  8:09 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Guennadi Liakhovetski, Sakari Ailus, Linux Media Mailing List,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

On Tuesday, September 27, 2011 19:08:38 Laurent Pinchart wrote:
> Hi Hans,
> 
> On Tuesday 27 September 2011 12:34:20 Hans Verkuil wrote:
> > On Thursday, September 08, 2011 09:45:15 Guennadi Liakhovetski wrote:
> > > A possibility to preallocate and initialise buffers of different sizes
> > > in V4L2 is required for an efficient implementation of a snapshot
> > > mode. This patch adds two new ioctl()s: VIDIOC_CREATE_BUFS and
> > > VIDIOC_PREPARE_BUF and defines respective data structures.
> > > 
> > > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > > ---
> 
> [snip]
> 
> > > @@ -2096,6 +2098,33 @@ static long __video_do_ioctl(struct file *file,
> > > 
> > >  		dbgarg(cmd, "type=0x%8.8x", sub->type);
> > >  		break;
> > >  	
> > >  	}
> > > 
> > > +	case VIDIOC_CREATE_BUFS:
> > > +	{
> > > +		struct v4l2_create_buffers *create = arg;
> > > +
> > > +		if (!ops->vidioc_create_bufs)
> > > +			break;
> > 
> > Just as with REQBUFS you need to add code here to handle priority checking:
> > 
> > 		if (ret_prio) {
> > 			ret = ret_prio;
> > 			break;
> > 		}
> 
> Speaking of prio support, how is locking handled here ?

Define 'here'. Are you talking about video_ioctl2() as a function? Or prio
support in particular?

> Does video_ioctl2() 
> require drivers to synchronize all ioctl calls or can it work with fine-grain 
> locking ?

It should always work OK with fine-grained locking.

Regards,

	Hans

>  
> > > +		ret = check_fmt(ops, create->format.type);
> > > +		if (ret)
> > > +			break;
> > > +
> > > +		ret = ops->vidioc_create_bufs(file, fh, create);
> > > +
> > > +		dbgarg(cmd, "count=%d @ %d\n", create->count, create->index);
> > > +		break;
> > > +	}
> 
> 

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v8] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-28  8:06                       ` Hans Verkuil
@ 2011-09-28  8:34                         ` Guennadi Liakhovetski
  2011-09-28  8:48                           ` Guennadi Liakhovetski
  0 siblings, 1 reply; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-09-28  8:34 UTC (permalink / raw)
  To: Hans Verkuil
  Cc: Sakari Ailus, Linux Media Mailing List, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

Hi Hans

On Wed, 28 Sep 2011, Hans Verkuil wrote:

> On Tuesday, September 27, 2011 18:54:53 Guennadi Liakhovetski wrote:
> > A possibility to preallocate and initialise buffers of different sizes
> > in V4L2 is required for an efficient implementation of a snapshot
> > mode. This patch adds two new ioctl()s: VIDIOC_CREATE_BUFS and
> > VIDIOC_PREPARE_BUF and defines respective data structures.
> > 
> > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > ---
> > 
> > v8: addressed comments from Hans - thanks:
> > 
> >     1. added checks in ioctl() preprocessing
> >     2. changed VIDIOC_PREPARE_BUF to _IOWR
> > 
> >  drivers/media/video/v4l2-compat-ioctl32.c |   67 +++++++++++++++++++++++++---
> >  drivers/media/video/v4l2-ioctl.c          |   36 +++++++++++++++
> >  include/linux/videodev2.h                 |   17 +++++++
> >  include/media/v4l2-ioctl.h                |    2 +
> >  4 files changed, 114 insertions(+), 8 deletions(-)
> > 
> 
> Almost:
> 
> > diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
> > index 9d14523..7d75dd1 100644
> > --- a/include/linux/videodev2.h
> > +++ b/include/linux/videodev2.h
> > @@ -653,6 +653,9 @@ struct v4l2_buffer {
> >  #define V4L2_BUF_FLAG_ERROR	0x0040
> >  #define V4L2_BUF_FLAG_TIMECODE	0x0100	/* timecode field is valid */
> >  #define V4L2_BUF_FLAG_INPUT     0x0200  /* input field is valid */
> > +/* Cache handling flags */
> > +#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE	0x0400
> > +#define V4L2_BUF_FLAG_NO_CACHE_CLEAN		0x0800
> >  
> >  /*
> >   *	O V E R L A Y   P R E V I E W
> > @@ -2099,6 +2102,15 @@ struct v4l2_dbg_chip_ident {
> >  	__u32 revision;    /* chip revision, chip specific */
> >  } __attribute__ ((packed));
> >  
> > +/* VIDIOC_CREATE_BUFS */
> > +struct v4l2_create_buffers {
> > +	__u32			index;		/* output: buffers index...index + count - 1 have been created */
> > +	__u32			count;
> > +	enum v4l2_memory        memory;
> > +	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
> > +	__u32			reserved[8];
> > +};
> > +
> >  /*
> >   *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
> >   *
> > @@ -2189,6 +2201,11 @@ struct v4l2_dbg_chip_ident {
> >  #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct v4l2_event_subscription)
> >  #define	VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
> >  
> > +/* Experimental, the below two ioctls may change over the next couple of kernel
> > +   versions */
> > +#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct v4l2_create_buffers)
> > +#define VIDIOC_PREPARE_BUF	_IOWR('V', 93, struct v4l2_buffer)
> > +
> >  /* Reminder: when adding new ioctls please add support for them to
> >     drivers/media/video/v4l2-compat-ioctl32.c as well! */
> >  
> > diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
> > index dd9f1e7..55cf8ae 100644
> > --- a/include/media/v4l2-ioctl.h
> > +++ b/include/media/v4l2-ioctl.h
> > @@ -122,6 +122,8 @@ struct v4l2_ioctl_ops {
> >  	int (*vidioc_qbuf)    (struct file *file, void *fh, struct v4l2_buffer *b);
> >  	int (*vidioc_dqbuf)   (struct file *file, void *fh, struct v4l2_buffer *b);
> >  
> > +	int (*vidioc_create_bufs)(struct file *file, void *fh, struct v4l2_create_buffers *b);
> > +	int (*vidioc_prepare_buf)(struct file *file, void *fh, const struct v4l2_buffer *b);
> 
> If this is IOWR, then there shouldn't be a const here.

hrm... Sure.

> I have been thinking about this a bit more. Currently we only have a V4L2_BUF_FLAG_QUEUED
> flag and no V4L2_BUF_FLAG_PREPARED flag. I do think we need this after all. The QUEUED flag
> can't be used here as the buffer isn't queued yet, it's only prepared.

Ok, I can add it to this patch together with the other two cache-handling 
flags. I presume, I shall also add it to

V4L2_BUFFER_STATE_FLAGS

in videobuf2-core.c, otherwise just let drivers and apps go figure?... We 
could set that flag centrally in __buf_prepare(), but since 
V4L2_BUF_FLAG_QUEUED is managed by individual drivers, we probably want to 
leave V4L2_BUF_FLAG_PREPARED like that too?

Thanks
Guennadi

> 
> Regards,
> 
> 	Hans
> 
> >  
> >  	int (*vidioc_overlay) (struct file *file, void *fh, unsigned int i);
> >  	int (*vidioc_g_fbuf)   (struct file *file, void *fh,
> > 
> 

---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v8] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-28  8:34                         ` Guennadi Liakhovetski
@ 2011-09-28  8:48                           ` Guennadi Liakhovetski
  2011-09-28  9:01                             ` Hans Verkuil
  0 siblings, 1 reply; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-09-28  8:48 UTC (permalink / raw)
  To: Hans Verkuil
  Cc: Sakari Ailus, Linux Media Mailing List, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

On Wed, 28 Sep 2011, Guennadi Liakhovetski wrote:

> Hi Hans
> 
> On Wed, 28 Sep 2011, Hans Verkuil wrote:
> 
> > On Tuesday, September 27, 2011 18:54:53 Guennadi Liakhovetski wrote:
> > > A possibility to preallocate and initialise buffers of different sizes
> > > in V4L2 is required for an efficient implementation of a snapshot
> > > mode. This patch adds two new ioctl()s: VIDIOC_CREATE_BUFS and
> > > VIDIOC_PREPARE_BUF and defines respective data structures.
> > > 
> > > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > > ---
> > > 
> > > v8: addressed comments from Hans - thanks:
> > > 
> > >     1. added checks in ioctl() preprocessing
> > >     2. changed VIDIOC_PREPARE_BUF to _IOWR
> > > 
> > >  drivers/media/video/v4l2-compat-ioctl32.c |   67 +++++++++++++++++++++++++---
> > >  drivers/media/video/v4l2-ioctl.c          |   36 +++++++++++++++
> > >  include/linux/videodev2.h                 |   17 +++++++
> > >  include/media/v4l2-ioctl.h                |    2 +
> > >  4 files changed, 114 insertions(+), 8 deletions(-)
> > > 
> > 
> > Almost:
> > 
> > > diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
> > > index 9d14523..7d75dd1 100644
> > > --- a/include/linux/videodev2.h
> > > +++ b/include/linux/videodev2.h
> > > @@ -653,6 +653,9 @@ struct v4l2_buffer {
> > >  #define V4L2_BUF_FLAG_ERROR	0x0040
> > >  #define V4L2_BUF_FLAG_TIMECODE	0x0100	/* timecode field is valid */
> > >  #define V4L2_BUF_FLAG_INPUT     0x0200  /* input field is valid */
> > > +/* Cache handling flags */
> > > +#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE	0x0400
> > > +#define V4L2_BUF_FLAG_NO_CACHE_CLEAN		0x0800
> > >  
> > >  /*
> > >   *	O V E R L A Y   P R E V I E W
> > > @@ -2099,6 +2102,15 @@ struct v4l2_dbg_chip_ident {
> > >  	__u32 revision;    /* chip revision, chip specific */
> > >  } __attribute__ ((packed));
> > >  
> > > +/* VIDIOC_CREATE_BUFS */
> > > +struct v4l2_create_buffers {
> > > +	__u32			index;		/* output: buffers index...index + count - 1 have been created */
> > > +	__u32			count;
> > > +	enum v4l2_memory        memory;
> > > +	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
> > > +	__u32			reserved[8];
> > > +};
> > > +
> > >  /*
> > >   *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
> > >   *
> > > @@ -2189,6 +2201,11 @@ struct v4l2_dbg_chip_ident {
> > >  #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct v4l2_event_subscription)
> > >  #define	VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
> > >  
> > > +/* Experimental, the below two ioctls may change over the next couple of kernel
> > > +   versions */
> > > +#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct v4l2_create_buffers)
> > > +#define VIDIOC_PREPARE_BUF	_IOWR('V', 93, struct v4l2_buffer)
> > > +
> > >  /* Reminder: when adding new ioctls please add support for them to
> > >     drivers/media/video/v4l2-compat-ioctl32.c as well! */
> > >  
> > > diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
> > > index dd9f1e7..55cf8ae 100644
> > > --- a/include/media/v4l2-ioctl.h
> > > +++ b/include/media/v4l2-ioctl.h
> > > @@ -122,6 +122,8 @@ struct v4l2_ioctl_ops {
> > >  	int (*vidioc_qbuf)    (struct file *file, void *fh, struct v4l2_buffer *b);
> > >  	int (*vidioc_dqbuf)   (struct file *file, void *fh, struct v4l2_buffer *b);
> > >  
> > > +	int (*vidioc_create_bufs)(struct file *file, void *fh, struct v4l2_create_buffers *b);
> > > +	int (*vidioc_prepare_buf)(struct file *file, void *fh, const struct v4l2_buffer *b);
> > 
> > If this is IOWR, then there shouldn't be a const here.
> 
> hrm... Sure.
> 
> > I have been thinking about this a bit more. Currently we only have a V4L2_BUF_FLAG_QUEUED
> > flag and no V4L2_BUF_FLAG_PREPARED flag. I do think we need this after all. The QUEUED flag
> > can't be used here as the buffer isn't queued yet, it's only prepared.
> 
> Ok, I can add it to this patch together with the other two cache-handling 
> flags. I presume, I shall also add it to
> 
> V4L2_BUFFER_STATE_FLAGS
> 
> in videobuf2-core.c, otherwise just let drivers and apps go figure?... We 
> could set that flag centrally in __buf_prepare(), but since 
> V4L2_BUF_FLAG_QUEUED is managed by individual drivers, we probably want to 
> leave V4L2_BUF_FLAG_PREPARED like that too?

Good, time to wake up. V4L2_BUF_FLAG_QUEUED is indeed set in 
videobuf2-core.c, so, I guess, the same should be done with 
V4L2_BUF_FLAG_PREPARED in __fill_v4l2_buffer().

Thanks
Guennadi

> > Regards,
> > 
> > 	Hans
> > 
> > >  
> > >  	int (*vidioc_overlay) (struct file *file, void *fh, unsigned int i);
> > >  	int (*vidioc_g_fbuf)   (struct file *file, void *fh,
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v8] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-28  8:48                           ` Guennadi Liakhovetski
@ 2011-09-28  9:01                             ` Hans Verkuil
  0 siblings, 0 replies; 59+ messages in thread
From: Hans Verkuil @ 2011-09-28  9:01 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Sakari Ailus, Linux Media Mailing List, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

On Wednesday, September 28, 2011 10:48:33 Guennadi Liakhovetski wrote:
> On Wed, 28 Sep 2011, Guennadi Liakhovetski wrote:
> 
> > Hi Hans
> > 
> > On Wed, 28 Sep 2011, Hans Verkuil wrote:
> > 
> > > On Tuesday, September 27, 2011 18:54:53 Guennadi Liakhovetski wrote:
> > > > A possibility to preallocate and initialise buffers of different sizes
> > > > in V4L2 is required for an efficient implementation of a snapshot
> > > > mode. This patch adds two new ioctl()s: VIDIOC_CREATE_BUFS and
> > > > VIDIOC_PREPARE_BUF and defines respective data structures.
> > > > 
> > > > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > > > ---
> > > > 
> > > > v8: addressed comments from Hans - thanks:
> > > > 
> > > >     1. added checks in ioctl() preprocessing
> > > >     2. changed VIDIOC_PREPARE_BUF to _IOWR
> > > > 
> > > >  drivers/media/video/v4l2-compat-ioctl32.c |   67 +++++++++++++++++++++++++---
> > > >  drivers/media/video/v4l2-ioctl.c          |   36 +++++++++++++++
> > > >  include/linux/videodev2.h                 |   17 +++++++
> > > >  include/media/v4l2-ioctl.h                |    2 +
> > > >  4 files changed, 114 insertions(+), 8 deletions(-)
> > > > 
> > > 
> > > Almost:
> > > 
> > > > diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
> > > > index 9d14523..7d75dd1 100644
> > > > --- a/include/linux/videodev2.h
> > > > +++ b/include/linux/videodev2.h
> > > > @@ -653,6 +653,9 @@ struct v4l2_buffer {
> > > >  #define V4L2_BUF_FLAG_ERROR	0x0040
> > > >  #define V4L2_BUF_FLAG_TIMECODE	0x0100	/* timecode field is valid */
> > > >  #define V4L2_BUF_FLAG_INPUT     0x0200  /* input field is valid */
> > > > +/* Cache handling flags */
> > > > +#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE	0x0400
> > > > +#define V4L2_BUF_FLAG_NO_CACHE_CLEAN		0x0800
> > > >  
> > > >  /*
> > > >   *	O V E R L A Y   P R E V I E W
> > > > @@ -2099,6 +2102,15 @@ struct v4l2_dbg_chip_ident {
> > > >  	__u32 revision;    /* chip revision, chip specific */
> > > >  } __attribute__ ((packed));
> > > >  
> > > > +/* VIDIOC_CREATE_BUFS */
> > > > +struct v4l2_create_buffers {
> > > > +	__u32			index;		/* output: buffers index...index + count - 1 have been created */
> > > > +	__u32			count;
> > > > +	enum v4l2_memory        memory;
> > > > +	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
> > > > +	__u32			reserved[8];
> > > > +};
> > > > +
> > > >  /*
> > > >   *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
> > > >   *
> > > > @@ -2189,6 +2201,11 @@ struct v4l2_dbg_chip_ident {
> > > >  #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct v4l2_event_subscription)
> > > >  #define	VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
> > > >  
> > > > +/* Experimental, the below two ioctls may change over the next couple of kernel
> > > > +   versions */
> > > > +#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct v4l2_create_buffers)
> > > > +#define VIDIOC_PREPARE_BUF	_IOWR('V', 93, struct v4l2_buffer)
> > > > +
> > > >  /* Reminder: when adding new ioctls please add support for them to
> > > >     drivers/media/video/v4l2-compat-ioctl32.c as well! */
> > > >  
> > > > diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
> > > > index dd9f1e7..55cf8ae 100644
> > > > --- a/include/media/v4l2-ioctl.h
> > > > +++ b/include/media/v4l2-ioctl.h
> > > > @@ -122,6 +122,8 @@ struct v4l2_ioctl_ops {
> > > >  	int (*vidioc_qbuf)    (struct file *file, void *fh, struct v4l2_buffer *b);
> > > >  	int (*vidioc_dqbuf)   (struct file *file, void *fh, struct v4l2_buffer *b);
> > > >  
> > > > +	int (*vidioc_create_bufs)(struct file *file, void *fh, struct v4l2_create_buffers *b);
> > > > +	int (*vidioc_prepare_buf)(struct file *file, void *fh, const struct v4l2_buffer *b);
> > > 
> > > If this is IOWR, then there shouldn't be a const here.
> > 
> > hrm... Sure.
> > 
> > > I have been thinking about this a bit more. Currently we only have a V4L2_BUF_FLAG_QUEUED
> > > flag and no V4L2_BUF_FLAG_PREPARED flag. I do think we need this after all. The QUEUED flag
> > > can't be used here as the buffer isn't queued yet, it's only prepared.
> > 
> > Ok, I can add it to this patch together with the other two cache-handling 
> > flags. I presume, I shall also add it to
> > 
> > V4L2_BUFFER_STATE_FLAGS
> > 
> > in videobuf2-core.c, otherwise just let drivers and apps go figure?... We 
> > could set that flag centrally in __buf_prepare(), but since 
> > V4L2_BUF_FLAG_QUEUED is managed by individual drivers, we probably want to 
> > leave V4L2_BUF_FLAG_PREPARED like that too?
> 
> Good, time to wake up. 

Good morning, Guennadi! :-)

> V4L2_BUF_FLAG_QUEUED is indeed set in 
> videobuf2-core.c, so, I guess, the same should be done with 
> V4L2_BUF_FLAG_PREPARED in __fill_v4l2_buffer().

Yup. Seems sensible to me.

Regards,

	Hans

> 
> Thanks
> Guennadi
> 
> > > Regards,
> > > 
> > > 	Hans
> > > 
> > > >  
> > > >  	int (*vidioc_overlay) (struct file *file, void *fh, unsigned int i);
> > > >  	int (*vidioc_g_fbuf)   (struct file *file, void *fh,
> ---
> Guennadi Liakhovetski, Ph.D.
> Freelance Open-Source Software Developer
> http://www.open-technology.de/
> 

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH 2/9 v9] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-27 16:54                     ` [PATCH 2/9 v8] " Guennadi Liakhovetski
  2011-09-28  8:06                       ` Hans Verkuil
@ 2011-09-28 13:19                       ` Guennadi Liakhovetski
  2011-09-28 13:33                         ` Sakari Ailus
  2011-09-28 14:56                         ` [PATCH 2/9 v10] " Guennadi Liakhovetski
  1 sibling, 2 replies; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-09-28 13:19 UTC (permalink / raw)
  To: Hans Verkuil
  Cc: Sakari Ailus, Linux Media Mailing List, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

A possibility to preallocate and initialise buffers of different sizes
in V4L2 is required for an efficient implementation of a snapshot
mode. This patch adds two new ioctl()s: VIDIOC_CREATE_BUFS and
VIDIOC_PREPARE_BUF and defines respective data structures.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v9:

1. added the V4L2_BUF_FLAG_PREPARED videobuffer flag
2. removed "const" from the .vidioc_prepare_buf() method argument

 drivers/media/video/v4l2-compat-ioctl32.c |   67 +++++++++++++++++++++++++---
 drivers/media/video/v4l2-ioctl.c          |   29 ++++++++++++
 include/linux/videodev2.h                 |   18 ++++++++
 include/media/v4l2-ioctl.h                |    2 +
 4 files changed, 108 insertions(+), 8 deletions(-)

diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
index 61979b7..85758d2 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -159,11 +159,16 @@ struct v4l2_format32 {
 	} fmt;
 };
 
-static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+struct v4l2_create_buffers32 {
+	__u32			index;		/* output: buffers index...index + count - 1 have been created */
+	__u32			count;
+	enum v4l2_memory        memory;
+	struct v4l2_format32	format;		/* filled in by the user, plane sizes calculated by the driver */
+	__u32			reserved[8];
+};
+
+static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
 {
-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
-			get_user(kp->type, &up->type))
-			return -EFAULT;
 	switch (kp->type) {
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
@@ -192,11 +197,24 @@ static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
 	}
 }
 
-static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+{
+	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
+			get_user(kp->type, &up->type))
+			return -EFAULT;
+	return __get_v4l2_format32(kp, up);
+}
+
+static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
+{
+	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)) ||
+	    copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format.fmt)))
+			return -EFAULT;
+	return __get_v4l2_format32(&kp->format, &up->format);
+}
+
+static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
 {
-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
-		put_user(kp->type, &up->type))
-		return -EFAULT;
 	switch (kp->type) {
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
@@ -225,6 +243,22 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
 	}
 }
 
+static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+{
+	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
+		put_user(kp->type, &up->type))
+		return -EFAULT;
+	return __put_v4l2_format32(kp, up);
+}
+
+static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
+{
+	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_create_buffers32)) ||
+	    copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format.fmt)))
+			return -EFAULT;
+	return __put_v4l2_format32(&kp->format, &up->format);
+}
+
 struct v4l2_standard32 {
 	__u32		     index;
 	__u32		     id[2]; /* __u64 would get the alignment wrong */
@@ -702,6 +736,8 @@ static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *u
 #define VIDIOC_S_EXT_CTRLS32    _IOWR('V', 72, struct v4l2_ext_controls32)
 #define VIDIOC_TRY_EXT_CTRLS32  _IOWR('V', 73, struct v4l2_ext_controls32)
 #define	VIDIOC_DQEVENT32	_IOR ('V', 89, struct v4l2_event32)
+#define VIDIOC_CREATE_BUFS32	_IOWR('V', 92, struct v4l2_create_buffers32)
+#define VIDIOC_PREPARE_BUF32	_IOW ('V', 93, struct v4l2_buffer32)
 
 #define VIDIOC_OVERLAY32	_IOW ('V', 14, s32)
 #define VIDIOC_STREAMON32	_IOW ('V', 18, s32)
@@ -721,6 +757,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
 		struct v4l2_standard v2s;
 		struct v4l2_ext_controls v2ecs;
 		struct v4l2_event v2ev;
+		struct v4l2_create_buffers v2crt;
 		unsigned long vx;
 		int vi;
 	} karg;
@@ -751,6 +788,8 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
 	case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break;
 	case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break;
 	case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break;
+	case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break;
+	case VIDIOC_PREPARE_BUF32: cmd = VIDIOC_PREPARE_BUF; break;
 	}
 
 	switch (cmd) {
@@ -775,6 +814,12 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
 		compatible_arg = 0;
 		break;
 
+	case VIDIOC_CREATE_BUFS:
+		err = get_v4l2_create32(&karg.v2crt, up);
+		compatible_arg = 0;
+		break;
+
+	case VIDIOC_PREPARE_BUF:
 	case VIDIOC_QUERYBUF:
 	case VIDIOC_QBUF:
 	case VIDIOC_DQBUF:
@@ -860,6 +905,10 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
 		err = put_v4l2_format32(&karg.v2f, up);
 		break;
 
+	case VIDIOC_CREATE_BUFS:
+		err = put_v4l2_create32(&karg.v2crt, up);
+		break;
+
 	case VIDIOC_QUERYBUF:
 	case VIDIOC_QBUF:
 	case VIDIOC_DQBUF:
@@ -959,6 +1008,8 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
 	case VIDIOC_DQEVENT32:
 	case VIDIOC_SUBSCRIBE_EVENT:
 	case VIDIOC_UNSUBSCRIBE_EVENT:
+	case VIDIOC_CREATE_BUFS32:
+	case VIDIOC_PREPARE_BUF32:
 		ret = do_video_ioctl(file, cmd, arg);
 		break;
 
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 21c49dc..3c2295b 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -273,6 +273,8 @@ static const char *v4l2_ioctls[] = {
 	[_IOC_NR(VIDIOC_DQEVENT)]	   = "VIDIOC_DQEVENT",
 	[_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)]  = "VIDIOC_SUBSCRIBE_EVENT",
 	[_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT",
+	[_IOC_NR(VIDIOC_CREATE_BUFS)]      = "VIDIOC_CREATE_BUFS",
+	[_IOC_NR(VIDIOC_PREPARE_BUF)]      = "VIDIOC_PREPARE_BUF",
 };
 #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
 
@@ -2096,6 +2098,33 @@ static long __video_do_ioctl(struct file *file,
 		dbgarg(cmd, "type=0x%8.8x", sub->type);
 		break;
 	}
+	case VIDIOC_CREATE_BUFS:
+	{
+		struct v4l2_create_buffers *create = arg;
+
+		if (!ops->vidioc_create_bufs)
+			break;
+		ret = check_fmt(ops, create->format.type);
+		if (ret)
+			break;
+
+		ret = ops->vidioc_create_bufs(file, fh, create);
+
+		dbgarg(cmd, "count=%d @ %d\n", create->count, create->index);
+		break;
+	}
+	case VIDIOC_PREPARE_BUF:
+	{
+		struct v4l2_buffer *b = arg;
+
+		if (!ops->vidioc_prepare_buf)
+			break;
+
+		ret = ops->vidioc_prepare_buf(file, fh, b);
+
+		dbgarg(cmd, "index=%d", b->index);
+		break;
+	}
 	default:
 		if (!ops->vidioc_default)
 			break;
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 9d14523..a552946 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -653,6 +653,10 @@ struct v4l2_buffer {
 #define V4L2_BUF_FLAG_ERROR	0x0040
 #define V4L2_BUF_FLAG_TIMECODE	0x0100	/* timecode field is valid */
 #define V4L2_BUF_FLAG_INPUT     0x0200  /* input field is valid */
+#define V4L2_BUF_FLAG_PREPARED	0x0400	/* Buffer is prepared for queuing */
+/* Cache handling flags */
+#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE	0x0800
+#define V4L2_BUF_FLAG_NO_CACHE_CLEAN		0x1000
 
 /*
  *	O V E R L A Y   P R E V I E W
@@ -2099,6 +2103,15 @@ struct v4l2_dbg_chip_ident {
 	__u32 revision;    /* chip revision, chip specific */
 } __attribute__ ((packed));
 
+/* VIDIOC_CREATE_BUFS */
+struct v4l2_create_buffers {
+	__u32			index;		/* output: buffers index...index + count - 1 have been created */
+	__u32			count;
+	enum v4l2_memory        memory;
+	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
+	__u32			reserved[8];
+};
+
 /*
  *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
  *
@@ -2189,6 +2202,11 @@ struct v4l2_dbg_chip_ident {
 #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct v4l2_event_subscription)
 #define	VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
 
+/* Experimental, the below two ioctls may change over the next couple of kernel
+   versions */
+#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct v4l2_create_buffers)
+#define VIDIOC_PREPARE_BUF	 _IOW('V', 93, struct v4l2_buffer)
+
 /* Reminder: when adding new ioctls please add support for them to
    drivers/media/video/v4l2-compat-ioctl32.c as well! */
 
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index dd9f1e7..4d1c74a 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -122,6 +122,8 @@ struct v4l2_ioctl_ops {
 	int (*vidioc_qbuf)    (struct file *file, void *fh, struct v4l2_buffer *b);
 	int (*vidioc_dqbuf)   (struct file *file, void *fh, struct v4l2_buffer *b);
 
+	int (*vidioc_create_bufs)(struct file *file, void *fh, struct v4l2_create_buffers *b);
+	int (*vidioc_prepare_buf)(struct file *file, void *fh, struct v4l2_buffer *b);
 
 	int (*vidioc_overlay) (struct file *file, void *fh, unsigned int i);
 	int (*vidioc_g_fbuf)   (struct file *file, void *fh,
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 3/9 v9] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s
  2011-09-27 17:01               ` [PATCH 3/9 v8] " Guennadi Liakhovetski
@ 2011-09-28 13:20                 ` Guennadi Liakhovetski
  2011-09-28 14:58                   ` [PATCH 3/9 v10] " Guennadi Liakhovetski
  0 siblings, 1 reply; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-09-28 13:20 UTC (permalink / raw)
  To: Hans Verkuil
  Cc: Sakari Ailus, Linux Media Mailing List, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v9: added documentation for the new V4L2_BUF_FLAG_PREPARED flag

 Documentation/DocBook/media/v4l/compat.xml         |    3 +
 Documentation/DocBook/media/v4l/io.xml             |   27 ++++
 Documentation/DocBook/media/v4l/v4l2.xml           |    2 +
 .../DocBook/media/v4l/vidioc-create-bufs.xml       |  147 ++++++++++++++++++++
 .../DocBook/media/v4l/vidioc-prepare-buf.xml       |   96 +++++++++++++
 5 files changed, 275 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
 create mode 100644 Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml

diff --git a/Documentation/DocBook/media/v4l/compat.xml b/Documentation/DocBook/media/v4l/compat.xml
index 91410b6..b68698f 100644
--- a/Documentation/DocBook/media/v4l/compat.xml
+++ b/Documentation/DocBook/media/v4l/compat.xml
@@ -2486,6 +2486,9 @@ ioctls.</para>
         <listitem>
 	  <para>Flash API. <xref linkend="flash-controls" /></para>
         </listitem>
+        <listitem>
+	  <para>&VIDIOC-CREATE-BUFS; and &VIDIOC-PREPARE-BUF; ioctls.</para>
+        </listitem>
       </itemizedlist>
     </section>
 
diff --git a/Documentation/DocBook/media/v4l/io.xml b/Documentation/DocBook/media/v4l/io.xml
index c57d1ec..3f47df1 100644
--- a/Documentation/DocBook/media/v4l/io.xml
+++ b/Documentation/DocBook/media/v4l/io.xml
@@ -927,6 +927,33 @@ ioctl is called.</entry>
 Applications set or clear this flag before calling the
 <constant>VIDIOC_QBUF</constant> ioctl.</entry>
 	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_FLAG_PREPARED</constant></entry>
+	    <entry>0x0400</entry>
+	    <entry>The buffer has been prepared for I/O and can be queued by the
+application. Drivers set or clear this flag when the
+<link linkend="vidioc-querybuf">VIDIOC_QUERYBUF</link>, <link
+	  linkend="vidioc-qbuf">VIDIOC_PREPARE_BUF</link>, <link
+	  linkend="vidioc-qbuf">VIDIOC_QBUF</link> or <link
+	  linkend="vidioc-qbuf">VIDIOC_DQBUF</link> ioctl is called.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant></entry>
+	    <entry>0x0400</entry>
+	    <entry>Caches do not have to be invalidated for this buffer.
+Typically applications shall use this flag if the data captured in the buffer
+is not going to be touched by the CPU, instead the buffer will, probably, be
+passed on to a DMA-capable hardware unit for further processing or output.
+</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant></entry>
+	    <entry>0x0800</entry>
+	    <entry>Caches do not have to be cleaned for this buffer.
+Typically applications shall use this flag for output buffers if the data
+in this buffer has not been created by the CPU but by some DMA-capable unit,
+in which case caches have not been used.</entry>
+	  </row>
 	</tbody>
       </tgroup>
     </table>
diff --git a/Documentation/DocBook/media/v4l/v4l2.xml b/Documentation/DocBook/media/v4l/v4l2.xml
index 40132c2..2ab365c 100644
--- a/Documentation/DocBook/media/v4l/v4l2.xml
+++ b/Documentation/DocBook/media/v4l/v4l2.xml
@@ -469,6 +469,7 @@ and discussions on the V4L mailing list.</revremark>
     &sub-close;
     &sub-ioctl;
     <!-- All ioctls go here. -->
+    &sub-create-bufs;
     &sub-cropcap;
     &sub-dbg-g-chip-ident;
     &sub-dbg-g-register;
@@ -511,6 +512,7 @@ and discussions on the V4L mailing list.</revremark>
     &sub-queryctrl;
     &sub-query-dv-preset;
     &sub-querystd;
+    &sub-prepare-buf;
     &sub-reqbufs;
     &sub-s-hw-freq-seek;
     &sub-streamon;
diff --git a/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
new file mode 100644
index 0000000..eb99604
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
@@ -0,0 +1,147 @@
+<refentry id="vidioc-create-bufs">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_CREATE_BUFS</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_CREATE_BUFS</refname>
+    <refpurpose>Create buffers for Memory Mapped or User Pointer I/O</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_create_buffers *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_CREATE_BUFS</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>This ioctl is used to create buffers for <link linkend="mmap">memory
+mapped</link> or <link linkend="userp">user pointer</link>
+I/O. It can be used as an alternative or in addition to the
+<constant>VIDIOC_REQBUFS</constant> ioctl, when a tighter control over buffers
+is required. This ioctl can be called multiple times to create buffers of
+different sizes.</para>
+
+    <para>To allocate device buffers applications initialize relevant fields of
+the <structname>v4l2_create_buffers</structname> structure. They set the
+<structfield>type</structfield> field in the
+<structname>v4l2_format</structname> structure, embedded in this
+structure, to the respective stream or buffer type.
+<structfield>count</structfield> must be set to the number of required buffers.
+<structfield>memory</structfield> specifies the required I/O method. The
+<structfield>format</structfield> field shall typically be filled in using
+either the <constant>VIDIOC_TRY_FMT</constant> or
+<constant>VIDIOC_G_FMT</constant> ioctl(). Additionally, applications can adjust
+<structfield>sizeimage</structfield> fields to fit their specific needs. The
+<structfield>reserved</structfield> array must be zeroed.</para>
+
+    <para>When the ioctl is called with a pointer to this structure the driver
+will attempt to allocate up to the requested number of buffers and store the
+actual number allocated and the starting index in the
+<structfield>count</structfield> and the <structfield>index</structfield> fields
+respectively. On return <structfield>count</structfield> can be smaller than
+the number requested. The driver may also adjust buffer sizes as it sees fit,
+however, it will not update <structfield>sizeimage</structfield> fields, the
+user has to use <constant>VIDIOC_QUERYBUF</constant> to retrieve that
+information.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-create-buffers">
+      <title>struct <structname>v4l2_create_buffers</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>index</structfield></entry>
+	    <entry>The starting buffer index, returned by the driver.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>count</structfield></entry>
+	    <entry>The number of buffers requested or granted.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-memory;</entry>
+	    <entry><structfield>memory</structfield></entry>
+	    <entry>Applications set this field to
+<constant>V4L2_MEMORY_MMAP</constant> or
+<constant>V4L2_MEMORY_USERPTR</constant>.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-format;</entry>
+	    <entry><structfield>format</structfield></entry>
+	    <entry>Filled in by the application, preserved by the driver.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[8]</entry>
+	    <entry>A place holder for future extensions.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>ENOMEM</errorcode></term>
+	<listitem>
+	  <para>No memory to allocate buffers for <link linkend="mmap">memory
+mapped</link> I/O.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The buffer type (<structfield>type</structfield> field) or the
+requested I/O method (<structfield>memory</structfield>) is not
+supported.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
new file mode 100644
index 0000000..509e752
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
@@ -0,0 +1,96 @@
+<refentry id="vidioc-prepare-buf">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_PREPARE_BUF</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_PREPARE_BUF</refname>
+    <refpurpose>Prepare a buffer for I/O</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_buffer *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_PREPARE_BUF</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>Applications can optionally call the
+<constant>VIDIOC_PREPARE_BUF</constant> ioctl to pass ownership of the buffer
+to the driver before actually enqueuing it, using the
+<constant>VIDIOC_QBUF</constant> ioctl, and to prepare it for future I/O.
+Such preparations may include cache invalidation or cleaning. Performing them
+in advance saves time during the actual I/O. In case such cache operations are
+not required, the application can use one of
+<constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant> and
+<constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant> flags to skip the respective
+step.</para>
+
+    <para>The <structname>v4l2_buffer</structname> structure is
+specified in <xref linkend="buffer" />.</para>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>File I/O is in progress.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The buffer <structfield>type</structfield> is not
+supported, or the <structfield>index</structfield> is out of bounds,
+or no buffers have been allocated yet, or the
+<structfield>userptr</structfield> or
+<structfield>length</structfield> are invalid.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v9] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-28 13:19                       ` [PATCH 2/9 v9] " Guennadi Liakhovetski
@ 2011-09-28 13:33                         ` Sakari Ailus
  2011-09-28 14:59                           ` Guennadi Liakhovetski
  2011-09-28 14:56                         ` [PATCH 2/9 v10] " Guennadi Liakhovetski
  1 sibling, 1 reply; 59+ messages in thread
From: Sakari Ailus @ 2011-09-28 13:33 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Hans Verkuil, Linux Media Mailing List, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

Guennadi Liakhovetski wrote:
> A possibility to preallocate and initialise buffers of different sizes
> in V4L2 is required for an efficient implementation of a snapshot
> mode. This patch adds two new ioctl()s: VIDIOC_CREATE_BUFS and
> VIDIOC_PREPARE_BUF and defines respective data structures.
> 
> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>

Hi Guennadi,

Thanks for the patch and your tireless efforts on this!

VIDIOC_PREPARE_BUF is actually _IOW (rather than _IOWR) in this patch. I
guess it shouldn't be this way, or have I failed to understand
something? :-)

[clip]

> @@ -2189,6 +2202,11 @@ struct v4l2_dbg_chip_ident {
>  #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct v4l2_event_subscription)
>  #define	VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
>  
> +/* Experimental, the below two ioctls may change over the next couple of kernel
> +   versions */
> +#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct v4l2_create_buffers)
> +#define VIDIOC_PREPARE_BUF	 _IOW('V', 93, struct v4l2_buffer)
> +
>  /* Reminder: when adding new ioctls please add support for them to
>     drivers/media/video/v4l2-compat-ioctl32.c as well! */
>  


-- 
Sakari Ailus
sakari.ailus@iki.fi

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH 2/9 v10] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-28 13:19                       ` [PATCH 2/9 v9] " Guennadi Liakhovetski
  2011-09-28 13:33                         ` Sakari Ailus
@ 2011-09-28 14:56                         ` Guennadi Liakhovetski
  2011-09-28 20:15                           ` Sakari Ailus
  1 sibling, 1 reply; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-09-28 14:56 UTC (permalink / raw)
  To: Hans Verkuil
  Cc: Sakari Ailus, Linux Media Mailing List, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

A possibility to preallocate and initialise buffers of different sizes
in V4L2 is required for an efficient implementation of a snapshot
mode. This patch adds two new ioctl()s: VIDIOC_CREATE_BUFS and
VIDIOC_PREPARE_BUF and defines respective data structures.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v10: merge v8 and v9

 drivers/media/video/v4l2-compat-ioctl32.c |   67 +++++++++++++++++++++++++---
 drivers/media/video/v4l2-ioctl.c          |   36 +++++++++++++++
 include/linux/videodev2.h                 |   18 ++++++++
 include/media/v4l2-ioctl.h                |    2 +
 4 files changed, 115 insertions(+), 8 deletions(-)

diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
index 61979b7..e77e0cf 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -159,11 +159,16 @@ struct v4l2_format32 {
 	} fmt;
 };
 
-static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+struct v4l2_create_buffers32 {
+	__u32			index;		/* output: buffers index...index + count - 1 have been created */
+	__u32			count;
+	enum v4l2_memory        memory;
+	struct v4l2_format32	format;		/* filled in by the user, plane sizes calculated by the driver */
+	__u32			reserved[8];
+};
+
+static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
 {
-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
-			get_user(kp->type, &up->type))
-			return -EFAULT;
 	switch (kp->type) {
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
@@ -192,11 +197,24 @@ static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
 	}
 }
 
-static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+{
+	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
+			get_user(kp->type, &up->type))
+			return -EFAULT;
+	return __get_v4l2_format32(kp, up);
+}
+
+static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
+{
+	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)) ||
+	    copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format.fmt)))
+			return -EFAULT;
+	return __get_v4l2_format32(&kp->format, &up->format);
+}
+
+static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
 {
-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
-		put_user(kp->type, &up->type))
-		return -EFAULT;
 	switch (kp->type) {
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
@@ -225,6 +243,22 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
 	}
 }
 
+static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+{
+	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
+		put_user(kp->type, &up->type))
+		return -EFAULT;
+	return __put_v4l2_format32(kp, up);
+}
+
+static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
+{
+	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_create_buffers32)) ||
+	    copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format.fmt)))
+			return -EFAULT;
+	return __put_v4l2_format32(&kp->format, &up->format);
+}
+
 struct v4l2_standard32 {
 	__u32		     index;
 	__u32		     id[2]; /* __u64 would get the alignment wrong */
@@ -702,6 +736,8 @@ static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *u
 #define VIDIOC_S_EXT_CTRLS32    _IOWR('V', 72, struct v4l2_ext_controls32)
 #define VIDIOC_TRY_EXT_CTRLS32  _IOWR('V', 73, struct v4l2_ext_controls32)
 #define	VIDIOC_DQEVENT32	_IOR ('V', 89, struct v4l2_event32)
+#define VIDIOC_CREATE_BUFS32	_IOWR('V', 92, struct v4l2_create_buffers32)
+#define VIDIOC_PREPARE_BUF32	_IOWR('V', 93, struct v4l2_buffer32)
 
 #define VIDIOC_OVERLAY32	_IOW ('V', 14, s32)
 #define VIDIOC_STREAMON32	_IOW ('V', 18, s32)
@@ -721,6 +757,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
 		struct v4l2_standard v2s;
 		struct v4l2_ext_controls v2ecs;
 		struct v4l2_event v2ev;
+		struct v4l2_create_buffers v2crt;
 		unsigned long vx;
 		int vi;
 	} karg;
@@ -751,6 +788,8 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
 	case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break;
 	case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break;
 	case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break;
+	case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break;
+	case VIDIOC_PREPARE_BUF32: cmd = VIDIOC_PREPARE_BUF; break;
 	}
 
 	switch (cmd) {
@@ -775,6 +814,12 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
 		compatible_arg = 0;
 		break;
 
+	case VIDIOC_CREATE_BUFS:
+		err = get_v4l2_create32(&karg.v2crt, up);
+		compatible_arg = 0;
+		break;
+
+	case VIDIOC_PREPARE_BUF:
 	case VIDIOC_QUERYBUF:
 	case VIDIOC_QBUF:
 	case VIDIOC_DQBUF:
@@ -860,6 +905,10 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
 		err = put_v4l2_format32(&karg.v2f, up);
 		break;
 
+	case VIDIOC_CREATE_BUFS:
+		err = put_v4l2_create32(&karg.v2crt, up);
+		break;
+
 	case VIDIOC_QUERYBUF:
 	case VIDIOC_QBUF:
 	case VIDIOC_DQBUF:
@@ -959,6 +1008,8 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
 	case VIDIOC_DQEVENT32:
 	case VIDIOC_SUBSCRIBE_EVENT:
 	case VIDIOC_UNSUBSCRIBE_EVENT:
+	case VIDIOC_CREATE_BUFS32:
+	case VIDIOC_PREPARE_BUF32:
 		ret = do_video_ioctl(file, cmd, arg);
 		break;
 
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 21c49dc..ff378eb 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -273,6 +273,8 @@ static const char *v4l2_ioctls[] = {
 	[_IOC_NR(VIDIOC_DQEVENT)]	   = "VIDIOC_DQEVENT",
 	[_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)]  = "VIDIOC_SUBSCRIBE_EVENT",
 	[_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT",
+	[_IOC_NR(VIDIOC_CREATE_BUFS)]      = "VIDIOC_CREATE_BUFS",
+	[_IOC_NR(VIDIOC_PREPARE_BUF)]      = "VIDIOC_PREPARE_BUF",
 };
 #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
 
@@ -2096,6 +2098,40 @@ static long __video_do_ioctl(struct file *file,
 		dbgarg(cmd, "type=0x%8.8x", sub->type);
 		break;
 	}
+	case VIDIOC_CREATE_BUFS:
+	{
+		struct v4l2_create_buffers *create = arg;
+
+		if (!ops->vidioc_create_bufs)
+			break;
+		if (ret_prio) {
+			ret = ret_prio;
+			break;
+		}
+		ret = check_fmt(ops, create->format.type);
+		if (ret)
+			break;
+
+		ret = ops->vidioc_create_bufs(file, fh, create);
+
+		dbgarg(cmd, "count=%d @ %d\n", create->count, create->index);
+		break;
+	}
+	case VIDIOC_PREPARE_BUF:
+	{
+		struct v4l2_buffer *b = arg;
+
+		if (!ops->vidioc_prepare_buf)
+			break;
+		ret = check_fmt(ops, b->type);
+		if (ret)
+			break;
+
+		ret = ops->vidioc_prepare_buf(file, fh, b);
+
+		dbgarg(cmd, "index=%d", b->index);
+		break;
+	}
 	default:
 		if (!ops->vidioc_default)
 			break;
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 9d14523..4c15b8b 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -653,6 +653,10 @@ struct v4l2_buffer {
 #define V4L2_BUF_FLAG_ERROR	0x0040
 #define V4L2_BUF_FLAG_TIMECODE	0x0100	/* timecode field is valid */
 #define V4L2_BUF_FLAG_INPUT     0x0200  /* input field is valid */
+#define V4L2_BUF_FLAG_PREPARED	0x0400	/* Buffer is prepared for queuing */
+/* Cache handling flags */
+#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE	0x0800
+#define V4L2_BUF_FLAG_NO_CACHE_CLEAN		0x1000
 
 /*
  *	O V E R L A Y   P R E V I E W
@@ -2099,6 +2103,15 @@ struct v4l2_dbg_chip_ident {
 	__u32 revision;    /* chip revision, chip specific */
 } __attribute__ ((packed));
 
+/* VIDIOC_CREATE_BUFS */
+struct v4l2_create_buffers {
+	__u32			index;		/* output: buffers index...index + count - 1 have been created */
+	__u32			count;
+	enum v4l2_memory        memory;
+	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
+	__u32			reserved[8];
+};
+
 /*
  *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
  *
@@ -2189,6 +2202,11 @@ struct v4l2_dbg_chip_ident {
 #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct v4l2_event_subscription)
 #define	VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
 
+/* Experimental, the below two ioctls may change over the next couple of kernel
+   versions */
+#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct v4l2_create_buffers)
+#define VIDIOC_PREPARE_BUF	_IOWR('V', 93, struct v4l2_buffer)
+
 /* Reminder: when adding new ioctls please add support for them to
    drivers/media/video/v4l2-compat-ioctl32.c as well! */
 
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index dd9f1e7..4d1c74a 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -122,6 +122,8 @@ struct v4l2_ioctl_ops {
 	int (*vidioc_qbuf)    (struct file *file, void *fh, struct v4l2_buffer *b);
 	int (*vidioc_dqbuf)   (struct file *file, void *fh, struct v4l2_buffer *b);
 
+	int (*vidioc_create_bufs)(struct file *file, void *fh, struct v4l2_create_buffers *b);
+	int (*vidioc_prepare_buf)(struct file *file, void *fh, struct v4l2_buffer *b);
 
 	int (*vidioc_overlay) (struct file *file, void *fh, unsigned int i);
 	int (*vidioc_g_fbuf)   (struct file *file, void *fh,
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 3/9 v10] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s
  2011-09-28 13:20                 ` [PATCH 3/9 v9] " Guennadi Liakhovetski
@ 2011-09-28 14:58                   ` Guennadi Liakhovetski
  0 siblings, 0 replies; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-09-28 14:58 UTC (permalink / raw)
  To: Hans Verkuil
  Cc: Sakari Ailus, Linux Media Mailing List, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v10: merge v8 and v9

 Documentation/DocBook/media/v4l/compat.xml         |    3 +
 Documentation/DocBook/media/v4l/io.xml             |   27 ++++
 Documentation/DocBook/media/v4l/v4l2.xml           |    2 +
 .../DocBook/media/v4l/vidioc-create-bufs.xml       |  147 ++++++++++++++++++++
 .../DocBook/media/v4l/vidioc-prepare-buf.xml       |   96 +++++++++++++
 5 files changed, 275 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
 create mode 100644 Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml

diff --git a/Documentation/DocBook/media/v4l/compat.xml b/Documentation/DocBook/media/v4l/compat.xml
index 91410b6..b68698f 100644
--- a/Documentation/DocBook/media/v4l/compat.xml
+++ b/Documentation/DocBook/media/v4l/compat.xml
@@ -2486,6 +2486,9 @@ ioctls.</para>
         <listitem>
 	  <para>Flash API. <xref linkend="flash-controls" /></para>
         </listitem>
+        <listitem>
+	  <para>&VIDIOC-CREATE-BUFS; and &VIDIOC-PREPARE-BUF; ioctls.</para>
+        </listitem>
       </itemizedlist>
     </section>
 
diff --git a/Documentation/DocBook/media/v4l/io.xml b/Documentation/DocBook/media/v4l/io.xml
index c57d1ec..3f47df1 100644
--- a/Documentation/DocBook/media/v4l/io.xml
+++ b/Documentation/DocBook/media/v4l/io.xml
@@ -927,6 +927,33 @@ ioctl is called.</entry>
 Applications set or clear this flag before calling the
 <constant>VIDIOC_QBUF</constant> ioctl.</entry>
 	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_FLAG_PREPARED</constant></entry>
+	    <entry>0x0400</entry>
+	    <entry>The buffer has been prepared for I/O and can be queued by the
+application. Drivers set or clear this flag when the
+<link linkend="vidioc-querybuf">VIDIOC_QUERYBUF</link>, <link
+	  linkend="vidioc-qbuf">VIDIOC_PREPARE_BUF</link>, <link
+	  linkend="vidioc-qbuf">VIDIOC_QBUF</link> or <link
+	  linkend="vidioc-qbuf">VIDIOC_DQBUF</link> ioctl is called.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant></entry>
+	    <entry>0x0400</entry>
+	    <entry>Caches do not have to be invalidated for this buffer.
+Typically applications shall use this flag if the data captured in the buffer
+is not going to be touched by the CPU, instead the buffer will, probably, be
+passed on to a DMA-capable hardware unit for further processing or output.
+</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant></entry>
+	    <entry>0x0800</entry>
+	    <entry>Caches do not have to be cleaned for this buffer.
+Typically applications shall use this flag for output buffers if the data
+in this buffer has not been created by the CPU but by some DMA-capable unit,
+in which case caches have not been used.</entry>
+	  </row>
 	</tbody>
       </tgroup>
     </table>
diff --git a/Documentation/DocBook/media/v4l/v4l2.xml b/Documentation/DocBook/media/v4l/v4l2.xml
index 40132c2..2ab365c 100644
--- a/Documentation/DocBook/media/v4l/v4l2.xml
+++ b/Documentation/DocBook/media/v4l/v4l2.xml
@@ -469,6 +469,7 @@ and discussions on the V4L mailing list.</revremark>
     &sub-close;
     &sub-ioctl;
     <!-- All ioctls go here. -->
+    &sub-create-bufs;
     &sub-cropcap;
     &sub-dbg-g-chip-ident;
     &sub-dbg-g-register;
@@ -511,6 +512,7 @@ and discussions on the V4L mailing list.</revremark>
     &sub-queryctrl;
     &sub-query-dv-preset;
     &sub-querystd;
+    &sub-prepare-buf;
     &sub-reqbufs;
     &sub-s-hw-freq-seek;
     &sub-streamon;
diff --git a/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
new file mode 100644
index 0000000..27d694d
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
@@ -0,0 +1,147 @@
+<refentry id="vidioc-create-bufs">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_CREATE_BUFS</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_CREATE_BUFS</refname>
+    <refpurpose>Create buffers for Memory Mapped or User Pointer I/O</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_create_buffers *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_CREATE_BUFS</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>This ioctl is used to create buffers for <link linkend="mmap">memory
+mapped</link> or <link linkend="userp">user pointer</link>
+I/O. It can be used as an alternative or in addition to the
+<constant>VIDIOC_REQBUFS</constant> ioctl, when a tighter control over buffers
+is required. This ioctl can be called multiple times to create buffers of
+different sizes.</para>
+
+    <para>To allocate device buffers applications initialize relevant fields of
+the <structname>v4l2_create_buffers</structname> structure. They set the
+<structfield>type</structfield> field in the
+<structname>v4l2_format</structname> structure, embedded in this
+structure, to the respective stream or buffer type.
+<structfield>count</structfield> must be set to the number of required buffers.
+<structfield>memory</structfield> specifies the required I/O method. The
+<structfield>format</structfield> field shall typically be filled in using
+either the <constant>VIDIOC_TRY_FMT</constant> or
+<constant>VIDIOC_G_FMT</constant> ioctl(). Additionally, applications can adjust
+<structfield>sizeimage</structfield> fields to fit their specific needs. The
+<structfield>reserved</structfield> array must be zeroed.</para>
+
+    <para>When the ioctl is called with a pointer to this structure the driver
+will attempt to allocate up to the requested number of buffers and store the
+actual number allocated and the starting index in the
+<structfield>count</structfield> and the <structfield>index</structfield> fields
+respectively. On return <structfield>count</structfield> can be smaller than
+the number requested. The driver may also increase buffer sizes if required,
+however, it will not update <structfield>sizeimage</structfield> field values.
+The user has to use <constant>VIDIOC_QUERYBUF</constant> to retrieve that
+information.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-create-buffers">
+      <title>struct <structname>v4l2_create_buffers</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>index</structfield></entry>
+	    <entry>The starting buffer index, returned by the driver.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>count</structfield></entry>
+	    <entry>The number of buffers requested or granted.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-memory;</entry>
+	    <entry><structfield>memory</structfield></entry>
+	    <entry>Applications set this field to
+<constant>V4L2_MEMORY_MMAP</constant> or
+<constant>V4L2_MEMORY_USERPTR</constant>.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-format;</entry>
+	    <entry><structfield>format</structfield></entry>
+	    <entry>Filled in by the application, preserved by the driver.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[8]</entry>
+	    <entry>A place holder for future extensions.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>ENOMEM</errorcode></term>
+	<listitem>
+	  <para>No memory to allocate buffers for <link linkend="mmap">memory
+mapped</link> I/O.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The buffer type (<structfield>type</structfield> field) or the
+requested I/O method (<structfield>memory</structfield>) is not
+supported.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
new file mode 100644
index 0000000..509e752
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
@@ -0,0 +1,96 @@
+<refentry id="vidioc-prepare-buf">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_PREPARE_BUF</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_PREPARE_BUF</refname>
+    <refpurpose>Prepare a buffer for I/O</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_buffer *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_PREPARE_BUF</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>Applications can optionally call the
+<constant>VIDIOC_PREPARE_BUF</constant> ioctl to pass ownership of the buffer
+to the driver before actually enqueuing it, using the
+<constant>VIDIOC_QBUF</constant> ioctl, and to prepare it for future I/O.
+Such preparations may include cache invalidation or cleaning. Performing them
+in advance saves time during the actual I/O. In case such cache operations are
+not required, the application can use one of
+<constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant> and
+<constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant> flags to skip the respective
+step.</para>
+
+    <para>The <structname>v4l2_buffer</structname> structure is
+specified in <xref linkend="buffer" />.</para>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>File I/O is in progress.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The buffer <structfield>type</structfield> is not
+supported, or the <structfield>index</structfield> is out of bounds,
+or no buffers have been allocated yet, or the
+<structfield>userptr</structfield> or
+<structfield>length</structfield> are invalid.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v9] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-28 13:33                         ` Sakari Ailus
@ 2011-09-28 14:59                           ` Guennadi Liakhovetski
  0 siblings, 0 replies; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-09-28 14:59 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Hans Verkuil, Linux Media Mailing List, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

Hi Sakari

On Wed, 28 Sep 2011, Sakari Ailus wrote:

> Guennadi Liakhovetski wrote:
> > A possibility to preallocate and initialise buffers of different sizes
> > in V4L2 is required for an efficient implementation of a snapshot
> > mode. This patch adds two new ioctl()s: VIDIOC_CREATE_BUFS and
> > VIDIOC_PREPARE_BUF and defines respective data structures.
> > 
> > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> 
> Hi Guennadi,
> 
> Thanks for the patch and your tireless efforts on this!
> 
> VIDIOC_PREPARE_BUF is actually _IOW (rather than _IOWR) in this patch. I
> guess it shouldn't be this way, or have I failed to understand
> something? :-)

hm, yeah, sure, thanks for catching.

Guennadi

> 
> [clip]
> 
> > @@ -2189,6 +2202,11 @@ struct v4l2_dbg_chip_ident {
> >  #define	VIDIOC_SUBSCRIBE_EVENT	 _IOW('V', 90, struct v4l2_event_subscription)
> >  #define	VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
> >  
> > +/* Experimental, the below two ioctls may change over the next couple of kernel
> > +   versions */
> > +#define VIDIOC_CREATE_BUFS	_IOWR('V', 92, struct v4l2_create_buffers)
> > +#define VIDIOC_PREPARE_BUF	 _IOW('V', 93, struct v4l2_buffer)
> > +
> >  /* Reminder: when adding new ioctls please add support for them to
> >     drivers/media/video/v4l2-compat-ioctl32.c as well! */
> >  
> 
> 
> -- 
> Sakari Ailus
> sakari.ailus@iki.fi
> 

---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v10] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-28 14:56                         ` [PATCH 2/9 v10] " Guennadi Liakhovetski
@ 2011-09-28 20:15                           ` Sakari Ailus
  2011-09-28 20:38                             ` Guennadi Liakhovetski
  0 siblings, 1 reply; 59+ messages in thread
From: Sakari Ailus @ 2011-09-28 20:15 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Hans Verkuil, Linux Media Mailing List, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

Hi Guennadi,

On Wed, Sep 28, 2011 at 04:56:11PM +0200, Guennadi Liakhovetski wrote:
> @@ -2099,6 +2103,15 @@ struct v4l2_dbg_chip_ident {
>  	__u32 revision;    /* chip revision, chip specific */
>  } __attribute__ ((packed));
>  
> +/* VIDIOC_CREATE_BUFS */
> +struct v4l2_create_buffers {
> +	__u32			index;		/* output: buffers index...index + count - 1 have been created */
> +	__u32			count;
> +	enum v4l2_memory        memory;
> +	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
> +	__u32			reserved[8];
> +};

What about the kerneldoc comments you wrote right after v6 on 1st September
for v4l2_create_buffers and the same for the compat32 version?

-- 
Sakari Ailus
e-mail: sakari.ailus@iki.fi	jabber/XMPP/Gmail: sailus@retiisi.org.uk

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 1/1] v4l: Add note on buffer locking to memory and DMA mapping to PREPARE_BUF
  2011-09-01 11:08       ` [PATCH 1/1] v4l: Add note on buffer locking to memory and DMA mapping to PREPARE_BUF Sakari Ailus
@ 2011-09-28 20:20         ` Sakari Ailus
  2011-09-28 20:31           ` Guennadi Liakhovetski
  0 siblings, 1 reply; 59+ messages in thread
From: Sakari Ailus @ 2011-09-28 20:20 UTC (permalink / raw)
  To: g.liakhovetski
  Cc: linux-media, hverkuil, laurent.pinchart, pawel, mchehab, m.szyprowski

Hi Guennadi,

What's your opinion on this? I was intended to complement the PREPARE_BUF
documentation.

On Thu, Sep 01, 2011 at 02:08:56PM +0300, Sakari Ailus wrote:
> Add note to documentation of VIDIOC_PREPARE_BUF that the preparation done by
> the IOCTL may include locking buffers to system memory and creating DMA
> mappings for them.
> 
> Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
> ---
>  .../DocBook/media/v4l/vidioc-prepare-buf.xml       |    8 +++++---
>  1 files changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
> index 509e752..7177c2f 100644
> --- a/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
> +++ b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
> @@ -52,9 +52,11 @@
>  <constant>VIDIOC_PREPARE_BUF</constant> ioctl to pass ownership of the buffer
>  to the driver before actually enqueuing it, using the
>  <constant>VIDIOC_QBUF</constant> ioctl, and to prepare it for future I/O.
> -Such preparations may include cache invalidation or cleaning. Performing them
> -in advance saves time during the actual I/O. In case such cache operations are
> -not required, the application can use one of
> +Such preparations may include locking the buffer to system memory and
> +creating DMA mapping for it (on the first time
> +<constant>VIDIOC_PREPARE_BUF</constant> is called), cache invalidation or
> +cleaning. Performing them in advance saves time during the actual I/O. In
> +case such cache operations are not required, the application can use one of
>  <constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant> and
>  <constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant> flags to skip the respective
>  step.</para>
> -- 
> 1.7.2.5
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Sakari Ailus
e-mail: sakari.ailus@iki.fi	jabber/XMPP/Gmail: sailus@retiisi.org.uk

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 1/1] v4l: Add note on buffer locking to memory and DMA mapping to PREPARE_BUF
  2011-09-28 20:20         ` Sakari Ailus
@ 2011-09-28 20:31           ` Guennadi Liakhovetski
  0 siblings, 0 replies; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-09-28 20:31 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, hverkuil, laurent.pinchart, pawel, mchehab, m.szyprowski

On Wed, 28 Sep 2011, Sakari Ailus wrote:

> Hi Guennadi,
> 
> What's your opinion on this? I was intended to complement the PREPARE_BUF
> documentation.

I don't think I have a very strong opinion about this. AFAIU this is so 
far just a (yet another) speculation about what the driver might want or 
need to do in PREPARE_BUF. Let's wait until the author of these patches 
manages to get them straight (...) and until all the reviewers are 
satisfied:-) Then you're certainly welcome to submit any improvement you 
see fit, then the usual suspects will express their opinions on them. So, 
business as usual, I would say;-)

Thanks
Guennadi

> 
> On Thu, Sep 01, 2011 at 02:08:56PM +0300, Sakari Ailus wrote:
> > Add note to documentation of VIDIOC_PREPARE_BUF that the preparation done by
> > the IOCTL may include locking buffers to system memory and creating DMA
> > mappings for them.
> > 
> > Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
> > ---
> >  .../DocBook/media/v4l/vidioc-prepare-buf.xml       |    8 +++++---
> >  1 files changed, 5 insertions(+), 3 deletions(-)
> > 
> > diff --git a/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
> > index 509e752..7177c2f 100644
> > --- a/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
> > +++ b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
> > @@ -52,9 +52,11 @@
> >  <constant>VIDIOC_PREPARE_BUF</constant> ioctl to pass ownership of the buffer
> >  to the driver before actually enqueuing it, using the
> >  <constant>VIDIOC_QBUF</constant> ioctl, and to prepare it for future I/O.
> > -Such preparations may include cache invalidation or cleaning. Performing them
> > -in advance saves time during the actual I/O. In case such cache operations are
> > -not required, the application can use one of
> > +Such preparations may include locking the buffer to system memory and
> > +creating DMA mapping for it (on the first time
> > +<constant>VIDIOC_PREPARE_BUF</constant> is called), cache invalidation or
> > +cleaning. Performing them in advance saves time during the actual I/O. In
> > +case such cache operations are not required, the application can use one of
> >  <constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant> and
> >  <constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant> flags to skip the respective
> >  step.</para>
> > -- 
> > 1.7.2.5
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-media" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> -- 
> Sakari Ailus
> e-mail: sakari.ailus@iki.fi	jabber/XMPP/Gmail: sailus@retiisi.org.uk
> 

---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v10] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-28 20:15                           ` Sakari Ailus
@ 2011-09-28 20:38                             ` Guennadi Liakhovetski
  2011-09-29  6:59                               ` Sakari Ailus
  0 siblings, 1 reply; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-09-28 20:38 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Hans Verkuil, Linux Media Mailing List, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

On Wed, 28 Sep 2011, Sakari Ailus wrote:

> Hi Guennadi,
> 
> On Wed, Sep 28, 2011 at 04:56:11PM +0200, Guennadi Liakhovetski wrote:
> > @@ -2099,6 +2103,15 @@ struct v4l2_dbg_chip_ident {
> >  	__u32 revision;    /* chip revision, chip specific */
> >  } __attribute__ ((packed));
> >  
> > +/* VIDIOC_CREATE_BUFS */
> > +struct v4l2_create_buffers {
> > +	__u32			index;		/* output: buffers index...index + count - 1 have been created */
> > +	__u32			count;
> > +	enum v4l2_memory        memory;
> > +	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
> > +	__u32			reserved[8];
> > +};
> 
> What about the kerneldoc comments you wrote right after v6 on 1st September
> for v4l2_create_buffers and the same for the compat32 version?

Looks like someone is trying very hard to cause me a heart failure;-) They 
are in a separate patch:

http://patchwork.linuxtv.org/patch/338/

and let's leave it that way.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v10] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-28 20:38                             ` Guennadi Liakhovetski
@ 2011-09-29  6:59                               ` Sakari Ailus
  2011-09-29  8:12                                 ` Guennadi Liakhovetski
  0 siblings, 1 reply; 59+ messages in thread
From: Sakari Ailus @ 2011-09-29  6:59 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Hans Verkuil, Linux Media Mailing List, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

Guennadi Liakhovetski wrote:
> On Wed, 28 Sep 2011, Sakari Ailus wrote:
>
>> Hi Guennadi,
>>
>> On Wed, Sep 28, 2011 at 04:56:11PM +0200, Guennadi Liakhovetski wrote:
>>> @@ -2099,6 +2103,15 @@ struct v4l2_dbg_chip_ident {
>>>   	__u32 revision;    /* chip revision, chip specific */
>>>   } __attribute__ ((packed));
>>>
>>> +/* VIDIOC_CREATE_BUFS */
>>> +struct v4l2_create_buffers {
>>> +	__u32			index;		/* output: buffers index...index + count - 1 have been created */
>>> +	__u32			count;
>>> +	enum v4l2_memory        memory;
>>> +	struct v4l2_format	format;		/* "type" is used always, the rest if sizeimage == 0 */
>>> +	__u32			reserved[8];
>>> +};
>>
>> What about the kerneldoc comments you wrote right after v6 on 1st September
>> for v4l2_create_buffers and the same for the compat32 version?
>
> Looks like someone is trying very hard to cause me a heart failure;-) They
> are in a separate patch:

No, I don't! :-) I'm just interested all the appropriate changes are in 
the patchset. My understanding was you intended to add these changes to 
the original patches.

Are you planning to put them to the same patchset still, or a different one?

Cheers,

-- 
Sakari Ailus
sakari.ailus@iki.fi

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/9 v10] V4L: add two new ioctl()s for multi-size videobuffer management
  2011-09-29  6:59                               ` Sakari Ailus
@ 2011-09-29  8:12                                 ` Guennadi Liakhovetski
  0 siblings, 0 replies; 59+ messages in thread
From: Guennadi Liakhovetski @ 2011-09-29  8:12 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Hans Verkuil, Linux Media Mailing List, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Mauro Carvalho Chehab,
	Marek Szyprowski

On Thu, 29 Sep 2011, Sakari Ailus wrote:

> Guennadi Liakhovetski wrote:
> > On Wed, 28 Sep 2011, Sakari Ailus wrote:
> > 
> > > Hi Guennadi,
> > > 
> > > On Wed, Sep 28, 2011 at 04:56:11PM +0200, Guennadi Liakhovetski wrote:
> > > > @@ -2099,6 +2103,15 @@ struct v4l2_dbg_chip_ident {
> > > >   	__u32 revision;    /* chip revision, chip specific */
> > > >   } __attribute__ ((packed));
> > > > 
> > > > +/* VIDIOC_CREATE_BUFS */
> > > > +struct v4l2_create_buffers {
> > > > +	__u32			index;		/* output: buffers
> > > > index...index + count - 1 have been created */
> > > > +	__u32			count;
> > > > +	enum v4l2_memory        memory;
> > > > +	struct v4l2_format	format;		/* "type" is used always, the
> > > > rest if sizeimage == 0 */
> > > > +	__u32			reserved[8];
> > > > +};
> > > 
> > > What about the kerneldoc comments you wrote right after v6 on 1st
> > > September
> > > for v4l2_create_buffers and the same for the compat32 version?
> > 
> > Looks like someone is trying very hard to cause me a heart failure;-) They
> > are in a separate patch:
> 
> No, I don't! :-) I'm just interested all the appropriate changes are in the
> patchset. My understanding was you intended to add these changes to the
> original patches.
> 
> Are you planning to put them to the same patchset still, or a different one?

The same.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 3/9 v6] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s
  2011-08-31 18:02 ` [PATCH 3/9 v6] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s Guennadi Liakhovetski
  2011-08-31 21:11   ` Sakari Ailus
@ 2011-11-03 12:13   ` Mauro Carvalho Chehab
  1 sibling, 0 replies; 59+ messages in thread
From: Mauro Carvalho Chehab @ 2011-11-03 12:13 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Linux Media Mailing List, Hans Verkuil, Laurent Pinchart,
	Pawel Osciak, Sakari Ailus, Marek Szyprowski

Em 31-08-2011 15:02, Guennadi Liakhovetski escreveu:

...

> +<!--
> +Local Variables:
> +mode: sgml
> +sgml-parent-document: "v4l2.sgml"
> +indent-tabs-mode: nil
> +End:
> +-->


Please, don't add emacs crap into the files. This violates CodingStyle, and won't
bring anything to the file, as developers can use any editors to edit it, that
won't understand emacs specific stuff, and might want to add their own crap on it.

Don't bother re-sending me the entire series just due to that. It is easier to me
to just drop this when merging than to re-read the other 68 patches that are 
before this one.

Regards,
Mauro




^ permalink raw reply	[flat|nested] 59+ messages in thread

end of thread, other threads:[~2011-11-03 12:13 UTC | newest]

Thread overview: 59+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-31 18:02 [PATCH 0/9 v6] new ioctl()s and soc-camera implementation Guennadi Liakhovetski
2011-08-31 18:02 ` [PATCH 1/9 v6] V4L: add a new videobuf2 buffer state VB2_BUF_STATE_PREPARED Guennadi Liakhovetski
2011-08-31 18:02 ` [PATCH 2/9 v6] V4L: add two new ioctl()s for multi-size videobuffer management Guennadi Liakhovetski
2011-08-31 21:06   ` Sakari Ailus
2011-09-01  7:03     ` Guennadi Liakhovetski
2011-09-01  8:35       ` Laurent Pinchart
2011-09-01  8:53         ` Guennadi Liakhovetski
2011-09-01  8:42       ` Sakari Ailus
2011-09-01  9:24         ` Guennadi Liakhovetski
2011-09-01 10:19           ` Sakari Ailus
2011-09-01 10:51             ` Guennadi Liakhovetski
2011-09-01 11:06               ` Sakari Ailus
2011-09-01 13:35                 ` Laurent Pinchart
2011-09-01 13:45                   ` Guennadi Liakhovetski
2011-09-08  7:45         ` [PATCH 2/9 v7] " Guennadi Liakhovetski
2011-09-08  7:46           ` [PATCH 3/9 v7] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s Guennadi Liakhovetski
2011-09-09 13:24             ` Laurent Pinchart
2011-09-27 10:51             ` Hans Verkuil
2011-09-27 15:49               ` Guennadi Liakhovetski
2011-09-27 19:50                 ` Sakari Ailus
2011-09-28  7:34                 ` Hans Verkuil
2011-09-27 17:01               ` [PATCH 3/9 v8] " Guennadi Liakhovetski
2011-09-28 13:20                 ` [PATCH 3/9 v9] " Guennadi Liakhovetski
2011-09-28 14:58                   ` [PATCH 3/9 v10] " Guennadi Liakhovetski
2011-09-08  7:48           ` [PATCH] V4L: docbook documentation for struct v4l2_create_buffers Guennadi Liakhovetski
2011-09-08  8:10           ` [PATCH 1/1] v4l: Mark VIDIOC_PREPARE_BUFS and VIDIOC_CREATE_BUFS experimental Sakari Ailus
2011-09-27 10:34           ` [PATCH 2/9 v7] V4L: add two new ioctl()s for multi-size videobuffer management Hans Verkuil
2011-09-27 11:00             ` Guennadi Liakhovetski
2011-09-27 11:06               ` Hans Verkuil
2011-09-27 12:19                 ` Guennadi Liakhovetski
2011-09-27 13:40                   ` Hans Verkuil
2011-09-27 16:54                     ` [PATCH 2/9 v8] " Guennadi Liakhovetski
2011-09-28  8:06                       ` Hans Verkuil
2011-09-28  8:34                         ` Guennadi Liakhovetski
2011-09-28  8:48                           ` Guennadi Liakhovetski
2011-09-28  9:01                             ` Hans Verkuil
2011-09-28 13:19                       ` [PATCH 2/9 v9] " Guennadi Liakhovetski
2011-09-28 13:33                         ` Sakari Ailus
2011-09-28 14:59                           ` Guennadi Liakhovetski
2011-09-28 14:56                         ` [PATCH 2/9 v10] " Guennadi Liakhovetski
2011-09-28 20:15                           ` Sakari Ailus
2011-09-28 20:38                             ` Guennadi Liakhovetski
2011-09-29  6:59                               ` Sakari Ailus
2011-09-29  8:12                                 ` Guennadi Liakhovetski
2011-09-27 17:08             ` [PATCH 2/9 v7] " Laurent Pinchart
2011-09-28  8:09               ` Hans Verkuil
2011-08-31 18:02 ` [PATCH 3/9 v6] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s Guennadi Liakhovetski
2011-08-31 21:11   ` Sakari Ailus
2011-09-01  7:10     ` Guennadi Liakhovetski
2011-09-01 11:08       ` [PATCH 1/1] v4l: Add note on buffer locking to memory and DMA mapping to PREPARE_BUF Sakari Ailus
2011-09-28 20:20         ` Sakari Ailus
2011-09-28 20:31           ` Guennadi Liakhovetski
2011-11-03 12:13   ` [PATCH 3/9 v6] V4L: document the new VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctl()s Mauro Carvalho Chehab
2011-08-31 18:02 ` [PATCH 4/9 v6] V4L: vb2: prepare to support multi-size buffers Guennadi Liakhovetski
2011-08-31 18:02 ` [PATCH 5/9 v6] V4L: vb2: add support for buffers of different sizes on a single queue Guennadi Liakhovetski
2011-08-31 18:02 ` [PATCH 6/9 v6] V4L: sh-mobile-ceu-camera: prepare to support multi-size buffers Guennadi Liakhovetski
2011-08-31 18:02 ` [PATCH 7/9 v6] dmaengine: ipu-idmac: add support for the DMA_PAUSE control Guennadi Liakhovetski
2011-08-31 18:02 ` [PATCH 8/9 v6] V4L: mx3-camera: prepare to support multi-size buffers Guennadi Liakhovetski
2011-08-31 18:02 ` [PATCH 9/9 v6] V4L: soc-camera: add 2 new ioctl() handlers Guennadi Liakhovetski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.