Hi,

today I released v4l-test 0.8. Please find attached the patch for LTP.

Changes:
Test cases added for VIDIOC_G_CROP, VIDIOC_G_CTRL and VIDIOC_S_CTRL.

Signed-off-by: Márton Németh <[email protected]>

Regards,

        Márton Németh

---
v4l-test home page: http://v4l-test.sourceforge.net/
diff -uprN ltp.orig/testcases/kernel/device-drivers/v4l/user_space/doc/index.html ltp/testcases/kernel/device-drivers/v4l/user_space/doc/index.html
--- ltp.orig/testcases/kernel/device-drivers/v4l/user_space/doc/index.html	2009-02-16 06:13:54.000000000 +0100
+++ ltp/testcases/kernel/device-drivers/v4l/user_space/doc/index.html	2009-02-22 16:53:27.000000000 +0100
@@ -209,7 +209,7 @@ implemented test cases.</p>
     </tr>
     <tr>
       <td>ioctl <a href="spec/r9994.htm">VIDIOC_G_CROP</a></td>
-      <td>no</td>
+      <td>yes, only when STREAM_OFF</td>
       <td>Opt.</td>
     </tr>
     <tr>
@@ -219,12 +219,12 @@ implemented test cases.</p>
     </tr>
     <tr>
       <td>ioctl <a href="spec/r10104.htm">VIDIOC_G_CTRL</a></td>
-      <td>no</td>
+      <td>yes, only when STREAM_OFF</td>
       <td><br></td>
     </tr>
     <tr>
       <td>ioctl <a href="spec/r10104.htm">VIDIOC_S_CTRL</a></td>
-      <td>no</td>
+      <td>yes, only when STREAM_OFF</td>
       <td><br></td>
     </tr>
     <tr>
@@ -509,7 +509,7 @@ The following documents and articles are
 <p>Any feedbacks, comments, ideas, etc. are welcome at the author's email address.</p>
 <hr style="width: 100%; height: 2px;">
 <p>Last changed:
-Mon Feb  9 07:41:37 2009
+Sun Feb 22 16:53:17 CET 2009
 </p>
 <p>
   <a href="http://validator.w3.org/check?uri=referer";><img
diff -uprN ltp.orig/testcases/kernel/device-drivers/v4l/user_space/Makefile ltp/testcases/kernel/device-drivers/v4l/user_space/Makefile
--- ltp.orig/testcases/kernel/device-drivers/v4l/user_space/Makefile	2009-02-16 06:13:54.000000000 +0100
+++ ltp/testcases/kernel/device-drivers/v4l/user_space/Makefile	2009-02-19 21:31:37.000000000 +0100
@@ -1,6 +1,7 @@
 #
 # v4l-test: Test environment for Video For Linux Two API
 #
+# 19 Feb 2009  0.9  test_VIDIOC_CTRL.c added
 #  7 Feb 2009  0.8  test_VIDIOC_CROP.c added
 #  3 Feb 2009  0.7  test_VIDIOC_AUDIO.c added,
 #                   test_VIDIOC_AUDOUT.c added,
@@ -48,6 +49,7 @@ OBJS = dev_video.o \
        test_VIDIOC_PRIORITY.o \
        test_VIDIOC_AUDIO.o \
        test_VIDIOC_AUDOUT.o \
+       test_VIDIOC_CTRL.o \
        test_invalid_ioctl.o \
        v4l2_test.o
 
diff -uprN ltp.orig/testcases/kernel/device-drivers/v4l/user_space/README ltp/testcases/kernel/device-drivers/v4l/user_space/README
--- ltp.orig/testcases/kernel/device-drivers/v4l/user_space/README	2009-02-16 06:13:54.000000000 +0100
+++ ltp/testcases/kernel/device-drivers/v4l/user_space/README	2009-02-22 16:58:37.000000000 +0100
@@ -4,7 +4,8 @@
 Release History
 ---------------
 
- 9 Feb 2009  0.10 Test cases added for VIDIOC_G_AUDIO, VIDIOC_G_AUDOUT,
+22 Feb 2009  0.8  Test cases added for VIDIOC_G_CROP, VIDIOC_G_CTRL and VIDIOC_S_CTRL
+ 9 Feb 2009  0.7  Test cases added for VIDIOC_G_AUDIO, VIDIOC_G_AUDOUT,
                   VIDIOC_S_AUDIO and VIDIOC_G_CROP;
                   Added video_dummy kernel driver to verify the test
                   environment;
