1 /*
2  * v4l-test: Test environment for Video For Linux Two API
3  *
4  * 19 May 2009  0.1  First release
5  *
6  * Written by M�rton N�meth <nm127@freemail.hu>
7  * Released under GPL
8  */
9 
10 /*
11  * Note: V4L2_CID_LASTP1 != V4L2_CID_BASE_LASTP1
12  */
13 
14 #include <sys/ioctl.h>
15 #include <errno.h>
16 #include <string.h>
17 
18 #include <linux/videodev2.h>
19 #include <linux/errno.h>
20 
21 #include <CUnit/CUnit.h>
22 
23 #include "v4l2_test.h"
24 #include "dev_video.h"
25 #include "video_limits.h"
26 
27 #include "test_VIDIOC_EXT_CTRLS.h"
28 
test_VIDIOC_G_EXT_CTRLS_zero()29 void test_VIDIOC_G_EXT_CTRLS_zero()
30 {
31 	struct v4l2_ext_controls controls;
32 	int ret_get, errno_get;
33 
34 	memset(&controls, 0xff, sizeof(controls));
35 	controls.ctrl_class = V4L2_CTRL_CLASS_USER;
36 	controls.count = 0;
37 	controls.controls = NULL;
38 
39 	ret_get = ioctl(get_video_fd(), VIDIOC_G_EXT_CTRLS, &controls);
40 	errno_get = errno;
41 
42 	dprintf("\t%s:%u: VIDIOC_G_EXT_CTRLS, ret_get=%i, errno_get=%i\n",
43 		__FILE__, __LINE__, ret_get, errno_get);
44 
45 	if (ret_get == 0) {
46 		CU_ASSERT_EQUAL(ret_get, 0);
47 
48 		CU_ASSERT_EQUAL(controls.ctrl_class, V4L2_CTRL_CLASS_USER);
49 		CU_ASSERT_EQUAL(controls.count, 0);
50 		// The value of controls.error_idx is not defined when ret_get == 0
51 		CU_ASSERT_EQUAL(controls.reserved[0], 0);
52 		CU_ASSERT_EQUAL(controls.reserved[1], 0);
53 		CU_ASSERT_EQUAL(controls.controls, NULL);
54 
55 	} else {
56 		CU_ASSERT_EQUAL(ret_get, -1);
57 		CU_ASSERT_EQUAL(errno_get, EINVAL);
58 	}
59 }
60 
test_VIDIOC_G_EXT_CTRLS_zero_invalid_count()61 void test_VIDIOC_G_EXT_CTRLS_zero_invalid_count()
62 {
63 	struct v4l2_ext_controls controls;
64 	int ret_get, errno_get;
65 	int ret_get_invalid, errno_get_invalid;
66 	__u32 count;
67 
68 	count = 0;
69 	memset(&controls, 0, sizeof(controls));
70 	controls.ctrl_class = V4L2_CTRL_CLASS_USER;
71 	controls.count = count;
72 	controls.controls = NULL;
73 
74 	ret_get = ioctl(get_video_fd(), VIDIOC_G_EXT_CTRLS, &controls);
75 	errno_get = errno;
76 
77 	dprintf
78 	    ("\t%s:%u: VIDIOC_G_EXT_CTRLS, count=0%x, ret_get=%i, errno_get=%i\n",
79 	     __FILE__, __LINE__, count, ret_get, errno_get);
80 
81 	count = 1;
82 	/* Note: this loop also covers ((__u32)S32_MAX)+1 = 0x80000000 */
83 	do {
84 		memset(&controls, 0xff, sizeof(controls));
85 		controls.ctrl_class = V4L2_CTRL_CLASS_USER;
86 		controls.count = count;
87 		controls.controls = NULL;
88 
89 		ret_get_invalid =
90 		    ioctl(get_video_fd(), VIDIOC_G_EXT_CTRLS, &controls);
91 		errno_get_invalid = errno;
92 
93 		dprintf
94 		    ("\t%s:%u: VIDIOC_G_EXT_CTRLS, count=0x%x, ret_get_invalid=%i, errno_get_invalid=%i\n",
95 		     __FILE__, __LINE__, count, ret_get_invalid,
96 		     errno_get_invalid);
97 
98 		if (ret_get == 0) {
99 			CU_ASSERT_EQUAL(ret_get, 0);
100 
101 			/* if the VIDIOC_G_EXT_CTRLS is supported by the driver
102 			 * it shall complain about the NULL pointer at
103 			 * cotrols.controls because this does not match the
104 			 * controls.count value
105 			 */
106 			CU_ASSERT_EQUAL(ret_get_invalid, -1);
107 			CU_ASSERT(errno_get_invalid == EFAULT
108 				  || errno_get_invalid == ENOMEM);
109 
110 		} else {
111 			CU_ASSERT_EQUAL(ret_get, -1);
112 			CU_ASSERT_EQUAL(errno_get, EINVAL);
113 
114 			CU_ASSERT_EQUAL(ret_get_invalid, -1);
115 			CU_ASSERT_EQUAL(errno_get_invalid, EINVAL);
116 		}
117 		count <<= 1;
118 	} while (count != 0);
119 
120 	count = (__u32) S32_MAX;
121 	memset(&controls, 0xff, sizeof(controls));
122 	controls.ctrl_class = V4L2_CTRL_CLASS_USER;
123 	controls.count = count;
124 	controls.controls = NULL;
125 
126 	ret_get_invalid = ioctl(get_video_fd(), VIDIOC_G_EXT_CTRLS, &controls);
127 	errno_get_invalid = errno;
128 
129 	dprintf
130 	    ("\t%s:%u: VIDIOC_G_EXT_CTRLS, count=0x%x, ret_get_invalid=%i, errno_get_invalid=%i\n",
131 	     __FILE__, __LINE__, count, ret_get_invalid, errno_get_invalid);
132 
133 	if (ret_get == 0) {
134 		CU_ASSERT_EQUAL(ret_get, 0);
135 
136 		CU_ASSERT_EQUAL(ret_get_invalid, -1);
137 		CU_ASSERT(errno_get_invalid == EFAULT
138 			  || errno_get_invalid == ENOMEM);
139 
140 	} else {
141 		CU_ASSERT_EQUAL(ret_get, -1);
142 		CU_ASSERT_EQUAL(errno_get, EINVAL);
143 
144 		CU_ASSERT_EQUAL(ret_get_invalid, -1);
145 		CU_ASSERT_EQUAL(errno_get_invalid, EINVAL);
146 	}
147 
148 	count = U32_MAX;
149 	memset(&controls, 0xff, sizeof(controls));
150 	controls.ctrl_class = V4L2_CTRL_CLASS_USER;
151 	controls.count = count;
152 	controls.controls = NULL;
153 
154 	ret_get_invalid = ioctl(get_video_fd(), VIDIOC_G_EXT_CTRLS, &controls);
155 	errno_get_invalid = errno;
156 
157 	dprintf
158 	    ("\t%s:%u: VIDIOC_G_EXT_CTRLS, count=0x%x, ret_get_invalid=%i, errno_get_invalid=%i\n",
159 	     __FILE__, __LINE__, count, ret_get_invalid, errno_get_invalid);
160 
161 	if (ret_get == 0) {
162 		CU_ASSERT_EQUAL(ret_get, 0);
163 
164 		CU_ASSERT_EQUAL(ret_get_invalid, -1);
165 		CU_ASSERT(errno_get_invalid == EFAULT
166 			  || errno_get_invalid == ENOMEM);
167 
168 	} else {
169 		CU_ASSERT_EQUAL(ret_get, -1);
170 		CU_ASSERT_EQUAL(errno_get, EINVAL);
171 
172 		CU_ASSERT_EQUAL(ret_get_invalid, -1);
173 		CU_ASSERT_EQUAL(errno_get_invalid, EINVAL);
174 	}
175 
176 }
177 
do_get_ext_control_one(__u32 ctrl_class,__u32 id)178 static int do_get_ext_control_one(__u32 ctrl_class, __u32 id)
179 {
180 	int ret_query, errno_query;
181 	int ret_get, errno_get;
182 	struct v4l2_queryctrl queryctrl;
183 	struct v4l2_ext_controls controls;
184 	struct v4l2_ext_control control;
185 
186 	/* The expected return value of VIDIOC_G_EXT_CTRLS depens on the value
187 	 * reported by VIDIOC_QUERYCTRL
188 	 */
189 
190 	memset(&queryctrl, 0, sizeof(queryctrl));
191 	queryctrl.id = id;
192 	ret_query = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl);
193 	errno_query = errno;
194 
195 	dprintf
196 	    ("\t%s:%u: VIDIOC_QUERYCTRL, id=%u (V4L2_CID_BASE+%i), ret_query=%i, errno_query=%i\n",
197 	     __FILE__, __LINE__, id, id - V4L2_CID_BASE, ret_query,
198 	     errno_query);
199 	if (ret_query == 0) {
200 		dprintf("\t%s:%u: queryctrl = {.id=%u, .type=%i, .name=\"%s\", "
201 			".minimum=%i, .maximum=%i, .step=%i, "
202 			".default_value=%i, "
203 			".flags=0x%X, "
204 			".reserved[]={ 0x%X, 0x%X } }\n",
205 			__FILE__, __LINE__,
206 			queryctrl.id,
207 			queryctrl.type,
208 			queryctrl.name,
209 			queryctrl.minimum,
210 			queryctrl.maximum,
211 			queryctrl.step,
212 			queryctrl.default_value,
213 			queryctrl.flags,
214 			queryctrl.reserved[0], queryctrl.reserved[1]
215 		    );
216 	}
217 
218 	memset(&control, 0xff, sizeof(control));
219 	control.id = id;
220 
221 	memset(&controls, 0xff, sizeof(controls));
222 	controls.ctrl_class = ctrl_class;
223 	controls.count = 1;
224 	controls.controls = &control;
225 
226 	ret_get = ioctl(get_video_fd(), VIDIOC_G_EXT_CTRLS, &controls);
227 	errno_get = errno;
228 
229 	dprintf
230 	    ("\t%s:%u: VIDIOC_G_EXT_CTRLS, id=%u (V4L2_CID_BASE+%i), ret_get=%i, errno_get=%i\n",
231 	     __FILE__, __LINE__, id, id - V4L2_CID_BASE, ret_get, errno_get);
232 
233 	if (ret_query == 0) {
234 		CU_ASSERT_EQUAL(ret_query, 0);
235 
236 		switch (queryctrl.type) {
237 		case V4L2_CTRL_TYPE_INTEGER:
238 		case V4L2_CTRL_TYPE_BOOLEAN:
239 		case V4L2_CTRL_TYPE_MENU:
240 			if (ret_get == 0) {
241 				CU_ASSERT_EQUAL(ret_get, 0);
242 
243 				CU_ASSERT(queryctrl.minimum <= control.value);
244 				CU_ASSERT(control.value <= queryctrl.maximum);
245 			} else {
246 				/* This is the case when VIDIOC_G_CTRLS is not
247 				 * supported at all.
248 				 */
249 				CU_ASSERT_EQUAL(ret_get, -1);
250 				CU_ASSERT_EQUAL(errno_get, EINVAL);
251 			}
252 			break;
253 
254 		case V4L2_CTRL_TYPE_BUTTON:
255 			/* This control only performs an action, does not have
256 			 * any value
257 			 */
258 			CU_ASSERT_EQUAL(ret_get, -1);
259 			CU_ASSERT_EQUAL(errno_get, EINVAL);
260 			break;
261 
262 		case V4L2_CTRL_TYPE_INTEGER64:	/* TODO: what about this case? */
263 		case V4L2_CTRL_TYPE_CTRL_CLASS:
264 		default:
265 			CU_ASSERT_EQUAL(ret_get, -1);
266 			CU_ASSERT_EQUAL(errno_get, EINVAL);
267 		}
268 	} else {
269 		CU_ASSERT_EQUAL(ret_query, -1);
270 		CU_ASSERT_EQUAL(errno_query, EINVAL);
271 
272 		CU_ASSERT_EQUAL(ret_get, -1);
273 		CU_ASSERT_EQUAL(errno_get, EINVAL);
274 
275 	}
276 
277 	return ret_query;
278 }
279 
test_VIDIOC_G_EXT_CTRLS_one()280 void test_VIDIOC_G_EXT_CTRLS_one()
281 {
282 	int ret1;
283 	__u32 i;
284 
285 	for (i = V4L2_CID_BASE; i < V4L2_CID_LASTP1; i++) {
286 		ret1 = do_get_ext_control_one(V4L2_CTRL_CLASS_USER, i);
287 	}
288 
289 	ret1 = do_get_ext_control_one(V4L2_CTRL_CLASS_USER, V4L2_CID_BASE - 1);
290 	ret1 = do_get_ext_control_one(V4L2_CTRL_CLASS_USER, V4L2_CID_LASTP1);
291 	ret1 =
292 	    do_get_ext_control_one(V4L2_CTRL_CLASS_USER,
293 				   V4L2_CID_PRIVATE_BASE - 1);
294 
295 	i = V4L2_CID_PRIVATE_BASE;
296 	do {
297 		ret1 = do_get_ext_control_one(V4L2_CTRL_CLASS_USER, i);
298 		i++;
299 	} while (ret1 == 0);
300 
301 	ret1 = do_get_ext_control_one(V4L2_CTRL_CLASS_USER, i);
302 }
303 
test_VIDIOC_G_EXT_CTRLS_NULL()304 void test_VIDIOC_G_EXT_CTRLS_NULL()
305 {
306 	struct v4l2_ext_controls controls;
307 	int ret_get, errno_get;
308 	int ret_null, errno_null;
309 
310 	memset(&controls, 0xff, sizeof(controls));
311 	controls.ctrl_class = V4L2_CTRL_CLASS_USER;
312 	controls.count = 0;
313 	controls.controls = NULL;
314 
315 	ret_get = ioctl(get_video_fd(), VIDIOC_G_EXT_CTRLS, &controls);
316 	errno_get = errno;
317 
318 	dprintf("\t%s:%u: VIDIOC_G_EXT_CTRLS, ret_get=%i, errno_get=%i\n",
319 		__FILE__, __LINE__, ret_get, errno_get);
320 
321 	ret_null = ioctl(get_video_fd(), VIDIOC_G_EXT_CTRLS, NULL);
322 	errno_null = errno;
323 
324 	dprintf("\t%s:%u: VIDIOC_G_EXT_CTRLS, ret_null=%i, errno_null=%i\n",
325 		__FILE__, __LINE__, ret_null, errno_null);
326 
327 	if (ret_get == 0) {
328 		CU_ASSERT_EQUAL(ret_get, 0);
329 
330 		CU_ASSERT_EQUAL(ret_null, -1);
331 		CU_ASSERT_EQUAL(errno_null, EFAULT);
332 
333 	} else {
334 		CU_ASSERT_EQUAL(ret_get, -1);
335 		CU_ASSERT_EQUAL(errno_get, EINVAL);
336 
337 		CU_ASSERT_EQUAL(ret_null, -1);
338 		CU_ASSERT_EQUAL(errno_null, EINVAL);
339 	}
340 }
341 
test_VIDIOC_S_EXT_CTRLS_zero()342 void test_VIDIOC_S_EXT_CTRLS_zero()
343 {
344 	struct v4l2_ext_controls controls;
345 	int ret_set, errno_set;
346 
347 	memset(&controls, 0xff, sizeof(controls));
348 	controls.ctrl_class = V4L2_CTRL_CLASS_USER;
349 	controls.count = 0;
350 	controls.controls = NULL;
351 
352 	ret_set = ioctl(get_video_fd(), VIDIOC_S_EXT_CTRLS, &controls);
353 	errno_set = errno;
354 
355 	dprintf("\t%s:%u: VIDIOC_S_EXT_CTRLS, ret_set=%i, errno_set=%i\n",
356 		__FILE__, __LINE__, ret_set, errno_set);
357 
358 	if (ret_set == 0) {
359 		CU_ASSERT_EQUAL(ret_set, 0);
360 
361 		CU_ASSERT_EQUAL(controls.ctrl_class, V4L2_CTRL_CLASS_USER);
362 		CU_ASSERT_EQUAL(controls.count, 0);
363 		// The value of controls.error_idx is not defined when ret_set == 0
364 		CU_ASSERT_EQUAL(controls.reserved[0], 0);
365 		CU_ASSERT_EQUAL(controls.reserved[1], 0);
366 		CU_ASSERT_EQUAL(controls.controls, NULL);
367 
368 	} else {
369 		CU_ASSERT_EQUAL(ret_set, -1);
370 		CU_ASSERT_EQUAL(errno_set, EINVAL);
371 	}
372 }
373 
test_VIDIOC_S_EXT_CTRLS_zero_invalid_count()374 void test_VIDIOC_S_EXT_CTRLS_zero_invalid_count()
375 {
376 	struct v4l2_ext_controls controls;
377 	int ret_set, errno_set;
378 	int ret_set_invalid, errno_set_invalid;
379 	__u32 count;
380 
381 	count = 0;
382 	memset(&controls, 0, sizeof(controls));
383 	controls.ctrl_class = V4L2_CTRL_CLASS_USER;
384 	controls.count = count;
385 	controls.controls = NULL;
386 
387 	ret_set = ioctl(get_video_fd(), VIDIOC_S_EXT_CTRLS, &controls);
388 	errno_set = errno;
389 
390 	dprintf
391 	    ("\t%s:%u: VIDIOC_S_EXT_CTRLS, count=0%x, ret_set=%i, errno_set=%i\n",
392 	     __FILE__, __LINE__, count, ret_set, errno_set);
393 
394 	count = 1;
395 	/* Note: this loop also covers ((__u32)S32_MAX)+1 = 0x80000000 */
396 	do {
397 		memset(&controls, 0xff, sizeof(controls));
398 		controls.ctrl_class = V4L2_CTRL_CLASS_USER;
399 		controls.count = count;
400 		controls.controls = NULL;
401 
402 		ret_set_invalid =
403 		    ioctl(get_video_fd(), VIDIOC_S_EXT_CTRLS, &controls);
404 		errno_set_invalid = errno;
405 
406 		dprintf
407 		    ("\t%s:%u: VIDIOC_S_EXT_CTRLS, count=0x%x, ret_set_invalid=%i, errno_set_invalid=%i\n",
408 		     __FILE__, __LINE__, count, ret_set_invalid,
409 		     errno_set_invalid);
410 
411 		if (ret_set == 0) {
412 			CU_ASSERT_EQUAL(ret_set, 0);
413 
414 			/* if the VIDIOC_S_EXT_CTRLS is supported by the driver
415 			 * it shall complain about the NULL pointer at
416 			 * cotrols.controls because this does not match the
417 			 * controls.count value
418 			 */
419 			CU_ASSERT_EQUAL(ret_set_invalid, -1);
420 			CU_ASSERT(errno_set_invalid == EFAULT
421 				  || errno_set_invalid == ENOMEM);
422 
423 		} else {
424 			CU_ASSERT_EQUAL(ret_set, -1);
425 			CU_ASSERT_EQUAL(errno_set, EINVAL);
426 
427 			CU_ASSERT_EQUAL(ret_set_invalid, -1);
428 			CU_ASSERT_EQUAL(errno_set_invalid, EINVAL);
429 		}
430 		count <<= 1;
431 	} while (count != 0);
432 
433 	count = (__u32) S32_MAX;
434 	memset(&controls, 0xff, sizeof(controls));
435 	controls.ctrl_class = V4L2_CTRL_CLASS_USER;
436 	controls.count = count;
437 	controls.controls = NULL;
438 
439 	ret_set_invalid = ioctl(get_video_fd(), VIDIOC_S_EXT_CTRLS, &controls);
440 	errno_set_invalid = errno;
441 
442 	dprintf
443 	    ("\t%s:%u: VIDIOC_S_EXT_CTRLS, count=0x%x, ret_set_invalid=%i, errno_set_invalid=%i\n",
444 	     __FILE__, __LINE__, count, ret_set_invalid, errno_set_invalid);
445 
446 	if (ret_set == 0) {
447 		CU_ASSERT_EQUAL(ret_set, 0);
448 
449 		CU_ASSERT_EQUAL(ret_set_invalid, -1);
450 		CU_ASSERT(errno_set_invalid == EFAULT
451 			  || errno_set_invalid == ENOMEM);
452 
453 	} else {
454 		CU_ASSERT_EQUAL(ret_set, -1);
455 		CU_ASSERT_EQUAL(errno_set, EINVAL);
456 
457 		CU_ASSERT_EQUAL(ret_set_invalid, -1);
458 		CU_ASSERT_EQUAL(errno_set_invalid, EINVAL);
459 	}
460 
461 	count = U32_MAX;
462 	memset(&controls, 0xff, sizeof(controls));
463 	controls.ctrl_class = V4L2_CTRL_CLASS_USER;
464 	controls.count = count;
465 	controls.controls = NULL;
466 
467 	ret_set_invalid = ioctl(get_video_fd(), VIDIOC_S_EXT_CTRLS, &controls);
468 	errno_set_invalid = errno;
469 
470 	dprintf
471 	    ("\t%s:%u: VIDIOC_S_EXT_CTRLS, count=0x%x, ret_set_invalid=%i, errno_set_invalid=%i\n",
472 	     __FILE__, __LINE__, count, ret_set_invalid, errno_set_invalid);
473 
474 	if (ret_set == 0) {
475 		CU_ASSERT_EQUAL(ret_set, 0);
476 
477 		CU_ASSERT_EQUAL(ret_set_invalid, -1);
478 		CU_ASSERT(errno_set_invalid == EFAULT
479 			  || errno_set_invalid == ENOMEM);
480 
481 	} else {
482 		CU_ASSERT_EQUAL(ret_set, -1);
483 		CU_ASSERT_EQUAL(errno_set, EINVAL);
484 
485 		CU_ASSERT_EQUAL(ret_set_invalid, -1);
486 		CU_ASSERT_EQUAL(errno_set_invalid, EINVAL);
487 	}
488 
489 }
490 
test_VIDIOC_S_EXT_CTRLS_NULL()491 void test_VIDIOC_S_EXT_CTRLS_NULL()
492 {
493 	struct v4l2_ext_controls controls;
494 	int ret_set, errno_set;
495 	int ret_null, errno_null;
496 
497 	memset(&controls, 0xff, sizeof(controls));
498 	controls.ctrl_class = V4L2_CTRL_CLASS_USER;
499 	controls.count = 0;
500 	controls.controls = NULL;
501 
502 	ret_set = ioctl(get_video_fd(), VIDIOC_S_EXT_CTRLS, &controls);
503 	errno_set = errno;
504 
505 	dprintf("\t%s:%u: VIDIOC_S_EXT_CTRLS, ret_set=%i, errno_set=%i\n",
506 		__FILE__, __LINE__, ret_set, errno_set);
507 
508 	ret_null = ioctl(get_video_fd(), VIDIOC_S_EXT_CTRLS, NULL);
509 	errno_null = errno;
510 
511 	dprintf("\t%s:%u: VIDIOC_S_EXT_CTRLS, ret_null=%i, errno_null=%i\n",
512 		__FILE__, __LINE__, ret_null, errno_null);
513 
514 	if (ret_set == 0) {
515 		CU_ASSERT_EQUAL(ret_set, 0);
516 
517 		CU_ASSERT_EQUAL(ret_null, -1);
518 		CU_ASSERT_EQUAL(errno_null, EFAULT);
519 
520 	} else {
521 		CU_ASSERT_EQUAL(ret_set, -1);
522 		CU_ASSERT_EQUAL(errno_set, EINVAL);
523 
524 		CU_ASSERT_EQUAL(ret_null, -1);
525 		CU_ASSERT_EQUAL(errno_null, EINVAL);
526 	}
527 }
528 
test_VIDIOC_TRY_EXT_CTRLS_zero()529 void test_VIDIOC_TRY_EXT_CTRLS_zero()
530 {
531 	struct v4l2_ext_controls controls;
532 	int ret_try, errno_try;
533 
534 	memset(&controls, 0xff, sizeof(controls));
535 	controls.ctrl_class = V4L2_CTRL_CLASS_USER;
536 	controls.count = 0;
537 	controls.controls = NULL;
538 
539 	ret_try = ioctl(get_video_fd(), VIDIOC_TRY_EXT_CTRLS, &controls);
540 	errno_try = errno;
541 
542 	dprintf("\t%s:%u: VIDIOC_TRY_EXT_CTRLS, ret_try=%i, errno_try=%i\n",
543 		__FILE__, __LINE__, ret_try, errno_try);
544 
545 	if (ret_try == 0) {
546 		CU_ASSERT_EQUAL(ret_try, 0);
547 
548 		CU_ASSERT_EQUAL(controls.ctrl_class, V4L2_CTRL_CLASS_USER);
549 		CU_ASSERT_EQUAL(controls.count, 0);
550 		// The value of controls.error_idx is not defined when ret_try == 0
551 		CU_ASSERT_EQUAL(controls.reserved[0], 0);
552 		CU_ASSERT_EQUAL(controls.reserved[1], 0);
553 		CU_ASSERT_EQUAL(controls.controls, NULL);
554 
555 	} else {
556 		CU_ASSERT_EQUAL(ret_try, -1);
557 		CU_ASSERT_EQUAL(errno_try, EINVAL);
558 	}
559 }
560 
test_VIDIOC_TRY_EXT_CTRLS_zero_invalid_count()561 void test_VIDIOC_TRY_EXT_CTRLS_zero_invalid_count()
562 {
563 	struct v4l2_ext_controls controls;
564 	int ret_try, errno_try;
565 	int ret_try_invalid, errno_try_invalid;
566 	__u32 count;
567 
568 	count = 0;
569 	memset(&controls, 0, sizeof(controls));
570 	controls.ctrl_class = V4L2_CTRL_CLASS_USER;
571 	controls.count = count;
572 	controls.controls = NULL;
573 
574 	ret_try = ioctl(get_video_fd(), VIDIOC_TRY_EXT_CTRLS, &controls);
575 	errno_try = errno;
576 
577 	dprintf
578 	    ("\t%s:%u: VIDIOC_TRY_EXT_CTRLS, count=0x%x, ret_try=%i, errno_try=%i\n",
579 	     __FILE__, __LINE__, count, ret_try, errno_try);
580 
581 	count = 1;
582 	/* Note: this loop also covers ((__u32)S32_MAX)+1 = 0x80000000 */
583 	do {
584 		memset(&controls, 0xff, sizeof(controls));
585 		controls.ctrl_class = V4L2_CTRL_CLASS_USER;
586 		controls.count = count;
587 		controls.controls = NULL;
588 
589 		ret_try_invalid =
590 		    ioctl(get_video_fd(), VIDIOC_TRY_EXT_CTRLS, &controls);
591 		errno_try_invalid = errno;
592 
593 		dprintf
594 		    ("\t%s:%u: VIDIOC_TRY_EXT_CTRLS, count=0x%x, ret_try_invalid=%i, errno_try_invalid=%i\n",
595 		     __FILE__, __LINE__, count, ret_try_invalid,
596 		     errno_try_invalid);
597 
598 		if (ret_try == 0) {
599 			CU_ASSERT_EQUAL(ret_try, 0);
600 
601 			/* if the VIDIOC_TRY_EXT_CTRLS is supported by the driver
602 			 * it shall complain about the NULL pointer at
603 			 * cotrols.controls because this does not match the
604 			 * controls.count value
605 			 */
606 			CU_ASSERT_EQUAL(ret_try_invalid, -1);
607 			CU_ASSERT(errno_try_invalid == EFAULT
608 				  || errno_try_invalid == ENOMEM);
609 
610 		} else {
611 			CU_ASSERT_EQUAL(ret_try, -1);
612 			CU_ASSERT_EQUAL(errno_try, EINVAL);
613 
614 			CU_ASSERT_EQUAL(ret_try_invalid, -1);
615 			CU_ASSERT_EQUAL(errno_try_invalid, EINVAL);
616 		}
617 		count <<= 1;
618 	} while (count != 0);
619 
620 	count = (__u32) S32_MAX;
621 	memset(&controls, 0xff, sizeof(controls));
622 	controls.ctrl_class = V4L2_CTRL_CLASS_USER;
623 	controls.count = count;
624 	controls.controls = NULL;
625 
626 	ret_try_invalid =
627 	    ioctl(get_video_fd(), VIDIOC_TRY_EXT_CTRLS, &controls);
628 	errno_try_invalid = errno;
629 
630 	dprintf
631 	    ("\t%s:%u: VIDIOC_TRY_EXT_CTRLS, count=0x%x, ret_try_invalid=%i, errno_try_invalid=%i\n",
632 	     __FILE__, __LINE__, count, ret_try_invalid, errno_try_invalid);
633 
634 	if (ret_try == 0) {
635 		CU_ASSERT_EQUAL(ret_try, 0);
636 
637 		CU_ASSERT_EQUAL(ret_try_invalid, -1);
638 		CU_ASSERT(errno_try_invalid == EFAULT
639 			  || errno_try_invalid == ENOMEM);
640 
641 	} else {
642 		CU_ASSERT_EQUAL(ret_try, -1);
643 		CU_ASSERT_EQUAL(errno_try, EINVAL);
644 
645 		CU_ASSERT_EQUAL(ret_try_invalid, -1);
646 		CU_ASSERT_EQUAL(errno_try_invalid, EINVAL);
647 	}
648 
649 	count = U32_MAX;
650 	memset(&controls, 0xff, sizeof(controls));
651 	controls.ctrl_class = V4L2_CTRL_CLASS_USER;
652 	controls.count = count;
653 	controls.controls = NULL;
654 
655 	ret_try_invalid =
656 	    ioctl(get_video_fd(), VIDIOC_TRY_EXT_CTRLS, &controls);
657 	errno_try_invalid = errno;
658 
659 	dprintf
660 	    ("\t%s:%u: VIDIOC_TRY_EXT_CTRLS, count=0x%x, ret_try_invalid=%i, errno_try_invalid=%i\n",
661 	     __FILE__, __LINE__, count, ret_try_invalid, errno_try_invalid);
662 
663 	if (ret_try == 0) {
664 		CU_ASSERT_EQUAL(ret_try, 0);
665 
666 		CU_ASSERT_EQUAL(ret_try_invalid, -1);
667 		CU_ASSERT(errno_try_invalid == EFAULT
668 			  || errno_try_invalid == ENOMEM);
669 
670 	} else {
671 		CU_ASSERT_EQUAL(ret_try, -1);
672 		CU_ASSERT_EQUAL(errno_try, EINVAL);
673 
674 		CU_ASSERT_EQUAL(ret_try_invalid, -1);
675 		CU_ASSERT_EQUAL(errno_try_invalid, EINVAL);
676 	}
677 
678 }
679 
test_VIDIOC_TRY_EXT_CTRLS_NULL()680 void test_VIDIOC_TRY_EXT_CTRLS_NULL()
681 {
682 	struct v4l2_ext_controls controls;
683 	int ret_try, errno_try;
684 	int ret_null, errno_null;
685 
686 	memset(&controls, 0xff, sizeof(controls));
687 	controls.ctrl_class = V4L2_CTRL_CLASS_USER;
688 	controls.count = 0;
689 	controls.controls = NULL;
690 
691 	ret_try = ioctl(get_video_fd(), VIDIOC_TRY_EXT_CTRLS, &controls);
692 	errno_try = errno;
693 
694 	dprintf("\t%s:%u: VIDIOC_TRY_EXT_CTRLS, ret_try=%i, errno_try=%i\n",
695 		__FILE__, __LINE__, ret_try, errno_try);
696 
697 	ret_null = ioctl(get_video_fd(), VIDIOC_TRY_EXT_CTRLS, NULL);
698 	errno_null = errno;
699 
700 	dprintf("\t%s:%u: VIDIOC_TRY_EXT_CTRLS, ret_null=%i, errno_null=%i\n",
701 		__FILE__, __LINE__, ret_null, errno_null);
702 
703 	if (ret_try == 0) {
704 		CU_ASSERT_EQUAL(ret_try, 0);
705 
706 		CU_ASSERT_EQUAL(ret_null, -1);
707 		CU_ASSERT_EQUAL(errno_null, EFAULT);
708 
709 	} else {
710 		CU_ASSERT_EQUAL(ret_try, -1);
711 		CU_ASSERT_EQUAL(errno_try, EINVAL);
712 
713 		CU_ASSERT_EQUAL(ret_null, -1);
714 		CU_ASSERT_EQUAL(errno_null, EINVAL);
715 	}
716 }
717