init from v2.6.32.60
[mach-moxart.git] / drivers / media / video / v4l2-ioctl.c
blobd7332c7580644b9299196eb7f41164ea02452f9b
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 err = -EINVAL;
418 if (p->count > V4L2_CID_MAX_CTRLS)
419 goto out_ext_ctrl;
420 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
421 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
422 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
423 err = -ENOMEM;
424 if (NULL == mbuf)
425 goto out_ext_ctrl;
426 err = -EFAULT;
427 if (copy_from_user(mbuf, user_ptr, ctrls_size))
428 goto out_ext_ctrl;
429 p->controls = mbuf;
433 /* call driver */
434 err = func(file, cmd, parg);
435 if (err == -ENOIOCTLCMD)
436 err = -EINVAL;
437 if (is_ext_ctrl) {
438 struct v4l2_ext_controls *p = parg;
440 p->controls = (void *)user_ptr;
441 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
442 err = -EFAULT;
443 goto out_ext_ctrl;
445 if (err < 0)
446 goto out;
448 out_ext_ctrl:
449 /* Copy results into user buffer */
450 switch (_IOC_DIR(cmd)) {
451 case _IOC_READ:
452 case (_IOC_WRITE | _IOC_READ):
453 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
454 err = -EFAULT;
455 break;
458 out:
459 kfree(mbuf);
460 return err;
462 EXPORT_SYMBOL(video_usercopy);
464 static void dbgbuf(unsigned int cmd, struct video_device *vfd,
465 struct v4l2_buffer *p)
467 struct v4l2_timecode *tc = &p->timecode;
469 dbgarg(cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
470 "bytesused=%d, flags=0x%08d, "
471 "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n",
472 p->timestamp.tv_sec / 3600,
473 (int)(p->timestamp.tv_sec / 60) % 60,
474 (int)(p->timestamp.tv_sec % 60),
475 (long)p->timestamp.tv_usec,
476 p->index,
477 prt_names(p->type, v4l2_type_names),
478 p->bytesused, p->flags,
479 p->field, p->sequence,
480 prt_names(p->memory, v4l2_memory_names),
481 p->m.userptr, p->length);
482 dbgarg2("timecode=%02d:%02d:%02d type=%d, "
483 "flags=0x%08d, frames=%d, userbits=0x%08x\n",
484 tc->hours, tc->minutes, tc->seconds,
485 tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits);
488 static inline void dbgrect(struct video_device *vfd, char *s,
489 struct v4l2_rect *r)
491 dbgarg2("%sRect start at %dx%d, size=%dx%d\n", s, r->left, r->top,
492 r->width, r->height);
495 static inline void v4l_print_pix_fmt(struct video_device *vfd,
496 struct v4l2_pix_format *fmt)
498 dbgarg2("width=%d, height=%d, format=%c%c%c%c, field=%s, "
499 "bytesperline=%d sizeimage=%d, colorspace=%d\n",
500 fmt->width, fmt->height,
501 (fmt->pixelformat & 0xff),
502 (fmt->pixelformat >> 8) & 0xff,
503 (fmt->pixelformat >> 16) & 0xff,
504 (fmt->pixelformat >> 24) & 0xff,
505 prt_names(fmt->field, v4l2_field_names),
506 fmt->bytesperline, fmt->sizeimage, fmt->colorspace);
509 static inline void v4l_print_ext_ctrls(unsigned int cmd,
510 struct video_device *vfd, struct v4l2_ext_controls *c, int show_vals)
512 __u32 i;
514 if (!(vfd->debug & V4L2_DEBUG_IOCTL_ARG))
515 return;
516 dbgarg(cmd, "");
517 printk(KERN_CONT "class=0x%x", c->ctrl_class);
518 for (i = 0; i < c->count; i++) {
519 if (show_vals && !c->controls[i].size)
520 printk(KERN_CONT " id/val=0x%x/0x%x",
521 c->controls[i].id, c->controls[i].value);
522 else
523 printk(KERN_CONT " id=0x%x,size=%u",
524 c->controls[i].id, c->controls[i].size);
526 printk(KERN_CONT "\n");
529 static inline int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)
531 __u32 i;
533 /* zero the reserved fields */
534 c->reserved[0] = c->reserved[1] = 0;
535 for (i = 0; i < c->count; i++)
536 c->controls[i].reserved2[0] = 0;
538 /* V4L2_CID_PRIVATE_BASE cannot be used as control class
539 when using extended controls.
540 Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
541 is it allowed for backwards compatibility.
543 if (!allow_priv && c->ctrl_class == V4L2_CID_PRIVATE_BASE)
544 return 0;
545 /* Check that all controls are from the same control class. */
546 for (i = 0; i < c->count; i++) {
547 if (V4L2_CTRL_ID2CLASS(c->controls[i].id) != c->ctrl_class) {
548 c->error_idx = i;
549 return 0;
552 return 1;
555 static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type)
557 if (ops == NULL)
558 return -EINVAL;
560 switch (type) {
561 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
562 if (ops->vidioc_g_fmt_vid_cap)
563 return 0;
564 break;
565 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
566 if (ops->vidioc_g_fmt_vid_overlay)
567 return 0;
568 break;
569 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
570 if (ops->vidioc_g_fmt_vid_out)
571 return 0;
572 break;
573 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
574 if (ops->vidioc_g_fmt_vid_out_overlay)
575 return 0;
576 break;
577 case V4L2_BUF_TYPE_VBI_CAPTURE:
578 if (ops->vidioc_g_fmt_vbi_cap)
579 return 0;
580 break;
581 case V4L2_BUF_TYPE_VBI_OUTPUT:
582 if (ops->vidioc_g_fmt_vbi_out)
583 return 0;
584 break;
585 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
586 if (ops->vidioc_g_fmt_sliced_vbi_cap)
587 return 0;
588 break;
589 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
590 if (ops->vidioc_g_fmt_sliced_vbi_out)
591 return 0;
592 break;
593 case V4L2_BUF_TYPE_PRIVATE:
594 if (ops->vidioc_g_fmt_type_private)
595 return 0;
596 break;
598 return -EINVAL;
601 static long __video_do_ioctl(struct file *file,
602 unsigned int cmd, void *arg)
604 struct video_device *vfd = video_devdata(file);
605 const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
606 void *fh = file->private_data;
607 long ret = -EINVAL;
609 if ((vfd->debug & V4L2_DEBUG_IOCTL) &&
610 !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) {
611 v4l_print_ioctl(vfd->name, cmd);
612 printk(KERN_CONT "\n");
615 if (ops == NULL) {
616 printk(KERN_WARNING "videodev: \"%s\" has no ioctl_ops.\n",
617 vfd->name);
618 return -EINVAL;
621 #ifdef CONFIG_VIDEO_V4L1_COMPAT
622 /***********************************************************
623 Handles calls to the obsoleted V4L1 API
624 Due to the nature of VIDIOCGMBUF, each driver that supports
625 V4L1 should implement its own handler for this ioctl.
626 ***********************************************************/
628 /* --- streaming capture ------------------------------------- */
629 if (cmd == VIDIOCGMBUF) {
630 struct video_mbuf *p = arg;
632 if (!ops->vidiocgmbuf)
633 return ret;
634 ret = ops->vidiocgmbuf(file, fh, p);
635 if (!ret)
636 dbgarg(cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
637 p->size, p->frames,
638 (unsigned long)p->offsets);
639 return ret;
642 /********************************************************
643 All other V4L1 calls are handled by v4l1_compat module.
644 Those calls will be translated into V4L2 calls, and
645 __video_do_ioctl will be called again, with one or more
646 V4L2 ioctls.
647 ********************************************************/
648 if (_IOC_TYPE(cmd) == 'v' && _IOC_NR(cmd) < BASE_VIDIOCPRIVATE)
649 return v4l_compat_translate_ioctl(file, cmd, arg,
650 __video_do_ioctl);
651 #endif
653 switch (cmd) {
654 /* --- capabilities ------------------------------------------ */
655 case VIDIOC_QUERYCAP:
657 struct v4l2_capability *cap = (struct v4l2_capability *)arg;
659 if (!ops->vidioc_querycap)
660 break;
662 ret = ops->vidioc_querycap(file, fh, cap);
663 if (!ret)
664 dbgarg(cmd, "driver=%s, card=%s, bus=%s, "
665 "version=0x%08x, "
666 "capabilities=0x%08x\n",
667 cap->driver, cap->card, cap->bus_info,
668 cap->version,
669 cap->capabilities);
670 break;
673 /* --- priority ------------------------------------------ */
674 case VIDIOC_G_PRIORITY:
676 enum v4l2_priority *p = arg;
678 if (!ops->vidioc_g_priority)
679 break;
680 ret = ops->vidioc_g_priority(file, fh, p);
681 if (!ret)
682 dbgarg(cmd, "priority is %d\n", *p);
683 break;
685 case VIDIOC_S_PRIORITY:
687 enum v4l2_priority *p = arg;
689 if (!ops->vidioc_s_priority)
690 break;
691 dbgarg(cmd, "setting priority to %d\n", *p);
692 ret = ops->vidioc_s_priority(file, fh, *p);
693 break;
696 /* --- capture ioctls ---------------------------------------- */
697 case VIDIOC_ENUM_FMT:
699 struct v4l2_fmtdesc *f = arg;
701 switch (f->type) {
702 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
703 if (ops->vidioc_enum_fmt_vid_cap)
704 ret = ops->vidioc_enum_fmt_vid_cap(file, fh, f);
705 break;
706 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
707 if (ops->vidioc_enum_fmt_vid_overlay)
708 ret = ops->vidioc_enum_fmt_vid_overlay(file,
709 fh, f);
710 break;
711 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
712 if (ops->vidioc_enum_fmt_vid_out)
713 ret = ops->vidioc_enum_fmt_vid_out(file, fh, f);
714 break;
715 case V4L2_BUF_TYPE_PRIVATE:
716 if (ops->vidioc_enum_fmt_type_private)
717 ret = ops->vidioc_enum_fmt_type_private(file,
718 fh, f);
719 break;
720 default:
721 break;
723 if (!ret)
724 dbgarg(cmd, "index=%d, type=%d, flags=%d, "
725 "pixelformat=%c%c%c%c, description='%s'\n",
726 f->index, f->type, f->flags,
727 (f->pixelformat & 0xff),
728 (f->pixelformat >> 8) & 0xff,
729 (f->pixelformat >> 16) & 0xff,
730 (f->pixelformat >> 24) & 0xff,
731 f->description);
732 break;
734 case VIDIOC_G_FMT:
736 struct v4l2_format *f = (struct v4l2_format *)arg;
738 /* FIXME: Should be one dump per type */
739 dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
741 switch (f->type) {
742 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
743 if (ops->vidioc_g_fmt_vid_cap)
744 ret = ops->vidioc_g_fmt_vid_cap(file, fh, f);
745 if (!ret)
746 v4l_print_pix_fmt(vfd, &f->fmt.pix);
747 break;
748 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
749 if (ops->vidioc_g_fmt_vid_overlay)
750 ret = ops->vidioc_g_fmt_vid_overlay(file,
751 fh, f);
752 break;
753 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
754 if (ops->vidioc_g_fmt_vid_out)
755 ret = ops->vidioc_g_fmt_vid_out(file, fh, f);
756 if (!ret)
757 v4l_print_pix_fmt(vfd, &f->fmt.pix);
758 break;
759 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
760 if (ops->vidioc_g_fmt_vid_out_overlay)
761 ret = ops->vidioc_g_fmt_vid_out_overlay(file,
762 fh, f);
763 break;
764 case V4L2_BUF_TYPE_VBI_CAPTURE:
765 if (ops->vidioc_g_fmt_vbi_cap)
766 ret = ops->vidioc_g_fmt_vbi_cap(file, fh, f);
767 break;
768 case V4L2_BUF_TYPE_VBI_OUTPUT:
769 if (ops->vidioc_g_fmt_vbi_out)
770 ret = ops->vidioc_g_fmt_vbi_out(file, fh, f);
771 break;
772 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
773 if (ops->vidioc_g_fmt_sliced_vbi_cap)
774 ret = ops->vidioc_g_fmt_sliced_vbi_cap(file,
775 fh, f);
776 break;
777 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
778 if (ops->vidioc_g_fmt_sliced_vbi_out)
779 ret = ops->vidioc_g_fmt_sliced_vbi_out(file,
780 fh, f);
781 break;
782 case V4L2_BUF_TYPE_PRIVATE:
783 if (ops->vidioc_g_fmt_type_private)
784 ret = ops->vidioc_g_fmt_type_private(file,
785 fh, f);
786 break;
789 break;
791 case VIDIOC_S_FMT:
793 struct v4l2_format *f = (struct v4l2_format *)arg;
795 /* FIXME: Should be one dump per type */
796 dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
798 switch (f->type) {
799 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
800 CLEAR_AFTER_FIELD(f, fmt.pix);
801 v4l_print_pix_fmt(vfd, &f->fmt.pix);
802 if (ops->vidioc_s_fmt_vid_cap)
803 ret = ops->vidioc_s_fmt_vid_cap(file, fh, f);
804 break;
805 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
806 CLEAR_AFTER_FIELD(f, fmt.win);
807 if (ops->vidioc_s_fmt_vid_overlay)
808 ret = ops->vidioc_s_fmt_vid_overlay(file,
809 fh, f);
810 break;
811 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
812 CLEAR_AFTER_FIELD(f, fmt.pix);
813 v4l_print_pix_fmt(vfd, &f->fmt.pix);
814 if (ops->vidioc_s_fmt_vid_out)
815 ret = ops->vidioc_s_fmt_vid_out(file, fh, f);
816 break;
817 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
818 CLEAR_AFTER_FIELD(f, fmt.win);
819 if (ops->vidioc_s_fmt_vid_out_overlay)
820 ret = ops->vidioc_s_fmt_vid_out_overlay(file,
821 fh, f);
822 break;
823 case V4L2_BUF_TYPE_VBI_CAPTURE:
824 CLEAR_AFTER_FIELD(f, fmt.vbi);
825 if (ops->vidioc_s_fmt_vbi_cap)
826 ret = ops->vidioc_s_fmt_vbi_cap(file, fh, f);
827 break;
828 case V4L2_BUF_TYPE_VBI_OUTPUT:
829 CLEAR_AFTER_FIELD(f, fmt.vbi);
830 if (ops->vidioc_s_fmt_vbi_out)
831 ret = ops->vidioc_s_fmt_vbi_out(file, fh, f);
832 break;
833 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
834 CLEAR_AFTER_FIELD(f, fmt.sliced);
835 if (ops->vidioc_s_fmt_sliced_vbi_cap)
836 ret = ops->vidioc_s_fmt_sliced_vbi_cap(file,
837 fh, f);
838 break;
839 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
840 CLEAR_AFTER_FIELD(f, fmt.sliced);
841 if (ops->vidioc_s_fmt_sliced_vbi_out)
842 ret = ops->vidioc_s_fmt_sliced_vbi_out(file,
843 fh, f);
844 break;
845 case V4L2_BUF_TYPE_PRIVATE:
846 /* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */
847 if (ops->vidioc_s_fmt_type_private)
848 ret = ops->vidioc_s_fmt_type_private(file,
849 fh, f);
850 break;
852 break;
854 case VIDIOC_TRY_FMT:
856 struct v4l2_format *f = (struct v4l2_format *)arg;
858 /* FIXME: Should be one dump per type */
859 dbgarg(cmd, "type=%s\n", prt_names(f->type,
860 v4l2_type_names));
861 switch (f->type) {
862 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
863 CLEAR_AFTER_FIELD(f, fmt.pix);
864 if (ops->vidioc_try_fmt_vid_cap)
865 ret = ops->vidioc_try_fmt_vid_cap(file, fh, f);
866 if (!ret)
867 v4l_print_pix_fmt(vfd, &f->fmt.pix);
868 break;
869 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
870 CLEAR_AFTER_FIELD(f, fmt.win);
871 if (ops->vidioc_try_fmt_vid_overlay)
872 ret = ops->vidioc_try_fmt_vid_overlay(file,
873 fh, f);
874 break;
875 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
876 CLEAR_AFTER_FIELD(f, fmt.pix);
877 if (ops->vidioc_try_fmt_vid_out)
878 ret = ops->vidioc_try_fmt_vid_out(file, fh, f);
879 if (!ret)
880 v4l_print_pix_fmt(vfd, &f->fmt.pix);
881 break;
882 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
883 CLEAR_AFTER_FIELD(f, fmt.win);
884 if (ops->vidioc_try_fmt_vid_out_overlay)
885 ret = ops->vidioc_try_fmt_vid_out_overlay(file,
886 fh, f);
887 break;
888 case V4L2_BUF_TYPE_VBI_CAPTURE:
889 CLEAR_AFTER_FIELD(f, fmt.vbi);
890 if (ops->vidioc_try_fmt_vbi_cap)
891 ret = ops->vidioc_try_fmt_vbi_cap(file, fh, f);
892 break;
893 case V4L2_BUF_TYPE_VBI_OUTPUT:
894 CLEAR_AFTER_FIELD(f, fmt.vbi);
895 if (ops->vidioc_try_fmt_vbi_out)
896 ret = ops->vidioc_try_fmt_vbi_out(file, fh, f);
897 break;
898 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
899 CLEAR_AFTER_FIELD(f, fmt.sliced);
900 if (ops->vidioc_try_fmt_sliced_vbi_cap)
901 ret = ops->vidioc_try_fmt_sliced_vbi_cap(file,
902 fh, f);
903 break;
904 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
905 CLEAR_AFTER_FIELD(f, fmt.sliced);
906 if (ops->vidioc_try_fmt_sliced_vbi_out)
907 ret = ops->vidioc_try_fmt_sliced_vbi_out(file,
908 fh, f);
909 break;
910 case V4L2_BUF_TYPE_PRIVATE:
911 /* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */
912 if (ops->vidioc_try_fmt_type_private)
913 ret = ops->vidioc_try_fmt_type_private(file,
914 fh, f);
915 break;
918 break;
920 /* FIXME: Those buf reqs could be handled here,
921 with some changes on videobuf to allow its header to be included at
922 videodev2.h or being merged at videodev2.
924 case VIDIOC_REQBUFS:
926 struct v4l2_requestbuffers *p = arg;
928 if (!ops->vidioc_reqbufs)
929 break;
930 ret = check_fmt(ops, p->type);
931 if (ret)
932 break;
934 if (p->type < V4L2_BUF_TYPE_PRIVATE)
935 CLEAR_AFTER_FIELD(p, memory);
937 ret = ops->vidioc_reqbufs(file, fh, p);
938 dbgarg(cmd, "count=%d, type=%s, memory=%s\n",
939 p->count,
940 prt_names(p->type, v4l2_type_names),
941 prt_names(p->memory, v4l2_memory_names));
942 break;
944 case VIDIOC_QUERYBUF:
946 struct v4l2_buffer *p = arg;
948 if (!ops->vidioc_querybuf)
949 break;
950 ret = check_fmt(ops, p->type);
951 if (ret)
952 break;
954 ret = ops->vidioc_querybuf(file, fh, p);
955 if (!ret)
956 dbgbuf(cmd, vfd, p);
957 break;
959 case VIDIOC_QBUF:
961 struct v4l2_buffer *p = arg;
963 if (!ops->vidioc_qbuf)
964 break;
965 ret = check_fmt(ops, p->type);
966 if (ret)
967 break;
969 ret = ops->vidioc_qbuf(file, fh, p);
970 if (!ret)
971 dbgbuf(cmd, vfd, p);
972 break;
974 case VIDIOC_DQBUF:
976 struct v4l2_buffer *p = arg;
978 if (!ops->vidioc_dqbuf)
979 break;
980 ret = check_fmt(ops, p->type);
981 if (ret)
982 break;
984 ret = ops->vidioc_dqbuf(file, fh, p);
985 if (!ret)
986 dbgbuf(cmd, vfd, p);
987 break;
989 case VIDIOC_OVERLAY:
991 int *i = arg;
993 if (!ops->vidioc_overlay)
994 break;
995 dbgarg(cmd, "value=%d\n", *i);
996 ret = ops->vidioc_overlay(file, fh, *i);
997 break;
999 case VIDIOC_G_FBUF:
1001 struct v4l2_framebuffer *p = arg;
1003 if (!ops->vidioc_g_fbuf)
1004 break;
1005 ret = ops->vidioc_g_fbuf(file, fh, arg);
1006 if (!ret) {
1007 dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
1008 p->capability, p->flags,
1009 (unsigned long)p->base);
1010 v4l_print_pix_fmt(vfd, &p->fmt);
1012 break;
1014 case VIDIOC_S_FBUF:
1016 struct v4l2_framebuffer *p = arg;
1018 if (!ops->vidioc_s_fbuf)
1019 break;
1020 dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
1021 p->capability, p->flags, (unsigned long)p->base);
1022 v4l_print_pix_fmt(vfd, &p->fmt);
1023 ret = ops->vidioc_s_fbuf(file, fh, arg);
1024 break;
1026 case VIDIOC_STREAMON:
1028 enum v4l2_buf_type i = *(int *)arg;
1030 if (!ops->vidioc_streamon)
1031 break;
1032 dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
1033 ret = ops->vidioc_streamon(file, fh, i);
1034 break;
1036 case VIDIOC_STREAMOFF:
1038 enum v4l2_buf_type i = *(int *)arg;
1040 if (!ops->vidioc_streamoff)
1041 break;
1042 dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
1043 ret = ops->vidioc_streamoff(file, fh, i);
1044 break;
1046 /* ---------- tv norms ---------- */
1047 case VIDIOC_ENUMSTD:
1049 struct v4l2_standard *p = arg;
1050 v4l2_std_id id = vfd->tvnorms, curr_id = 0;
1051 unsigned int index = p->index, i, j = 0;
1052 const char *descr = "";
1054 /* Return norm array in a canonical way */
1055 for (i = 0; i <= index && id; i++) {
1056 /* last std value in the standards array is 0, so this
1057 while always ends there since (id & 0) == 0. */
1058 while ((id & standards[j].std) != standards[j].std)
1059 j++;
1060 curr_id = standards[j].std;
1061 descr = standards[j].descr;
1062 j++;
1063 if (curr_id == 0)
1064 break;
1065 if (curr_id != V4L2_STD_PAL &&
1066 curr_id != V4L2_STD_SECAM &&
1067 curr_id != V4L2_STD_NTSC)
1068 id &= ~curr_id;
1070 if (i <= index)
1071 return -EINVAL;
1073 v4l2_video_std_construct(p, curr_id, descr);
1075 dbgarg(cmd, "index=%d, id=0x%Lx, name=%s, fps=%d/%d, "
1076 "framelines=%d\n", p->index,
1077 (unsigned long long)p->id, p->name,
1078 p->frameperiod.numerator,
1079 p->frameperiod.denominator,
1080 p->framelines);
1082 ret = 0;
1083 break;
1085 case VIDIOC_G_STD:
1087 v4l2_std_id *id = arg;
1089 ret = 0;
1090 /* Calls the specific handler */
1091 if (ops->vidioc_g_std)
1092 ret = ops->vidioc_g_std(file, fh, id);
1093 else if (vfd->current_norm)
1094 *id = vfd->current_norm;
1095 else
1096 ret = -EINVAL;
1098 if (!ret)
1099 dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id);
1100 break;
1102 case VIDIOC_S_STD:
1104 v4l2_std_id *id = arg, norm;
1106 dbgarg(cmd, "std=%08Lx\n", (long long unsigned)*id);
1108 norm = (*id) & vfd->tvnorms;
1109 if (vfd->tvnorms && !norm) /* Check if std is supported */
1110 break;
1112 /* Calls the specific handler */
1113 if (ops->vidioc_s_std)
1114 ret = ops->vidioc_s_std(file, fh, &norm);
1115 else
1116 ret = -EINVAL;
1118 /* Updates standard information */
1119 if (ret >= 0)
1120 vfd->current_norm = norm;
1121 break;
1123 case VIDIOC_QUERYSTD:
1125 v4l2_std_id *p = arg;
1127 if (!ops->vidioc_querystd)
1128 break;
1129 ret = ops->vidioc_querystd(file, fh, arg);
1130 if (!ret)
1131 dbgarg(cmd, "detected std=%08Lx\n",
1132 (unsigned long long)*p);
1133 break;
1135 /* ------ input switching ---------- */
1136 /* FIXME: Inputs can be handled inside videodev2 */
1137 case VIDIOC_ENUMINPUT:
1139 struct v4l2_input *p = arg;
1141 if (!ops->vidioc_enum_input)
1142 break;
1144 ret = ops->vidioc_enum_input(file, fh, p);
1145 if (!ret)
1146 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1147 "audioset=%d, "
1148 "tuner=%d, std=%08Lx, status=%d\n",
1149 p->index, p->name, p->type, p->audioset,
1150 p->tuner,
1151 (unsigned long long)p->std,
1152 p->status);
1153 break;
1155 case VIDIOC_G_INPUT:
1157 unsigned int *i = arg;
1159 if (!ops->vidioc_g_input)
1160 break;
1161 ret = ops->vidioc_g_input(file, fh, i);
1162 if (!ret)
1163 dbgarg(cmd, "value=%d\n", *i);
1164 break;
1166 case VIDIOC_S_INPUT:
1168 unsigned int *i = arg;
1170 if (!ops->vidioc_s_input)
1171 break;
1172 dbgarg(cmd, "value=%d\n", *i);
1173 ret = ops->vidioc_s_input(file, fh, *i);
1174 break;
1177 /* ------ output switching ---------- */
1178 case VIDIOC_ENUMOUTPUT:
1180 struct v4l2_output *p = arg;
1182 if (!ops->vidioc_enum_output)
1183 break;
1185 ret = ops->vidioc_enum_output(file, fh, p);
1186 if (!ret)
1187 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1188 "audioset=0x%x, "
1189 "modulator=%d, std=0x%08Lx\n",
1190 p->index, p->name, p->type, p->audioset,
1191 p->modulator, (unsigned long long)p->std);
1192 break;
1194 case VIDIOC_G_OUTPUT:
1196 unsigned int *i = arg;
1198 if (!ops->vidioc_g_output)
1199 break;
1200 ret = ops->vidioc_g_output(file, fh, i);
1201 if (!ret)
1202 dbgarg(cmd, "value=%d\n", *i);
1203 break;
1205 case VIDIOC_S_OUTPUT:
1207 unsigned int *i = arg;
1209 if (!ops->vidioc_s_output)
1210 break;
1211 dbgarg(cmd, "value=%d\n", *i);
1212 ret = ops->vidioc_s_output(file, fh, *i);
1213 break;
1216 /* --- controls ---------------------------------------------- */
1217 case VIDIOC_QUERYCTRL:
1219 struct v4l2_queryctrl *p = arg;
1221 if (!ops->vidioc_queryctrl)
1222 break;
1223 ret = ops->vidioc_queryctrl(file, fh, p);
1224 if (!ret)
1225 dbgarg(cmd, "id=0x%x, type=%d, name=%s, min/max=%d/%d, "
1226 "step=%d, default=%d, flags=0x%08x\n",
1227 p->id, p->type, p->name,
1228 p->minimum, p->maximum,
1229 p->step, p->default_value, p->flags);
1230 else
1231 dbgarg(cmd, "id=0x%x\n", p->id);
1232 break;
1234 case VIDIOC_G_CTRL:
1236 struct v4l2_control *p = arg;
1238 if (ops->vidioc_g_ctrl)
1239 ret = ops->vidioc_g_ctrl(file, fh, p);
1240 else if (ops->vidioc_g_ext_ctrls) {
1241 struct v4l2_ext_controls ctrls;
1242 struct v4l2_ext_control ctrl;
1244 ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
1245 ctrls.count = 1;
1246 ctrls.controls = &ctrl;
1247 ctrl.id = p->id;
1248 ctrl.value = p->value;
1249 if (check_ext_ctrls(&ctrls, 1)) {
1250 ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls);
1251 if (ret == 0)
1252 p->value = ctrl.value;
1254 } else
1255 break;
1256 if (!ret)
1257 dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
1258 else
1259 dbgarg(cmd, "id=0x%x\n", p->id);
1260 break;
1262 case VIDIOC_S_CTRL:
1264 struct v4l2_control *p = arg;
1265 struct v4l2_ext_controls ctrls;
1266 struct v4l2_ext_control ctrl;
1268 if (!ops->vidioc_s_ctrl && !ops->vidioc_s_ext_ctrls)
1269 break;
1271 dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
1273 if (ops->vidioc_s_ctrl) {
1274 ret = ops->vidioc_s_ctrl(file, fh, p);
1275 break;
1277 if (!ops->vidioc_s_ext_ctrls)
1278 break;
1280 ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
1281 ctrls.count = 1;
1282 ctrls.controls = &ctrl;
1283 ctrl.id = p->id;
1284 ctrl.value = p->value;
1285 if (check_ext_ctrls(&ctrls, 1))
1286 ret = ops->vidioc_s_ext_ctrls(file, fh, &ctrls);
1287 break;
1289 case VIDIOC_G_EXT_CTRLS:
1291 struct v4l2_ext_controls *p = arg;
1293 p->error_idx = p->count;
1294 if (!ops->vidioc_g_ext_ctrls)
1295 break;
1296 if (check_ext_ctrls(p, 0))
1297 ret = ops->vidioc_g_ext_ctrls(file, fh, p);
1298 v4l_print_ext_ctrls(cmd, vfd, p, !ret);
1299 break;
1301 case VIDIOC_S_EXT_CTRLS:
1303 struct v4l2_ext_controls *p = arg;
1305 p->error_idx = p->count;
1306 if (!ops->vidioc_s_ext_ctrls)
1307 break;
1308 v4l_print_ext_ctrls(cmd, vfd, p, 1);
1309 if (check_ext_ctrls(p, 0))
1310 ret = ops->vidioc_s_ext_ctrls(file, fh, p);
1311 break;
1313 case VIDIOC_TRY_EXT_CTRLS:
1315 struct v4l2_ext_controls *p = arg;
1317 p->error_idx = p->count;
1318 if (!ops->vidioc_try_ext_ctrls)
1319 break;
1320 v4l_print_ext_ctrls(cmd, vfd, p, 1);
1321 if (check_ext_ctrls(p, 0))
1322 ret = ops->vidioc_try_ext_ctrls(file, fh, p);
1323 break;
1325 case VIDIOC_QUERYMENU:
1327 struct v4l2_querymenu *p = arg;
1329 if (!ops->vidioc_querymenu)
1330 break;
1331 ret = ops->vidioc_querymenu(file, fh, p);
1332 if (!ret)
1333 dbgarg(cmd, "id=0x%x, index=%d, name=%s\n",
1334 p->id, p->index, p->name);
1335 else
1336 dbgarg(cmd, "id=0x%x, index=%d\n",
1337 p->id, p->index);
1338 break;
1340 /* --- audio ---------------------------------------------- */
1341 case VIDIOC_ENUMAUDIO:
1343 struct v4l2_audio *p = arg;
1345 if (!ops->vidioc_enumaudio)
1346 break;
1347 ret = ops->vidioc_enumaudio(file, fh, p);
1348 if (!ret)
1349 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
1350 "mode=0x%x\n", p->index, p->name,
1351 p->capability, p->mode);
1352 else
1353 dbgarg(cmd, "index=%d\n", p->index);
1354 break;
1356 case VIDIOC_G_AUDIO:
1358 struct v4l2_audio *p = arg;
1360 if (!ops->vidioc_g_audio)
1361 break;
1363 ret = ops->vidioc_g_audio(file, fh, p);
1364 if (!ret)
1365 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
1366 "mode=0x%x\n", p->index,
1367 p->name, p->capability, p->mode);
1368 else
1369 dbgarg(cmd, "index=%d\n", p->index);
1370 break;
1372 case VIDIOC_S_AUDIO:
1374 struct v4l2_audio *p = arg;
1376 if (!ops->vidioc_s_audio)
1377 break;
1378 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
1379 "mode=0x%x\n", p->index, p->name,
1380 p->capability, p->mode);
1381 ret = ops->vidioc_s_audio(file, fh, p);
1382 break;
1384 case VIDIOC_ENUMAUDOUT:
1386 struct v4l2_audioout *p = arg;
1388 if (!ops->vidioc_enumaudout)
1389 break;
1390 dbgarg(cmd, "Enum for index=%d\n", p->index);
1391 ret = ops->vidioc_enumaudout(file, fh, p);
1392 if (!ret)
1393 dbgarg2("index=%d, name=%s, capability=%d, "
1394 "mode=%d\n", p->index, p->name,
1395 p->capability, p->mode);
1396 break;
1398 case VIDIOC_G_AUDOUT:
1400 struct v4l2_audioout *p = arg;
1402 if (!ops->vidioc_g_audout)
1403 break;
1405 ret = ops->vidioc_g_audout(file, fh, p);
1406 if (!ret)
1407 dbgarg2("index=%d, name=%s, capability=%d, "
1408 "mode=%d\n", p->index, p->name,
1409 p->capability, p->mode);
1410 break;
1412 case VIDIOC_S_AUDOUT:
1414 struct v4l2_audioout *p = arg;
1416 if (!ops->vidioc_s_audout)
1417 break;
1418 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1419 "mode=%d\n", p->index, p->name,
1420 p->capability, p->mode);
1422 ret = ops->vidioc_s_audout(file, fh, p);
1423 break;
1425 case VIDIOC_G_MODULATOR:
1427 struct v4l2_modulator *p = arg;
1429 if (!ops->vidioc_g_modulator)
1430 break;
1431 ret = ops->vidioc_g_modulator(file, fh, p);
1432 if (!ret)
1433 dbgarg(cmd, "index=%d, name=%s, "
1434 "capability=%d, rangelow=%d,"
1435 " rangehigh=%d, txsubchans=%d\n",
1436 p->index, p->name, p->capability,
1437 p->rangelow, p->rangehigh,
1438 p->txsubchans);
1439 break;
1441 case VIDIOC_S_MODULATOR:
1443 struct v4l2_modulator *p = arg;
1445 if (!ops->vidioc_s_modulator)
1446 break;
1447 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1448 "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
1449 p->index, p->name, p->capability, p->rangelow,
1450 p->rangehigh, p->txsubchans);
1451 ret = ops->vidioc_s_modulator(file, fh, p);
1452 break;
1454 case VIDIOC_G_CROP:
1456 struct v4l2_crop *p = arg;
1458 if (!ops->vidioc_g_crop)
1459 break;
1461 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1462 ret = ops->vidioc_g_crop(file, fh, p);
1463 if (!ret)
1464 dbgrect(vfd, "", &p->c);
1465 break;
1467 case VIDIOC_S_CROP:
1469 struct v4l2_crop *p = arg;
1471 if (!ops->vidioc_s_crop)
1472 break;
1473 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1474 dbgrect(vfd, "", &p->c);
1475 ret = ops->vidioc_s_crop(file, fh, p);
1476 break;
1478 case VIDIOC_CROPCAP:
1480 struct v4l2_cropcap *p = arg;
1482 /*FIXME: Should also show v4l2_fract pixelaspect */
1483 if (!ops->vidioc_cropcap)
1484 break;
1486 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1487 ret = ops->vidioc_cropcap(file, fh, p);
1488 if (!ret) {
1489 dbgrect(vfd, "bounds ", &p->bounds);
1490 dbgrect(vfd, "defrect ", &p->defrect);
1492 break;
1494 case VIDIOC_G_JPEGCOMP:
1496 struct v4l2_jpegcompression *p = arg;
1498 if (!ops->vidioc_g_jpegcomp)
1499 break;
1501 ret = ops->vidioc_g_jpegcomp(file, fh, p);
1502 if (!ret)
1503 dbgarg(cmd, "quality=%d, APPn=%d, "
1504 "APP_len=%d, COM_len=%d, "
1505 "jpeg_markers=%d\n",
1506 p->quality, p->APPn, p->APP_len,
1507 p->COM_len, p->jpeg_markers);
1508 break;
1510 case VIDIOC_S_JPEGCOMP:
1512 struct v4l2_jpegcompression *p = arg;
1514 if (!ops->vidioc_g_jpegcomp)
1515 break;
1516 dbgarg(cmd, "quality=%d, APPn=%d, APP_len=%d, "
1517 "COM_len=%d, jpeg_markers=%d\n",
1518 p->quality, p->APPn, p->APP_len,
1519 p->COM_len, p->jpeg_markers);
1520 ret = ops->vidioc_s_jpegcomp(file, fh, p);
1521 break;
1523 case VIDIOC_G_ENC_INDEX:
1525 struct v4l2_enc_idx *p = arg;
1527 if (!ops->vidioc_g_enc_index)
1528 break;
1529 ret = ops->vidioc_g_enc_index(file, fh, p);
1530 if (!ret)
1531 dbgarg(cmd, "entries=%d, entries_cap=%d\n",
1532 p->entries, p->entries_cap);
1533 break;
1535 case VIDIOC_ENCODER_CMD:
1537 struct v4l2_encoder_cmd *p = arg;
1539 if (!ops->vidioc_encoder_cmd)
1540 break;
1541 ret = ops->vidioc_encoder_cmd(file, fh, p);
1542 if (!ret)
1543 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
1544 break;
1546 case VIDIOC_TRY_ENCODER_CMD:
1548 struct v4l2_encoder_cmd *p = arg;
1550 if (!ops->vidioc_try_encoder_cmd)
1551 break;
1552 ret = ops->vidioc_try_encoder_cmd(file, fh, p);
1553 if (!ret)
1554 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
1555 break;
1557 case VIDIOC_G_PARM:
1559 struct v4l2_streamparm *p = arg;
1561 if (ops->vidioc_g_parm) {
1562 ret = check_fmt(ops, p->type);
1563 if (ret)
1564 break;
1565 ret = ops->vidioc_g_parm(file, fh, p);
1566 } else {
1567 v4l2_std_id std = vfd->current_norm;
1569 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1570 return -EINVAL;
1572 ret = 0;
1573 if (ops->vidioc_g_std)
1574 ret = ops->vidioc_g_std(file, fh, &std);
1575 else if (std == 0)
1576 ret = -EINVAL;
1577 if (ret == 0)
1578 v4l2_video_std_frame_period(std,
1579 &p->parm.capture.timeperframe);
1582 dbgarg(cmd, "type=%d\n", p->type);
1583 break;
1585 case VIDIOC_S_PARM:
1587 struct v4l2_streamparm *p = arg;
1589 if (!ops->vidioc_s_parm)
1590 break;
1591 ret = check_fmt(ops, p->type);
1592 if (ret)
1593 break;
1595 dbgarg(cmd, "type=%d\n", p->type);
1596 ret = ops->vidioc_s_parm(file, fh, p);
1597 break;
1599 case VIDIOC_G_TUNER:
1601 struct v4l2_tuner *p = arg;
1603 if (!ops->vidioc_g_tuner)
1604 break;
1606 p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
1607 V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1608 ret = ops->vidioc_g_tuner(file, fh, p);
1609 if (!ret)
1610 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1611 "capability=0x%x, rangelow=%d, "
1612 "rangehigh=%d, signal=%d, afc=%d, "
1613 "rxsubchans=0x%x, audmode=%d\n",
1614 p->index, p->name, p->type,
1615 p->capability, p->rangelow,
1616 p->rangehigh, p->signal, p->afc,
1617 p->rxsubchans, p->audmode);
1618 break;
1620 case VIDIOC_S_TUNER:
1622 struct v4l2_tuner *p = arg;
1624 if (!ops->vidioc_s_tuner)
1625 break;
1626 p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
1627 V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1628 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1629 "capability=0x%x, rangelow=%d, "
1630 "rangehigh=%d, signal=%d, afc=%d, "
1631 "rxsubchans=0x%x, audmode=%d\n",
1632 p->index, p->name, p->type,
1633 p->capability, p->rangelow,
1634 p->rangehigh, p->signal, p->afc,
1635 p->rxsubchans, p->audmode);
1636 ret = ops->vidioc_s_tuner(file, fh, p);
1637 break;
1639 case VIDIOC_G_FREQUENCY:
1641 struct v4l2_frequency *p = arg;
1643 if (!ops->vidioc_g_frequency)
1644 break;
1646 p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
1647 V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1648 ret = ops->vidioc_g_frequency(file, fh, p);
1649 if (!ret)
1650 dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
1651 p->tuner, p->type, p->frequency);
1652 break;
1654 case VIDIOC_S_FREQUENCY:
1656 struct v4l2_frequency *p = arg;
1658 if (!ops->vidioc_s_frequency)
1659 break;
1660 dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
1661 p->tuner, p->type, p->frequency);
1662 ret = ops->vidioc_s_frequency(file, fh, p);
1663 break;
1665 case VIDIOC_G_SLICED_VBI_CAP:
1667 struct v4l2_sliced_vbi_cap *p = arg;
1669 if (!ops->vidioc_g_sliced_vbi_cap)
1670 break;
1672 /* Clear up to type, everything after type is zerod already */
1673 memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type));
1675 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1676 ret = ops->vidioc_g_sliced_vbi_cap(file, fh, p);
1677 if (!ret)
1678 dbgarg2("service_set=%d\n", p->service_set);
1679 break;
1681 case VIDIOC_LOG_STATUS:
1683 if (!ops->vidioc_log_status)
1684 break;
1685 ret = ops->vidioc_log_status(file, fh);
1686 break;
1688 #ifdef CONFIG_VIDEO_ADV_DEBUG
1689 case VIDIOC_DBG_G_REGISTER:
1691 struct v4l2_dbg_register *p = arg;
1693 if (!capable(CAP_SYS_ADMIN))
1694 ret = -EPERM;
1695 else if (ops->vidioc_g_register)
1696 ret = ops->vidioc_g_register(file, fh, p);
1697 break;
1699 case VIDIOC_DBG_S_REGISTER:
1701 struct v4l2_dbg_register *p = arg;
1703 if (!capable(CAP_SYS_ADMIN))
1704 ret = -EPERM;
1705 else if (ops->vidioc_s_register)
1706 ret = ops->vidioc_s_register(file, fh, p);
1707 break;
1709 #endif
1710 case VIDIOC_DBG_G_CHIP_IDENT:
1712 struct v4l2_dbg_chip_ident *p = arg;
1714 if (!ops->vidioc_g_chip_ident)
1715 break;
1716 p->ident = V4L2_IDENT_NONE;
1717 p->revision = 0;
1718 ret = ops->vidioc_g_chip_ident(file, fh, p);
1719 if (!ret)
1720 dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
1721 break;
1723 case VIDIOC_S_HW_FREQ_SEEK:
1725 struct v4l2_hw_freq_seek *p = arg;
1727 if (!ops->vidioc_s_hw_freq_seek)
1728 break;
1729 dbgarg(cmd,
1730 "tuner=%d, type=%d, seek_upward=%d, wrap_around=%d\n",
1731 p->tuner, p->type, p->seek_upward, p->wrap_around);
1732 ret = ops->vidioc_s_hw_freq_seek(file, fh, p);
1733 break;
1735 case VIDIOC_ENUM_FRAMESIZES:
1737 struct v4l2_frmsizeenum *p = arg;
1739 if (!ops->vidioc_enum_framesizes)
1740 break;
1742 ret = ops->vidioc_enum_framesizes(file, fh, p);
1743 dbgarg(cmd,
1744 "index=%d, pixelformat=%c%c%c%c, type=%d ",
1745 p->index,
1746 (p->pixel_format & 0xff),
1747 (p->pixel_format >> 8) & 0xff,
1748 (p->pixel_format >> 16) & 0xff,
1749 (p->pixel_format >> 24) & 0xff,
1750 p->type);
1751 switch (p->type) {
1752 case V4L2_FRMSIZE_TYPE_DISCRETE:
1753 dbgarg3("width = %d, height=%d\n",
1754 p->discrete.width, p->discrete.height);
1755 break;
1756 case V4L2_FRMSIZE_TYPE_STEPWISE:
1757 dbgarg3("min %dx%d, max %dx%d, step %dx%d\n",
1758 p->stepwise.min_width, p->stepwise.min_height,
1759 p->stepwise.step_width, p->stepwise.step_height,
1760 p->stepwise.max_width, p->stepwise.max_height);
1761 break;
1762 case V4L2_FRMSIZE_TYPE_CONTINUOUS:
1763 dbgarg3("continuous\n");
1764 break;
1765 default:
1766 dbgarg3("- Unknown type!\n");
1769 break;
1771 case VIDIOC_ENUM_FRAMEINTERVALS:
1773 struct v4l2_frmivalenum *p = arg;
1775 if (!ops->vidioc_enum_frameintervals)
1776 break;
1778 ret = ops->vidioc_enum_frameintervals(file, fh, p);
1779 dbgarg(cmd,
1780 "index=%d, pixelformat=%d, width=%d, height=%d, type=%d ",
1781 p->index, p->pixel_format,
1782 p->width, p->height, p->type);
1783 switch (p->type) {
1784 case V4L2_FRMIVAL_TYPE_DISCRETE:
1785 dbgarg2("fps=%d/%d\n",
1786 p->discrete.numerator,
1787 p->discrete.denominator);
1788 break;
1789 case V4L2_FRMIVAL_TYPE_STEPWISE:
1790 dbgarg2("min=%d/%d, max=%d/%d, step=%d/%d\n",
1791 p->stepwise.min.numerator,
1792 p->stepwise.min.denominator,
1793 p->stepwise.max.numerator,
1794 p->stepwise.max.denominator,
1795 p->stepwise.step.numerator,
1796 p->stepwise.step.denominator);
1797 break;
1798 case V4L2_FRMIVAL_TYPE_CONTINUOUS:
1799 dbgarg2("continuous\n");
1800 break;
1801 default:
1802 dbgarg2("- Unknown type!\n");
1804 break;
1807 default:
1809 if (!ops->vidioc_default)
1810 break;
1811 ret = ops->vidioc_default(file, fh, cmd, arg);
1812 break;
1814 } /* switch */
1816 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1817 if (ret < 0) {
1818 v4l_print_ioctl(vfd->name, cmd);
1819 printk(KERN_CONT " error %ld\n", ret);
1823 return ret;
1826 /* In some cases, only a few fields are used as input, i.e. when the app sets
1827 * "index" and then the driver fills in the rest of the structure for the thing
1828 * with that index. We only need to copy up the first non-input field. */
1829 static unsigned long cmd_input_size(unsigned int cmd)
1831 /* Size of structure up to and including 'field' */
1832 #define CMDINSIZE(cmd, type, field) \
1833 case VIDIOC_##cmd: \
1834 return offsetof(struct v4l2_##type, field) + \
1835 sizeof(((struct v4l2_##type *)0)->field);
1837 switch (cmd) {
1838 CMDINSIZE(ENUM_FMT, fmtdesc, type);
1839 CMDINSIZE(G_FMT, format, type);
1840 CMDINSIZE(QUERYBUF, buffer, type);
1841 CMDINSIZE(G_PARM, streamparm, type);
1842 CMDINSIZE(ENUMSTD, standard, index);
1843 CMDINSIZE(ENUMINPUT, input, index);
1844 CMDINSIZE(G_CTRL, control, id);
1845 CMDINSIZE(G_TUNER, tuner, index);
1846 CMDINSIZE(QUERYCTRL, queryctrl, id);
1847 CMDINSIZE(QUERYMENU, querymenu, index);
1848 CMDINSIZE(ENUMOUTPUT, output, index);
1849 CMDINSIZE(G_MODULATOR, modulator, index);
1850 CMDINSIZE(G_FREQUENCY, frequency, tuner);
1851 CMDINSIZE(CROPCAP, cropcap, type);
1852 CMDINSIZE(G_CROP, crop, type);
1853 CMDINSIZE(ENUMAUDIO, audio, index);
1854 CMDINSIZE(ENUMAUDOUT, audioout, index);
1855 CMDINSIZE(ENCODER_CMD, encoder_cmd, flags);
1856 CMDINSIZE(TRY_ENCODER_CMD, encoder_cmd, flags);
1857 CMDINSIZE(G_SLICED_VBI_CAP, sliced_vbi_cap, type);
1858 CMDINSIZE(ENUM_FRAMESIZES, frmsizeenum, pixel_format);
1859 CMDINSIZE(ENUM_FRAMEINTERVALS, frmivalenum, height);
1860 default:
1861 return _IOC_SIZE(cmd);
1865 long video_ioctl2(struct file *file,
1866 unsigned int cmd, unsigned long arg)
1868 char sbuf[128];
1869 void *mbuf = NULL;
1870 void *parg = NULL;
1871 long err = -EINVAL;
1872 int is_ext_ctrl;
1873 size_t ctrls_size = 0;
1874 void __user *user_ptr = NULL;
1876 #ifdef __OLD_VIDIOC_
1877 cmd = video_fix_command(cmd);
1878 #endif
1879 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
1880 cmd == VIDIOC_TRY_EXT_CTRLS);
1882 /* Copy arguments into temp kernel buffer */
1883 if (_IOC_DIR(cmd) != _IOC_NONE) {
1884 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
1885 parg = sbuf;
1886 } else {
1887 /* too big to allocate from stack */
1888 mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
1889 if (NULL == mbuf)
1890 return -ENOMEM;
1891 parg = mbuf;
1894 err = -EFAULT;
1895 if (_IOC_DIR(cmd) & _IOC_WRITE) {
1896 unsigned long n = cmd_input_size(cmd);
1898 if (copy_from_user(parg, (void __user *)arg, n))
1899 goto out;
1901 /* zero out anything we don't copy from userspace */
1902 if (n < _IOC_SIZE(cmd))
1903 memset((u8 *)parg + n, 0, _IOC_SIZE(cmd) - n);
1904 } else {
1905 /* read-only ioctl */
1906 memset(parg, 0, _IOC_SIZE(cmd));
1910 if (is_ext_ctrl) {
1911 struct v4l2_ext_controls *p = parg;
1913 /* In case of an error, tell the caller that it wasn't
1914 a specific control that caused it. */
1915 p->error_idx = p->count;
1916 user_ptr = (void __user *)p->controls;
1917 if (p->count) {
1918 err = -EINVAL;
1919 if (p->count > V4L2_CID_MAX_CTRLS)
1920 goto out_ext_ctrl;
1921 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
1922 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
1923 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
1924 err = -ENOMEM;
1925 if (NULL == mbuf)
1926 goto out_ext_ctrl;
1927 err = -EFAULT;
1928 if (copy_from_user(mbuf, user_ptr, ctrls_size))
1929 goto out_ext_ctrl;
1930 p->controls = mbuf;
1934 /* Handles IOCTL */
1935 err = __video_do_ioctl(file, cmd, parg);
1936 if (err == -ENOIOCTLCMD)
1937 err = -EINVAL;
1938 if (is_ext_ctrl) {
1939 struct v4l2_ext_controls *p = parg;
1941 p->controls = (void *)user_ptr;
1942 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
1943 err = -EFAULT;
1944 goto out_ext_ctrl;
1946 if (err < 0)
1947 goto out;
1949 out_ext_ctrl:
1950 /* Copy results into user buffer */
1951 switch (_IOC_DIR(cmd)) {
1952 case _IOC_READ:
1953 case (_IOC_WRITE | _IOC_READ):
1954 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
1955 err = -EFAULT;
1956 break;
1959 out:
1960 kfree(mbuf);
1961 return err;
1963 EXPORT_SYMBOL(video_ioctl2);