diff -uprN ltp.orig/testcases/kernel/device-drivers/v4l/user_space/test_VIDIOC_CROP.c ltp/testcases/kernel/device-drivers/v4l/user_space/test_VIDIOC_CROP.c
--- ltp.orig/testcases/kernel/device-drivers/v4l/user_space/test_VIDIOC_CROP.c	2009-02-16 06:13:54.000000000 +0100
+++ ltp/testcases/kernel/device-drivers/v4l/user_space/test_VIDIOC_CROP.c	2009-02-13 23:16:08.000000000 +0100
@@ -1,6 +1,7 @@
 /*
  * v4l-test: Test environment for Video For Linux Two API
  *
+ * 13 Feb 2009  0.2  Test cases added for VIDIOC_G_CROP
  *  7 Feb 2009  0.1  First release
  *
  * Written by Márton Németh <[email protected]>
@@ -23,15 +24,17 @@
 #include "test_VIDIOC_CROP.h"
 
 
-void test_VIDIOC_G_CROP() {
+void do_get_crop(enum v4l2_buf_type type) {
 	int ret1, errno1;
 	struct v4l2_crop crop;
 
 	memset(&crop, 0xff, sizeof(crop));
+	crop.type = type;
 	ret1 = ioctl(get_video_fd(), VIDIOC_G_CROP, &crop);
 	errno1 = errno;
 
-	dprintf("VIDIOC_G_CROP ret1=%i, errno1=%i\n", ret1, errno1);
+	dprintf("\tVIDIOC_G_CROP: type=%i, ret1=%i, errno1=%i\n",
+		type, ret1, errno1);
 
 	if (ret1 == 0) {
 		CU_ASSERT_EQUAL(ret1, 0);
@@ -39,38 +42,96 @@ void test_VIDIOC_G_CROP() {
 	} else {
 		CU_ASSERT_EQUAL(ret1, -1);
 		CU_ASSERT_EQUAL(errno1, EINVAL);
-
 	}
 
 }
 
+void test_VIDIOC_G_CROP() {
+	do_get_crop(V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	do_get_crop(V4L2_BUF_TYPE_VIDEO_OUTPUT);
+	do_get_crop(V4L2_BUF_TYPE_VIDEO_OVERLAY);
+}
+
+
+void do_get_crop_invalid(enum v4l2_buf_type type) {
+	int ret1, errno1;
+	struct v4l2_crop crop;
+
+	memset(&crop, 0xff, sizeof(crop));
+	crop.type = type;
+	ret1 = ioctl(get_video_fd(), VIDIOC_G_CROP, &crop);
+	errno1 = errno;
+
+	dprintf("\tVIDIOC_G_CROP: type=%i, ret1=%i, errno1=%i\n",
+		type, ret1, errno1);
+
+	CU_ASSERT_EQUAL(ret1, -1);
+	CU_ASSERT_EQUAL(errno1, EINVAL);
+}
+
+void test_VIDIOC_G_CROP_invalid() {
+	do_get_crop_invalid(0);
+	do_get_crop_invalid(V4L2_BUF_TYPE_VBI_CAPTURE);
+	do_get_crop_invalid(V4L2_BUF_TYPE_VBI_OUTPUT);
+	do_get_crop_invalid(V4L2_BUF_TYPE_SLICED_VBI_CAPTURE);
+	do_get_crop_invalid(V4L2_BUF_TYPE_SLICED_VBI_OUTPUT);
+	do_get_crop_invalid(V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY);
+	do_get_crop_invalid(V4L2_BUF_TYPE_PRIVATE);
+	do_get_crop_invalid(S32_MAX);
+	do_get_crop_invalid( ((__u32)S32_MAX)+1 );
+	do_get_crop_invalid(U32_MAX);
+}
+
 void test_VIDIOC_G_CROP_NULL() {
 	int ret1, errno1;
 	int ret2, errno2;
+	int ret3, errno3;
+	int ret4, errno4;
 	struct v4l2_crop crop;
 
-	memset(&crop, 0xff, sizeof(crop));
+	memset(&crop, 0, sizeof(crop));
+	crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
 	ret1 = ioctl(get_video_fd(), VIDIOC_G_CROP, &crop);
 	errno1 = errno;
 
 	dprintf("VIDIOC_G_CROP ret1=%i, errno1=%i\n", ret1, errno1);
 
-	memset(&crop, 0xff, sizeof(crop));
-	ret2 = ioctl(get_video_fd(), VIDIOC_G_CROP, NULL);
+	memset(&crop, 0, sizeof(crop));
+	crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+
+	ret2 = ioctl(get_video_fd(), VIDIOC_G_CROP, &crop);
 	errno2 = errno;
 
 	dprintf("VIDIOC_G_CROP ret2=%i, errno2=%i\n", ret2, errno2);
 
-	if (ret1 == 0) {
-		CU_ASSERT_EQUAL(ret1, 0);
-		CU_ASSERT_EQUAL(ret2, -1);
-		CU_ASSERT_EQUAL(errno2, EFAULT);
+	memset(&crop, 0, sizeof(crop));
+	crop.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
+
+	ret3 = ioctl(get_video_fd(), VIDIOC_G_CROP, &crop);
+	errno3 = errno;
+
+	dprintf("VIDIOC_G_CROP ret3=%i, errno3=%i\n", ret3, errno3);
+
+
+	ret4 = ioctl(get_video_fd(), VIDIOC_G_CROP, NULL);
+	errno4 = errno;
+
+	dprintf("VIDIOC_G_CROP ret4=%i, errno4=%i\n", ret4, errno4);
+
+	if (ret1 == 0 || ret2 == 0 || ret3 == 0) {
+		CU_ASSERT_EQUAL(ret4, -1);
+		CU_ASSERT_EQUAL(errno4, EFAULT);
 
 	} else {
 		CU_ASSERT_EQUAL(ret1, -1);
 		CU_ASSERT_EQUAL(errno1, EINVAL);
 		CU_ASSERT_EQUAL(ret2, -1);
 		CU_ASSERT_EQUAL(errno2, EINVAL);
+		CU_ASSERT_EQUAL(ret3, -1);
+		CU_ASSERT_EQUAL(errno3, EINVAL);
+		CU_ASSERT_EQUAL(ret4, -1);
+		CU_ASSERT_EQUAL(errno4, EINVAL);
 
 	}
 
diff -uprN ltp.orig/testcases/kernel/device-drivers/v4l/user_space/test_VIDIOC_CROP.h ltp/testcases/kernel/device-drivers/v4l/user_space/test_VIDIOC_CROP.h
--- ltp.orig/testcases/kernel/device-drivers/v4l/user_space/test_VIDIOC_CROP.h	2009-02-16 06:13:54.000000000 +0100
+++ ltp/testcases/kernel/device-drivers/v4l/user_space/test_VIDIOC_CROP.h	2009-02-13 23:05:18.000000000 +0100
@@ -1,6 +1,7 @@
 /*
  * v4l-test: Test environment for Video For Linux Two API
  *
+ * 13 Feb 2009  0.2  Test cases added for VIDIOC_G_CROP
  *  7 Feb 2009  0.1  First release
  *
  * Written by Márton Németh <[email protected]>
@@ -8,4 +9,5 @@
  */
 
 void test_VIDIOC_G_CROP(void);
+void test_VIDIOC_G_CROP_invalid(void);
 void test_VIDIOC_G_CROP_NULL(void);
