Home | History | Annotate | Download | only in user_space
      1 /*
      2  * v4l-test: Test environment for Video For Linux Two API
      3  *
      4  * 20 Apr 2009  0.4  Added string content validation
      5  * 18 Apr 2009  0.3  More strict check for strings
      6  * 28 Mar 2009  0.2  Clean up ret and errno variable names and dprintf() output
      7  *  2 Jan 2009  0.1  First release
      8  *
      9  * Written by Mrton Nmeth <nm127 (at) freemail.hu>
     10  * Released under GPL
     11  */
     12 
     13 /*
     14  * Note: V4L2_CID_LASTP1 != V4L2_CID_BASE_LASTP1
     15  */
     16 
     17 #include <sys/ioctl.h>
     18 #include <errno.h>
     19 #include <string.h>
     20 
     21 #include <linux/videodev2.h>
     22 #include <linux/errno.h>
     23 
     24 #include <CUnit/CUnit.h>
     25 
     26 #include "v4l2_test.h"
     27 #include "dev_video.h"
     28 #include "video_limits.h"
     29 #include "v4l2_validator.h"
     30 
     31 #include "test_VIDIOC_QUERYCTRL.h"
     32 
     33 static int valid_control_flag(__u32 flags)
     34 {
     35 	int valid = 0;
     36 
     37 	if ((flags & ~(V4L2_CTRL_FLAG_DISABLED |
     38 		       V4L2_CTRL_FLAG_GRABBED |
     39 		       V4L2_CTRL_FLAG_READ_ONLY |
     40 		       V4L2_CTRL_FLAG_UPDATE |
     41 		       V4L2_CTRL_FLAG_INACTIVE | V4L2_CTRL_FLAG_SLIDER))
     42 	    == 0) {
     43 		valid = 1;
     44 	} else {
     45 		valid = 0;
     46 	}
     47 	return valid;
     48 }
     49 
     50 static int valid_control_type(__u32 type)
     51 {
     52 	int valid = 0;
     53 
     54 	switch (type) {
     55 	case V4L2_CTRL_TYPE_INTEGER:
     56 	case V4L2_CTRL_TYPE_BOOLEAN:
     57 	case V4L2_CTRL_TYPE_MENU:
     58 	case V4L2_CTRL_TYPE_BUTTON:
     59 	case V4L2_CTRL_TYPE_INTEGER64:
     60 	case V4L2_CTRL_TYPE_CTRL_CLASS:
     61 		valid = 1;
     62 		break;
     63 	default:
     64 		valid = 0;
     65 	}
     66 	return valid;
     67 }
     68 
     69 void test_VIDIOC_QUERYCTRL()
     70 {
     71 	int ret_query, errno_query;
     72 	struct v4l2_queryctrl queryctrl;
     73 	struct v4l2_queryctrl queryctrl2;
     74 	__u32 i;
     75 
     76 	/* The available controls and their parameters
     77 	 * may change with different
     78 	 *  - input or output
     79 	 *  - tuner or modulator
     80 	 *  - audio input or audio output
     81 	 * See V4L API specification rev. 0.24, Chapter 1.8.
     82 	 * "User Controls" for details
     83 	 *
     84 	 * TODO: iterate through the mentioned settings.
     85 	 * TODO: check for deprecated controls (maybe in a
     86 	 * separated test case which could fail when a
     87 	 * deprecated control is supported)
     88 	 */
     89 
     90 	for (i = V4L2_CID_BASE; i < V4L2_CID_LASTP1; i++) {
     91 
     92 		memset(&queryctrl, 0xff, sizeof(queryctrl));
     93 		queryctrl.id = i;
     94 		ret_query = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl);
     95 		errno_query = errno;
     96 
     97 		dprintf
     98 		    ("\t%s:%u: VIDIOC_QUERYCTRL, id=%u (V4L2_CID_BASE+%i), ret_query=%i, errno_query=%i\n",
     99 		     __FILE__, __LINE__, i, i - V4L2_CID_BASE, ret_query,
    100 		     errno_query);
    101 
    102 		if (ret_query == 0) {
    103 			CU_ASSERT_EQUAL(ret_query, 0);
    104 			CU_ASSERT_EQUAL(queryctrl.id, i);
    105 
    106 			CU_ASSERT(0 < strlen((char *)queryctrl.name));
    107 			CU_ASSERT(valid_string
    108 				  ((char *)queryctrl.name,
    109 				   sizeof(queryctrl.name)));
    110 
    111 			CU_ASSERT(valid_control_type(queryctrl.type));
    112 
    113 			switch (queryctrl.type) {
    114 			case V4L2_CTRL_TYPE_INTEGER:
    115 				/* min < max, because otherwise this control makes no sense */
    116 				CU_ASSERT(queryctrl.minimum <
    117 					  queryctrl.maximum);
    118 
    119 				CU_ASSERT(0 < queryctrl.step);
    120 
    121 				CU_ASSERT(queryctrl.minimum <=
    122 					  queryctrl.default_value);
    123 				CU_ASSERT(queryctrl.default_value <=
    124 					  queryctrl.maximum);
    125 				break;
    126 
    127 			case V4L2_CTRL_TYPE_BOOLEAN:
    128 				CU_ASSERT_EQUAL(queryctrl.minimum, 0);
    129 				CU_ASSERT_EQUAL(queryctrl.maximum, 1);
    130 				CU_ASSERT_EQUAL(queryctrl.step, 1);
    131 				CU_ASSERT((queryctrl.default_value == 0)
    132 					  || (queryctrl.default_value == 1));
    133 				break;
    134 
    135 			case V4L2_CTRL_TYPE_MENU:
    136 				CU_ASSERT_EQUAL(queryctrl.minimum, 0);
    137 				CU_ASSERT(queryctrl.minimum <=
    138 					  queryctrl.default_value);
    139 				CU_ASSERT_EQUAL(queryctrl.step, 1);
    140 				CU_ASSERT(queryctrl.minimum <=
    141 					  queryctrl.default_value);
    142 				CU_ASSERT(queryctrl.default_value <=
    143 					  queryctrl.maximum);
    144 				break;
    145 
    146 			case V4L2_CTRL_TYPE_BUTTON:
    147 				CU_ASSERT_EQUAL(queryctrl.minimum, 0);
    148 				CU_ASSERT_EQUAL(queryctrl.maximum, 0);
    149 				CU_ASSERT_EQUAL(queryctrl.step, 0);
    150 				CU_ASSERT_EQUAL(queryctrl.default_value, 0);
    151 				break;
    152 
    153 			case V4L2_CTRL_TYPE_INTEGER64:	/* fallthrough */
    154 			case V4L2_CTRL_TYPE_CTRL_CLASS:
    155 				/* These parameters are defined as n/a by V4L2, so
    156 				 * they should be filled with zeros, the same like
    157 				 * the reserved fields.
    158 				 */
    159 				CU_ASSERT_EQUAL(queryctrl.minimum, 0);
    160 				CU_ASSERT_EQUAL(queryctrl.maximum, 0);
    161 				CU_ASSERT_EQUAL(queryctrl.step, 0);
    162 				CU_ASSERT_EQUAL(queryctrl.default_value, 0);
    163 				break;
    164 
    165 			default:
    166 				CU_ASSERT_EQUAL(queryctrl.minimum, 0);
    167 				CU_ASSERT_EQUAL(queryctrl.maximum, 0);
    168 				CU_ASSERT_EQUAL(queryctrl.step, 0);
    169 				CU_ASSERT_EQUAL(queryctrl.default_value, 0);
    170 			}
    171 
    172 			CU_ASSERT(valid_control_flag(queryctrl.flags));
    173 
    174 			CU_ASSERT_EQUAL(queryctrl.reserved[0], 0);
    175 			CU_ASSERT_EQUAL(queryctrl.reserved[1], 0);
    176 
    177 			/* Check if the unused bytes of the name string are
    178 			 * also filled with zeros. Also check if there is any
    179 			 * padding byte between any two fields then this
    180 			 * padding byte is also filled with zeros.
    181 			 */
    182 			memset(&queryctrl2, 0, sizeof(queryctrl2));
    183 			queryctrl2.id = queryctrl.id;
    184 			queryctrl2.type = queryctrl.type;
    185 			strncpy((char *)queryctrl2.name, (char *)queryctrl.name,
    186 				sizeof(queryctrl2.name));
    187 			queryctrl2.minimum = queryctrl.minimum;
    188 			queryctrl2.maximum = queryctrl.maximum;
    189 			queryctrl2.step = queryctrl.step;
    190 			queryctrl2.default_value = queryctrl.default_value;
    191 			queryctrl2.flags = queryctrl.flags;
    192 			CU_ASSERT_EQUAL(memcmp
    193 					(&queryctrl, &queryctrl2,
    194 					 sizeof(queryctrl)), 0);
    195 
    196 			dprintf
    197 			    ("\tqueryctrl = {.id=%u, .type=%i, .name=\"%s\", "
    198 			     ".minimum=%i, .maximum=%i, .step=%i, "
    199 			     ".default_value=%i, " ".flags=0x%X, "
    200 			     ".reserved[]={ 0x%X, 0x%X } }\n", queryctrl.id,
    201 			     queryctrl.type, queryctrl.name, queryctrl.minimum,
    202 			     queryctrl.maximum, queryctrl.step,
    203 			     queryctrl.default_value, queryctrl.flags,
    204 			     queryctrl.reserved[0], queryctrl.reserved[1]
    205 			    );
    206 
    207 		} else {
    208 			CU_ASSERT_EQUAL(ret_query, -1);
    209 			CU_ASSERT_EQUAL(errno_query, EINVAL);
    210 
    211 			memset(&queryctrl2, 0xff, sizeof(queryctrl2));
    212 			queryctrl2.id = i;
    213 			CU_ASSERT_EQUAL(memcmp
    214 					(&queryctrl, &queryctrl2,
    215 					 sizeof(queryctrl)), 0);
    216 
    217 		}
    218 	}
    219 
    220 }
    221 
    222 void test_VIDIOC_QUERYCTRL_BASE_1()
    223 {
    224 	int ret_query, errno_query;
    225 	struct v4l2_queryctrl queryctrl;
    226 	struct v4l2_queryctrl queryctrl2;
    227 
    228 	memset(&queryctrl, 0xff, sizeof(queryctrl));
    229 	queryctrl.id = V4L2_CID_BASE - 1;
    230 	ret_query = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl);
    231 	errno_query = errno;
    232 
    233 	dprintf
    234 	    ("\t%s:%u: VIDIOC_QUERYCTRL, id=%u (V4L2_CID_BASE-1), ret_query=%i, errno_query=%i\n",
    235 	     __FILE__, __LINE__, V4L2_CID_BASE - 1, ret_query, errno_query);
    236 
    237 	CU_ASSERT_EQUAL(ret_query, -1);
    238 	CU_ASSERT_EQUAL(errno_query, EINVAL);
    239 
    240 	memset(&queryctrl2, 0xff, sizeof(queryctrl2));
    241 	queryctrl2.id = V4L2_CID_BASE - 1;
    242 	CU_ASSERT_EQUAL(memcmp(&queryctrl, &queryctrl2, sizeof(queryctrl)), 0);
    243 
    244 }
    245 
    246 void test_VIDIOC_QUERYCTRL_LASTP1()
    247 {
    248 	int ret_query, errno_query;
    249 	struct v4l2_queryctrl queryctrl;
    250 	struct v4l2_queryctrl queryctrl2;
    251 
    252 	memset(&queryctrl, 0xff, sizeof(queryctrl));
    253 	queryctrl.id = V4L2_CID_LASTP1;
    254 	ret_query = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl);
    255 	errno_query = errno;
    256 
    257 	dprintf
    258 	    ("\t%s:%u: VIDIOC_QUERYCTRL, id=%u (V4L2_CID_LASTP1), ret_query=%i, errno_query=%i\n",
    259 	     __FILE__, __LINE__, V4L2_CID_LASTP1, ret_query, errno_query);
    260 
    261 	CU_ASSERT_EQUAL(ret_query, -1);
    262 	CU_ASSERT_EQUAL(errno_query, EINVAL);
    263 
    264 	memset(&queryctrl2, 0xff, sizeof(queryctrl2));
    265 	queryctrl2.id = V4L2_CID_LASTP1;
    266 	CU_ASSERT_EQUAL(memcmp(&queryctrl, &queryctrl2, sizeof(queryctrl)), 0);
    267 
    268 }
    269 
    270 void test_VIDIOC_QUERYCTRL_LASTP1_1()
    271 {
    272 	int ret_query, errno_query;
    273 	struct v4l2_queryctrl queryctrl;
    274 	struct v4l2_queryctrl queryctrl2;
    275 
    276 	memset(&queryctrl, 0xff, sizeof(queryctrl));
    277 	queryctrl.id = V4L2_CID_LASTP1 + 1;
    278 	ret_query = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl);
    279 	errno_query = errno;
    280 
    281 	dprintf
    282 	    ("\t%s:%u: VIDIOC_QUERYCTRL, id=%u (V4L2_CID_LASTP1+1), ret_query=%i, errno_query=%i\n",
    283 	     __FILE__, __LINE__, V4L2_CID_LASTP1 + 1, ret_query, errno_query);
    284 
    285 	CU_ASSERT_EQUAL(ret_query, -1);
    286 	CU_ASSERT_EQUAL(errno_query, EINVAL);
    287 
    288 	memset(&queryctrl2, 0xff, sizeof(queryctrl2));
    289 	queryctrl2.id = V4L2_CID_LASTP1 + 1;
    290 	CU_ASSERT_EQUAL(memcmp(&queryctrl, &queryctrl2, sizeof(queryctrl)), 0);
    291 
    292 }
    293 
    294 void test_VIDIOC_QUERYCTRL_flag_NEXT_CTRL()
    295 {
    296 	int ret_query, errno_query;
    297 	char count_controls1[V4L2_CID_LASTP1 - V4L2_CID_BASE];
    298 	char count_controls2[V4L2_CID_LASTP1 - V4L2_CID_BASE];
    299 	struct v4l2_queryctrl controls[V4L2_CID_LASTP1 - V4L2_CID_BASE];
    300 	struct v4l2_queryctrl queryctrl;
    301 	__u32 i;
    302 
    303 	/* find out all the possible user controls */
    304 	memset(count_controls1, 0, sizeof(count_controls1));
    305 	memset(controls, 0, sizeof(controls));
    306 
    307 	for (i = V4L2_CID_BASE; i < V4L2_CID_LASTP1; i++) {
    308 
    309 		memset(&queryctrl, 0xff, sizeof(queryctrl));
    310 		queryctrl.id = i;
    311 		ret_query = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl);
    312 		errno_query = errno;
    313 
    314 		if (ret_query == 0) {
    315 			CU_ASSERT_EQUAL(ret_query, 0);
    316 			CU_ASSERT_EQUAL(queryctrl.id, i);
    317 			count_controls1[i - V4L2_CID_BASE]++;
    318 			controls[i - V4L2_CID_BASE] = queryctrl;
    319 
    320 			dprintf
    321 			    ("\tqueryctrl = {.id=%u, .type=%i, .name=\"%s\", "
    322 			     ".minimum=%i, .maximum=%i, .step=%i, "
    323 			     ".default_value=%i, " ".flags=0x%X, "
    324 			     ".reserved[]={ 0x%X, 0x%X } }\n", queryctrl.id,
    325 			     queryctrl.type, queryctrl.name, queryctrl.minimum,
    326 			     queryctrl.maximum, queryctrl.step,
    327 			     queryctrl.default_value, queryctrl.flags,
    328 			     queryctrl.reserved[0], queryctrl.reserved[1]
    329 			    );
    330 
    331 		} else {
    332 			CU_ASSERT_EQUAL(ret_query, -1);
    333 			CU_ASSERT_EQUAL(errno_query, EINVAL);
    334 		}
    335 	}
    336 
    337 	/* enumerate the controls with V4L2_CTRL_FLAG_NEXT_CTRL */
    338 	dprintf1("\tStarting enumeration with V4L2_CTRL_FLAG_NEXT_CTRL\n");
    339 	memset(count_controls2, 0, sizeof(count_controls2));
    340 
    341 	/* As described at V4L2 Chapter 1.9.3. Enumerating Extended Controls */
    342 	i = 0;
    343 	memset(&queryctrl, 0xff, sizeof(queryctrl));
    344 	queryctrl.id = i | V4L2_CTRL_FLAG_NEXT_CTRL;
    345 	dprintf
    346 	    ("\tasking for id=%i=V4L2_CID_BASE+%i | V4L2_CTRL_FLAG_NEXT_CTRL\n",
    347 	     i, i - V4L2_CID_BASE);
    348 	ret_query = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl);
    349 	errno_query = errno;
    350 
    351 	dprintf("\tret_query=%i\n", ret_query);
    352 
    353 	if (ret_query == 0) {
    354 		do {
    355 			/* protect the count_controls2[] from overindexing */
    356 			if ((V4L2_CID_BASE <= queryctrl.id)
    357 			    && (queryctrl.id < V4L2_CID_LASTP1)) {
    358 				count_controls2[queryctrl.id - V4L2_CID_BASE]++;
    359 				CU_ASSERT_EQUAL(memcmp
    360 						(&queryctrl,
    361 						 &controls[queryctrl.id -
    362 							   V4L2_CID_BASE],
    363 						 sizeof(queryctrl)), 0);
    364 			}
    365 
    366 			/* "The VIDIOC_QUERYCTRL ioctl will return the first
    367 			 *  control with a higher ID than the specified one."
    368 			 */
    369 			CU_ASSERT(i < queryctrl.id);
    370 
    371 			CU_ASSERT(V4L2_CID_BASE <= queryctrl.id);
    372 			CU_ASSERT(queryctrl.id < V4L2_CID_LASTP1);
    373 
    374 			dprintf
    375 			    ("\tqueryctrl = {.id=%u, .type=%i, .name=\"%s\", "
    376 			     ".minimum=%i, .maximum=%i, .step=%i, "
    377 			     ".default_value=%i, " ".flags=0x%X, "
    378 			     ".reserved[]={ 0x%X, 0x%X } }\n", queryctrl.id,
    379 			     queryctrl.type, queryctrl.name, queryctrl.minimum,
    380 			     queryctrl.maximum, queryctrl.step,
    381 			     queryctrl.default_value, queryctrl.flags,
    382 			     queryctrl.reserved[0], queryctrl.reserved[1]
    383 			    );
    384 
    385 			i = queryctrl.id;
    386 			memset(&queryctrl, 0xff, sizeof(queryctrl));
    387 			queryctrl.id = i | V4L2_CTRL_FLAG_NEXT_CTRL;
    388 			dprintf
    389 			    ("\tasking for id=%i=V4L2_CID_BASE+%i | V4L2_CTRL_FLAG_NEXT_CTRL\n",
    390 			     i, i - V4L2_CID_BASE);
    391 			ret_query =
    392 			    ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl);
    393 			errno_query = errno;
    394 
    395 			dprintf("\tret_query=%i\n", ret_query);
    396 
    397 		} while (ret_query == 0
    398 			 && V4L2_CTRL_ID2CLASS(queryctrl.id) ==
    399 			 V4L2_CTRL_CLASS_USER);
    400 
    401 		if (ret_query == 0) {
    402 			/* some other controls also exists, stop for now. */
    403 		} else {
    404 			CU_ASSERT_EQUAL(ret_query, -1);
    405 			CU_ASSERT_EQUAL(errno_query, EINVAL);
    406 		}
    407 
    408 		/* Check whether the same controls are reported if using
    409 		 * V4L2_CTRL_FLAG_NEXT_CTRL and without using it.
    410 		 * This also checks if one control is not reported twice.
    411 		 */
    412 		CU_ASSERT_EQUAL(memcmp
    413 				(count_controls1, count_controls2,
    414 				 sizeof(count_controls1)), 0);
    415 
    416 		dprintf1("count_controls1 = { ");
    417 		for (i = 0;
    418 		     i < sizeof(count_controls1) / sizeof(*count_controls1);
    419 		     i++) {
    420 			dprintf("%i ", count_controls1[i]);
    421 		}
    422 		dprintf1("}\n");
    423 
    424 		dprintf1("count_controls2 = { ");
    425 		for (i = 0;
    426 		     i < sizeof(count_controls2) / sizeof(*count_controls2);
    427 		     i++) {
    428 			dprintf("%i ", count_controls2[i]);
    429 		}
    430 		dprintf1("}\n");
    431 
    432 	} else {
    433 		dprintf1
    434 		    ("V4L2_CTRL_FLAG_NEXT_CTRL is not supported or no control is available\n");
    435 		/* The flag V4L2_CTRL_FLAG_NEXT_CTRL is not supported
    436 		 * or no control is avaliable at all. Do not continue the
    437 		 * enumeration.
    438 		 */
    439 		CU_ASSERT_EQUAL(ret_query, -1);
    440 		CU_ASSERT_EQUAL(errno_query, EINVAL);
    441 	}
    442 
    443 }
    444 
    445 void test_VIDIOC_QUERYCTRL_private()
    446 {
    447 	int ret_query, errno_query;
    448 	struct v4l2_queryctrl queryctrl;
    449 	struct v4l2_queryctrl queryctrl2;
    450 	__u32 i;
    451 
    452 	i = V4L2_CID_PRIVATE_BASE;
    453 	do {
    454 		memset(&queryctrl, 0xff, sizeof(queryctrl));
    455 		queryctrl.id = i;
    456 		ret_query = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl);
    457 		errno_query = errno;
    458 
    459 		dprintf
    460 		    ("\t%s:%u: VIDIOC_QUERYCTRL, id=%u (V4L2_CID_BASE+%i), ret_query=%i, errno_query=%i\n",
    461 		     __FILE__, __LINE__, i, i - V4L2_CID_BASE, ret_query,
    462 		     errno_query);
    463 
    464 		if (ret_query == 0) {
    465 			CU_ASSERT_EQUAL(ret_query, 0);
    466 			CU_ASSERT_EQUAL(queryctrl.id, i);
    467 
    468 			CU_ASSERT(0 < strlen((char *)queryctrl.name));
    469 			CU_ASSERT(valid_string
    470 				  ((char *)queryctrl.name,
    471 				   sizeof(queryctrl.name)));
    472 
    473 			CU_ASSERT(valid_control_type(queryctrl.type));
    474 
    475 			switch (queryctrl.type) {
    476 			case V4L2_CTRL_TYPE_INTEGER:
    477 				/* min < max, because otherwise this control makes no sense */
    478 				CU_ASSERT(queryctrl.minimum <
    479 					  queryctrl.maximum);
    480 
    481 				CU_ASSERT(0 < queryctrl.step);
    482 
    483 				CU_ASSERT(queryctrl.minimum <=
    484 					  queryctrl.default_value);
    485 				CU_ASSERT(queryctrl.default_value <=
    486 					  queryctrl.maximum);
    487 				break;
    488 
    489 			case V4L2_CTRL_TYPE_BOOLEAN:
    490 				CU_ASSERT_EQUAL(queryctrl.minimum, 0);
    491 				CU_ASSERT_EQUAL(queryctrl.maximum, 1);
    492 				CU_ASSERT_EQUAL(queryctrl.step, 1);
    493 				CU_ASSERT((queryctrl.default_value == 0)
    494 					  || (queryctrl.default_value == 1));
    495 				break;
    496 
    497 			case V4L2_CTRL_TYPE_MENU:
    498 				CU_ASSERT_EQUAL(queryctrl.minimum, 0);
    499 				CU_ASSERT(queryctrl.minimum <=
    500 					  queryctrl.default_value);
    501 				CU_ASSERT_EQUAL(queryctrl.step, 1);
    502 				CU_ASSERT(queryctrl.minimum <=
    503 					  queryctrl.default_value);
    504 				CU_ASSERT(queryctrl.default_value <=
    505 					  queryctrl.maximum);
    506 				break;
    507 
    508 			case V4L2_CTRL_TYPE_BUTTON:
    509 				CU_ASSERT_EQUAL(queryctrl.minimum, 0);
    510 				CU_ASSERT_EQUAL(queryctrl.maximum, 0);
    511 				CU_ASSERT_EQUAL(queryctrl.step, 0);
    512 				CU_ASSERT_EQUAL(queryctrl.default_value, 0);
    513 				break;
    514 
    515 			case V4L2_CTRL_TYPE_INTEGER64:	/* fallthrough */
    516 			case V4L2_CTRL_TYPE_CTRL_CLASS:
    517 				/* These parameters are defined as n/a by V4L2, so
    518 				 * they should be filled with zeros, the same like
    519 				 * the reserved fields.
    520 				 */
    521 				CU_ASSERT_EQUAL(queryctrl.minimum, 0);
    522 				CU_ASSERT_EQUAL(queryctrl.maximum, 0);
    523 				CU_ASSERT_EQUAL(queryctrl.step, 0);
    524 				CU_ASSERT_EQUAL(queryctrl.default_value, 0);
    525 				break;
    526 
    527 			default:
    528 				CU_ASSERT_EQUAL(queryctrl.minimum, 0);
    529 				CU_ASSERT_EQUAL(queryctrl.maximum, 0);
    530 				CU_ASSERT_EQUAL(queryctrl.step, 0);
    531 				CU_ASSERT_EQUAL(queryctrl.default_value, 0);
    532 			}
    533 
    534 			CU_ASSERT(valid_control_flag(queryctrl.flags));
    535 
    536 			CU_ASSERT_EQUAL(queryctrl.reserved[0], 0);
    537 			CU_ASSERT_EQUAL(queryctrl.reserved[1], 0);
    538 
    539 			/* Check if the unused bytes of the name string are
    540 			 * also filled with zeros. Also check if there is any
    541 			 * padding byte between any two fields then this
    542 			 * padding byte is also filled with zeros.
    543 			 */
    544 			memset(&queryctrl2, 0, sizeof(queryctrl2));
    545 			queryctrl2.id = queryctrl.id;
    546 			queryctrl2.type = queryctrl.type;
    547 			strncpy((char *)queryctrl2.name, (char *)queryctrl.name,
    548 				sizeof(queryctrl2.name));
    549 			queryctrl2.minimum = queryctrl.minimum;
    550 			queryctrl2.maximum = queryctrl.maximum;
    551 			queryctrl2.step = queryctrl.step;
    552 			queryctrl2.default_value = queryctrl.default_value;
    553 			queryctrl2.flags = queryctrl.flags;
    554 			CU_ASSERT_EQUAL(memcmp
    555 					(&queryctrl, &queryctrl2,
    556 					 sizeof(queryctrl)), 0);
    557 
    558 			dprintf
    559 			    ("\tqueryctrl = {.id=%u, .type=%i, .name=\"%s\", "
    560 			     ".minimum=%i, .maximum=%i, .step=%i, "
    561 			     ".default_value=%i, " ".flags=0x%X, "
    562 			     ".reserved[]={ 0x%X, 0x%X } }\n", queryctrl.id,
    563 			     queryctrl.type, queryctrl.name, queryctrl.minimum,
    564 			     queryctrl.maximum, queryctrl.step,
    565 			     queryctrl.default_value, queryctrl.flags,
    566 			     queryctrl.reserved[0], queryctrl.reserved[1]
    567 			    );
    568 
    569 		} else {
    570 			CU_ASSERT_EQUAL(ret_query, -1);
    571 			CU_ASSERT_EQUAL(errno_query, EINVAL);
    572 
    573 			memset(&queryctrl2, 0xff, sizeof(queryctrl2));
    574 			queryctrl2.id = i;
    575 			CU_ASSERT_EQUAL(memcmp
    576 					(&queryctrl, &queryctrl2,
    577 					 sizeof(queryctrl)), 0);
    578 
    579 		}
    580 	} while (ret_query == 0);
    581 
    582 }
    583 
    584 void test_VIDIOC_QUERYCTRL_private_base_1()
    585 {
    586 	int ret_query, errno_query;
    587 	struct v4l2_queryctrl queryctrl;
    588 	struct v4l2_queryctrl queryctrl2;
    589 
    590 	memset(&queryctrl, 0xff, sizeof(queryctrl));
    591 	queryctrl.id = V4L2_CID_PRIVATE_BASE - 1;
    592 	ret_query = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl);
    593 	errno_query = errno;
    594 
    595 	dprintf
    596 	    ("\t%s:%u: VIDIOC_QUERYCTRL, id=%u (V4L2_CID_PRIVATE_BASE-1), ret_query=%i, errno_query=%i\n",
    597 	     __FILE__, __LINE__, V4L2_CID_PRIVATE_BASE - 1, ret_query,
    598 	     errno_query);
    599 
    600 	CU_ASSERT_EQUAL(ret_query, -1);
    601 	CU_ASSERT_EQUAL(errno_query, EINVAL);
    602 
    603 	memset(&queryctrl2, 0xff, sizeof(queryctrl2));
    604 	queryctrl2.id = V4L2_CID_PRIVATE_BASE - 1;
    605 	CU_ASSERT_EQUAL(memcmp(&queryctrl, &queryctrl2, sizeof(queryctrl)), 0);
    606 
    607 }
    608 
    609 void test_VIDIOC_QUERYCTRL_private_last_1()
    610 {
    611 	int ret_query, errno_query;
    612 	struct v4l2_queryctrl queryctrl;
    613 	struct v4l2_queryctrl queryctrl2;
    614 	__u32 i;
    615 
    616 	i = V4L2_CID_PRIVATE_BASE;
    617 	do {
    618 		memset(&queryctrl, 0xff, sizeof(queryctrl));
    619 		queryctrl.id = i;
    620 		ret_query = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl);
    621 		errno_query = errno;
    622 
    623 		i++;
    624 	} while (ret_query == 0);
    625 
    626 	memset(&queryctrl, 0xff, sizeof(queryctrl));
    627 	queryctrl.id = i;
    628 	ret_query = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl);
    629 
    630 	dprintf
    631 	    ("\t%s:%u: VIDIOC_QUERYCTRL, id=%u (V4L2_CID_PRIVATE_BASE+%u), ret_query=%i, errno_query=%i\n",
    632 	     __FILE__, __LINE__, i, i - V4L2_CID_PRIVATE_BASE, ret_query,
    633 	     errno_query);
    634 
    635 	CU_ASSERT_EQUAL(ret_query, -1);
    636 	CU_ASSERT_EQUAL(errno_query, EINVAL);
    637 
    638 	memset(&queryctrl2, 0xff, sizeof(queryctrl2));
    639 	queryctrl2.id = i;
    640 	CU_ASSERT_EQUAL(memcmp(&queryctrl, &queryctrl2, sizeof(queryctrl)), 0);
    641 
    642 }
    643 
    644 void test_VIDIOC_QUERYCTRL_NULL()
    645 {
    646 	int ret_query, errno_query;
    647 	int ret_null, errno_null;
    648 	struct v4l2_queryctrl queryctrl;
    649 	__u32 i;
    650 	unsigned int count_ctrl;
    651 
    652 	count_ctrl = 0;
    653 
    654 	i = V4L2_CID_BASE;
    655 	for (i = V4L2_CID_BASE; i < V4L2_CID_LASTP1; i++) {
    656 		memset(&queryctrl, 0xff, sizeof(queryctrl));
    657 		queryctrl.id = i;
    658 		ret_query = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl);
    659 		errno_query = errno;
    660 
    661 		dprintf
    662 		    ("\t%s:%u: VIDIOC_QUERYCTRL, id=%u (V4L2_CID_BASE+%i), ret_query=%i, errno_query=%i\n",
    663 		     __FILE__, __LINE__, i, i - V4L2_CID_BASE, ret_query,
    664 		     errno_query);
    665 
    666 		if (ret_query == 0) {
    667 			CU_ASSERT_EQUAL(ret_query, 0);
    668 			count_ctrl++;
    669 		} else {
    670 			CU_ASSERT_EQUAL(ret_query, -1);
    671 			CU_ASSERT_EQUAL(errno_query, EINVAL);
    672 		}
    673 	}
    674 
    675 	i = V4L2_CID_PRIVATE_BASE;
    676 	do {
    677 		memset(&queryctrl, 0xff, sizeof(queryctrl));
    678 		queryctrl.id = i;
    679 		ret_query = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl);
    680 		errno_query = errno;
    681 
    682 		dprintf
    683 		    ("\t%s:%u: VIDIOC_QUERYCTRL, id=%u (V4L2_CID_PRIVATE_BASE+%i), ret_query=%i, errno_query=%i\n",
    684 		     __FILE__, __LINE__, i, i - V4L2_CID_PRIVATE_BASE,
    685 		     ret_query, errno_query);
    686 
    687 		if (ret_query == 0) {
    688 			CU_ASSERT_EQUAL(ret_query, 0);
    689 			count_ctrl++;
    690 		} else {
    691 			CU_ASSERT_EQUAL(ret_query, -1);
    692 			CU_ASSERT_EQUAL(errno_query, EINVAL);
    693 		}
    694 
    695 		i++;
    696 	} while (ret_query == 0 && V4L2_CID_PRIVATE_BASE <= i);
    697 
    698 	ret_null = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, NULL);
    699 	errno_null = errno;
    700 
    701 	dprintf("\t%s:%u: VIDIOC_QUERYCTRL, ret_null=%i, errno_null=%i\n",
    702 		__FILE__, __LINE__, ret_null, errno_null);
    703 
    704 	if (0 < count_ctrl) {
    705 		CU_ASSERT_EQUAL(ret_null, -1);
    706 		CU_ASSERT_EQUAL(errno_null, EFAULT);
    707 	} else {
    708 		CU_ASSERT_EQUAL(ret_null, -1);
    709 		CU_ASSERT_EQUAL(errno_null, EINVAL);
    710 	}
    711 
    712 }
    713