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
29void 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
61void 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
178static 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
280void 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
304void 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
342void 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
374void 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
491void 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
529void 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
561void 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
680void 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