diff -uprN ltp.orig/testcases/kernel/device-drivers/v4l/user_space/test_VIDIOC_CTRL.c ltp/testcases/kernel/device-drivers/v4l/user_space/test_VIDIOC_CTRL.c
--- ltp.orig/testcases/kernel/device-drivers/v4l/user_space/test_VIDIOC_CTRL.c	1970-01-01 01:00:00.000000000 +0100
+++ ltp/testcases/kernel/device-drivers/v4l/user_space/test_VIDIOC_CTRL.c	2009-02-22 16:35:59.000000000 +0100
@@ -0,0 +1,951 @@
+/*
+ * v4l-test: Test environment for Video For Linux Two API
+ *
+ * 22 Feb 2009  0.2  Added test cases for VIDIOC_S_CTRL
+ * 19 Feb 2009  0.1  First release
+ *
+ * Written by Márton Németh <[email protected]>
+ * Released under GPL
+ */
+
+/*
+ * Note: V4L2_CID_LASTP1 != V4L2_CID_BASE_LASTP1
+ */
+
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <string.h>
+
+#include <linux/videodev2.h>
+#include <linux/errno.h>
+
+#include <CUnit/CUnit.h>
+
+#include "v4l2_test.h"
+#include "dev_video.h"
+#include "video_limits.h"
+
+#include "test_VIDIOC_CTRL.h"
+
+int do_get_control(__u32 id) {
+	int ret1, errno1;
+	int ret2, errno2;
+	struct v4l2_queryctrl queryctrl;
+	struct v4l2_control control;
+
+	/* The expected return value of VIDIOC_G_CTRL depens on the value
+	 * reported by VIDIOC_QUERYCTRL
+	 */
+
+	memset(&queryctrl, 0, sizeof(queryctrl));
+	queryctrl.id = id;
+	ret1 = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl);
+	errno1 = errno;
+
+	dprintf("\t%s:%u: VIDIOC_QUERYCTRL, id=%u (V4L2_CID_BASE+%i), ret1=%i, errno1=%i\n",
+		__FILE__, __LINE__, id, id-V4L2_CID_BASE, ret1, errno1);
+	if (ret1 == 0) {
+		dprintf("\t%s:%u: queryctrl = {.id=%u, .type=%i, .name=\"%s\", "
+		".minimum=%i, .maximum=%i, .step=%i, "
+		".default_value=%i, "
+		".flags=0x%X, "
+		".reserved[]={ 0x%X, 0x%X } }\n",
+		__FILE__, __LINE__,
+		queryctrl.id,
+		queryctrl.type,
+		queryctrl.name,
+		queryctrl.minimum,
+		queryctrl.maximum,
+		queryctrl.step,
+		queryctrl.default_value,
+		queryctrl.flags,
+		queryctrl.reserved[0],
+		queryctrl.reserved[1]
+		);
+	}
+
+	memset(&control, 0xff, sizeof(control));
+	control.id = id;
+	ret2 = ioctl(get_video_fd(), VIDIOC_G_CTRL, &control);
+	errno2 = errno;
+
+	dprintf("\tVIDIOC_G_CTRL, id=%u (V4L2_CID_BASE+%i), ret2=%i, errno2=%i\n",
+		id, id-V4L2_CID_BASE, ret2, errno2);
+
+	if (ret1 == 0) {
+		CU_ASSERT_EQUAL(ret1, 0);
+
+		switch (queryctrl.type) {
+		case V4L2_CTRL_TYPE_INTEGER:
+		case V4L2_CTRL_TYPE_BOOLEAN:
+		case V4L2_CTRL_TYPE_MENU:
+			CU_ASSERT_EQUAL(ret2, 0);
+			if (ret2 == 0) {
+				CU_ASSERT(queryctrl.minimum <= control.value);
+				CU_ASSERT(control.value <= queryctrl.maximum);
+			}
+			break;
+
+		case V4L2_CTRL_TYPE_BUTTON:
+			/* This control only performs an action, does not have
+			 * any value
+			 */
+			CU_ASSERT_EQUAL(ret2, -1);
+			CU_ASSERT_EQUAL(errno2, EINVAL);
+			break;
+
+		case V4L2_CTRL_TYPE_INTEGER64: /* TODO: what about this case? */
+		case V4L2_CTRL_TYPE_CTRL_CLASS:
+		default:
+			CU_ASSERT_EQUAL(ret2, -1);
+			CU_ASSERT_EQUAL(errno2, -1);
+		}
+	} else {
+		CU_ASSERT_EQUAL(ret1, -1);
+		CU_ASSERT_EQUAL(errno1, EINVAL);
+
+		CU_ASSERT_EQUAL(ret2, -1);
+		CU_ASSERT_EQUAL(errno2, EINVAL);
+
+	}
+
+	return ret1;
+}
+
+void test_VIDIOC_G_CTRL() {
+	int ret1;
+	__u32 i;
+
+	for (i = V4L2_CID_BASE; i < V4L2_CID_LASTP1; i++) {
+		ret1 = do_get_control(i);
+	}
+
+	ret1 = do_get_control(V4L2_CID_BASE-1);
+	ret1 = do_get_control(V4L2_CID_LASTP1);
+	ret1 = do_get_control(V4L2_CID_PRIVATE_BASE-1);
+
+	i = V4L2_CID_PRIVATE_BASE;
+	do {
+		ret1 = do_get_control(i);
+		i++;
+	} while (ret1 == 0);
+
+	ret1 = do_get_control(i);
+}
+
+void test_VIDIOC_G_CTRL_NULL() {
+	int ret;
+
+	ret = ioctl(get_video_fd(), VIDIOC_G_CTRL, NULL);
+	CU_ASSERT_EQUAL(ret, -1);
+	CU_ASSERT_EQUAL(errno, EFAULT);
+
+}
+
+int do_set_control(__u32 id) {
+	int ret1, errno1;
+	int ret_set, errno_set;
+	int ret_get, errno_get;
+	int ret_orig, errno_orig;
+	struct v4l2_queryctrl queryctrl;
+	struct v4l2_control control_orig;
+	struct v4l2_control control;
+	struct v4l2_control control_new;
+	__s32 value;
+
+	/* The expected return value of VIDIOC_S_CTRL depens on the value
+	 * reported by VIDIOC_QUERYCTRL. The allowed limits are also
+	 * reported by VIDIOC_QUERYCTRL.
+	 */
+
+	memset(&queryctrl, 0, sizeof(queryctrl));
+	queryctrl.id = id;
+	ret1 = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl);
+	errno1 = errno;
+
+	dprintf("\t%s:%u: VIDIOC_QUERYCTRL, id=%u (V4L2_CID_BASE+%i), ret1=%i, errno1=%i\n",
+		__FILE__, __LINE__, id, id-V4L2_CID_BASE, ret1, errno1);
+	if (ret1 == 0) {
+		dprintf("\t%s:%u: queryctrl = {.id=%u, .type=%i, .name=\"%s\", "
+		".minimum=%i, .maximum=%i, .step=%i, "
+		".default_value=%i, "
+		".flags=0x%X, "
+		".reserved[]={ 0x%X, 0x%X } }\n",
+		__FILE__, __LINE__,
+		queryctrl.id,
+		queryctrl.type,
+		queryctrl.name,
+		queryctrl.minimum,
+		queryctrl.maximum,
+		queryctrl.step,
+		queryctrl.default_value,
+		queryctrl.flags,
+		queryctrl.reserved[0],
+		queryctrl.reserved[1]
+		);
+	}
+
+	memset(&control_orig, 0, sizeof(control_orig));
+	control_orig.id = id;
+	ret_orig = ioctl(get_video_fd(), VIDIOC_G_CTRL, &control_orig);
+	errno_orig = errno;
+
+	dprintf("\t%s:%u: VIDIOC_G_CTRL, id=%u (V4L2_CID_BASE+%i), ret_orig=%i, errno_orig=%i, control_orig.value=%i\n",
+		__FILE__, __LINE__, id, id-V4L2_CID_BASE, ret_orig, errno_orig, control_orig.value);
+
+	if (ret1 == 0) {
+		CU_ASSERT_EQUAL(ret1, 0);
+
+		switch (queryctrl.type) {
+		case V4L2_CTRL_TYPE_INTEGER:
+		case V4L2_CTRL_TYPE_BOOLEAN:
+		case V4L2_CTRL_TYPE_MENU:
+
+			/* TODO: this is an infinite loop if queryctrl.maximum == S32_MAX */
+			for (value = queryctrl.minimum; value <= queryctrl.maximum; value++) {
+				memset(&control, 0xff, sizeof(control));
+				control.id = id;
+				control.value = value;
+				ret_set = ioctl(get_video_fd(), VIDIOC_S_CTRL, &control);
+				errno_set = errno;
+
+				dprintf("\t%s:%u: VIDIOC_S_CTRL, id=%u (V4L2_CID_BASE+%i), value=%i, ret_set=%i, errno_set=%i\n",
+					__FILE__, __LINE__, id, id-V4L2_CID_BASE, value, ret_set, errno_set);
+
+				if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED ||
+				    queryctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) {
+					CU_ASSERT_EQUAL(ret_set, -1);
+					CU_ASSERT_EQUAL(errno_set, EINVAL);
+				} else if (queryctrl.flags & V4L2_CTRL_FLAG_GRABBED) {
+					CU_ASSERT_EQUAL(ret_set, -1);
+					CU_ASSERT_EQUAL(errno_set, EBUSY);
+				} else {
+					CU_ASSERT_EQUAL(ret_set, 0);
+				}
+
+				memset(&control_new, 0, sizeof(control_new));
+				control_new.id = id;
+				ret_get = ioctl(get_video_fd(), VIDIOC_G_CTRL, &control_new);
+				errno_get = errno;
+
+				dprintf("\t%s:%u: VIDIOC_G_CTRL, id=%u (V4L2_CID_BASE+%i), ret_get=%i, errno_get=%i, control_new.value=%i\n",
+					__FILE__, __LINE__, id, id-V4L2_CID_BASE, ret_get, errno_get, control_new.value);
+
+				CU_ASSERT_EQUAL(ret_get, 0);
+				if (ret_get == 0) {
+					CU_ASSERT(queryctrl.minimum <= control_new.value);
+					CU_ASSERT(control_new.value <= queryctrl.maximum);
+
+					if (ret_set == 0) {
+						/* TODO: the following checks works correctly only if
+						 * S32_MIN <= queryctrl.minimum-queryctrl.step and
+						 * queryctrl.maximum+queryctrl.step <= S32_MAX
+						 */
+						 
+/*
+ * If we try to set the new control value to "value" then the possible results can be
+ * "x" and "x-step". These two values can be expressed with the range
+ * (value-step, value+step) where the ranges are not included. 
+ *
+ *           value-step        value         value+step
+ *              |                |                |
+ *              |                v                |
+ *              +----------------+----------------+
+ *               *********************************
+ * ... -+----------------+----------------+----------------+----------------+- ...
+ *      |                |                |                |                |
+ *   x-2*step          x-step             x              x+step          x+2*step
+ *
+ * The following figure shows the case when we try to set value to "x" which is
+ * a possible set value. In this case the only valid result is the "x".
+ *
+ *                    value-step        value         value+step
+ *                       |                |                |
+ *                       |                v                |
+ *                       +----------------+----------------+
+ *                        *********************************
+ * ... -+----------------+----------------+----------------+----------------+- ...
+ *      |                |                |                |                |
+ *   x-2*step          x-step             x              x+step          x+2*step
+ *
+ *
+ *                                    value-step        value         value+step
+ *                                       |                |                |
+ *                                       |                v                |
+ *                                       +----------------+----------------+
+ *                                        *********************************
+ * ... -+----------------+----------------+----------------+----------------+- ...
+ *      |                |                |                |                |
+ *   x-2*step          x-step             x              x+step          x+2*step
+ *
+ *
+ */
+						CU_ASSERT(value-queryctrl.step < control_new.value);
+						CU_ASSERT(control_new.value < value+queryctrl.step);
+					}
+				}
+
+			}
+
+			break;
+
+		case V4L2_CTRL_TYPE_BUTTON:
+			/* This control only performs an action, does not have
+			 * any value
+			 */
+			CU_ASSERT_EQUAL(ret_orig, -1);
+			CU_ASSERT_EQUAL(errno_orig, EINVAL);
+
+			/* The set value shall be ignored by button controls */
+
+			memset(&control, 0xff, sizeof(control));
+			control.id = id;
+			control.value = S32_MIN;
+			ret_set = ioctl(get_video_fd(), VIDIOC_S_CTRL, &control);
+			errno_set = errno;
+
+			if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED ||
+			    queryctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) {
+				CU_ASSERT_EQUAL(ret_set, -1);
+				CU_ASSERT_EQUAL(errno_set, EINVAL);
+			} else if (queryctrl.flags & V4L2_CTRL_FLAG_GRABBED) {
+				CU_ASSERT_EQUAL(ret_set, -1);
+				CU_ASSERT_EQUAL(errno_set, EBUSY);
+			} else {
+				CU_ASSERT_EQUAL(ret_set, 0);
+			}
+
+			memset(&control, 0xff, sizeof(control));
+			control.id = id;
+			control.value = -1;
+			ret_set = ioctl(get_video_fd(), VIDIOC_S_CTRL, &control);
+			errno_set = errno;
+
+			if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED ||
+			    queryctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) {
+				CU_ASSERT_EQUAL(ret_set, -1);
+				CU_ASSERT_EQUAL(errno_set, EINVAL);
+			} else if (queryctrl.flags & V4L2_CTRL_FLAG_GRABBED) {
+				CU_ASSERT_EQUAL(ret_set, -1);
+				CU_ASSERT_EQUAL(errno_set, EBUSY);
+			} else {
+				CU_ASSERT_EQUAL(ret_set, 0);
+			}
+
+			memset(&control, 0xff, sizeof(control));
+			control.id = id;
+			control.value = 0;
+			ret_set = ioctl(get_video_fd(), VIDIOC_S_CTRL, &control);
+			errno_set = errno;
+
+			if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED ||
+			    queryctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) {
+				CU_ASSERT_EQUAL(ret_set, -1);
+				CU_ASSERT_EQUAL(errno_set, EINVAL);
+			} else if (queryctrl.flags & V4L2_CTRL_FLAG_GRABBED) {
+				CU_ASSERT_EQUAL(ret_set, -1);
+				CU_ASSERT_EQUAL(errno_set, EBUSY);
+			} else {
+				CU_ASSERT_EQUAL(ret_set, 0);
+			}
+
+			memset(&control, 0xff, sizeof(control));
+			control.id = id;
+			control.value = 1;
+			ret_set = ioctl(get_video_fd(), VIDIOC_S_CTRL, &control);
+			errno_set = errno;
+
+			if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED ||
+			    queryctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) {
+				CU_ASSERT_EQUAL(ret_set, -1);
+				CU_ASSERT_EQUAL(errno_set, EINVAL);
+			} else if (queryctrl.flags & V4L2_CTRL_FLAG_GRABBED) {
+				CU_ASSERT_EQUAL(ret_set, -1);
+				CU_ASSERT_EQUAL(errno_set, EBUSY);
+			} else {
+				CU_ASSERT_EQUAL(ret_set, 0);
+			}
+
+			memset(&control, 0xff, sizeof(control));
+			control.id = id;
+			control.value = S32_MAX;
+			ret_set = ioctl(get_video_fd(), VIDIOC_S_CTRL, &control);
+			errno_set = errno;
+
+			if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED ||
+			    queryctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) {
+				CU_ASSERT_EQUAL(ret_set, -1);
+				CU_ASSERT_EQUAL(errno_set, EINVAL);
+			} else if (queryctrl.flags & V4L2_CTRL_FLAG_GRABBED) {
+				CU_ASSERT_EQUAL(ret_set, -1);
+				CU_ASSERT_EQUAL(errno_set, EBUSY);
+			} else {
+				CU_ASSERT_EQUAL(ret_set, 0);
+			}
+
+			break;
+
+		case V4L2_CTRL_TYPE_INTEGER64: /* TODO: what about this case? */
+		case V4L2_CTRL_TYPE_CTRL_CLASS:
+		default:
+			CU_ASSERT_EQUAL(ret_orig, -1);
+			CU_ASSERT_EQUAL(errno_orig, -1);
+		}
+	} else {
+		CU_ASSERT_EQUAL(ret1, -1);
+		CU_ASSERT_EQUAL(errno1, EINVAL);
+
+		CU_ASSERT_EQUAL(ret_orig, -1);
+		CU_ASSERT_EQUAL(errno_orig, EINVAL);
+
+
+	}
+
+	if (ret_orig == 0) {
+		CU_ASSERT_EQUAL(ret_orig, 0);
+
+		/* restore the original control value */
+		value = control_orig.value;
+		memset(&control, 0xff, sizeof(control));
+		control.id = id;
+		control.value = value;
+		ret_set = ioctl(get_video_fd(), VIDIOC_S_CTRL, &control);
+		errno_set = errno;
+
+		dprintf("\t%s:%u: VIDIOC_S_CTRL, id=%u (V4L2_CID_BASE+%i), value=%i, ret_set=%i, errno_set=%i\n",
+			__FILE__, __LINE__, id, id-V4L2_CID_BASE, value, ret_set, errno_set);
+
+		/* it shall be possible to set to the original value if the control
+		 * is not disabled, read only or grabbed by other application
+		 */
+		if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED ||
+		    queryctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) {
+			CU_ASSERT_EQUAL(ret_set, -1);
+			CU_ASSERT_EQUAL(errno_set, EINVAL);
+		} else if (queryctrl.flags & V4L2_CTRL_FLAG_GRABBED) {
+			CU_ASSERT_EQUAL(ret_set, -1);
+			CU_ASSERT_EQUAL(errno_set, EBUSY);
+		} else {
+			CU_ASSERT_EQUAL(ret_set, 0);
+		}
+
+		memset(&control_new, 0, sizeof(control_new));
+		control_new.id = id;
+		ret_get = ioctl(get_video_fd(), VIDIOC_G_CTRL, &control_new);
+		errno_get = errno;
+
+		dprintf("\t%s:%u: VIDIOC_G_CTRL, id=%u (V4L2_CID_BASE+%i), ret_get=%i, errno_get=%i, control_new.value=%i\n",
+			__FILE__, __LINE__, id, id-V4L2_CID_BASE, ret_get, errno_get, control_new.value);
+
+		CU_ASSERT_EQUAL(ret_get, 0);
+		if (ret_get == 0) {
+			CU_ASSERT(queryctrl.minimum <= control_new.value);
+			CU_ASSERT(control_new.value <= queryctrl.maximum);
+			CU_ASSERT_EQUAL(control_new.value, control_orig.value);
+		}
+
+	}
+
+	return ret1;
+}
+
+int do_set_control_invalid(__u32 id) {
+	int ret1, errno1;
+	int ret_set, errno_set;
+	int ret_get, errno_get;
+	int ret_orig, errno_orig;
+	struct v4l2_queryctrl queryctrl;
+	struct v4l2_control control_orig;
+	struct v4l2_control control;
+	struct v4l2_control control_new;
+	__s32 value;
+
+	/* The expected return value of VIDIOC_S_CTRL depens on the value
+	 * reported by VIDIOC_QUERYCTRL. The allowed limits are also
+	 * reported by VIDIOC_QUERYCTRL.
+	 */
+
+	memset(&queryctrl, 0, sizeof(queryctrl));
+	queryctrl.id = id;
+	ret1 = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl);
+	errno1 = errno;
+
+	dprintf("\t%s:%u: VIDIOC_QUERYCTRL, id=%u (V4L2_CID_BASE+%i), ret1=%i, errno1=%i\n",
+		__FILE__, __LINE__, id, id-V4L2_CID_BASE, ret1, errno1);
+	if (ret1 == 0) {
+		dprintf("\t%s:%u: queryctrl = {.id=%u, .type=%i, .name=\"%s\", "
+		".minimum=%i, .maximum=%i, .step=%i, "
+		".default_value=%i, "
+		".flags=0x%X, "
+		".reserved[]={ 0x%X, 0x%X } }\n",
+		__FILE__, __LINE__,
+		queryctrl.id,
+		queryctrl.type,
+		queryctrl.name,
+		queryctrl.minimum,
+		queryctrl.maximum,
+		queryctrl.step,
+		queryctrl.default_value,
+		queryctrl.flags,
+		queryctrl.reserved[0],
+		queryctrl.reserved[1]
+		);
+	}
+
+	memset(&control_orig, 0, sizeof(control_orig));
+	control_orig.id = id;
+	ret_orig = ioctl(get_video_fd(), VIDIOC_G_CTRL, &control_orig);
+	errno_orig = errno;
+
+	dprintf("\t%s:%u: VIDIOC_G_CTRL, id=%u (V4L2_CID_BASE+%i), ret_orig=%i, errno_orig=%i, control_orig.value=%i\n",
+		__FILE__, __LINE__, id, id-V4L2_CID_BASE, ret_orig, errno_orig, control_orig.value);
+
+	if (ret1 == 0) {
+		CU_ASSERT_EQUAL(ret1, 0);
+
+		switch (queryctrl.type) {
+		case V4L2_CTRL_TYPE_INTEGER:
+		case V4L2_CTRL_TYPE_BOOLEAN:
+		case V4L2_CTRL_TYPE_MENU:
+			if (S32_MIN < queryctrl.minimum) {
+			
+				value = S32_MIN;
+				memset(&control, 0xff, sizeof(control));
+				control.id = id;
+				control.value = value;
+				ret_set = ioctl(get_video_fd(), VIDIOC_S_CTRL, &control);
+				errno_set = errno;
+
+				dprintf("\t%s:%u: VIDIOC_S_CTRL, id=%u (V4L2_CID_BASE+%i), value=%i, ret_set=%i, errno_set=%i\n",
+					__FILE__, __LINE__, id, id-V4L2_CID_BASE, value, ret_set, errno_set);
+
+				/* The driver can decide if it returns ERANGE or
+				 * accepts the value and converts it to
+				 * the nearest limit
+				 */
+				if (ret_set == -1) {
+					CU_ASSERT_EQUAL(ret_set, -1);
+					if (!(queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) &&
+					    !(queryctrl.flags & V4L2_CTRL_FLAG_READ_ONLY)) {
+						CU_ASSERT_EQUAL(errno_set, ERANGE);
+					} else {
+						CU_ASSERT_EQUAL(errno_set, EINVAL);
+					}
+
+					/* check whether the new value is not out of bounds */
+					memset(&control_new, 0, sizeof(control_new));
+					control_new.id = id;
+					ret_get = ioctl(get_video_fd(), VIDIOC_G_CTRL, &control_new);
+					errno_get = errno;
+
+					dprintf("\t%s:%u: VIDIOC_G_CTRL, id=%u (V4L2_CID_BASE+%i), ret_get=%i, errno_get=%i, control_new.value=%i\n",
+						__FILE__, __LINE__, id, id-V4L2_CID_BASE, ret_get, errno_get, control_new.value);
+
+					CU_ASSERT_EQUAL(ret_get, 0);
+					if (ret_get == 0) {
+						CU_ASSERT(queryctrl.minimum <= control_new.value);
+						CU_ASSERT(control_new.value <= queryctrl.maximum);
+					}
+
+				} else {
+					CU_ASSERT_EQUAL(ret_set, 0);
+
+					/* check whether the new value is not out of bounds */
+					memset(&control_new, 0, sizeof(control_new));
+					control_new.id = id;
+					ret_get = ioctl(get_video_fd(), VIDIOC_G_CTRL, &control_new);
+					errno_get = errno;
+
+					dprintf("\t%s:%u: VIDIOC_G_CTRL, id=%u (V4L2_CID_BASE+%i), ret_get=%i, errno_get=%i, control_new.value=%i\n",
+						__FILE__, __LINE__, id, id-V4L2_CID_BASE, ret_get, errno_get, control_new.value);
+
+					CU_ASSERT_EQUAL(ret_get, 0);
+					if (ret_get == 0) {
+						CU_ASSERT(queryctrl.minimum <= control_new.value);
+						CU_ASSERT(control_new.value <= queryctrl.maximum);
+					}
+				}
+			}
+
+			if (S32_MIN < queryctrl.minimum) {
+			
+				value = queryctrl.minimum-1;
+				memset(&control, 0xff, sizeof(control));
+				control.id = id;
+				control.value = value;
+				ret_set = ioctl(get_video_fd(), VIDIOC_S_CTRL, &control);
+				errno_set = errno;
+
+				dprintf("\t%s:%u: VIDIOC_S_CTRL, id=%u (V4L2_CID_BASE+%i), value=%i, ret_set=%i, errno_set=%i\n",
+					__FILE__, __LINE__, id, id-V4L2_CID_BASE, value, ret_set, errno_set);
+
+				if (ret_set == -1) {
+					CU_ASSERT_EQUAL(ret_set, -1);
+					CU_ASSERT_EQUAL(errno_set, ERANGE);
+
+					/* check whether the new value is not out of bounds */
+					memset(&control_new, 0, sizeof(control_new));
+					control_new.id = id;
+					ret_get = ioctl(get_video_fd(), VIDIOC_G_CTRL, &control_new);
+					errno_get = errno;
+
+					dprintf("\t%s:%u: VIDIOC_G_CTRL, id=%u (V4L2_CID_BASE+%i), ret_get=%i, errno_get=%i, control_new.value=%i\n",
+						__FILE__, __LINE__, id, id-V4L2_CID_BASE, ret_get, errno_get, control_new.value);
+
+					CU_ASSERT_EQUAL(ret_get, 0);
+					if (ret_get == 0) {
+						CU_ASSERT(queryctrl.minimum <= control_new.value);
+						CU_ASSERT(control_new.value <= queryctrl.maximum);
+					}
+
+				} else {
+					CU_ASSERT_EQUAL(ret_set, 0);
+
+					/* check whether the new value is not out of bounds */
+					memset(&control_new, 0, sizeof(control_new));
+					control_new.id = id;
+					ret_get = ioctl(get_video_fd(), VIDIOC_G_CTRL, &control_new);
+					errno_get = errno;
+
+					dprintf("\t%s:%u: VIDIOC_G_CTRL, id=%u (V4L2_CID_BASE+%i), ret_get=%i, errno_get=%i, control_new.value=%i\n",
+						__FILE__, __LINE__, id, id-V4L2_CID_BASE, ret_get, errno_get, control_new.value);
+
+					CU_ASSERT_EQUAL(ret_get, 0);
+					if (ret_get == 0) {
+						CU_ASSERT(queryctrl.minimum <= control_new.value);
+						CU_ASSERT(control_new.value <= queryctrl.maximum);
+					}
+				}
+			}
+
+			if (queryctrl.maximum < S32_MAX) {
+			
+				value = queryctrl.maximum+1;
+				memset(&control, 0xff, sizeof(control));
+				control.id = id;
+				control.value = value;
+				ret_set = ioctl(get_video_fd(), VIDIOC_S_CTRL, &control);
+				errno_set = errno;
+
+				dprintf("\t%s:%u: VIDIOC_S_CTRL, id=%u (V4L2_CID_BASE+%i), value=%i, ret_set=%i, errno_set=%i\n",
+					__FILE__, __LINE__, id, id-V4L2_CID_BASE, value, ret_set, errno_set);
+
+				/* The driver can decide if it returns ERANGE or
+				 * accepts the value and converts it to
+				 * the nearest limit
+				 */
+				if (ret_set == -1) {
+					CU_ASSERT_EQUAL(ret_set, -1);
+					CU_ASSERT_EQUAL(errno_set, ERANGE);
+
+					/* check whether the new value is not out of bounds */
+					memset(&control_new, 0, sizeof(control_new));
+					control_new.id = id;
+					ret_get = ioctl(get_video_fd(), VIDIOC_G_CTRL, &control_new);
+					errno_get = errno;
+
+					dprintf("\t%s:%u: VIDIOC_G_CTRL, id=%u (V4L2_CID_BASE+%i), ret_get=%i, errno_get=%i, control_new.value=%i\n",
+						__FILE__, __LINE__, id, id-V4L2_CID_BASE, ret_get, errno_get, control_new.value);
+
+					CU_ASSERT_EQUAL(ret_get, 0);
+					if (ret_get == 0) {
+						CU_ASSERT(queryctrl.minimum <= control_new.value);
+						CU_ASSERT(control_new.value <= queryctrl.maximum);
+					}
+
+				} else {
+					CU_ASSERT_EQUAL(ret_set, 0);
+
+					/* check whether the new value is not out of bounds */
+					memset(&control_new, 0, sizeof(control_new));
+					control_new.id = id;
+					ret_get = ioctl(get_video_fd(), VIDIOC_G_CTRL, &control_new);
+					errno_get = errno;
+
+					dprintf("\t%s:%u: VIDIOC_G_CTRL, id=%u (V4L2_CID_BASE+%i), ret_get=%i, errno_get=%i, control_new.value=%i\n",
+						__FILE__, __LINE__, id, id-V4L2_CID_BASE, ret_get, errno_get, control_new.value);
+
+					CU_ASSERT_EQUAL(ret_get, 0);
+					if (ret_get == 0) {
+						CU_ASSERT(queryctrl.minimum <= control_new.value);
+						CU_ASSERT(control_new.value <= queryctrl.maximum);
+					}
+				}
+			}
+
+			if (queryctrl.maximum < S32_MAX) {
+			
+				value = S32_MAX;
+				memset(&control, 0xff, sizeof(control));
+				control.id = id;
+				control.value = value;
+				ret_set = ioctl(get_video_fd(), VIDIOC_S_CTRL, &control);
+				errno_set = errno;
+
+				dprintf("\t%s:%u: VIDIOC_S_CTRL, id=%u (V4L2_CID_BASE+%i), value=%i, ret_set=%i, errno_set=%i\n",
+					__FILE__, __LINE__, id, id-V4L2_CID_BASE, value, ret_set, errno_set);
+
+				if (ret_set == -1) {
+					CU_ASSERT_EQUAL(ret_set, -1);
+					CU_ASSERT_EQUAL(errno_set, ERANGE);
+
+					/* check whether the new value is not out of bounds */
+					memset(&control_new, 0, sizeof(control_new));
+					control_new.id = id;
+					ret_get = ioctl(get_video_fd(), VIDIOC_G_CTRL, &control_new);
+					errno_get = errno;
+
+					dprintf("\t%s:%u: VIDIOC_G_CTRL, id=%u (V4L2_CID_BASE+%i), ret_get=%i, errno_get=%i, control_new.value=%i\n",
+						__FILE__, __LINE__, id, id-V4L2_CID_BASE, ret_get, errno_get, control_new.value);
+
+					CU_ASSERT_EQUAL(ret_get, 0);
+					if (ret_get == 0) {
+						CU_ASSERT(queryctrl.minimum <= control_new.value);
+						CU_ASSERT(control_new.value <= queryctrl.maximum);
+					}
+
+				} else {
+					CU_ASSERT_EQUAL(ret_set, 0);
+
+					/* check whether the new value is not out of bounds */
+					memset(&control_new, 0, sizeof(control_new));
+					control_new.id = id;
+					ret_get = ioctl(get_video_fd(), VIDIOC_G_CTRL, &control_new);
+					errno_get = errno;
+
+					dprintf("\t%s:%u: VIDIOC_G_CTRL, id=%u (V4L2_CID_BASE+%i), ret_get=%i, errno_get=%i, control_new.value=%i\n",
+						__FILE__, __LINE__, id, id-V4L2_CID_BASE, ret_get, errno_get, control_new.value);
+
+					CU_ASSERT_EQUAL(ret_get, 0);
+					if (ret_get == 0) {
+						CU_ASSERT(queryctrl.minimum <= control_new.value);
+						CU_ASSERT(control_new.value <= queryctrl.maximum);
+					}
+				}
+			}
+
+
+			break;
+
+		case V4L2_CTRL_TYPE_BUTTON:
+			/* This control only performs an action, does not have
+			 * any value
+			 */
+			CU_ASSERT_EQUAL(ret_orig, -1);
+			CU_ASSERT_EQUAL(errno_orig, EINVAL);
+
+			/* there is no invalid value for button control */
+
+			break;
+
+		case V4L2_CTRL_TYPE_INTEGER64: /* TODO: what about this case? */
+		case V4L2_CTRL_TYPE_CTRL_CLASS:
+		default:
+			CU_ASSERT_EQUAL(ret_orig, -1);
+			CU_ASSERT_EQUAL(errno_orig, -1);
+		}
+	} else {
+		CU_ASSERT_EQUAL(ret1, -1);
+		CU_ASSERT_EQUAL(errno1, EINVAL);
+
+		CU_ASSERT_EQUAL(ret_orig, -1);
+		CU_ASSERT_EQUAL(errno_orig, EINVAL);
+
+		memset(&control, 0xff, sizeof(control));
+		control.id = id;
+		control.value = S32_MIN;
+		ret_set = ioctl(get_video_fd(), VIDIOC_S_CTRL, &control);
+		errno_set = errno;
+
+		CU_ASSERT_EQUAL(ret_set, -1);
+		CU_ASSERT_EQUAL(errno_set, EINVAL);
+
+		memset(&control, 0xff, sizeof(control));
+		control.id = id;
+		control.value = -1;
+		ret_set = ioctl(get_video_fd(), VIDIOC_S_CTRL, &control);
+		errno_set = errno;
+
+		CU_ASSERT_EQUAL(ret_set, -1);
+		CU_ASSERT_EQUAL(errno_set, EINVAL);
+
+		memset(&control, 0xff, sizeof(control));
+		control.id = id;
+		control.value = 0;
+		ret_set = ioctl(get_video_fd(), VIDIOC_S_CTRL, &control);
+		errno_set = errno;
+
+		CU_ASSERT_EQUAL(ret_set, -1);
+		CU_ASSERT_EQUAL(errno_set, EINVAL);
+
+		memset(&control, 0xff, sizeof(control));
+		control.id = id;
+		control.value = 1;
+		ret_set = ioctl(get_video_fd(), VIDIOC_S_CTRL, &control);
+		errno_set = errno;
+
+		CU_ASSERT_EQUAL(ret_set, -1);
+		CU_ASSERT_EQUAL(errno_set, EINVAL);
+
+		memset(&control, 0xff, sizeof(control));
+		control.id = id;
+		control.value = S32_MAX;
+		ret_set = ioctl(get_video_fd(), VIDIOC_S_CTRL, &control);
+		errno_set = errno;
+
+		CU_ASSERT_EQUAL(ret_set, -1);
+		CU_ASSERT_EQUAL(errno_set, EINVAL);
+
+	}
+
+	if (ret_orig == 0) {
+		CU_ASSERT_EQUAL(ret_orig, 0);
+
+		/* restore the original control value */
+		value = control_orig.value;
+		memset(&control, 0xff, sizeof(control));
+		control.id = id;
+		control.value = value;
+		ret_set = ioctl(get_video_fd(), VIDIOC_S_CTRL, &control);
+		errno_set = errno;
+
+		dprintf("\t%s:%u: VIDIOC_S_CTRL, id=%u (V4L2_CID_BASE+%i), value=%i, ret_set=%i, errno_set=%i\n",
+			__FILE__, __LINE__, id, id-V4L2_CID_BASE, value, ret_set, errno_set);
+
+		/* it shall be possible to set to the original value if the control
+		 * is not disabled, read only or grabbed by other application
+		 */
+		if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED ||
+		    queryctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) {
+			CU_ASSERT_EQUAL(ret_set, -1);
+			CU_ASSERT_EQUAL(errno_set, EINVAL);
+		} else if (queryctrl.flags & V4L2_CTRL_FLAG_GRABBED) {
+			CU_ASSERT_EQUAL(ret_set, -1);
+			CU_ASSERT_EQUAL(errno_set, EBUSY);
+		} else {
+			CU_ASSERT_EQUAL(ret_set, 0);
+		}
+
+		memset(&control_new, 0, sizeof(control_new));
+		control_new.id = id;
+		ret_get = ioctl(get_video_fd(), VIDIOC_G_CTRL, &control_new);
+		errno_get = errno;
+
+		dprintf("\t%s:%u: VIDIOC_G_CTRL, id=%u (V4L2_CID_BASE+%i), ret_get=%i, errno_get=%i, control_new.value=%i\n",
+			__FILE__, __LINE__, id, id-V4L2_CID_BASE, ret_get, errno_get, control_new.value);
+
+		CU_ASSERT_EQUAL(ret_get, 0);
+		if (ret_get == 0) {
+			CU_ASSERT(queryctrl.minimum <= control_new.value);
+			CU_ASSERT(control_new.value <= queryctrl.maximum);
+			CU_ASSERT_EQUAL(control_new.value, control_orig.value);
+		}
+
+	}
+
+	return ret1;
+}
+
+
+void test_VIDIOC_S_CTRL() {
+	int ret1;
+	__u32 i;
+
+	for (i = V4L2_CID_BASE; i < V4L2_CID_LASTP1; i++) {
+		if (i != V4L2_CID_AUTO_WHITE_BALANCE &&
+		    i != V4L2_CID_DO_WHITE_BALANCE &&
+		    i != V4L2_CID_RED_BALANCE &&
+		    i != V4L2_CID_BLUE_BALANCE &&
+		    i != V4L2_CID_AUTOGAIN &&
+		    i != V4L2_CID_GAIN)
+			ret1 = do_set_control(i);
+	}
+
+	ret1 = do_set_control(V4L2_CID_BASE-1);
+	ret1 = do_set_control(V4L2_CID_LASTP1);
+	ret1 = do_set_control(V4L2_CID_PRIVATE_BASE-1);
+
+	i = V4L2_CID_PRIVATE_BASE;
+	do {
+		ret1 = do_set_control(i);
+		i++;
+	} while (ret1 == 0);
+
+	ret1 = do_set_control(i);
+}
+
+
+void test_VIDIOC_S_CTRL_invalid() {
+	int ret1;
+	__u32 i;
+
+	for (i = V4L2_CID_BASE; i < V4L2_CID_LASTP1; i++) {
+		if (i != V4L2_CID_AUTO_WHITE_BALANCE &&
+		    i != V4L2_CID_DO_WHITE_BALANCE &&
+		    i != V4L2_CID_RED_BALANCE &&
+		    i != V4L2_CID_BLUE_BALANCE &&
+		    i != V4L2_CID_AUTOGAIN &&
+		    i != V4L2_CID_GAIN)
+			ret1 = do_set_control_invalid(i);
+	}
+
+	ret1 = do_set_control_invalid(V4L2_CID_BASE-1);
+	ret1 = do_set_control_invalid(V4L2_CID_LASTP1);
+	ret1 = do_set_control_invalid(V4L2_CID_PRIVATE_BASE-1);
+
+	i = V4L2_CID_PRIVATE_BASE;
+	do {
+		ret1 = do_set_control_invalid(i);
+		i++;
+	} while (ret1 == 0);
+
+	ret1 = do_set_control_invalid(i);
+}
+
+void test_VIDIOC_S_CTRL_white_balance() {
+	int ret1;
+
+	/* TODO: handle V4L2_CID_AUTO_WHITE_BALANCE activated and deactivated separately */
+	ret1 = do_set_control(V4L2_CID_AUTO_WHITE_BALANCE);
+	ret1 = do_set_control(V4L2_CID_DO_WHITE_BALANCE);
+	ret1 = do_set_control(V4L2_CID_RED_BALANCE);
+	ret1 = do_set_control(V4L2_CID_BLUE_BALANCE);
+}
+
+
+void test_VIDIOC_S_CTRL_white_balance_invalid() {
+	int ret1;
+
+	/* TODO: handle V4L2_CID_AUTO_WHITE_BALANCE activated and deactivated separately */
+	ret1 = do_set_control_invalid(V4L2_CID_AUTO_WHITE_BALANCE);
+	ret1 = do_set_control_invalid(V4L2_CID_DO_WHITE_BALANCE);
+	ret1 = do_set_control_invalid(V4L2_CID_RED_BALANCE);
+	ret1 = do_set_control_invalid(V4L2_CID_BLUE_BALANCE);
+}
+
+void test_VIDIOC_S_CTRL_gain() {
+	int ret1;
+
+	/* TODO: handle V4L2_CID_AUTOGAIN activated and deactivated separately */
+	ret1 = do_set_control(V4L2_CID_AUTOGAIN);
+	ret1 = do_set_control(V4L2_CID_GAIN);
+}
+
+
+void test_VIDIOC_S_CTRL_gain_invalid() {
+	int ret1;
+
+	/* TODO: handle V4L2_CID_AUTOGAIN activated and deactivated separately */
+	ret1 = do_set_control_invalid(V4L2_CID_AUTOGAIN);
+	ret1 = do_set_control_invalid(V4L2_CID_GAIN);
+}
+
+
+void test_VIDIOC_S_CTRL_NULL() {
+	int ret;
+
+	ret = ioctl(get_video_fd(), VIDIOC_S_CTRL, NULL);
+	CU_ASSERT_EQUAL(ret, -1);
+	CU_ASSERT_EQUAL(errno, EFAULT);
+
+}
diff -uprN ltp.orig/testcases/kernel/device-drivers/v4l/user_space/test_VIDIOC_CTRL.h ltp/testcases/kernel/device-drivers/v4l/user_space/test_VIDIOC_CTRL.h
--- ltp.orig/testcases/kernel/device-drivers/v4l/user_space/test_VIDIOC_CTRL.h	1970-01-01 01:00:00.000000000 +0100
+++ ltp/testcases/kernel/device-drivers/v4l/user_space/test_VIDIOC_CTRL.h	2009-02-22 16:36:28.000000000 +0100
@@ -0,0 +1,19 @@
+/*
+ * v4l-test: Test environment for Video For Linux Two API
+ *
+ * 19 Feb 2009  0.1  First release
+ *
+ * Written by Márton Németh <[email protected]>
+ * Released under GPL
+ */
+
+void test_VIDIOC_G_CTRL(void);
+void test_VIDIOC_G_CTRL_NULL(void);
+
+void test_VIDIOC_S_CTRL(void);
+void test_VIDIOC_S_CTRL_invalid(void);
+void test_VIDIOC_S_CTRL_white_balance(void);
+void test_VIDIOC_S_CTRL_white_balance_invalid(void);
+void test_VIDIOC_S_CTRL_gain(void);
+void test_VIDIOC_S_CTRL_gain_invalid(void);
+void test_VIDIOC_S_CTRL_NULL(void);
diff -uprN ltp.orig/testcases/kernel/device-drivers/v4l/user_space/test_VIDIOC_TUNER.c ltp/testcases/kernel/device-drivers/v4l/user_space/test_VIDIOC_TUNER.c
--- ltp.orig/testcases/kernel/device-drivers/v4l/user_space/test_VIDIOC_TUNER.c	2009-02-16 06:13:54.000000000 +0100
+++ ltp/testcases/kernel/device-drivers/v4l/user_space/test_VIDIOC_TUNER.c	2009-02-13 23:01:02.000000000 +0100
@@ -445,7 +445,7 @@ void test_VIDIOC_S_TUNER_NULL() {
 	ret_orig = ioctl(get_video_fd(), VIDIOC_G_TUNER, &tuner_orig);
 	errno_orig = errno;
 
-	dprintf("\tVIDIOC_G_TUNER, ret_orig=%i, errno_orig=%i\n", ret_set, errno_set);
+	dprintf("\tVIDIOC_G_TUNER, ret_orig=%i, errno_orig=%i\n", ret_orig, errno_orig);
 
 	memset(&tuner, 0, sizeof(tuner));
 	tuner.index = tuner_orig.index;
diff -uprN ltp.orig/testcases/kernel/device-drivers/v4l/user_space/v4l2_test.c ltp/testcases/kernel/device-drivers/v4l/user_space/v4l2_test.c
--- ltp.orig/testcases/kernel/device-drivers/v4l/user_space/v4l2_test.c	2009-02-16 06:13:54.000000000 +0100
+++ ltp/testcases/kernel/device-drivers/v4l/user_space/v4l2_test.c	2009-02-22 16:37:24.000000000 +0100
@@ -1,6 +1,8 @@
 /*
  * v4l-test: Test environment for Video For Linux Two API
  *
+ * 22 Feb 2009  0.12 Test cases added for VIDIOC_S_CTRL
+ * 19 Feb 2009  0.11 Test cases added for VIDIOC_G_CTRL
  *  7 Feb 2009  0.10 Test cases added for VIDIOC_G_AUDIO, VIDIOC_G_AUDOUT,
  *                   VIDIOC_S_AUDIO and VIDIOC_G_CROP
  *  3 Feb 2009  0.9  Test cases for VIDIOC_G_AUDIO and VIDIOC_G_AUDOUT added
@@ -63,6 +65,7 @@
 #include "test_VIDIOC_AUDIO.h"
 #include "test_VIDIOC_AUDOUT.h"
 #include "test_VIDIOC_CROP.h"
+#include "test_VIDIOC_CTRL.h"
 
 #include "test_VIDIOC_LOG_STATUS.h"
 #include "test_invalid_ioctl.h"
@@ -131,6 +134,7 @@ static CU_TestInfo suite_enums[] = {
 };
 
 static CU_TestInfo suite_get_set_try[] = {
+#if 1
   { "VIDIOC_G_STD", test_VIDIOC_G_STD },
   { "VIDIOC_S_STD with the enumerated values", test_VIDIOC_S_STD_from_enum },
   { "VIDIOC_S_STD", test_VIDIOC_S_STD },
@@ -197,7 +201,21 @@ static CU_TestInfo suite_get_set_try[] =
   { "VIDIOC_S_AUDOUT with NULL parameter", test_VIDIOC_S_AUDOUT_NULL },
 
   { "VIDIOC_G_CROP", test_VIDIOC_G_CROP },
+  { "VIDIOC_G_CROP with invalid type", test_VIDIOC_G_CROP_invalid },
   { "VIDIOC_G_CROP with NULL parameter", test_VIDIOC_G_CROP_NULL },
+#endif
+
+  { "VIDIOC_G_CTRL", test_VIDIOC_G_CTRL },
+  { "VIDIOC_G_CTRL with NULL parameter", test_VIDIOC_G_CTRL_NULL },
+
+  { "VIDIOC_S_CTRL", test_VIDIOC_S_CTRL },
+  { "VIDIOC_S_CTRL with invalid value parameter", test_VIDIOC_S_CTRL_invalid },
+  { "VIDIOC_S_CTRL, withe balance", test_VIDIOC_S_CTRL_white_balance },
+  { "VIDIOC_S_CTRL, white balance with invalid value parameter", test_VIDIOC_S_CTRL_white_balance_invalid },
+  { "VIDIOC_S_CTRL, gain control", test_VIDIOC_S_CTRL_gain },
+  { "VIDIOC_S_CTRL, gain control with invalid value parameter", test_VIDIOC_S_CTRL_gain_invalid },
+
+  { "VIDIOC_S_CTRL with NULL parameter", test_VIDIOC_S_CTRL_NULL },
 
   CU_TEST_INFO_NULL,
 };
diff -uprN ltp.orig/testcases/kernel/device-drivers/v4l/user_space/video_limits.h ltp/testcases/kernel/device-drivers/v4l/user_space/video_limits.h
--- ltp.orig/testcases/kernel/device-drivers/v4l/user_space/video_limits.h	2009-01-05 08:25:21.000000000 +0100
+++ ltp/testcases/kernel/device-drivers/v4l/user_space/video_limits.h	2009-02-22 11:22:46.000000000 +0100
@@ -1,6 +1,7 @@
 /*
  * v4l-test: Test environment for Video For Linux Two API
  *
+ * 22 Feb 2009  0.3  S32_MIN and U32_MIN added
  *  1 Jan 2009  0.2  SINT_MAX and SINT_MIN added
  * 18 Dec 2008  0.1  First release
  *
@@ -10,8 +11,11 @@
 
 #include <limits.h>
 
+#define S32_MIN		((__s32)0x80000000)
 #define S32_MAX		0x7FFFFFFF
+
+#define U32_MIN		0
 #define U32_MAX		0xFFFFFFFFU
 
-#define SINT_MAX        INT_MAX
 #define SINT_MIN        INT_MIN
+#define SINT_MAX        INT_MAX
------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list

Reply via email to