OMAP3 SRF: Generic shared resource f/w
[linux-ginger.git] / drivers / media / video / v4l2-ioctl.c
blob30cc3347ae52a417c83c9c899cb9c39f88b36667
1 /*
2 * Video capture interface for Linux version 2
4 * A generic framework to process V4L2 ioctl commands.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
11 * Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1)
12 * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2)
15 #include <linux/module.h>
16 #include <linux/types.h>
17 #include <linux/kernel.h>
19 #define __OLD_VIDIOC_ /* To allow fixing old calls */
20 #include <linux/videodev.h>
21 #include <linux/videodev2.h>
23 #ifdef CONFIG_VIDEO_V4L1
24 #include <linux/videodev.h>
25 #endif
26 #include <media/v4l2-common.h>
27 #include <media/v4l2-ioctl.h>
28 #include <media/v4l2-chip-ident.h>
30 #define dbgarg(cmd, fmt, arg...) \
31 do { \
32 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { \
33 printk(KERN_DEBUG "%s: ", vfd->name); \
34 v4l_printk_ioctl(cmd); \
35 printk(" " fmt, ## arg); \
36 } \
37 } while (0)
39 #define dbgarg2(fmt, arg...) \
40 do { \
41 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \
42 printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg);\
43 } while (0)
45 #define dbgarg3(fmt, arg...) \
46 do { \
47 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \
48 printk(KERN_CONT "%s: " fmt, vfd->name, ## arg);\
49 } while (0)
51 /* Zero out the end of the struct pointed to by p. Everthing after, but
52 * not including, the specified field is cleared. */
53 #define CLEAR_AFTER_FIELD(p, field) \
54 memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \
55 0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field))
57 struct std_descr {
58 v4l2_std_id std;
59 const char *descr;
62 static const struct std_descr standards[] = {
63 { V4L2_STD_NTSC, "NTSC" },
64 { V4L2_STD_NTSC_M, "NTSC-M" },
65 { V4L2_STD_NTSC_M_JP, "NTSC-M-JP" },
66 { V4L2_STD_NTSC_M_KR, "NTSC-M-KR" },
67 { V4L2_STD_NTSC_443, "NTSC-443" },
68 { V4L2_STD_PAL, "PAL" },
69 { V4L2_STD_PAL_BG, "PAL-BG" },
70 { V4L2_STD_PAL_B, "PAL-B" },
71 { V4L2_STD_PAL_B1, "PAL-B1" },
72 { V4L2_STD_PAL_G, "PAL-G" },
73 { V4L2_STD_PAL_H, "PAL-H" },
74 { V4L2_STD_PAL_I, "PAL-I" },
75 { V4L2_STD_PAL_DK, "PAL-DK" },
76 { V4L2_STD_PAL_D, "PAL-D" },
77 { V4L2_STD_PAL_D1, "PAL-D1" },
78 { V4L2_STD_PAL_K, "PAL-K" },
79 { V4L2_STD_PAL_M, "PAL-M" },
80 { V4L2_STD_PAL_N, "PAL-N" },
81 { V4L2_STD_PAL_Nc, "PAL-Nc" },
82 { V4L2_STD_PAL_60, "PAL-60" },
83 { V4L2_STD_SECAM, "SECAM" },
84 { V4L2_STD_SECAM_B, "SECAM-B" },
85 { V4L2_STD_SECAM_G, "SECAM-G" },
86 { V4L2_STD_SECAM_H, "SECAM-H" },
87 { V4L2_STD_SECAM_DK, "SECAM-DK" },
88 { V4L2_STD_SECAM_D, "SECAM-D" },
89 { V4L2_STD_SECAM_K, "SECAM-K" },
90 { V4L2_STD_SECAM_K1, "SECAM-K1" },
91 { V4L2_STD_SECAM_L, "SECAM-L" },
92 { V4L2_STD_SECAM_LC, "SECAM-Lc" },
93 { 0, "Unknown" }
96 /* video4linux standard ID conversion to standard name
98 const char *v4l2_norm_to_name(v4l2_std_id id)
100 u32 myid = id;
101 int i;
103 /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
104 64 bit comparations. So, on that architecture, with some gcc
105 variants, compilation fails. Currently, the max value is 30bit wide.
107 BUG_ON(myid != id);
109 for (i = 0; standards[i].std; i++)
110 if (myid == standards[i].std)
111 break;
112 return standards[i].descr;
114 EXPORT_SYMBOL(v4l2_norm_to_name);
116 /* Returns frame period for the given standard */
117 void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod)
119 if (id & V4L2_STD_525_60) {
120 frameperiod->numerator = 1001;
121 frameperiod->denominator = 30000;
122 } else {
123 frameperiod->numerator = 1;
124 frameperiod->denominator = 25;
127 EXPORT_SYMBOL(v4l2_video_std_frame_period);
129 /* Fill in the fields of a v4l2_standard structure according to the
130 'id' and 'transmission' parameters. Returns negative on error. */
131 int v4l2_video_std_construct(struct v4l2_standard *vs,
132 int id, const char *name)
134 vs->id = id;
135 v4l2_video_std_frame_period(id, &vs->frameperiod);
136 vs->framelines = (id & V4L2_STD_525_60) ? 525 : 625;
137 strlcpy(vs->name, name, sizeof(vs->name));
138 return 0;
140 EXPORT_SYMBOL(v4l2_video_std_construct);
142 /* ----------------------------------------------------------------- */
143 /* some arrays for pretty-printing debug messages of enum types */
145 const char *v4l2_field_names[] = {
146 [V4L2_FIELD_ANY] = "any",
147 [V4L2_FIELD_NONE] = "none",
148 [V4L2_FIELD_TOP] = "top",
149 [V4L2_FIELD_BOTTOM] = "bottom",
150 [V4L2_FIELD_INTERLACED] = "interlaced",
151 [V4L2_FIELD_SEQ_TB] = "seq-tb",
152 [V4L2_FIELD_SEQ_BT] = "seq-bt",
153 [V4L2_FIELD_ALTERNATE] = "alternate",
154 [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
155 [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
157 EXPORT_SYMBOL(v4l2_field_names);
159 const char *v4l2_type_names[] = {
160 [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "vid-cap",
161 [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "vid-overlay",
162 [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "vid-out",
163 [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
164 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
165 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
166 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
167 [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay",
169 EXPORT_SYMBOL(v4l2_type_names);
171 static const char *v4l2_memory_names[] = {
172 [V4L2_MEMORY_MMAP] = "mmap",
173 [V4L2_MEMORY_USERPTR] = "userptr",
174 [V4L2_MEMORY_OVERLAY] = "overlay",
177 #define prt_names(a, arr) ((((a) >= 0) && ((a) < ARRAY_SIZE(arr))) ? \
178 arr[a] : "unknown")
180 /* ------------------------------------------------------------------ */
181 /* debug help functions */
183 #ifdef CONFIG_VIDEO_V4L1_COMPAT
184 static const char *v4l1_ioctls[] = {
185 [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP",
186 [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN",
187 [_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN",
188 [_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER",
189 [_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER",
190 [_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT",
191 [_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT",
192 [_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE",
193 [_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN",
194 [_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN",
195 [_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF",
196 [_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF",
197 [_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY",
198 [_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ",
199 [_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ",
200 [_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO",
201 [_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO",
202 [_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC",
203 [_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE",
204 [_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF",
205 [_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT",
206 [_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE",
207 [_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE",
208 [_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE",
209 [_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE",
210 [_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO",
211 [_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE",
212 [_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT",
213 [_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT"
215 #define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
216 #endif
218 static const char *v4l2_ioctls[] = {
219 [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP",
220 [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED",
221 [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT",
222 [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT",
223 [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT",
224 [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS",
225 [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF",
226 [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF",
227 [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF",
228 [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY",
229 [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF",
230 [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF",
231 [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON",
232 [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF",
233 [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM",
234 [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM",
235 [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD",
236 [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD",
237 [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD",
238 [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT",
239 [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL",
240 [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL",
241 [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER",
242 [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER",
243 [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO",
244 [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO",
245 [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL",
246 [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU",
247 [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT",
248 [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT",
249 [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT",
250 [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT",
251 [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT",
252 [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT",
253 [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT",
254 [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR",
255 [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR",
256 [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY",
257 [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY",
258 [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP",
259 [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP",
260 [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP",
261 [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP",
262 [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP",
263 [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD",
264 [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT",
265 [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO",
266 [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT",
267 [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY",
268 [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY",
269 [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
270 [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS",
271 [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS",
272 [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS",
273 [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS",
274 #if 1
275 [_IOC_NR(VIDIOC_ENUM_FRAMESIZES)] = "VIDIOC_ENUM_FRAMESIZES",
276 [_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS",
277 [_IOC_NR(VIDIOC_G_ENC_INDEX)] = "VIDIOC_G_ENC_INDEX",
278 [_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD",
279 [_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD",
281 [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER",
282 [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER",
284 [_IOC_NR(VIDIOC_DBG_G_CHIP_IDENT)] = "VIDIOC_DBG_G_CHIP_IDENT",
285 [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK",
286 #endif
288 #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
290 /* Common ioctl debug function. This function can be used by
291 external ioctl messages as well as internal V4L ioctl */
292 void v4l_printk_ioctl(unsigned int cmd)
294 char *dir, *type;
296 switch (_IOC_TYPE(cmd)) {
297 case 'd':
298 type = "v4l2_int";
299 break;
300 #ifdef CONFIG_VIDEO_V4L1_COMPAT
301 case 'v':
302 if (_IOC_NR(cmd) >= V4L1_IOCTLS) {
303 type = "v4l1";
304 break;
306 printk("%s", v4l1_ioctls[_IOC_NR(cmd)]);
307 return;
308 #endif
309 case 'V':
310 if (_IOC_NR(cmd) >= V4L2_IOCTLS) {
311 type = "v4l2";
312 break;
314 printk("%s", v4l2_ioctls[_IOC_NR(cmd)]);
315 return;
316 default:
317 type = "unknown";
320 switch (_IOC_DIR(cmd)) {
321 case _IOC_NONE: dir = "--"; break;
322 case _IOC_READ: dir = "r-"; break;
323 case _IOC_WRITE: dir = "-w"; break;
324 case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
325 default: dir = "*ERR*"; break;
327 printk("%s ioctl '%c', dir=%s, #%d (0x%08x)",
328 type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
330 EXPORT_SYMBOL(v4l_printk_ioctl);
333 * helper function -- handles userspace copying for ioctl arguments
336 #ifdef __OLD_VIDIOC_
337 static unsigned int
338 video_fix_command(unsigned int cmd)
340 switch (cmd) {
341 case VIDIOC_OVERLAY_OLD:
342 cmd = VIDIOC_OVERLAY;
343 break;
344 case VIDIOC_S_PARM_OLD:
345 cmd = VIDIOC_S_PARM;
346 break;
347 case VIDIOC_S_CTRL_OLD:
348 cmd = VIDIOC_S_CTRL;
349 break;
350 case VIDIOC_G_AUDIO_OLD:
351 cmd = VIDIOC_G_AUDIO;
352 break;
353 case VIDIOC_G_AUDOUT_OLD:
354 cmd = VIDIOC_G_AUDOUT;
355 break;
356 case VIDIOC_CROPCAP_OLD:
357 cmd = VIDIOC_CROPCAP;
358 break;
360 return cmd;
362 #endif
365 * Obsolete usercopy function - Should be removed soon
367 long
368 video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
369 v4l2_kioctl func)
371 char sbuf[128];
372 void *mbuf = NULL;
373 void *parg = NULL;
374 long err = -EINVAL;
375 int is_ext_ctrl;
376 size_t ctrls_size = 0;
377 void __user *user_ptr = NULL;
379 #ifdef __OLD_VIDIOC_
380 cmd = video_fix_command(cmd);
381 #endif
382 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
383 cmd == VIDIOC_TRY_EXT_CTRLS);
385 /* Copy arguments into temp kernel buffer */
386 switch (_IOC_DIR(cmd)) {
387 case _IOC_NONE:
388 parg = NULL;
389 break;
390 case _IOC_READ:
391 case _IOC_WRITE:
392 case (_IOC_WRITE | _IOC_READ):
393 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
394 parg = sbuf;
395 } else {
396 /* too big to allocate from stack */
397 mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
398 if (NULL == mbuf)
399 return -ENOMEM;
400 parg = mbuf;
403 err = -EFAULT;
404 if (_IOC_DIR(cmd) & _IOC_WRITE)
405 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
406 goto out;
407 break;
409 if (is_ext_ctrl) {
410 struct v4l2_ext_controls *p = parg;
412 /* In case of an error, tell the caller that it wasn't
413 a specific control that caused it. */
414 p->error_idx = p->count;
415 user_ptr = (void __user *)p->controls;
416 if (p->count) {
417 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
418 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
419 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
420 err = -ENOMEM;
421 if (NULL == mbuf)
422 goto out_ext_ctrl;
423 err = -EFAULT;
424 if (copy_from_user(mbuf, user_ptr, ctrls_size))
425 goto out_ext_ctrl;
426 p->controls = mbuf;
430 /* call driver */
431 err = func(file, cmd, parg);
432 if (err == -ENOIOCTLCMD)
433 err = -EINVAL;
434 if (is_ext_ctrl) {
435 struct v4l2_ext_controls *p = parg;
437 p->controls = (void *)user_ptr;
438 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
439 err = -EFAULT;
440 goto out_ext_ctrl;
442 if (err < 0)
443 goto out;
445 out_ext_ctrl:
446 /* Copy results into user buffer */
447 switch (_IOC_DIR(cmd)) {
448 case _IOC_READ:
449 case (_IOC_WRITE | _IOC_READ):
450 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
451 err = -EFAULT;
452 break;
455 out:
456 kfree(mbuf);
457 return err;
459 EXPORT_SYMBOL(video_usercopy);
461 static void dbgbuf(unsigned int cmd, struct video_device *vfd,
462 struct v4l2_buffer *p)
464 struct v4l2_timecode *tc = &p->timecode;
466 dbgarg(cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
467 "bytesused=%d, flags=0x%08d, "
468 "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n",
469 p->timestamp.tv_sec / 3600,
470 (int)(p->timestamp.tv_sec / 60) % 60,
471 (int)(p->timestamp.tv_sec % 60),
472 (long)p->timestamp.tv_usec,
473 p->index,
474 prt_names(p->type, v4l2_type_names),
475 p->bytesused, p->flags,
476 p->field, p->sequence,
477 prt_names(p->memory, v4l2_memory_names),
478 p->m.userptr, p->length);
479 dbgarg2("timecode=%02d:%02d:%02d type=%d, "
480 "flags=0x%08d, frames=%d, userbits=0x%08x\n",
481 tc->hours, tc->minutes, tc->seconds,
482 tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits);
485 static inline void dbgrect(struct video_device *vfd, char *s,
486 struct v4l2_rect *r)
488 dbgarg2("%sRect start at %dx%d, size=%dx%d\n", s, r->left, r->top,
489 r->width, r->height);
492 static inline void v4l_print_pix_fmt(struct video_device *vfd,
493 struct v4l2_pix_format *fmt)
495 dbgarg2("width=%d, height=%d, format=%c%c%c%c, field=%s, "
496 "bytesperline=%d sizeimage=%d, colorspace=%d\n",
497 fmt->width, fmt->height,
498 (fmt->pixelformat & 0xff),
499 (fmt->pixelformat >> 8) & 0xff,
500 (fmt->pixelformat >> 16) & 0xff,
501 (fmt->pixelformat >> 24) & 0xff,
502 prt_names(fmt->field, v4l2_field_names),
503 fmt->bytesperline, fmt->sizeimage, fmt->colorspace);
506 static inline void v4l_print_ext_ctrls(unsigned int cmd,
507 struct video_device *vfd, struct v4l2_ext_controls *c, int show_vals)
509 __u32 i;
511 if (!(vfd->debug & V4L2_DEBUG_IOCTL_ARG))
512 return;
513 dbgarg(cmd, "");
514 printk(KERN_CONT "class=0x%x", c->ctrl_class);
515 for (i = 0; i < c->count; i++) {
516 if (show_vals && !c->controls[i].size)
517 printk(KERN_CONT " id/val=0x%x/0x%x",
518 c->controls[i].id, c->controls[i].value);
519 else
520 printk(KERN_CONT " id=0x%x,size=%u",
521 c->controls[i].id, c->controls[i].size);
523 printk(KERN_CONT "\n");
526 static inline int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)
528 __u32 i;
530 /* zero the reserved fields */
531 c->reserved[0] = c->reserved[1] = 0;
532 for (i = 0; i < c->count; i++)
533 c->controls[i].reserved2[0] = 0;
535 /* V4L2_CID_PRIVATE_BASE cannot be used as control class
536 when using extended controls.
537 Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
538 is it allowed for backwards compatibility.
540 if (!allow_priv && c->ctrl_class == V4L2_CID_PRIVATE_BASE)
541 return 0;
542 /* Check that all controls are from the same control class. */
543 for (i = 0; i < c->count; i++) {
544 if (V4L2_CTRL_ID2CLASS(c->controls[i].id) != c->ctrl_class) {
545 c->error_idx = i;
546 return 0;
549 return 1;
552 static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type)
554 if (ops == NULL)
555 return -EINVAL;
557 switch (type) {
558 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
559 if (ops->vidioc_g_fmt_vid_cap)
560 return 0;
561 break;
562 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
563 if (ops->vidioc_g_fmt_vid_overlay)
564 return 0;
565 break;
566 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
567 if (ops->vidioc_g_fmt_vid_out)
568 return 0;
569 break;
570 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
571 if (ops->vidioc_g_fmt_vid_out_overlay)
572 return 0;
573 break;
574 case V4L2_BUF_TYPE_VBI_CAPTURE:
575 if (ops->vidioc_g_fmt_vbi_cap)
576 return 0;
577 break;
578 case V4L2_BUF_TYPE_VBI_OUTPUT:
579 if (ops->vidioc_g_fmt_vbi_out)
580 return 0;
581 break;
582 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
583 if (ops->vidioc_g_fmt_sliced_vbi_cap)
584 return 0;
585 break;
586 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
587 if (ops->vidioc_g_fmt_sliced_vbi_out)
588 return 0;
589 break;
590 case V4L2_BUF_TYPE_PRIVATE:
591 if (ops->vidioc_g_fmt_type_private)
592 return 0;
593 break;
595 return -EINVAL;
598 static long __video_do_ioctl(struct file *file,
599 unsigned int cmd, void *arg)
601 struct video_device *vfd = video_devdata(file);
602 const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
603 void *fh = file->private_data;
604 long ret = -EINVAL;
606 if ((vfd->debug & V4L2_DEBUG_IOCTL) &&
607 !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) {
608 v4l_print_ioctl(vfd->name, cmd);
609 printk(KERN_CONT "\n");
612 if (ops == NULL) {
613 printk(KERN_WARNING "videodev: \"%s\" has no ioctl_ops.\n",
614 vfd->name);
615 return -EINVAL;
618 #ifdef CONFIG_VIDEO_V4L1_COMPAT
619 /***********************************************************
620 Handles calls to the obsoleted V4L1 API
621 Due to the nature of VIDIOCGMBUF, each driver that supports
622 V4L1 should implement its own handler for this ioctl.
623 ***********************************************************/
625 /* --- streaming capture ------------------------------------- */
626 if (cmd == VIDIOCGMBUF) {
627 struct video_mbuf *p = arg;
629 if (!ops->vidiocgmbuf)
630 return ret;
631 ret = ops->vidiocgmbuf(file, fh, p);
632 if (!ret)
633 dbgarg(cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
634 p->size, p->frames,
635 (unsigned long)p->offsets);
636 return ret;
639 /********************************************************
640 All other V4L1 calls are handled by v4l1_compat module.
641 Those calls will be translated into V4L2 calls, and
642 __video_do_ioctl will be called again, with one or more
643 V4L2 ioctls.
644 ********************************************************/
645 if (_IOC_TYPE(cmd) == 'v' && _IOC_NR(cmd) < BASE_VIDIOCPRIVATE)
646 return v4l_compat_translate_ioctl(file, cmd, arg,
647 __video_do_ioctl);
648 #endif
650 switch (cmd) {
651 /* --- capabilities ------------------------------------------ */
652 case VIDIOC_QUERYCAP:
654 struct v4l2_capability *cap = (struct v4l2_capability *)arg;
656 if (!ops->vidioc_querycap)
657 break;
659 ret = ops->vidioc_querycap(file, fh, cap);
660 if (!ret)
661 dbgarg(cmd, "driver=%s, card=%s, bus=%s, "
662 "version=0x%08x, "
663 "capabilities=0x%08x\n",
664 cap->driver, cap->card, cap->bus_info,
665 cap->version,
666 cap->capabilities);
667 break;
670 /* --- priority ------------------------------------------ */
671 case VIDIOC_G_PRIORITY:
673 enum v4l2_priority *p = arg;
675 if (!ops->vidioc_g_priority)
676 break;
677 ret = ops->vidioc_g_priority(file, fh, p);
678 if (!ret)
679 dbgarg(cmd, "priority is %d\n", *p);
680 break;
682 case VIDIOC_S_PRIORITY:
684 enum v4l2_priority *p = arg;
686 if (!ops->vidioc_s_priority)
687 break;
688 dbgarg(cmd, "setting priority to %d\n", *p);
689 ret = ops->vidioc_s_priority(file, fh, *p);
690 break;
693 /* --- capture ioctls ---------------------------------------- */
694 case VIDIOC_ENUM_FMT:
696 struct v4l2_fmtdesc *f = arg;
698 switch (f->type) {
699 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
700 if (ops->vidioc_enum_fmt_vid_cap)
701 ret = ops->vidioc_enum_fmt_vid_cap(file, fh, f);
702 break;
703 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
704 if (ops->vidioc_enum_fmt_vid_overlay)
705 ret = ops->vidioc_enum_fmt_vid_overlay(file,
706 fh, f);
707 break;
708 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
709 if (ops->vidioc_enum_fmt_vid_out)
710 ret = ops->vidioc_enum_fmt_vid_out(file, fh, f);
711 break;
712 case V4L2_BUF_TYPE_PRIVATE:
713 if (ops->vidioc_enum_fmt_type_private)
714 ret = ops->vidioc_enum_fmt_type_private(file,
715 fh, f);
716 break;
717 default:
718 break;
720 if (!ret)
721 dbgarg(cmd, "index=%d, type=%d, flags=%d, "
722 "pixelformat=%c%c%c%c, description='%s'\n",
723 f->index, f->type, f->flags,
724 (f->pixelformat & 0xff),
725 (f->pixelformat >> 8) & 0xff,
726 (f->pixelformat >> 16) & 0xff,
727 (f->pixelformat >> 24) & 0xff,
728 f->description);
729 break;
731 case VIDIOC_G_FMT:
733 struct v4l2_format *f = (struct v4l2_format *)arg;
735 /* FIXME: Should be one dump per type */
736 dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
738 switch (f->type) {
739 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
740 if (ops->vidioc_g_fmt_vid_cap)
741 ret = ops->vidioc_g_fmt_vid_cap(file, fh, f);
742 if (!ret)
743 v4l_print_pix_fmt(vfd, &f->fmt.pix);
744 break;
745 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
746 if (ops->vidioc_g_fmt_vid_overlay)
747 ret = ops->vidioc_g_fmt_vid_overlay(file,
748 fh, f);
749 break;
750 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
751 if (ops->vidioc_g_fmt_vid_out)
752 ret = ops->vidioc_g_fmt_vid_out(file, fh, f);
753 if (!ret)
754 v4l_print_pix_fmt(vfd, &f->fmt.pix);
755 break;
756 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
757 if (ops->vidioc_g_fmt_vid_out_overlay)
758 ret = ops->vidioc_g_fmt_vid_out_overlay(file,
759 fh, f);
760 break;
761 case V4L2_BUF_TYPE_VBI_CAPTURE:
762 if (ops->vidioc_g_fmt_vbi_cap)
763 ret = ops->vidioc_g_fmt_vbi_cap(file, fh, f);
764 break;
765 case V4L2_BUF_TYPE_VBI_OUTPUT:
766 if (ops->vidioc_g_fmt_vbi_out)
767 ret = ops->vidioc_g_fmt_vbi_out(file, fh, f);
768 break;
769 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
770 if (ops->vidioc_g_fmt_sliced_vbi_cap)
771 ret = ops->vidioc_g_fmt_sliced_vbi_cap(file,
772 fh, f);
773 break;
774 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
775 if (ops->vidioc_g_fmt_sliced_vbi_out)
776 ret = ops->vidioc_g_fmt_sliced_vbi_out(file,
777 fh, f);
778 break;
779 case V4L2_BUF_TYPE_PRIVATE:
780 if (ops->vidioc_g_fmt_type_private)
781 ret = ops->vidioc_g_fmt_type_private(file,
782 fh, f);
783 break;
786 break;
788 case VIDIOC_S_FMT:
790 struct v4l2_format *f = (struct v4l2_format *)arg;
792 /* FIXME: Should be one dump per type */
793 dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
795 switch (f->type) {
796 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
797 CLEAR_AFTER_FIELD(f, fmt.pix);
798 v4l_print_pix_fmt(vfd, &f->fmt.pix);
799 if (ops->vidioc_s_fmt_vid_cap)
800 ret = ops->vidioc_s_fmt_vid_cap(file, fh, f);
801 break;
802 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
803 CLEAR_AFTER_FIELD(f, fmt.win);
804 if (ops->vidioc_s_fmt_vid_overlay)
805 ret = ops->vidioc_s_fmt_vid_overlay(file,
806 fh, f);
807 break;
808 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
809 CLEAR_AFTER_FIELD(f, fmt.pix);
810 v4l_print_pix_fmt(vfd, &f->fmt.pix);
811 if (ops->vidioc_s_fmt_vid_out)
812 ret = ops->vidioc_s_fmt_vid_out(file, fh, f);
813 break;
814 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
815 CLEAR_AFTER_FIELD(f, fmt.win);
816 if (ops->vidioc_s_fmt_vid_out_overlay)
817 ret = ops->vidioc_s_fmt_vid_out_overlay(file,
818 fh, f);
819 break;
820 case V4L2_BUF_TYPE_VBI_CAPTURE:
821 CLEAR_AFTER_FIELD(f, fmt.vbi);
822 if (ops->vidioc_s_fmt_vbi_cap)
823 ret = ops->vidioc_s_fmt_vbi_cap(file, fh, f);
824 break;
825 case V4L2_BUF_TYPE_VBI_OUTPUT:
826 CLEAR_AFTER_FIELD(f, fmt.vbi);
827 if (ops->vidioc_s_fmt_vbi_out)
828 ret = ops->vidioc_s_fmt_vbi_out(file, fh, f);
829 break;
830 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
831 CLEAR_AFTER_FIELD(f, fmt.sliced);
832 if (ops->vidioc_s_fmt_sliced_vbi_cap)
833 ret = ops->vidioc_s_fmt_sliced_vbi_cap(file,
834 fh, f);
835 break;
836 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
837 CLEAR_AFTER_FIELD(f, fmt.sliced);
838 if (ops->vidioc_s_fmt_sliced_vbi_out)
839 ret = ops->vidioc_s_fmt_sliced_vbi_out(file,
840 fh, f);
841 break;
842 case V4L2_BUF_TYPE_PRIVATE:
843 /* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */
844 if (ops->vidioc_s_fmt_type_private)
845 ret = ops->vidioc_s_fmt_type_private(file,
846 fh, f);
847 break;
849 break;
851 case VIDIOC_TRY_FMT:
853 struct v4l2_format *f = (struct v4l2_format *)arg;
855 /* FIXME: Should be one dump per type */
856 dbgarg(cmd, "type=%s\n", prt_names(f->type,
857 v4l2_type_names));
858 switch (f->type) {
859 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
860 CLEAR_AFTER_FIELD(f, fmt.pix);
861 if (ops->vidioc_try_fmt_vid_cap)
862 ret = ops->vidioc_try_fmt_vid_cap(file, fh, f);
863 if (!ret)
864 v4l_print_pix_fmt(vfd, &f->fmt.pix);
865 break;
866 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
867 CLEAR_AFTER_FIELD(f, fmt.win);
868 if (ops->vidioc_try_fmt_vid_overlay)
869 ret = ops->vidioc_try_fmt_vid_overlay(file,
870 fh, f);
871 break;
872 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
873 CLEAR_AFTER_FIELD(f, fmt.pix);
874 if (ops->vidioc_try_fmt_vid_out)
875 ret = ops->vidioc_try_fmt_vid_out(file, fh, f);
876 if (!ret)
877 v4l_print_pix_fmt(vfd, &f->fmt.pix);
878 break;
879 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
880 CLEAR_AFTER_FIELD(f, fmt.win);
881 if (ops->vidioc_try_fmt_vid_out_overlay)
882 ret = ops->vidioc_try_fmt_vid_out_overlay(file,
883 fh, f);
884 break;
885 case V4L2_BUF_TYPE_VBI_CAPTURE:
886 CLEAR_AFTER_FIELD(f, fmt.vbi);
887 if (ops->vidioc_try_fmt_vbi_cap)
888 ret = ops->vidioc_try_fmt_vbi_cap(file, fh, f);
889 break;
890 case V4L2_BUF_TYPE_VBI_OUTPUT:
891 CLEAR_AFTER_FIELD(f, fmt.vbi);
892 if (ops->vidioc_try_fmt_vbi_out)
893 ret = ops->vidioc_try_fmt_vbi_out(file, fh, f);
894 break;
895 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
896 CLEAR_AFTER_FIELD(f, fmt.sliced);
897 if (ops->vidioc_try_fmt_sliced_vbi_cap)
898 ret = ops->vidioc_try_fmt_sliced_vbi_cap(file,
899 fh, f);
900 break;
901 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
902 CLEAR_AFTER_FIELD(f, fmt.sliced);
903 if (ops->vidioc_try_fmt_sliced_vbi_out)
904 ret = ops->vidioc_try_fmt_sliced_vbi_out(file,
905 fh, f);
906 break;
907 case V4L2_BUF_TYPE_PRIVATE:
908 /* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */
909 if (ops->vidioc_try_fmt_type_private)
910 ret = ops->vidioc_try_fmt_type_private(file,
911 fh, f);
912 break;
915 break;
917 /* FIXME: Those buf reqs could be handled here,
918 with some changes on videobuf to allow its header to be included at
919 videodev2.h or being merged at videodev2.
921 case VIDIOC_REQBUFS:
923 struct v4l2_requestbuffers *p = arg;
925 if (!ops->vidioc_reqbufs)
926 break;
927 ret = check_fmt(ops, p->type);
928 if (ret)
929 break;
931 if (p->type < V4L2_BUF_TYPE_PRIVATE)
932 CLEAR_AFTER_FIELD(p, memory);
934 ret = ops->vidioc_reqbufs(file, fh, p);
935 dbgarg(cmd, "count=%d, type=%s, memory=%s\n",
936 p->count,
937 prt_names(p->type, v4l2_type_names),
938 prt_names(p->memory, v4l2_memory_names));
939 break;
941 case VIDIOC_QUERYBUF:
943 struct v4l2_buffer *p = arg;
945 if (!ops->vidioc_querybuf)
946 break;
947 ret = check_fmt(ops, p->type);
948 if (ret)
949 break;
951 ret = ops->vidioc_querybuf(file, fh, p);
952 if (!ret)
953 dbgbuf(cmd, vfd, p);
954 break;
956 case VIDIOC_QBUF:
958 struct v4l2_buffer *p = arg;
960 if (!ops->vidioc_qbuf)
961 break;
962 ret = check_fmt(ops, p->type);
963 if (ret)
964 break;
966 ret = ops->vidioc_qbuf(file, fh, p);
967 if (!ret)
968 dbgbuf(cmd, vfd, p);
969 break;
971 case VIDIOC_DQBUF:
973 struct v4l2_buffer *p = arg;
975 if (!ops->vidioc_dqbuf)
976 break;
977 ret = check_fmt(ops, p->type);
978 if (ret)
979 break;
981 ret = ops->vidioc_dqbuf(file, fh, p);
982 if (!ret)
983 dbgbuf(cmd, vfd, p);
984 break;
986 case VIDIOC_OVERLAY:
988 int *i = arg;
990 if (!ops->vidioc_overlay)
991 break;
992 dbgarg(cmd, "value=%d\n", *i);
993 ret = ops->vidioc_overlay(file, fh, *i);
994 break;
996 case VIDIOC_G_FBUF:
998 struct v4l2_framebuffer *p = arg;
1000 if (!ops->vidioc_g_fbuf)
1001 break;
1002 ret = ops->vidioc_g_fbuf(file, fh, arg);
1003 if (!ret) {
1004 dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
1005 p->capability, p->flags,
1006 (unsigned long)p->base);
1007 v4l_print_pix_fmt(vfd, &p->fmt);
1009 break;
1011 case VIDIOC_S_FBUF:
1013 struct v4l2_framebuffer *p = arg;
1015 if (!ops->vidioc_s_fbuf)
1016 break;
1017 dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
1018 p->capability, p->flags, (unsigned long)p->base);
1019 v4l_print_pix_fmt(vfd, &p->fmt);
1020 ret = ops->vidioc_s_fbuf(file, fh, arg);
1021 break;
1023 case VIDIOC_STREAMON:
1025 enum v4l2_buf_type i = *(int *)arg;
1027 if (!ops->vidioc_streamon)
1028 break;
1029 dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
1030 ret = ops->vidioc_streamon(file, fh, i);
1031 break;
1033 case VIDIOC_STREAMOFF:
1035 enum v4l2_buf_type i = *(int *)arg;
1037 if (!ops->vidioc_streamoff)
1038 break;
1039 dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
1040 ret = ops->vidioc_streamoff(file, fh, i);
1041 break;
1043 /* ---------- tv norms ---------- */
1044 case VIDIOC_ENUMSTD:
1046 struct v4l2_standard *p = arg;
1047 v4l2_std_id id = vfd->tvnorms, curr_id = 0;
1048 unsigned int index = p->index, i, j = 0;
1049 const char *descr = "";
1051 /* Return norm array in a canonical way */
1052 for (i = 0; i <= index && id; i++) {
1053 /* last std value in the standards array is 0, so this
1054 while always ends there since (id & 0) == 0. */
1055 while ((id & standards[j].std) != standards[j].std)
1056 j++;
1057 curr_id = standards[j].std;
1058 descr = standards[j].descr;
1059 j++;
1060 if (curr_id == 0)
1061 break;
1062 if (curr_id != V4L2_STD_PAL &&
1063 curr_id != V4L2_STD_SECAM &&
1064 curr_id != V4L2_STD_NTSC)
1065 id &= ~curr_id;
1067 if (i <= index)
1068 return -EINVAL;
1070 v4l2_video_std_construct(p, curr_id, descr);
1072 dbgarg(cmd, "index=%d, id=0x%Lx, name=%s, fps=%d/%d, "
1073 "framelines=%d\n", p->index,
1074 (unsigned long long)p->id, p->name,
1075 p->frameperiod.numerator,
1076 p->frameperiod.denominator,
1077 p->framelines);
1079 ret = 0;
1080 break;
1082 case VIDIOC_G_STD:
1084 v4l2_std_id *id = arg;
1086 ret = 0;
1087 /* Calls the specific handler */
1088 if (ops->vidioc_g_std)
1089 ret = ops->vidioc_g_std(file, fh, id);
1090 else if (vfd->current_norm)
1091 *id = vfd->current_norm;
1092 else
1093 ret = -EINVAL;
1095 if (!ret)
1096 dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id);
1097 break;
1099 case VIDIOC_S_STD:
1101 v4l2_std_id *id = arg, norm;
1103 dbgarg(cmd, "std=%08Lx\n", (long long unsigned)*id);
1105 norm = (*id) & vfd->tvnorms;
1106 if (vfd->tvnorms && !norm) /* Check if std is supported */
1107 break;
1109 /* Calls the specific handler */
1110 if (ops->vidioc_s_std)
1111 ret = ops->vidioc_s_std(file, fh, &norm);
1112 else
1113 ret = -EINVAL;
1115 /* Updates standard information */
1116 if (ret >= 0)
1117 vfd->current_norm = norm;
1118 break;
1120 case VIDIOC_QUERYSTD:
1122 v4l2_std_id *p = arg;
1124 if (!ops->vidioc_querystd)
1125 break;
1126 ret = ops->vidioc_querystd(file, fh, arg);
1127 if (!ret)
1128 dbgarg(cmd, "detected std=%08Lx\n",
1129 (unsigned long long)*p);
1130 break;
1132 /* ------ input switching ---------- */
1133 /* FIXME: Inputs can be handled inside videodev2 */
1134 case VIDIOC_ENUMINPUT:
1136 struct v4l2_input *p = arg;
1138 if (!ops->vidioc_enum_input)
1139 break;
1141 ret = ops->vidioc_enum_input(file, fh, p);
1142 if (!ret)
1143 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1144 "audioset=%d, "
1145 "tuner=%d, std=%08Lx, status=%d\n",
1146 p->index, p->name, p->type, p->audioset,
1147 p->tuner,
1148 (unsigned long long)p->std,
1149 p->status);
1150 break;
1152 case VIDIOC_G_INPUT:
1154 unsigned int *i = arg;
1156 if (!ops->vidioc_g_input)
1157 break;
1158 ret = ops->vidioc_g_input(file, fh, i);
1159 if (!ret)
1160 dbgarg(cmd, "value=%d\n", *i);
1161 break;
1163 case VIDIOC_S_INPUT:
1165 unsigned int *i = arg;
1167 if (!ops->vidioc_s_input)
1168 break;
1169 dbgarg(cmd, "value=%d\n", *i);
1170 ret = ops->vidioc_s_input(file, fh, *i);
1171 break;
1174 /* ------ output switching ---------- */
1175 case VIDIOC_ENUMOUTPUT:
1177 struct v4l2_output *p = arg;
1179 if (!ops->vidioc_enum_output)
1180 break;
1182 ret = ops->vidioc_enum_output(file, fh, p);
1183 if (!ret)
1184 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1185 "audioset=0x%x, "
1186 "modulator=%d, std=0x%08Lx\n",
1187 p->index, p->name, p->type, p->audioset,
1188 p->modulator, (unsigned long long)p->std);
1189 break;
1191 case VIDIOC_G_OUTPUT:
1193 unsigned int *i = arg;
1195 if (!ops->vidioc_g_output)
1196 break;
1197 ret = ops->vidioc_g_output(file, fh, i);
1198 if (!ret)
1199 dbgarg(cmd, "value=%d\n", *i);
1200 break;
1202 case VIDIOC_S_OUTPUT:
1204 unsigned int *i = arg;
1206 if (!ops->vidioc_s_output)
1207 break;
1208 dbgarg(cmd, "value=%d\n", *i);
1209 ret = ops->vidioc_s_output(file, fh, *i);
1210 break;
1213 /* --- controls ---------------------------------------------- */
1214 case VIDIOC_QUERYCTRL:
1216 struct v4l2_queryctrl *p = arg;
1218 if (!ops->vidioc_queryctrl)
1219 break;
1220 ret = ops->vidioc_queryctrl(file, fh, p);
1221 if (!ret)
1222 dbgarg(cmd, "id=0x%x, type=%d, name=%s, min/max=%d/%d, "
1223 "step=%d, default=%d, flags=0x%08x\n",
1224 p->id, p->type, p->name,
1225 p->minimum, p->maximum,
1226 p->step, p->default_value, p->flags);
1227 else
1228 dbgarg(cmd, "id=0x%x\n", p->id);
1229 break;
1231 case VIDIOC_G_CTRL:
1233 struct v4l2_control *p = arg;
1235 if (ops->vidioc_g_ctrl)
1236 ret = ops->vidioc_g_ctrl(file, fh, p);
1237 else if (ops->vidioc_g_ext_ctrls) {
1238 struct v4l2_ext_controls ctrls;
1239 struct v4l2_ext_control ctrl;
1241 ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
1242 ctrls.count = 1;
1243 ctrls.controls = &ctrl;
1244 ctrl.id = p->id;
1245 ctrl.value = p->value;
1246 if (check_ext_ctrls(&ctrls, 1)) {
1247 ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls);
1248 if (ret == 0)
1249 p->value = ctrl.value;
1251 } else
1252 break;
1253 if (!ret)
1254 dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
1255 else
1256 dbgarg(cmd, "id=0x%x\n", p->id);
1257 break;
1259 case VIDIOC_S_CTRL:
1261 struct v4l2_control *p = arg;
1262 struct v4l2_ext_controls ctrls;
1263 struct v4l2_ext_control ctrl;
1265 if (!ops->vidioc_s_ctrl && !ops->vidioc_s_ext_ctrls)
1266 break;
1268 dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
1270 if (ops->vidioc_s_ctrl) {
1271 ret = ops->vidioc_s_ctrl(file, fh, p);
1272 break;
1274 if (!ops->vidioc_s_ext_ctrls)
1275 break;
1277 ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
1278 ctrls.count = 1;
1279 ctrls.controls = &ctrl;
1280 ctrl.id = p->id;
1281 ctrl.value = p->value;
1282 if (check_ext_ctrls(&ctrls, 1))
1283 ret = ops->vidioc_s_ext_ctrls(file, fh, &ctrls);
1284 break;
1286 case VIDIOC_G_EXT_CTRLS:
1288 struct v4l2_ext_controls *p = arg;
1290 p->error_idx = p->count;
1291 if (!ops->vidioc_g_ext_ctrls)
1292 break;
1293 if (check_ext_ctrls(p, 0))
1294 ret = ops->vidioc_g_ext_ctrls(file, fh, p);
1295 v4l_print_ext_ctrls(cmd, vfd, p, !ret);
1296 break;
1298 case VIDIOC_S_EXT_CTRLS:
1300 struct v4l2_ext_controls *p = arg;
1302 p->error_idx = p->count;
1303 if (!ops->vidioc_s_ext_ctrls)
1304 break;
1305 v4l_print_ext_ctrls(cmd, vfd, p, 1);
1306 if (check_ext_ctrls(p, 0))
1307 ret = ops->vidioc_s_ext_ctrls(file, fh, p);
1308 break;
1310 case VIDIOC_TRY_EXT_CTRLS:
1312 struct v4l2_ext_controls *p = arg;
1314 p->error_idx = p->count;
1315 if (!ops->vidioc_try_ext_ctrls)
1316 break;
1317 v4l_print_ext_ctrls(cmd, vfd, p, 1);
1318 if (check_ext_ctrls(p, 0))
1319 ret = ops->vidioc_try_ext_ctrls(file, fh, p);
1320 break;
1322 case VIDIOC_QUERYMENU:
1324 struct v4l2_querymenu *p = arg;
1326 if (!ops->vidioc_querymenu)
1327 break;
1328 ret = ops->vidioc_querymenu(file, fh, p);
1329 if (!ret)
1330 dbgarg(cmd, "id=0x%x, index=%d, name=%s\n",
1331 p->id, p->index, p->name);
1332 else
1333 dbgarg(cmd, "id=0x%x, index=%d\n",
1334 p->id, p->index);
1335 break;
1337 /* --- audio ---------------------------------------------- */
1338 case VIDIOC_ENUMAUDIO:
1340 struct v4l2_audio *p = arg;
1342 if (!ops->vidioc_enumaudio)
1343 break;
1344 ret = ops->vidioc_enumaudio(file, fh, p);
1345 if (!ret)
1346 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
1347 "mode=0x%x\n", p->index, p->name,
1348 p->capability, p->mode);
1349 else
1350 dbgarg(cmd, "index=%d\n", p->index);
1351 break;
1353 case VIDIOC_G_AUDIO:
1355 struct v4l2_audio *p = arg;
1357 if (!ops->vidioc_g_audio)
1358 break;
1360 ret = ops->vidioc_g_audio(file, fh, p);
1361 if (!ret)
1362 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
1363 "mode=0x%x\n", p->index,
1364 p->name, p->capability, p->mode);
1365 else
1366 dbgarg(cmd, "index=%d\n", p->index);
1367 break;
1369 case VIDIOC_S_AUDIO:
1371 struct v4l2_audio *p = arg;
1373 if (!ops->vidioc_s_audio)
1374 break;
1375 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
1376 "mode=0x%x\n", p->index, p->name,
1377 p->capability, p->mode);
1378 ret = ops->vidioc_s_audio(file, fh, p);
1379 break;
1381 case VIDIOC_ENUMAUDOUT:
1383 struct v4l2_audioout *p = arg;
1385 if (!ops->vidioc_enumaudout)
1386 break;
1387 dbgarg(cmd, "Enum for index=%d\n", p->index);
1388 ret = ops->vidioc_enumaudout(file, fh, p);
1389 if (!ret)
1390 dbgarg2("index=%d, name=%s, capability=%d, "
1391 "mode=%d\n", p->index, p->name,
1392 p->capability, p->mode);
1393 break;
1395 case VIDIOC_G_AUDOUT:
1397 struct v4l2_audioout *p = arg;
1399 if (!ops->vidioc_g_audout)
1400 break;
1402 ret = ops->vidioc_g_audout(file, fh, p);
1403 if (!ret)
1404 dbgarg2("index=%d, name=%s, capability=%d, "
1405 "mode=%d\n", p->index, p->name,
1406 p->capability, p->mode);
1407 break;
1409 case VIDIOC_S_AUDOUT:
1411 struct v4l2_audioout *p = arg;
1413 if (!ops->vidioc_s_audout)
1414 break;
1415 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1416 "mode=%d\n", p->index, p->name,
1417 p->capability, p->mode);
1419 ret = ops->vidioc_s_audout(file, fh, p);
1420 break;
1422 case VIDIOC_G_MODULATOR:
1424 struct v4l2_modulator *p = arg;
1426 if (!ops->vidioc_g_modulator)
1427 break;
1428 ret = ops->vidioc_g_modulator(file, fh, p);
1429 if (!ret)
1430 dbgarg(cmd, "index=%d, name=%s, "
1431 "capability=%d, rangelow=%d,"
1432 " rangehigh=%d, txsubchans=%d\n",
1433 p->index, p->name, p->capability,
1434 p->rangelow, p->rangehigh,
1435 p->txsubchans);
1436 break;
1438 case VIDIOC_S_MODULATOR:
1440 struct v4l2_modulator *p = arg;
1442 if (!ops->vidioc_s_modulator)
1443 break;
1444 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1445 "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
1446 p->index, p->name, p->capability, p->rangelow,
1447 p->rangehigh, p->txsubchans);
1448 ret = ops->vidioc_s_modulator(file, fh, p);
1449 break;
1451 case VIDIOC_G_CROP:
1453 struct v4l2_crop *p = arg;
1455 if (!ops->vidioc_g_crop)
1456 break;
1458 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1459 ret = ops->vidioc_g_crop(file, fh, p);
1460 if (!ret)
1461 dbgrect(vfd, "", &p->c);
1462 break;
1464 case VIDIOC_S_CROP:
1466 struct v4l2_crop *p = arg;
1468 if (!ops->vidioc_s_crop)
1469 break;
1470 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1471 dbgrect(vfd, "", &p->c);
1472 ret = ops->vidioc_s_crop(file, fh, p);
1473 break;
1475 case VIDIOC_CROPCAP:
1477 struct v4l2_cropcap *p = arg;
1479 /*FIXME: Should also show v4l2_fract pixelaspect */
1480 if (!ops->vidioc_cropcap)
1481 break;
1483 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1484 ret = ops->vidioc_cropcap(file, fh, p);
1485 if (!ret) {
1486 dbgrect(vfd, "bounds ", &p->bounds);
1487 dbgrect(vfd, "defrect ", &p->defrect);
1489 break;
1491 case VIDIOC_G_JPEGCOMP:
1493 struct v4l2_jpegcompression *p = arg;
1495 if (!ops->vidioc_g_jpegcomp)
1496 break;
1498 ret = ops->vidioc_g_jpegcomp(file, fh, p);
1499 if (!ret)
1500 dbgarg(cmd, "quality=%d, APPn=%d, "
1501 "APP_len=%d, COM_len=%d, "
1502 "jpeg_markers=%d\n",
1503 p->quality, p->APPn, p->APP_len,
1504 p->COM_len, p->jpeg_markers);
1505 break;
1507 case VIDIOC_S_JPEGCOMP:
1509 struct v4l2_jpegcompression *p = arg;
1511 if (!ops->vidioc_g_jpegcomp)
1512 break;
1513 dbgarg(cmd, "quality=%d, APPn=%d, APP_len=%d, "
1514 "COM_len=%d, jpeg_markers=%d\n",
1515 p->quality, p->APPn, p->APP_len,
1516 p->COM_len, p->jpeg_markers);
1517 ret = ops->vidioc_s_jpegcomp(file, fh, p);
1518 break;
1520 case VIDIOC_G_ENC_INDEX:
1522 struct v4l2_enc_idx *p = arg;
1524 if (!ops->vidioc_g_enc_index)
1525 break;
1526 ret = ops->vidioc_g_enc_index(file, fh, p);
1527 if (!ret)
1528 dbgarg(cmd, "entries=%d, entries_cap=%d\n",
1529 p->entries, p->entries_cap);
1530 break;
1532 case VIDIOC_ENCODER_CMD:
1534 struct v4l2_encoder_cmd *p = arg;
1536 if (!ops->vidioc_encoder_cmd)
1537 break;
1538 ret = ops->vidioc_encoder_cmd(file, fh, p);
1539 if (!ret)
1540 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
1541 break;
1543 case VIDIOC_TRY_ENCODER_CMD:
1545 struct v4l2_encoder_cmd *p = arg;
1547 if (!ops->vidioc_try_encoder_cmd)
1548 break;
1549 ret = ops->vidioc_try_encoder_cmd(file, fh, p);
1550 if (!ret)
1551 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
1552 break;
1554 case VIDIOC_G_PARM:
1556 struct v4l2_streamparm *p = arg;
1558 if (ops->vidioc_g_parm) {
1559 ret = check_fmt(ops, p->type);
1560 if (ret)
1561 break;
1562 ret = ops->vidioc_g_parm(file, fh, p);
1563 } else {
1564 v4l2_std_id std = vfd->current_norm;
1566 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1567 return -EINVAL;
1569 ret = 0;
1570 if (ops->vidioc_g_std)
1571 ret = ops->vidioc_g_std(file, fh, &std);
1572 else if (std == 0)
1573 ret = -EINVAL;
1574 if (ret == 0)
1575 v4l2_video_std_frame_period(std,
1576 &p->parm.capture.timeperframe);
1579 dbgarg(cmd, "type=%d\n", p->type);
1580 break;
1582 case VIDIOC_S_PARM:
1584 struct v4l2_streamparm *p = arg;
1586 if (!ops->vidioc_s_parm)
1587 break;
1588 ret = check_fmt(ops, p->type);
1589 if (ret)
1590 break;
1592 dbgarg(cmd, "type=%d\n", p->type);
1593 ret = ops->vidioc_s_parm(file, fh, p);
1594 break;
1596 case VIDIOC_G_TUNER:
1598 struct v4l2_tuner *p = arg;
1600 if (!ops->vidioc_g_tuner)
1601 break;
1603 ret = ops->vidioc_g_tuner(file, fh, p);
1604 if (!ret)
1605 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1606 "capability=0x%x, rangelow=%d, "
1607 "rangehigh=%d, signal=%d, afc=%d, "
1608 "rxsubchans=0x%x, audmode=%d\n",
1609 p->index, p->name, p->type,
1610 p->capability, p->rangelow,
1611 p->rangehigh, p->signal, p->afc,
1612 p->rxsubchans, p->audmode);
1613 break;
1615 case VIDIOC_S_TUNER:
1617 struct v4l2_tuner *p = arg;
1619 if (!ops->vidioc_s_tuner)
1620 break;
1621 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1622 "capability=0x%x, rangelow=%d, "
1623 "rangehigh=%d, signal=%d, afc=%d, "
1624 "rxsubchans=0x%x, audmode=%d\n",
1625 p->index, p->name, p->type,
1626 p->capability, p->rangelow,
1627 p->rangehigh, p->signal, p->afc,
1628 p->rxsubchans, p->audmode);
1629 ret = ops->vidioc_s_tuner(file, fh, p);
1630 break;
1632 case VIDIOC_G_FREQUENCY:
1634 struct v4l2_frequency *p = arg;
1636 if (!ops->vidioc_g_frequency)
1637 break;
1639 ret = ops->vidioc_g_frequency(file, fh, p);
1640 if (!ret)
1641 dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
1642 p->tuner, p->type, p->frequency);
1643 break;
1645 case VIDIOC_S_FREQUENCY:
1647 struct v4l2_frequency *p = arg;
1649 if (!ops->vidioc_s_frequency)
1650 break;
1651 dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
1652 p->tuner, p->type, p->frequency);
1653 ret = ops->vidioc_s_frequency(file, fh, p);
1654 break;
1656 case VIDIOC_G_SLICED_VBI_CAP:
1658 struct v4l2_sliced_vbi_cap *p = arg;
1660 if (!ops->vidioc_g_sliced_vbi_cap)
1661 break;
1663 /* Clear up to type, everything after type is zerod already */
1664 memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type));
1666 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1667 ret = ops->vidioc_g_sliced_vbi_cap(file, fh, p);
1668 if (!ret)
1669 dbgarg2("service_set=%d\n", p->service_set);
1670 break;
1672 case VIDIOC_LOG_STATUS:
1674 if (!ops->vidioc_log_status)
1675 break;
1676 ret = ops->vidioc_log_status(file, fh);
1677 break;
1679 #ifdef CONFIG_VIDEO_ADV_DEBUG
1680 case VIDIOC_DBG_G_REGISTER:
1682 struct v4l2_dbg_register *p = arg;
1684 if (!capable(CAP_SYS_ADMIN))
1685 ret = -EPERM;
1686 else if (ops->vidioc_g_register)
1687 ret = ops->vidioc_g_register(file, fh, p);
1688 break;
1690 case VIDIOC_DBG_S_REGISTER:
1692 struct v4l2_dbg_register *p = arg;
1694 if (!capable(CAP_SYS_ADMIN))
1695 ret = -EPERM;
1696 else if (ops->vidioc_s_register)
1697 ret = ops->vidioc_s_register(file, fh, p);
1698 break;
1700 #endif
1701 case VIDIOC_DBG_G_CHIP_IDENT:
1703 struct v4l2_dbg_chip_ident *p = arg;
1705 if (!ops->vidioc_g_chip_ident)
1706 break;
1707 p->ident = V4L2_IDENT_NONE;
1708 p->revision = 0;
1709 ret = ops->vidioc_g_chip_ident(file, fh, p);
1710 if (!ret)
1711 dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
1712 break;
1714 case VIDIOC_S_HW_FREQ_SEEK:
1716 struct v4l2_hw_freq_seek *p = arg;
1718 if (!ops->vidioc_s_hw_freq_seek)
1719 break;
1720 dbgarg(cmd,
1721 "tuner=%d, type=%d, seek_upward=%d, wrap_around=%d\n",
1722 p->tuner, p->type, p->seek_upward, p->wrap_around);
1723 ret = ops->vidioc_s_hw_freq_seek(file, fh, p);
1724 break;
1726 case VIDIOC_ENUM_FRAMESIZES:
1728 struct v4l2_frmsizeenum *p = arg;
1730 if (!ops->vidioc_enum_framesizes)
1731 break;
1733 ret = ops->vidioc_enum_framesizes(file, fh, p);
1734 dbgarg(cmd,
1735 "index=%d, pixelformat=%c%c%c%c, type=%d ",
1736 p->index,
1737 (p->pixel_format & 0xff),
1738 (p->pixel_format >> 8) & 0xff,
1739 (p->pixel_format >> 16) & 0xff,
1740 (p->pixel_format >> 24) & 0xff,
1741 p->type);
1742 switch (p->type) {
1743 case V4L2_FRMSIZE_TYPE_DISCRETE:
1744 dbgarg3("width = %d, height=%d\n",
1745 p->discrete.width, p->discrete.height);
1746 break;
1747 case V4L2_FRMSIZE_TYPE_STEPWISE:
1748 dbgarg3("min %dx%d, max %dx%d, step %dx%d\n",
1749 p->stepwise.min_width, p->stepwise.min_height,
1750 p->stepwise.step_width, p->stepwise.step_height,
1751 p->stepwise.max_width, p->stepwise.max_height);
1752 break;
1753 case V4L2_FRMSIZE_TYPE_CONTINUOUS:
1754 dbgarg3("continuous\n");
1755 break;
1756 default:
1757 dbgarg3("- Unknown type!\n");
1760 break;
1762 case VIDIOC_ENUM_FRAMEINTERVALS:
1764 struct v4l2_frmivalenum *p = arg;
1766 if (!ops->vidioc_enum_frameintervals)
1767 break;
1769 ret = ops->vidioc_enum_frameintervals(file, fh, p);
1770 dbgarg(cmd,
1771 "index=%d, pixelformat=%d, width=%d, height=%d, type=%d ",
1772 p->index, p->pixel_format,
1773 p->width, p->height, p->type);
1774 switch (p->type) {
1775 case V4L2_FRMIVAL_TYPE_DISCRETE:
1776 dbgarg2("fps=%d/%d\n",
1777 p->discrete.numerator,
1778 p->discrete.denominator);
1779 break;
1780 case V4L2_FRMIVAL_TYPE_STEPWISE:
1781 dbgarg2("min=%d/%d, max=%d/%d, step=%d/%d\n",
1782 p->stepwise.min.numerator,
1783 p->stepwise.min.denominator,
1784 p->stepwise.max.numerator,
1785 p->stepwise.max.denominator,
1786 p->stepwise.step.numerator,
1787 p->stepwise.step.denominator);
1788 break;
1789 case V4L2_FRMIVAL_TYPE_CONTINUOUS:
1790 dbgarg2("continuous\n");
1791 break;
1792 default:
1793 dbgarg2("- Unknown type!\n");
1795 break;
1798 default:
1800 if (!ops->vidioc_default)
1801 break;
1802 ret = ops->vidioc_default(file, fh, cmd, arg);
1803 break;
1805 } /* switch */
1807 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1808 if (ret < 0) {
1809 v4l_print_ioctl(vfd->name, cmd);
1810 printk(KERN_CONT " error %ld\n", ret);
1814 return ret;
1817 /* In some cases, only a few fields are used as input, i.e. when the app sets
1818 * "index" and then the driver fills in the rest of the structure for the thing
1819 * with that index. We only need to copy up the first non-input field. */
1820 static unsigned long cmd_input_size(unsigned int cmd)
1822 /* Size of structure up to and including 'field' */
1823 #define CMDINSIZE(cmd, type, field) \
1824 case VIDIOC_##cmd: \
1825 return offsetof(struct v4l2_##type, field) + \
1826 sizeof(((struct v4l2_##type *)0)->field);
1828 switch (cmd) {
1829 CMDINSIZE(ENUM_FMT, fmtdesc, type);
1830 CMDINSIZE(G_FMT, format, type);
1831 CMDINSIZE(QUERYBUF, buffer, type);
1832 CMDINSIZE(G_PARM, streamparm, type);
1833 CMDINSIZE(ENUMSTD, standard, index);
1834 CMDINSIZE(ENUMINPUT, input, index);
1835 CMDINSIZE(G_CTRL, control, id);
1836 CMDINSIZE(G_TUNER, tuner, index);
1837 CMDINSIZE(QUERYCTRL, queryctrl, id);
1838 CMDINSIZE(QUERYMENU, querymenu, index);
1839 CMDINSIZE(ENUMOUTPUT, output, index);
1840 CMDINSIZE(G_MODULATOR, modulator, index);
1841 CMDINSIZE(G_FREQUENCY, frequency, tuner);
1842 CMDINSIZE(CROPCAP, cropcap, type);
1843 CMDINSIZE(G_CROP, crop, type);
1844 CMDINSIZE(ENUMAUDIO, audio, index);
1845 CMDINSIZE(ENUMAUDOUT, audioout, index);
1846 CMDINSIZE(ENCODER_CMD, encoder_cmd, flags);
1847 CMDINSIZE(TRY_ENCODER_CMD, encoder_cmd, flags);
1848 CMDINSIZE(G_SLICED_VBI_CAP, sliced_vbi_cap, type);
1849 CMDINSIZE(ENUM_FRAMESIZES, frmsizeenum, pixel_format);
1850 CMDINSIZE(ENUM_FRAMEINTERVALS, frmivalenum, height);
1851 default:
1852 return _IOC_SIZE(cmd);
1856 long video_ioctl2(struct file *file,
1857 unsigned int cmd, unsigned long arg)
1859 char sbuf[128];
1860 void *mbuf = NULL;
1861 void *parg = NULL;
1862 long err = -EINVAL;
1863 int is_ext_ctrl;
1864 size_t ctrls_size = 0;
1865 void __user *user_ptr = NULL;
1867 #ifdef __OLD_VIDIOC_
1868 cmd = video_fix_command(cmd);
1869 #endif
1870 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
1871 cmd == VIDIOC_TRY_EXT_CTRLS);
1873 /* Copy arguments into temp kernel buffer */
1874 if (_IOC_DIR(cmd) != _IOC_NONE) {
1875 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
1876 parg = sbuf;
1877 } else {
1878 /* too big to allocate from stack */
1879 mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
1880 if (NULL == mbuf)
1881 return -ENOMEM;
1882 parg = mbuf;
1885 err = -EFAULT;
1886 if (_IOC_DIR(cmd) & _IOC_WRITE) {
1887 unsigned long n = cmd_input_size(cmd);
1889 if (copy_from_user(parg, (void __user *)arg, n))
1890 goto out;
1892 /* zero out anything we don't copy from userspace */
1893 if (n < _IOC_SIZE(cmd))
1894 memset((u8 *)parg + n, 0, _IOC_SIZE(cmd) - n);
1895 } else {
1896 /* read-only ioctl */
1897 memset(parg, 0, _IOC_SIZE(cmd));
1901 if (is_ext_ctrl) {
1902 struct v4l2_ext_controls *p = parg;
1904 /* In case of an error, tell the caller that it wasn't
1905 a specific control that caused it. */
1906 p->error_idx = p->count;
1907 user_ptr = (void __user *)p->controls;
1908 if (p->count) {
1909 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
1910 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
1911 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
1912 err = -ENOMEM;
1913 if (NULL == mbuf)
1914 goto out_ext_ctrl;
1915 err = -EFAULT;
1916 if (copy_from_user(mbuf, user_ptr, ctrls_size))
1917 goto out_ext_ctrl;
1918 p->controls = mbuf;
1922 /* Handles IOCTL */
1923 err = __video_do_ioctl(file, cmd, parg);
1924 if (err == -ENOIOCTLCMD)
1925 err = -EINVAL;
1926 if (is_ext_ctrl) {
1927 struct v4l2_ext_controls *p = parg;
1929 p->controls = (void *)user_ptr;
1930 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
1931 err = -EFAULT;
1932 goto out_ext_ctrl;
1934 if (err < 0)
1935 goto out;
1937 out_ext_ctrl:
1938 /* Copy results into user buffer */
1939 switch (_IOC_DIR(cmd)) {
1940 case _IOC_READ:
1941 case (_IOC_WRITE | _IOC_READ):
1942 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
1943 err = -EFAULT;
1944 break;
1947 out:
1948 kfree(mbuf);
1949 return err;
1951 EXPORT_SYMBOL(video_ioctl2);