V4L/DVB: video_ioctl2: don't return, use break
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / media / video / v4l2-ioctl.c
blob571f0c6e7c834c1344bfc87dd3d6f41fbf7df5f1
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/slab.h>
17 #include <linux/types.h>
18 #include <linux/kernel.h>
20 #define __OLD_VIDIOC_ /* To allow fixing old calls */
21 #include <linux/videodev.h>
22 #include <linux/videodev2.h>
24 #ifdef CONFIG_VIDEO_V4L1
25 #include <linux/videodev.h>
26 #endif
27 #include <media/v4l2-common.h>
28 #include <media/v4l2-ioctl.h>
29 #include <media/v4l2-chip-ident.h>
31 #define dbgarg(cmd, fmt, arg...) \
32 do { \
33 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { \
34 printk(KERN_DEBUG "%s: ", vfd->name); \
35 v4l_printk_ioctl(cmd); \
36 printk(" " fmt, ## arg); \
37 } \
38 } while (0)
40 #define dbgarg2(fmt, arg...) \
41 do { \
42 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \
43 printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg);\
44 } while (0)
46 #define dbgarg3(fmt, arg...) \
47 do { \
48 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \
49 printk(KERN_CONT "%s: " fmt, vfd->name, ## arg);\
50 } while (0)
52 /* Zero out the end of the struct pointed to by p. Everthing after, but
53 * not including, the specified field is cleared. */
54 #define CLEAR_AFTER_FIELD(p, field) \
55 memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \
56 0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field))
58 struct std_descr {
59 v4l2_std_id std;
60 const char *descr;
63 static const struct std_descr standards[] = {
64 { V4L2_STD_NTSC, "NTSC" },
65 { V4L2_STD_NTSC_M, "NTSC-M" },
66 { V4L2_STD_NTSC_M_JP, "NTSC-M-JP" },
67 { V4L2_STD_NTSC_M_KR, "NTSC-M-KR" },
68 { V4L2_STD_NTSC_443, "NTSC-443" },
69 { V4L2_STD_PAL, "PAL" },
70 { V4L2_STD_PAL_BG, "PAL-BG" },
71 { V4L2_STD_PAL_B, "PAL-B" },
72 { V4L2_STD_PAL_B1, "PAL-B1" },
73 { V4L2_STD_PAL_G, "PAL-G" },
74 { V4L2_STD_PAL_H, "PAL-H" },
75 { V4L2_STD_PAL_I, "PAL-I" },
76 { V4L2_STD_PAL_DK, "PAL-DK" },
77 { V4L2_STD_PAL_D, "PAL-D" },
78 { V4L2_STD_PAL_D1, "PAL-D1" },
79 { V4L2_STD_PAL_K, "PAL-K" },
80 { V4L2_STD_PAL_M, "PAL-M" },
81 { V4L2_STD_PAL_N, "PAL-N" },
82 { V4L2_STD_PAL_Nc, "PAL-Nc" },
83 { V4L2_STD_PAL_60, "PAL-60" },
84 { V4L2_STD_SECAM, "SECAM" },
85 { V4L2_STD_SECAM_B, "SECAM-B" },
86 { V4L2_STD_SECAM_G, "SECAM-G" },
87 { V4L2_STD_SECAM_H, "SECAM-H" },
88 { V4L2_STD_SECAM_DK, "SECAM-DK" },
89 { V4L2_STD_SECAM_D, "SECAM-D" },
90 { V4L2_STD_SECAM_K, "SECAM-K" },
91 { V4L2_STD_SECAM_K1, "SECAM-K1" },
92 { V4L2_STD_SECAM_L, "SECAM-L" },
93 { V4L2_STD_SECAM_LC, "SECAM-Lc" },
94 { 0, "Unknown" }
97 /* video4linux standard ID conversion to standard name
99 const char *v4l2_norm_to_name(v4l2_std_id id)
101 u32 myid = id;
102 int i;
104 /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
105 64 bit comparations. So, on that architecture, with some gcc
106 variants, compilation fails. Currently, the max value is 30bit wide.
108 BUG_ON(myid != id);
110 for (i = 0; standards[i].std; i++)
111 if (myid == standards[i].std)
112 break;
113 return standards[i].descr;
115 EXPORT_SYMBOL(v4l2_norm_to_name);
117 /* Returns frame period for the given standard */
118 void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod)
120 if (id & V4L2_STD_525_60) {
121 frameperiod->numerator = 1001;
122 frameperiod->denominator = 30000;
123 } else {
124 frameperiod->numerator = 1;
125 frameperiod->denominator = 25;
128 EXPORT_SYMBOL(v4l2_video_std_frame_period);
130 /* Fill in the fields of a v4l2_standard structure according to the
131 'id' and 'transmission' parameters. Returns negative on error. */
132 int v4l2_video_std_construct(struct v4l2_standard *vs,
133 int id, const char *name)
135 vs->id = id;
136 v4l2_video_std_frame_period(id, &vs->frameperiod);
137 vs->framelines = (id & V4L2_STD_525_60) ? 525 : 625;
138 strlcpy(vs->name, name, sizeof(vs->name));
139 return 0;
141 EXPORT_SYMBOL(v4l2_video_std_construct);
143 /* ----------------------------------------------------------------- */
144 /* some arrays for pretty-printing debug messages of enum types */
146 const char *v4l2_field_names[] = {
147 [V4L2_FIELD_ANY] = "any",
148 [V4L2_FIELD_NONE] = "none",
149 [V4L2_FIELD_TOP] = "top",
150 [V4L2_FIELD_BOTTOM] = "bottom",
151 [V4L2_FIELD_INTERLACED] = "interlaced",
152 [V4L2_FIELD_SEQ_TB] = "seq-tb",
153 [V4L2_FIELD_SEQ_BT] = "seq-bt",
154 [V4L2_FIELD_ALTERNATE] = "alternate",
155 [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
156 [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
158 EXPORT_SYMBOL(v4l2_field_names);
160 const char *v4l2_type_names[] = {
161 [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "vid-cap",
162 [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "vid-overlay",
163 [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "vid-out",
164 [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
165 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
166 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
167 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
168 [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay",
170 EXPORT_SYMBOL(v4l2_type_names);
172 static const char *v4l2_memory_names[] = {
173 [V4L2_MEMORY_MMAP] = "mmap",
174 [V4L2_MEMORY_USERPTR] = "userptr",
175 [V4L2_MEMORY_OVERLAY] = "overlay",
178 #define prt_names(a, arr) ((((a) >= 0) && ((a) < ARRAY_SIZE(arr))) ? \
179 arr[a] : "unknown")
181 /* ------------------------------------------------------------------ */
182 /* debug help functions */
184 #ifdef CONFIG_VIDEO_V4L1_COMPAT
185 static const char *v4l1_ioctls[] = {
186 [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP",
187 [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN",
188 [_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN",
189 [_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER",
190 [_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER",
191 [_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT",
192 [_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT",
193 [_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE",
194 [_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN",
195 [_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN",
196 [_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF",
197 [_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF",
198 [_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY",
199 [_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ",
200 [_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ",
201 [_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO",
202 [_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO",
203 [_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC",
204 [_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE",
205 [_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF",
206 [_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT",
207 [_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE",
208 [_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE",
209 [_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE",
210 [_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE",
211 [_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO",
212 [_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE",
213 [_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT",
214 [_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT"
216 #define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
217 #endif
219 static const char *v4l2_ioctls[] = {
220 [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP",
221 [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED",
222 [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT",
223 [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT",
224 [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT",
225 [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS",
226 [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF",
227 [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF",
228 [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF",
229 [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY",
230 [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF",
231 [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF",
232 [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON",
233 [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF",
234 [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM",
235 [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM",
236 [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD",
237 [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD",
238 [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD",
239 [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT",
240 [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL",
241 [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL",
242 [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER",
243 [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER",
244 [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO",
245 [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO",
246 [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL",
247 [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU",
248 [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT",
249 [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT",
250 [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT",
251 [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT",
252 [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT",
253 [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT",
254 [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT",
255 [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR",
256 [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR",
257 [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY",
258 [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY",
259 [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP",
260 [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP",
261 [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP",
262 [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP",
263 [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP",
264 [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD",
265 [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT",
266 [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO",
267 [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT",
268 [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY",
269 [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY",
270 [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
271 [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS",
272 [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS",
273 [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS",
274 [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS",
275 #if 1
276 [_IOC_NR(VIDIOC_ENUM_FRAMESIZES)] = "VIDIOC_ENUM_FRAMESIZES",
277 [_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS",
278 [_IOC_NR(VIDIOC_G_ENC_INDEX)] = "VIDIOC_G_ENC_INDEX",
279 [_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD",
280 [_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD",
282 [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER",
283 [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER",
285 [_IOC_NR(VIDIOC_DBG_G_CHIP_IDENT)] = "VIDIOC_DBG_G_CHIP_IDENT",
286 [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK",
287 #endif
288 [_IOC_NR(VIDIOC_ENUM_DV_PRESETS)] = "VIDIOC_ENUM_DV_PRESETS",
289 [_IOC_NR(VIDIOC_S_DV_PRESET)] = "VIDIOC_S_DV_PRESET",
290 [_IOC_NR(VIDIOC_G_DV_PRESET)] = "VIDIOC_G_DV_PRESET",
291 [_IOC_NR(VIDIOC_QUERY_DV_PRESET)] = "VIDIOC_QUERY_DV_PRESET",
292 [_IOC_NR(VIDIOC_S_DV_TIMINGS)] = "VIDIOC_S_DV_TIMINGS",
293 [_IOC_NR(VIDIOC_G_DV_TIMINGS)] = "VIDIOC_G_DV_TIMINGS",
295 #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
297 /* Common ioctl debug function. This function can be used by
298 external ioctl messages as well as internal V4L ioctl */
299 void v4l_printk_ioctl(unsigned int cmd)
301 char *dir, *type;
303 switch (_IOC_TYPE(cmd)) {
304 case 'd':
305 type = "v4l2_int";
306 break;
307 #ifdef CONFIG_VIDEO_V4L1_COMPAT
308 case 'v':
309 if (_IOC_NR(cmd) >= V4L1_IOCTLS) {
310 type = "v4l1";
311 break;
313 printk("%s", v4l1_ioctls[_IOC_NR(cmd)]);
314 return;
315 #endif
316 case 'V':
317 if (_IOC_NR(cmd) >= V4L2_IOCTLS) {
318 type = "v4l2";
319 break;
321 printk("%s", v4l2_ioctls[_IOC_NR(cmd)]);
322 return;
323 default:
324 type = "unknown";
327 switch (_IOC_DIR(cmd)) {
328 case _IOC_NONE: dir = "--"; break;
329 case _IOC_READ: dir = "r-"; break;
330 case _IOC_WRITE: dir = "-w"; break;
331 case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
332 default: dir = "*ERR*"; break;
334 printk("%s ioctl '%c', dir=%s, #%d (0x%08x)",
335 type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
337 EXPORT_SYMBOL(v4l_printk_ioctl);
340 * helper function -- handles userspace copying for ioctl arguments
343 #ifdef __OLD_VIDIOC_
344 static unsigned int
345 video_fix_command(unsigned int cmd)
347 switch (cmd) {
348 case VIDIOC_OVERLAY_OLD:
349 cmd = VIDIOC_OVERLAY;
350 break;
351 case VIDIOC_S_PARM_OLD:
352 cmd = VIDIOC_S_PARM;
353 break;
354 case VIDIOC_S_CTRL_OLD:
355 cmd = VIDIOC_S_CTRL;
356 break;
357 case VIDIOC_G_AUDIO_OLD:
358 cmd = VIDIOC_G_AUDIO;
359 break;
360 case VIDIOC_G_AUDOUT_OLD:
361 cmd = VIDIOC_G_AUDOUT;
362 break;
363 case VIDIOC_CROPCAP_OLD:
364 cmd = VIDIOC_CROPCAP;
365 break;
367 return cmd;
369 #endif
372 * Obsolete usercopy function - Should be removed soon
374 long
375 video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
376 v4l2_kioctl func)
378 char sbuf[128];
379 void *mbuf = NULL;
380 void *parg = NULL;
381 long err = -EINVAL;
382 int is_ext_ctrl;
383 size_t ctrls_size = 0;
384 void __user *user_ptr = NULL;
386 #ifdef __OLD_VIDIOC_
387 cmd = video_fix_command(cmd);
388 #endif
389 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
390 cmd == VIDIOC_TRY_EXT_CTRLS);
392 /* Copy arguments into temp kernel buffer */
393 switch (_IOC_DIR(cmd)) {
394 case _IOC_NONE:
395 parg = NULL;
396 break;
397 case _IOC_READ:
398 case _IOC_WRITE:
399 case (_IOC_WRITE | _IOC_READ):
400 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
401 parg = sbuf;
402 } else {
403 /* too big to allocate from stack */
404 mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
405 if (NULL == mbuf)
406 return -ENOMEM;
407 parg = mbuf;
410 err = -EFAULT;
411 if (_IOC_DIR(cmd) & _IOC_WRITE)
412 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
413 goto out;
414 break;
416 if (is_ext_ctrl) {
417 struct v4l2_ext_controls *p = parg;
419 /* In case of an error, tell the caller that it wasn't
420 a specific control that caused it. */
421 p->error_idx = p->count;
422 user_ptr = (void __user *)p->controls;
423 if (p->count) {
424 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
425 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
426 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
427 err = -ENOMEM;
428 if (NULL == mbuf)
429 goto out_ext_ctrl;
430 err = -EFAULT;
431 if (copy_from_user(mbuf, user_ptr, ctrls_size))
432 goto out_ext_ctrl;
433 p->controls = mbuf;
437 /* call driver */
438 err = func(file, cmd, parg);
439 if (err == -ENOIOCTLCMD)
440 err = -EINVAL;
441 if (is_ext_ctrl) {
442 struct v4l2_ext_controls *p = parg;
444 p->controls = (void *)user_ptr;
445 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
446 err = -EFAULT;
447 goto out_ext_ctrl;
449 if (err < 0)
450 goto out;
452 out_ext_ctrl:
453 /* Copy results into user buffer */
454 switch (_IOC_DIR(cmd)) {
455 case _IOC_READ:
456 case (_IOC_WRITE | _IOC_READ):
457 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
458 err = -EFAULT;
459 break;
462 out:
463 kfree(mbuf);
464 return err;
466 EXPORT_SYMBOL(video_usercopy);
468 static void dbgbuf(unsigned int cmd, struct video_device *vfd,
469 struct v4l2_buffer *p)
471 struct v4l2_timecode *tc = &p->timecode;
473 dbgarg(cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
474 "bytesused=%d, flags=0x%08d, "
475 "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n",
476 p->timestamp.tv_sec / 3600,
477 (int)(p->timestamp.tv_sec / 60) % 60,
478 (int)(p->timestamp.tv_sec % 60),
479 (long)p->timestamp.tv_usec,
480 p->index,
481 prt_names(p->type, v4l2_type_names),
482 p->bytesused, p->flags,
483 p->field, p->sequence,
484 prt_names(p->memory, v4l2_memory_names),
485 p->m.userptr, p->length);
486 dbgarg2("timecode=%02d:%02d:%02d type=%d, "
487 "flags=0x%08d, frames=%d, userbits=0x%08x\n",
488 tc->hours, tc->minutes, tc->seconds,
489 tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits);
492 static inline void dbgrect(struct video_device *vfd, char *s,
493 struct v4l2_rect *r)
495 dbgarg2("%sRect start at %dx%d, size=%dx%d\n", s, r->left, r->top,
496 r->width, r->height);
499 static inline void v4l_print_pix_fmt(struct video_device *vfd,
500 struct v4l2_pix_format *fmt)
502 dbgarg2("width=%d, height=%d, format=%c%c%c%c, field=%s, "
503 "bytesperline=%d sizeimage=%d, colorspace=%d\n",
504 fmt->width, fmt->height,
505 (fmt->pixelformat & 0xff),
506 (fmt->pixelformat >> 8) & 0xff,
507 (fmt->pixelformat >> 16) & 0xff,
508 (fmt->pixelformat >> 24) & 0xff,
509 prt_names(fmt->field, v4l2_field_names),
510 fmt->bytesperline, fmt->sizeimage, fmt->colorspace);
513 static inline void v4l_print_ext_ctrls(unsigned int cmd,
514 struct video_device *vfd, struct v4l2_ext_controls *c, int show_vals)
516 __u32 i;
518 if (!(vfd->debug & V4L2_DEBUG_IOCTL_ARG))
519 return;
520 dbgarg(cmd, "");
521 printk(KERN_CONT "class=0x%x", c->ctrl_class);
522 for (i = 0; i < c->count; i++) {
523 if (show_vals && !c->controls[i].size)
524 printk(KERN_CONT " id/val=0x%x/0x%x",
525 c->controls[i].id, c->controls[i].value);
526 else
527 printk(KERN_CONT " id=0x%x,size=%u",
528 c->controls[i].id, c->controls[i].size);
530 printk(KERN_CONT "\n");
533 static inline int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)
535 __u32 i;
537 /* zero the reserved fields */
538 c->reserved[0] = c->reserved[1] = 0;
539 for (i = 0; i < c->count; i++)
540 c->controls[i].reserved2[0] = 0;
542 /* V4L2_CID_PRIVATE_BASE cannot be used as control class
543 when using extended controls.
544 Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
545 is it allowed for backwards compatibility.
547 if (!allow_priv && c->ctrl_class == V4L2_CID_PRIVATE_BASE)
548 return 0;
549 /* Check that all controls are from the same control class. */
550 for (i = 0; i < c->count; i++) {
551 if (V4L2_CTRL_ID2CLASS(c->controls[i].id) != c->ctrl_class) {
552 c->error_idx = i;
553 return 0;
556 return 1;
559 static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type)
561 if (ops == NULL)
562 return -EINVAL;
564 switch (type) {
565 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
566 if (ops->vidioc_g_fmt_vid_cap)
567 return 0;
568 break;
569 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
570 if (ops->vidioc_g_fmt_vid_overlay)
571 return 0;
572 break;
573 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
574 if (ops->vidioc_g_fmt_vid_out)
575 return 0;
576 break;
577 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
578 if (ops->vidioc_g_fmt_vid_out_overlay)
579 return 0;
580 break;
581 case V4L2_BUF_TYPE_VBI_CAPTURE:
582 if (ops->vidioc_g_fmt_vbi_cap)
583 return 0;
584 break;
585 case V4L2_BUF_TYPE_VBI_OUTPUT:
586 if (ops->vidioc_g_fmt_vbi_out)
587 return 0;
588 break;
589 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
590 if (ops->vidioc_g_fmt_sliced_vbi_cap)
591 return 0;
592 break;
593 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
594 if (ops->vidioc_g_fmt_sliced_vbi_out)
595 return 0;
596 break;
597 case V4L2_BUF_TYPE_PRIVATE:
598 if (ops->vidioc_g_fmt_type_private)
599 return 0;
600 break;
602 return -EINVAL;
605 static long __video_do_ioctl(struct file *file,
606 unsigned int cmd, void *arg)
608 struct video_device *vfd = video_devdata(file);
609 const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
610 void *fh = file->private_data;
611 long ret = -EINVAL;
613 if ((vfd->debug & V4L2_DEBUG_IOCTL) &&
614 !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) {
615 v4l_print_ioctl(vfd->name, cmd);
616 printk(KERN_CONT "\n");
619 if (ops == NULL) {
620 printk(KERN_WARNING "videodev: \"%s\" has no ioctl_ops.\n",
621 vfd->name);
622 return -EINVAL;
625 #ifdef CONFIG_VIDEO_V4L1_COMPAT
626 /***********************************************************
627 Handles calls to the obsoleted V4L1 API
628 Due to the nature of VIDIOCGMBUF, each driver that supports
629 V4L1 should implement its own handler for this ioctl.
630 ***********************************************************/
632 /* --- streaming capture ------------------------------------- */
633 if (cmd == VIDIOCGMBUF) {
634 struct video_mbuf *p = arg;
636 if (!ops->vidiocgmbuf)
637 return ret;
638 ret = ops->vidiocgmbuf(file, fh, p);
639 if (!ret)
640 dbgarg(cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
641 p->size, p->frames,
642 (unsigned long)p->offsets);
643 return ret;
646 /********************************************************
647 All other V4L1 calls are handled by v4l1_compat module.
648 Those calls will be translated into V4L2 calls, and
649 __video_do_ioctl will be called again, with one or more
650 V4L2 ioctls.
651 ********************************************************/
652 if (_IOC_TYPE(cmd) == 'v' && _IOC_NR(cmd) < BASE_VIDIOCPRIVATE)
653 return v4l_compat_translate_ioctl(file, cmd, arg,
654 __video_do_ioctl);
655 #endif
657 switch (cmd) {
658 /* --- capabilities ------------------------------------------ */
659 case VIDIOC_QUERYCAP:
661 struct v4l2_capability *cap = (struct v4l2_capability *)arg;
663 if (!ops->vidioc_querycap)
664 break;
666 ret = ops->vidioc_querycap(file, fh, cap);
667 if (!ret)
668 dbgarg(cmd, "driver=%s, card=%s, bus=%s, "
669 "version=0x%08x, "
670 "capabilities=0x%08x\n",
671 cap->driver, cap->card, cap->bus_info,
672 cap->version,
673 cap->capabilities);
674 break;
677 /* --- priority ------------------------------------------ */
678 case VIDIOC_G_PRIORITY:
680 enum v4l2_priority *p = arg;
682 if (!ops->vidioc_g_priority)
683 break;
684 ret = ops->vidioc_g_priority(file, fh, p);
685 if (!ret)
686 dbgarg(cmd, "priority is %d\n", *p);
687 break;
689 case VIDIOC_S_PRIORITY:
691 enum v4l2_priority *p = arg;
693 if (!ops->vidioc_s_priority)
694 break;
695 dbgarg(cmd, "setting priority to %d\n", *p);
696 ret = ops->vidioc_s_priority(file, fh, *p);
697 break;
700 /* --- capture ioctls ---------------------------------------- */
701 case VIDIOC_ENUM_FMT:
703 struct v4l2_fmtdesc *f = arg;
705 switch (f->type) {
706 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
707 if (ops->vidioc_enum_fmt_vid_cap)
708 ret = ops->vidioc_enum_fmt_vid_cap(file, fh, f);
709 break;
710 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
711 if (ops->vidioc_enum_fmt_vid_overlay)
712 ret = ops->vidioc_enum_fmt_vid_overlay(file,
713 fh, f);
714 break;
715 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
716 if (ops->vidioc_enum_fmt_vid_out)
717 ret = ops->vidioc_enum_fmt_vid_out(file, fh, f);
718 break;
719 case V4L2_BUF_TYPE_PRIVATE:
720 if (ops->vidioc_enum_fmt_type_private)
721 ret = ops->vidioc_enum_fmt_type_private(file,
722 fh, f);
723 break;
724 default:
725 break;
727 if (!ret)
728 dbgarg(cmd, "index=%d, type=%d, flags=%d, "
729 "pixelformat=%c%c%c%c, description='%s'\n",
730 f->index, f->type, f->flags,
731 (f->pixelformat & 0xff),
732 (f->pixelformat >> 8) & 0xff,
733 (f->pixelformat >> 16) & 0xff,
734 (f->pixelformat >> 24) & 0xff,
735 f->description);
736 break;
738 case VIDIOC_G_FMT:
740 struct v4l2_format *f = (struct v4l2_format *)arg;
742 /* FIXME: Should be one dump per type */
743 dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
745 switch (f->type) {
746 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
747 if (ops->vidioc_g_fmt_vid_cap)
748 ret = ops->vidioc_g_fmt_vid_cap(file, fh, f);
749 if (!ret)
750 v4l_print_pix_fmt(vfd, &f->fmt.pix);
751 break;
752 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
753 if (ops->vidioc_g_fmt_vid_overlay)
754 ret = ops->vidioc_g_fmt_vid_overlay(file,
755 fh, f);
756 break;
757 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
758 if (ops->vidioc_g_fmt_vid_out)
759 ret = ops->vidioc_g_fmt_vid_out(file, fh, f);
760 if (!ret)
761 v4l_print_pix_fmt(vfd, &f->fmt.pix);
762 break;
763 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
764 if (ops->vidioc_g_fmt_vid_out_overlay)
765 ret = ops->vidioc_g_fmt_vid_out_overlay(file,
766 fh, f);
767 break;
768 case V4L2_BUF_TYPE_VBI_CAPTURE:
769 if (ops->vidioc_g_fmt_vbi_cap)
770 ret = ops->vidioc_g_fmt_vbi_cap(file, fh, f);
771 break;
772 case V4L2_BUF_TYPE_VBI_OUTPUT:
773 if (ops->vidioc_g_fmt_vbi_out)
774 ret = ops->vidioc_g_fmt_vbi_out(file, fh, f);
775 break;
776 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
777 if (ops->vidioc_g_fmt_sliced_vbi_cap)
778 ret = ops->vidioc_g_fmt_sliced_vbi_cap(file,
779 fh, f);
780 break;
781 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
782 if (ops->vidioc_g_fmt_sliced_vbi_out)
783 ret = ops->vidioc_g_fmt_sliced_vbi_out(file,
784 fh, f);
785 break;
786 case V4L2_BUF_TYPE_PRIVATE:
787 if (ops->vidioc_g_fmt_type_private)
788 ret = ops->vidioc_g_fmt_type_private(file,
789 fh, f);
790 break;
793 break;
795 case VIDIOC_S_FMT:
797 struct v4l2_format *f = (struct v4l2_format *)arg;
799 /* FIXME: Should be one dump per type */
800 dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
802 switch (f->type) {
803 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
804 CLEAR_AFTER_FIELD(f, fmt.pix);
805 v4l_print_pix_fmt(vfd, &f->fmt.pix);
806 if (ops->vidioc_s_fmt_vid_cap)
807 ret = ops->vidioc_s_fmt_vid_cap(file, fh, f);
808 break;
809 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
810 CLEAR_AFTER_FIELD(f, fmt.win);
811 if (ops->vidioc_s_fmt_vid_overlay)
812 ret = ops->vidioc_s_fmt_vid_overlay(file,
813 fh, f);
814 break;
815 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
816 CLEAR_AFTER_FIELD(f, fmt.pix);
817 v4l_print_pix_fmt(vfd, &f->fmt.pix);
818 if (ops->vidioc_s_fmt_vid_out)
819 ret = ops->vidioc_s_fmt_vid_out(file, fh, f);
820 break;
821 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
822 CLEAR_AFTER_FIELD(f, fmt.win);
823 if (ops->vidioc_s_fmt_vid_out_overlay)
824 ret = ops->vidioc_s_fmt_vid_out_overlay(file,
825 fh, f);
826 break;
827 case V4L2_BUF_TYPE_VBI_CAPTURE:
828 CLEAR_AFTER_FIELD(f, fmt.vbi);
829 if (ops->vidioc_s_fmt_vbi_cap)
830 ret = ops->vidioc_s_fmt_vbi_cap(file, fh, f);
831 break;
832 case V4L2_BUF_TYPE_VBI_OUTPUT:
833 CLEAR_AFTER_FIELD(f, fmt.vbi);
834 if (ops->vidioc_s_fmt_vbi_out)
835 ret = ops->vidioc_s_fmt_vbi_out(file, fh, f);
836 break;
837 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
838 CLEAR_AFTER_FIELD(f, fmt.sliced);
839 if (ops->vidioc_s_fmt_sliced_vbi_cap)
840 ret = ops->vidioc_s_fmt_sliced_vbi_cap(file,
841 fh, f);
842 break;
843 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
844 CLEAR_AFTER_FIELD(f, fmt.sliced);
845 if (ops->vidioc_s_fmt_sliced_vbi_out)
846 ret = ops->vidioc_s_fmt_sliced_vbi_out(file,
847 fh, f);
848 break;
849 case V4L2_BUF_TYPE_PRIVATE:
850 /* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */
851 if (ops->vidioc_s_fmt_type_private)
852 ret = ops->vidioc_s_fmt_type_private(file,
853 fh, f);
854 break;
856 break;
858 case VIDIOC_TRY_FMT:
860 struct v4l2_format *f = (struct v4l2_format *)arg;
862 /* FIXME: Should be one dump per type */
863 dbgarg(cmd, "type=%s\n", prt_names(f->type,
864 v4l2_type_names));
865 switch (f->type) {
866 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
867 CLEAR_AFTER_FIELD(f, fmt.pix);
868 if (ops->vidioc_try_fmt_vid_cap)
869 ret = ops->vidioc_try_fmt_vid_cap(file, fh, f);
870 if (!ret)
871 v4l_print_pix_fmt(vfd, &f->fmt.pix);
872 break;
873 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
874 CLEAR_AFTER_FIELD(f, fmt.win);
875 if (ops->vidioc_try_fmt_vid_overlay)
876 ret = ops->vidioc_try_fmt_vid_overlay(file,
877 fh, f);
878 break;
879 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
880 CLEAR_AFTER_FIELD(f, fmt.pix);
881 if (ops->vidioc_try_fmt_vid_out)
882 ret = ops->vidioc_try_fmt_vid_out(file, fh, f);
883 if (!ret)
884 v4l_print_pix_fmt(vfd, &f->fmt.pix);
885 break;
886 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
887 CLEAR_AFTER_FIELD(f, fmt.win);
888 if (ops->vidioc_try_fmt_vid_out_overlay)
889 ret = ops->vidioc_try_fmt_vid_out_overlay(file,
890 fh, f);
891 break;
892 case V4L2_BUF_TYPE_VBI_CAPTURE:
893 CLEAR_AFTER_FIELD(f, fmt.vbi);
894 if (ops->vidioc_try_fmt_vbi_cap)
895 ret = ops->vidioc_try_fmt_vbi_cap(file, fh, f);
896 break;
897 case V4L2_BUF_TYPE_VBI_OUTPUT:
898 CLEAR_AFTER_FIELD(f, fmt.vbi);
899 if (ops->vidioc_try_fmt_vbi_out)
900 ret = ops->vidioc_try_fmt_vbi_out(file, fh, f);
901 break;
902 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
903 CLEAR_AFTER_FIELD(f, fmt.sliced);
904 if (ops->vidioc_try_fmt_sliced_vbi_cap)
905 ret = ops->vidioc_try_fmt_sliced_vbi_cap(file,
906 fh, f);
907 break;
908 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
909 CLEAR_AFTER_FIELD(f, fmt.sliced);
910 if (ops->vidioc_try_fmt_sliced_vbi_out)
911 ret = ops->vidioc_try_fmt_sliced_vbi_out(file,
912 fh, f);
913 break;
914 case V4L2_BUF_TYPE_PRIVATE:
915 /* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */
916 if (ops->vidioc_try_fmt_type_private)
917 ret = ops->vidioc_try_fmt_type_private(file,
918 fh, f);
919 break;
922 break;
924 /* FIXME: Those buf reqs could be handled here,
925 with some changes on videobuf to allow its header to be included at
926 videodev2.h or being merged at videodev2.
928 case VIDIOC_REQBUFS:
930 struct v4l2_requestbuffers *p = arg;
932 if (!ops->vidioc_reqbufs)
933 break;
934 ret = check_fmt(ops, p->type);
935 if (ret)
936 break;
938 if (p->type < V4L2_BUF_TYPE_PRIVATE)
939 CLEAR_AFTER_FIELD(p, memory);
941 ret = ops->vidioc_reqbufs(file, fh, p);
942 dbgarg(cmd, "count=%d, type=%s, memory=%s\n",
943 p->count,
944 prt_names(p->type, v4l2_type_names),
945 prt_names(p->memory, v4l2_memory_names));
946 break;
948 case VIDIOC_QUERYBUF:
950 struct v4l2_buffer *p = arg;
952 if (!ops->vidioc_querybuf)
953 break;
954 ret = check_fmt(ops, p->type);
955 if (ret)
956 break;
958 ret = ops->vidioc_querybuf(file, fh, p);
959 if (!ret)
960 dbgbuf(cmd, vfd, p);
961 break;
963 case VIDIOC_QBUF:
965 struct v4l2_buffer *p = arg;
967 if (!ops->vidioc_qbuf)
968 break;
969 ret = check_fmt(ops, p->type);
970 if (ret)
971 break;
973 ret = ops->vidioc_qbuf(file, fh, p);
974 if (!ret)
975 dbgbuf(cmd, vfd, p);
976 break;
978 case VIDIOC_DQBUF:
980 struct v4l2_buffer *p = arg;
982 if (!ops->vidioc_dqbuf)
983 break;
984 ret = check_fmt(ops, p->type);
985 if (ret)
986 break;
988 ret = ops->vidioc_dqbuf(file, fh, p);
989 if (!ret)
990 dbgbuf(cmd, vfd, p);
991 break;
993 case VIDIOC_OVERLAY:
995 int *i = arg;
997 if (!ops->vidioc_overlay)
998 break;
999 dbgarg(cmd, "value=%d\n", *i);
1000 ret = ops->vidioc_overlay(file, fh, *i);
1001 break;
1003 case VIDIOC_G_FBUF:
1005 struct v4l2_framebuffer *p = arg;
1007 if (!ops->vidioc_g_fbuf)
1008 break;
1009 ret = ops->vidioc_g_fbuf(file, fh, arg);
1010 if (!ret) {
1011 dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
1012 p->capability, p->flags,
1013 (unsigned long)p->base);
1014 v4l_print_pix_fmt(vfd, &p->fmt);
1016 break;
1018 case VIDIOC_S_FBUF:
1020 struct v4l2_framebuffer *p = arg;
1022 if (!ops->vidioc_s_fbuf)
1023 break;
1024 dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
1025 p->capability, p->flags, (unsigned long)p->base);
1026 v4l_print_pix_fmt(vfd, &p->fmt);
1027 ret = ops->vidioc_s_fbuf(file, fh, arg);
1028 break;
1030 case VIDIOC_STREAMON:
1032 enum v4l2_buf_type i = *(int *)arg;
1034 if (!ops->vidioc_streamon)
1035 break;
1036 dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
1037 ret = ops->vidioc_streamon(file, fh, i);
1038 break;
1040 case VIDIOC_STREAMOFF:
1042 enum v4l2_buf_type i = *(int *)arg;
1044 if (!ops->vidioc_streamoff)
1045 break;
1046 dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
1047 ret = ops->vidioc_streamoff(file, fh, i);
1048 break;
1050 /* ---------- tv norms ---------- */
1051 case VIDIOC_ENUMSTD:
1053 struct v4l2_standard *p = arg;
1054 v4l2_std_id id = vfd->tvnorms, curr_id = 0;
1055 unsigned int index = p->index, i, j = 0;
1056 const char *descr = "";
1058 /* Return norm array in a canonical way */
1059 for (i = 0; i <= index && id; i++) {
1060 /* last std value in the standards array is 0, so this
1061 while always ends there since (id & 0) == 0. */
1062 while ((id & standards[j].std) != standards[j].std)
1063 j++;
1064 curr_id = standards[j].std;
1065 descr = standards[j].descr;
1066 j++;
1067 if (curr_id == 0)
1068 break;
1069 if (curr_id != V4L2_STD_PAL &&
1070 curr_id != V4L2_STD_SECAM &&
1071 curr_id != V4L2_STD_NTSC)
1072 id &= ~curr_id;
1074 if (i <= index)
1075 break;
1077 v4l2_video_std_construct(p, curr_id, descr);
1079 dbgarg(cmd, "index=%d, id=0x%Lx, name=%s, fps=%d/%d, "
1080 "framelines=%d\n", p->index,
1081 (unsigned long long)p->id, p->name,
1082 p->frameperiod.numerator,
1083 p->frameperiod.denominator,
1084 p->framelines);
1086 ret = 0;
1087 break;
1089 case VIDIOC_G_STD:
1091 v4l2_std_id *id = arg;
1093 ret = 0;
1094 /* Calls the specific handler */
1095 if (ops->vidioc_g_std)
1096 ret = ops->vidioc_g_std(file, fh, id);
1097 else if (vfd->current_norm)
1098 *id = vfd->current_norm;
1099 else
1100 ret = -EINVAL;
1102 if (!ret)
1103 dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id);
1104 break;
1106 case VIDIOC_S_STD:
1108 v4l2_std_id *id = arg, norm;
1110 dbgarg(cmd, "std=%08Lx\n", (long long unsigned)*id);
1112 norm = (*id) & vfd->tvnorms;
1113 if (vfd->tvnorms && !norm) /* Check if std is supported */
1114 break;
1116 /* Calls the specific handler */
1117 if (ops->vidioc_s_std)
1118 ret = ops->vidioc_s_std(file, fh, &norm);
1119 else
1120 ret = -EINVAL;
1122 /* Updates standard information */
1123 if (ret >= 0)
1124 vfd->current_norm = norm;
1125 break;
1127 case VIDIOC_QUERYSTD:
1129 v4l2_std_id *p = arg;
1131 if (!ops->vidioc_querystd)
1132 break;
1133 ret = ops->vidioc_querystd(file, fh, arg);
1134 if (!ret)
1135 dbgarg(cmd, "detected std=%08Lx\n",
1136 (unsigned long long)*p);
1137 break;
1139 /* ------ input switching ---------- */
1140 /* FIXME: Inputs can be handled inside videodev2 */
1141 case VIDIOC_ENUMINPUT:
1143 struct v4l2_input *p = arg;
1146 * We set the flags for CAP_PRESETS, CAP_CUSTOM_TIMINGS &
1147 * CAP_STD here based on ioctl handler provided by the
1148 * driver. If the driver doesn't support these
1149 * for a specific input, it must override these flags.
1151 if (ops->vidioc_s_std)
1152 p->capabilities |= V4L2_IN_CAP_STD;
1153 if (ops->vidioc_s_dv_preset)
1154 p->capabilities |= V4L2_IN_CAP_PRESETS;
1155 if (ops->vidioc_s_dv_timings)
1156 p->capabilities |= V4L2_IN_CAP_CUSTOM_TIMINGS;
1158 if (!ops->vidioc_enum_input)
1159 break;
1161 ret = ops->vidioc_enum_input(file, fh, p);
1162 if (!ret)
1163 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1164 "audioset=%d, "
1165 "tuner=%d, std=%08Lx, status=%d\n",
1166 p->index, p->name, p->type, p->audioset,
1167 p->tuner,
1168 (unsigned long long)p->std,
1169 p->status);
1170 break;
1172 case VIDIOC_G_INPUT:
1174 unsigned int *i = arg;
1176 if (!ops->vidioc_g_input)
1177 break;
1178 ret = ops->vidioc_g_input(file, fh, i);
1179 if (!ret)
1180 dbgarg(cmd, "value=%d\n", *i);
1181 break;
1183 case VIDIOC_S_INPUT:
1185 unsigned int *i = arg;
1187 if (!ops->vidioc_s_input)
1188 break;
1189 dbgarg(cmd, "value=%d\n", *i);
1190 ret = ops->vidioc_s_input(file, fh, *i);
1191 break;
1194 /* ------ output switching ---------- */
1195 case VIDIOC_ENUMOUTPUT:
1197 struct v4l2_output *p = arg;
1199 if (!ops->vidioc_enum_output)
1200 break;
1203 * We set the flags for CAP_PRESETS, CAP_CUSTOM_TIMINGS &
1204 * CAP_STD here based on ioctl handler provided by the
1205 * driver. If the driver doesn't support these
1206 * for a specific output, it must override these flags.
1208 if (ops->vidioc_s_std)
1209 p->capabilities |= V4L2_OUT_CAP_STD;
1210 if (ops->vidioc_s_dv_preset)
1211 p->capabilities |= V4L2_OUT_CAP_PRESETS;
1212 if (ops->vidioc_s_dv_timings)
1213 p->capabilities |= V4L2_OUT_CAP_CUSTOM_TIMINGS;
1215 ret = ops->vidioc_enum_output(file, fh, p);
1216 if (!ret)
1217 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1218 "audioset=0x%x, "
1219 "modulator=%d, std=0x%08Lx\n",
1220 p->index, p->name, p->type, p->audioset,
1221 p->modulator, (unsigned long long)p->std);
1222 break;
1224 case VIDIOC_G_OUTPUT:
1226 unsigned int *i = arg;
1228 if (!ops->vidioc_g_output)
1229 break;
1230 ret = ops->vidioc_g_output(file, fh, i);
1231 if (!ret)
1232 dbgarg(cmd, "value=%d\n", *i);
1233 break;
1235 case VIDIOC_S_OUTPUT:
1237 unsigned int *i = arg;
1239 if (!ops->vidioc_s_output)
1240 break;
1241 dbgarg(cmd, "value=%d\n", *i);
1242 ret = ops->vidioc_s_output(file, fh, *i);
1243 break;
1246 /* --- controls ---------------------------------------------- */
1247 case VIDIOC_QUERYCTRL:
1249 struct v4l2_queryctrl *p = arg;
1251 if (!ops->vidioc_queryctrl)
1252 break;
1253 ret = ops->vidioc_queryctrl(file, fh, p);
1254 if (!ret)
1255 dbgarg(cmd, "id=0x%x, type=%d, name=%s, min/max=%d/%d, "
1256 "step=%d, default=%d, flags=0x%08x\n",
1257 p->id, p->type, p->name,
1258 p->minimum, p->maximum,
1259 p->step, p->default_value, p->flags);
1260 else
1261 dbgarg(cmd, "id=0x%x\n", p->id);
1262 break;
1264 case VIDIOC_G_CTRL:
1266 struct v4l2_control *p = arg;
1268 if (ops->vidioc_g_ctrl)
1269 ret = ops->vidioc_g_ctrl(file, fh, p);
1270 else if (ops->vidioc_g_ext_ctrls) {
1271 struct v4l2_ext_controls ctrls;
1272 struct v4l2_ext_control ctrl;
1274 ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
1275 ctrls.count = 1;
1276 ctrls.controls = &ctrl;
1277 ctrl.id = p->id;
1278 ctrl.value = p->value;
1279 if (check_ext_ctrls(&ctrls, 1)) {
1280 ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls);
1281 if (ret == 0)
1282 p->value = ctrl.value;
1284 } else
1285 break;
1286 if (!ret)
1287 dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
1288 else
1289 dbgarg(cmd, "id=0x%x\n", p->id);
1290 break;
1292 case VIDIOC_S_CTRL:
1294 struct v4l2_control *p = arg;
1295 struct v4l2_ext_controls ctrls;
1296 struct v4l2_ext_control ctrl;
1298 if (!ops->vidioc_s_ctrl && !ops->vidioc_s_ext_ctrls)
1299 break;
1301 dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
1303 if (ops->vidioc_s_ctrl) {
1304 ret = ops->vidioc_s_ctrl(file, fh, p);
1305 break;
1307 if (!ops->vidioc_s_ext_ctrls)
1308 break;
1310 ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
1311 ctrls.count = 1;
1312 ctrls.controls = &ctrl;
1313 ctrl.id = p->id;
1314 ctrl.value = p->value;
1315 if (check_ext_ctrls(&ctrls, 1))
1316 ret = ops->vidioc_s_ext_ctrls(file, fh, &ctrls);
1317 break;
1319 case VIDIOC_G_EXT_CTRLS:
1321 struct v4l2_ext_controls *p = arg;
1323 p->error_idx = p->count;
1324 if (!ops->vidioc_g_ext_ctrls)
1325 break;
1326 if (check_ext_ctrls(p, 0))
1327 ret = ops->vidioc_g_ext_ctrls(file, fh, p);
1328 v4l_print_ext_ctrls(cmd, vfd, p, !ret);
1329 break;
1331 case VIDIOC_S_EXT_CTRLS:
1333 struct v4l2_ext_controls *p = arg;
1335 p->error_idx = p->count;
1336 if (!ops->vidioc_s_ext_ctrls)
1337 break;
1338 v4l_print_ext_ctrls(cmd, vfd, p, 1);
1339 if (check_ext_ctrls(p, 0))
1340 ret = ops->vidioc_s_ext_ctrls(file, fh, p);
1341 break;
1343 case VIDIOC_TRY_EXT_CTRLS:
1345 struct v4l2_ext_controls *p = arg;
1347 p->error_idx = p->count;
1348 if (!ops->vidioc_try_ext_ctrls)
1349 break;
1350 v4l_print_ext_ctrls(cmd, vfd, p, 1);
1351 if (check_ext_ctrls(p, 0))
1352 ret = ops->vidioc_try_ext_ctrls(file, fh, p);
1353 break;
1355 case VIDIOC_QUERYMENU:
1357 struct v4l2_querymenu *p = arg;
1359 if (!ops->vidioc_querymenu)
1360 break;
1361 ret = ops->vidioc_querymenu(file, fh, p);
1362 if (!ret)
1363 dbgarg(cmd, "id=0x%x, index=%d, name=%s\n",
1364 p->id, p->index, p->name);
1365 else
1366 dbgarg(cmd, "id=0x%x, index=%d\n",
1367 p->id, p->index);
1368 break;
1370 /* --- audio ---------------------------------------------- */
1371 case VIDIOC_ENUMAUDIO:
1373 struct v4l2_audio *p = arg;
1375 if (!ops->vidioc_enumaudio)
1376 break;
1377 ret = ops->vidioc_enumaudio(file, fh, p);
1378 if (!ret)
1379 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
1380 "mode=0x%x\n", p->index, p->name,
1381 p->capability, p->mode);
1382 else
1383 dbgarg(cmd, "index=%d\n", p->index);
1384 break;
1386 case VIDIOC_G_AUDIO:
1388 struct v4l2_audio *p = arg;
1390 if (!ops->vidioc_g_audio)
1391 break;
1393 ret = ops->vidioc_g_audio(file, fh, p);
1394 if (!ret)
1395 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
1396 "mode=0x%x\n", p->index,
1397 p->name, p->capability, p->mode);
1398 else
1399 dbgarg(cmd, "index=%d\n", p->index);
1400 break;
1402 case VIDIOC_S_AUDIO:
1404 struct v4l2_audio *p = arg;
1406 if (!ops->vidioc_s_audio)
1407 break;
1408 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
1409 "mode=0x%x\n", p->index, p->name,
1410 p->capability, p->mode);
1411 ret = ops->vidioc_s_audio(file, fh, p);
1412 break;
1414 case VIDIOC_ENUMAUDOUT:
1416 struct v4l2_audioout *p = arg;
1418 if (!ops->vidioc_enumaudout)
1419 break;
1420 dbgarg(cmd, "Enum for index=%d\n", p->index);
1421 ret = ops->vidioc_enumaudout(file, fh, p);
1422 if (!ret)
1423 dbgarg2("index=%d, name=%s, capability=%d, "
1424 "mode=%d\n", p->index, p->name,
1425 p->capability, p->mode);
1426 break;
1428 case VIDIOC_G_AUDOUT:
1430 struct v4l2_audioout *p = arg;
1432 if (!ops->vidioc_g_audout)
1433 break;
1435 ret = ops->vidioc_g_audout(file, fh, p);
1436 if (!ret)
1437 dbgarg2("index=%d, name=%s, capability=%d, "
1438 "mode=%d\n", p->index, p->name,
1439 p->capability, p->mode);
1440 break;
1442 case VIDIOC_S_AUDOUT:
1444 struct v4l2_audioout *p = arg;
1446 if (!ops->vidioc_s_audout)
1447 break;
1448 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1449 "mode=%d\n", p->index, p->name,
1450 p->capability, p->mode);
1452 ret = ops->vidioc_s_audout(file, fh, p);
1453 break;
1455 case VIDIOC_G_MODULATOR:
1457 struct v4l2_modulator *p = arg;
1459 if (!ops->vidioc_g_modulator)
1460 break;
1461 ret = ops->vidioc_g_modulator(file, fh, p);
1462 if (!ret)
1463 dbgarg(cmd, "index=%d, name=%s, "
1464 "capability=%d, rangelow=%d,"
1465 " rangehigh=%d, txsubchans=%d\n",
1466 p->index, p->name, p->capability,
1467 p->rangelow, p->rangehigh,
1468 p->txsubchans);
1469 break;
1471 case VIDIOC_S_MODULATOR:
1473 struct v4l2_modulator *p = arg;
1475 if (!ops->vidioc_s_modulator)
1476 break;
1477 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1478 "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
1479 p->index, p->name, p->capability, p->rangelow,
1480 p->rangehigh, p->txsubchans);
1481 ret = ops->vidioc_s_modulator(file, fh, p);
1482 break;
1484 case VIDIOC_G_CROP:
1486 struct v4l2_crop *p = arg;
1488 if (!ops->vidioc_g_crop)
1489 break;
1491 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1492 ret = ops->vidioc_g_crop(file, fh, p);
1493 if (!ret)
1494 dbgrect(vfd, "", &p->c);
1495 break;
1497 case VIDIOC_S_CROP:
1499 struct v4l2_crop *p = arg;
1501 if (!ops->vidioc_s_crop)
1502 break;
1503 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1504 dbgrect(vfd, "", &p->c);
1505 ret = ops->vidioc_s_crop(file, fh, p);
1506 break;
1508 case VIDIOC_CROPCAP:
1510 struct v4l2_cropcap *p = arg;
1512 /*FIXME: Should also show v4l2_fract pixelaspect */
1513 if (!ops->vidioc_cropcap)
1514 break;
1516 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1517 ret = ops->vidioc_cropcap(file, fh, p);
1518 if (!ret) {
1519 dbgrect(vfd, "bounds ", &p->bounds);
1520 dbgrect(vfd, "defrect ", &p->defrect);
1522 break;
1524 case VIDIOC_G_JPEGCOMP:
1526 struct v4l2_jpegcompression *p = arg;
1528 if (!ops->vidioc_g_jpegcomp)
1529 break;
1531 ret = ops->vidioc_g_jpegcomp(file, fh, p);
1532 if (!ret)
1533 dbgarg(cmd, "quality=%d, APPn=%d, "
1534 "APP_len=%d, COM_len=%d, "
1535 "jpeg_markers=%d\n",
1536 p->quality, p->APPn, p->APP_len,
1537 p->COM_len, p->jpeg_markers);
1538 break;
1540 case VIDIOC_S_JPEGCOMP:
1542 struct v4l2_jpegcompression *p = arg;
1544 if (!ops->vidioc_g_jpegcomp)
1545 break;
1546 dbgarg(cmd, "quality=%d, APPn=%d, APP_len=%d, "
1547 "COM_len=%d, jpeg_markers=%d\n",
1548 p->quality, p->APPn, p->APP_len,
1549 p->COM_len, p->jpeg_markers);
1550 ret = ops->vidioc_s_jpegcomp(file, fh, p);
1551 break;
1553 case VIDIOC_G_ENC_INDEX:
1555 struct v4l2_enc_idx *p = arg;
1557 if (!ops->vidioc_g_enc_index)
1558 break;
1559 ret = ops->vidioc_g_enc_index(file, fh, p);
1560 if (!ret)
1561 dbgarg(cmd, "entries=%d, entries_cap=%d\n",
1562 p->entries, p->entries_cap);
1563 break;
1565 case VIDIOC_ENCODER_CMD:
1567 struct v4l2_encoder_cmd *p = arg;
1569 if (!ops->vidioc_encoder_cmd)
1570 break;
1571 ret = ops->vidioc_encoder_cmd(file, fh, p);
1572 if (!ret)
1573 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
1574 break;
1576 case VIDIOC_TRY_ENCODER_CMD:
1578 struct v4l2_encoder_cmd *p = arg;
1580 if (!ops->vidioc_try_encoder_cmd)
1581 break;
1582 ret = ops->vidioc_try_encoder_cmd(file, fh, p);
1583 if (!ret)
1584 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
1585 break;
1587 case VIDIOC_G_PARM:
1589 struct v4l2_streamparm *p = arg;
1591 if (ops->vidioc_g_parm) {
1592 ret = check_fmt(ops, p->type);
1593 if (ret)
1594 break;
1595 ret = ops->vidioc_g_parm(file, fh, p);
1596 } else {
1597 v4l2_std_id std = vfd->current_norm;
1599 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1600 break;
1602 ret = 0;
1603 if (ops->vidioc_g_std)
1604 ret = ops->vidioc_g_std(file, fh, &std);
1605 else if (std == 0)
1606 ret = -EINVAL;
1607 if (ret == 0)
1608 v4l2_video_std_frame_period(std,
1609 &p->parm.capture.timeperframe);
1612 dbgarg(cmd, "type=%d\n", p->type);
1613 break;
1615 case VIDIOC_S_PARM:
1617 struct v4l2_streamparm *p = arg;
1619 if (!ops->vidioc_s_parm)
1620 break;
1621 ret = check_fmt(ops, p->type);
1622 if (ret)
1623 break;
1625 dbgarg(cmd, "type=%d\n", p->type);
1626 ret = ops->vidioc_s_parm(file, fh, p);
1627 break;
1629 case VIDIOC_G_TUNER:
1631 struct v4l2_tuner *p = arg;
1633 if (!ops->vidioc_g_tuner)
1634 break;
1636 ret = ops->vidioc_g_tuner(file, fh, p);
1637 if (!ret)
1638 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1639 "capability=0x%x, rangelow=%d, "
1640 "rangehigh=%d, signal=%d, afc=%d, "
1641 "rxsubchans=0x%x, audmode=%d\n",
1642 p->index, p->name, p->type,
1643 p->capability, p->rangelow,
1644 p->rangehigh, p->signal, p->afc,
1645 p->rxsubchans, p->audmode);
1646 break;
1648 case VIDIOC_S_TUNER:
1650 struct v4l2_tuner *p = arg;
1652 if (!ops->vidioc_s_tuner)
1653 break;
1654 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1655 "capability=0x%x, rangelow=%d, "
1656 "rangehigh=%d, signal=%d, afc=%d, "
1657 "rxsubchans=0x%x, audmode=%d\n",
1658 p->index, p->name, p->type,
1659 p->capability, p->rangelow,
1660 p->rangehigh, p->signal, p->afc,
1661 p->rxsubchans, p->audmode);
1662 ret = ops->vidioc_s_tuner(file, fh, p);
1663 break;
1665 case VIDIOC_G_FREQUENCY:
1667 struct v4l2_frequency *p = arg;
1669 if (!ops->vidioc_g_frequency)
1670 break;
1672 ret = ops->vidioc_g_frequency(file, fh, p);
1673 if (!ret)
1674 dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
1675 p->tuner, p->type, p->frequency);
1676 break;
1678 case VIDIOC_S_FREQUENCY:
1680 struct v4l2_frequency *p = arg;
1682 if (!ops->vidioc_s_frequency)
1683 break;
1684 dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
1685 p->tuner, p->type, p->frequency);
1686 ret = ops->vidioc_s_frequency(file, fh, p);
1687 break;
1689 case VIDIOC_G_SLICED_VBI_CAP:
1691 struct v4l2_sliced_vbi_cap *p = arg;
1693 if (!ops->vidioc_g_sliced_vbi_cap)
1694 break;
1696 /* Clear up to type, everything after type is zerod already */
1697 memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type));
1699 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1700 ret = ops->vidioc_g_sliced_vbi_cap(file, fh, p);
1701 if (!ret)
1702 dbgarg2("service_set=%d\n", p->service_set);
1703 break;
1705 case VIDIOC_LOG_STATUS:
1707 if (!ops->vidioc_log_status)
1708 break;
1709 ret = ops->vidioc_log_status(file, fh);
1710 break;
1712 #ifdef CONFIG_VIDEO_ADV_DEBUG
1713 case VIDIOC_DBG_G_REGISTER:
1715 struct v4l2_dbg_register *p = arg;
1717 if (!capable(CAP_SYS_ADMIN))
1718 ret = -EPERM;
1719 else if (ops->vidioc_g_register)
1720 ret = ops->vidioc_g_register(file, fh, p);
1721 break;
1723 case VIDIOC_DBG_S_REGISTER:
1725 struct v4l2_dbg_register *p = arg;
1727 if (!capable(CAP_SYS_ADMIN))
1728 ret = -EPERM;
1729 else if (ops->vidioc_s_register)
1730 ret = ops->vidioc_s_register(file, fh, p);
1731 break;
1733 #endif
1734 case VIDIOC_DBG_G_CHIP_IDENT:
1736 struct v4l2_dbg_chip_ident *p = arg;
1738 if (!ops->vidioc_g_chip_ident)
1739 break;
1740 p->ident = V4L2_IDENT_NONE;
1741 p->revision = 0;
1742 ret = ops->vidioc_g_chip_ident(file, fh, p);
1743 if (!ret)
1744 dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
1745 break;
1747 case VIDIOC_S_HW_FREQ_SEEK:
1749 struct v4l2_hw_freq_seek *p = arg;
1751 if (!ops->vidioc_s_hw_freq_seek)
1752 break;
1753 dbgarg(cmd,
1754 "tuner=%d, type=%d, seek_upward=%d, wrap_around=%d\n",
1755 p->tuner, p->type, p->seek_upward, p->wrap_around);
1756 ret = ops->vidioc_s_hw_freq_seek(file, fh, p);
1757 break;
1759 case VIDIOC_ENUM_FRAMESIZES:
1761 struct v4l2_frmsizeenum *p = arg;
1763 if (!ops->vidioc_enum_framesizes)
1764 break;
1766 ret = ops->vidioc_enum_framesizes(file, fh, p);
1767 dbgarg(cmd,
1768 "index=%d, pixelformat=%c%c%c%c, type=%d ",
1769 p->index,
1770 (p->pixel_format & 0xff),
1771 (p->pixel_format >> 8) & 0xff,
1772 (p->pixel_format >> 16) & 0xff,
1773 (p->pixel_format >> 24) & 0xff,
1774 p->type);
1775 switch (p->type) {
1776 case V4L2_FRMSIZE_TYPE_DISCRETE:
1777 dbgarg3("width = %d, height=%d\n",
1778 p->discrete.width, p->discrete.height);
1779 break;
1780 case V4L2_FRMSIZE_TYPE_STEPWISE:
1781 dbgarg3("min %dx%d, max %dx%d, step %dx%d\n",
1782 p->stepwise.min_width, p->stepwise.min_height,
1783 p->stepwise.step_width, p->stepwise.step_height,
1784 p->stepwise.max_width, p->stepwise.max_height);
1785 break;
1786 case V4L2_FRMSIZE_TYPE_CONTINUOUS:
1787 dbgarg3("continuous\n");
1788 break;
1789 default:
1790 dbgarg3("- Unknown type!\n");
1793 break;
1795 case VIDIOC_ENUM_FRAMEINTERVALS:
1797 struct v4l2_frmivalenum *p = arg;
1799 if (!ops->vidioc_enum_frameintervals)
1800 break;
1802 ret = ops->vidioc_enum_frameintervals(file, fh, p);
1803 dbgarg(cmd,
1804 "index=%d, pixelformat=%d, width=%d, height=%d, type=%d ",
1805 p->index, p->pixel_format,
1806 p->width, p->height, p->type);
1807 switch (p->type) {
1808 case V4L2_FRMIVAL_TYPE_DISCRETE:
1809 dbgarg2("fps=%d/%d\n",
1810 p->discrete.numerator,
1811 p->discrete.denominator);
1812 break;
1813 case V4L2_FRMIVAL_TYPE_STEPWISE:
1814 dbgarg2("min=%d/%d, max=%d/%d, step=%d/%d\n",
1815 p->stepwise.min.numerator,
1816 p->stepwise.min.denominator,
1817 p->stepwise.max.numerator,
1818 p->stepwise.max.denominator,
1819 p->stepwise.step.numerator,
1820 p->stepwise.step.denominator);
1821 break;
1822 case V4L2_FRMIVAL_TYPE_CONTINUOUS:
1823 dbgarg2("continuous\n");
1824 break;
1825 default:
1826 dbgarg2("- Unknown type!\n");
1828 break;
1830 case VIDIOC_ENUM_DV_PRESETS:
1832 struct v4l2_dv_enum_preset *p = arg;
1834 if (!ops->vidioc_enum_dv_presets)
1835 break;
1837 ret = ops->vidioc_enum_dv_presets(file, fh, p);
1838 if (!ret)
1839 dbgarg(cmd,
1840 "index=%d, preset=%d, name=%s, width=%d,"
1841 " height=%d ",
1842 p->index, p->preset, p->name, p->width,
1843 p->height);
1844 break;
1846 case VIDIOC_S_DV_PRESET:
1848 struct v4l2_dv_preset *p = arg;
1850 if (!ops->vidioc_s_dv_preset)
1851 break;
1853 dbgarg(cmd, "preset=%d\n", p->preset);
1854 ret = ops->vidioc_s_dv_preset(file, fh, p);
1855 break;
1857 case VIDIOC_G_DV_PRESET:
1859 struct v4l2_dv_preset *p = arg;
1861 if (!ops->vidioc_g_dv_preset)
1862 break;
1864 ret = ops->vidioc_g_dv_preset(file, fh, p);
1865 if (!ret)
1866 dbgarg(cmd, "preset=%d\n", p->preset);
1867 break;
1869 case VIDIOC_QUERY_DV_PRESET:
1871 struct v4l2_dv_preset *p = arg;
1873 if (!ops->vidioc_query_dv_preset)
1874 break;
1876 ret = ops->vidioc_query_dv_preset(file, fh, p);
1877 if (!ret)
1878 dbgarg(cmd, "preset=%d\n", p->preset);
1879 break;
1881 case VIDIOC_S_DV_TIMINGS:
1883 struct v4l2_dv_timings *p = arg;
1885 if (!ops->vidioc_s_dv_timings)
1886 break;
1888 switch (p->type) {
1889 case V4L2_DV_BT_656_1120:
1890 dbgarg2("bt-656/1120:interlaced=%d, pixelclock=%lld,"
1891 " width=%d, height=%d, polarities=%x,"
1892 " hfrontporch=%d, hsync=%d, hbackporch=%d,"
1893 " vfrontporch=%d, vsync=%d, vbackporch=%d,"
1894 " il_vfrontporch=%d, il_vsync=%d,"
1895 " il_vbackporch=%d\n",
1896 p->bt.interlaced, p->bt.pixelclock,
1897 p->bt.width, p->bt.height, p->bt.polarities,
1898 p->bt.hfrontporch, p->bt.hsync,
1899 p->bt.hbackporch, p->bt.vfrontporch,
1900 p->bt.vsync, p->bt.vbackporch,
1901 p->bt.il_vfrontporch, p->bt.il_vsync,
1902 p->bt.il_vbackporch);
1903 ret = ops->vidioc_s_dv_timings(file, fh, p);
1904 break;
1905 default:
1906 dbgarg2("Unknown type %d!\n", p->type);
1907 break;
1909 break;
1911 case VIDIOC_G_DV_TIMINGS:
1913 struct v4l2_dv_timings *p = arg;
1915 if (!ops->vidioc_g_dv_timings)
1916 break;
1918 ret = ops->vidioc_g_dv_timings(file, fh, p);
1919 if (!ret) {
1920 switch (p->type) {
1921 case V4L2_DV_BT_656_1120:
1922 dbgarg2("bt-656/1120:interlaced=%d,"
1923 " pixelclock=%lld,"
1924 " width=%d, height=%d, polarities=%x,"
1925 " hfrontporch=%d, hsync=%d,"
1926 " hbackporch=%d, vfrontporch=%d,"
1927 " vsync=%d, vbackporch=%d,"
1928 " il_vfrontporch=%d, il_vsync=%d,"
1929 " il_vbackporch=%d\n",
1930 p->bt.interlaced, p->bt.pixelclock,
1931 p->bt.width, p->bt.height,
1932 p->bt.polarities, p->bt.hfrontporch,
1933 p->bt.hsync, p->bt.hbackporch,
1934 p->bt.vfrontporch, p->bt.vsync,
1935 p->bt.vbackporch, p->bt.il_vfrontporch,
1936 p->bt.il_vsync, p->bt.il_vbackporch);
1937 break;
1938 default:
1939 dbgarg2("Unknown type %d!\n", p->type);
1940 break;
1943 break;
1946 default:
1948 if (!ops->vidioc_default)
1949 break;
1950 ret = ops->vidioc_default(file, fh, cmd, arg);
1951 break;
1953 } /* switch */
1955 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1956 if (ret < 0) {
1957 v4l_print_ioctl(vfd->name, cmd);
1958 printk(KERN_CONT " error %ld\n", ret);
1962 return ret;
1965 /* In some cases, only a few fields are used as input, i.e. when the app sets
1966 * "index" and then the driver fills in the rest of the structure for the thing
1967 * with that index. We only need to copy up the first non-input field. */
1968 static unsigned long cmd_input_size(unsigned int cmd)
1970 /* Size of structure up to and including 'field' */
1971 #define CMDINSIZE(cmd, type, field) \
1972 case VIDIOC_##cmd: \
1973 return offsetof(struct v4l2_##type, field) + \
1974 sizeof(((struct v4l2_##type *)0)->field);
1976 switch (cmd) {
1977 CMDINSIZE(ENUM_FMT, fmtdesc, type);
1978 CMDINSIZE(G_FMT, format, type);
1979 CMDINSIZE(QUERYBUF, buffer, type);
1980 CMDINSIZE(G_PARM, streamparm, type);
1981 CMDINSIZE(ENUMSTD, standard, index);
1982 CMDINSIZE(ENUMINPUT, input, index);
1983 CMDINSIZE(G_CTRL, control, id);
1984 CMDINSIZE(G_TUNER, tuner, index);
1985 CMDINSIZE(QUERYCTRL, queryctrl, id);
1986 CMDINSIZE(QUERYMENU, querymenu, index);
1987 CMDINSIZE(ENUMOUTPUT, output, index);
1988 CMDINSIZE(G_MODULATOR, modulator, index);
1989 CMDINSIZE(G_FREQUENCY, frequency, tuner);
1990 CMDINSIZE(CROPCAP, cropcap, type);
1991 CMDINSIZE(G_CROP, crop, type);
1992 CMDINSIZE(ENUMAUDIO, audio, index);
1993 CMDINSIZE(ENUMAUDOUT, audioout, index);
1994 CMDINSIZE(ENCODER_CMD, encoder_cmd, flags);
1995 CMDINSIZE(TRY_ENCODER_CMD, encoder_cmd, flags);
1996 CMDINSIZE(G_SLICED_VBI_CAP, sliced_vbi_cap, type);
1997 CMDINSIZE(ENUM_FRAMESIZES, frmsizeenum, pixel_format);
1998 CMDINSIZE(ENUM_FRAMEINTERVALS, frmivalenum, height);
1999 default:
2000 return _IOC_SIZE(cmd);
2004 long video_ioctl2(struct file *file,
2005 unsigned int cmd, unsigned long arg)
2007 char sbuf[128];
2008 void *mbuf = NULL;
2009 void *parg = (void *)arg;
2010 long err = -EINVAL;
2011 int is_ext_ctrl;
2012 size_t ctrls_size = 0;
2013 void __user *user_ptr = NULL;
2015 #ifdef __OLD_VIDIOC_
2016 cmd = video_fix_command(cmd);
2017 #endif
2018 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
2019 cmd == VIDIOC_TRY_EXT_CTRLS);
2021 /* Copy arguments into temp kernel buffer */
2022 if (_IOC_DIR(cmd) != _IOC_NONE) {
2023 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
2024 parg = sbuf;
2025 } else {
2026 /* too big to allocate from stack */
2027 mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
2028 if (NULL == mbuf)
2029 return -ENOMEM;
2030 parg = mbuf;
2033 err = -EFAULT;
2034 if (_IOC_DIR(cmd) & _IOC_WRITE) {
2035 unsigned long n = cmd_input_size(cmd);
2037 if (copy_from_user(parg, (void __user *)arg, n))
2038 goto out;
2040 /* zero out anything we don't copy from userspace */
2041 if (n < _IOC_SIZE(cmd))
2042 memset((u8 *)parg + n, 0, _IOC_SIZE(cmd) - n);
2043 } else {
2044 /* read-only ioctl */
2045 memset(parg, 0, _IOC_SIZE(cmd));
2049 if (is_ext_ctrl) {
2050 struct v4l2_ext_controls *p = parg;
2052 /* In case of an error, tell the caller that it wasn't
2053 a specific control that caused it. */
2054 p->error_idx = p->count;
2055 user_ptr = (void __user *)p->controls;
2056 if (p->count) {
2057 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
2058 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
2059 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
2060 err = -ENOMEM;
2061 if (NULL == mbuf)
2062 goto out_ext_ctrl;
2063 err = -EFAULT;
2064 if (copy_from_user(mbuf, user_ptr, ctrls_size))
2065 goto out_ext_ctrl;
2066 p->controls = mbuf;
2070 /* Handles IOCTL */
2071 err = __video_do_ioctl(file, cmd, parg);
2072 if (err == -ENOIOCTLCMD)
2073 err = -EINVAL;
2074 if (is_ext_ctrl) {
2075 struct v4l2_ext_controls *p = parg;
2077 p->controls = (void *)user_ptr;
2078 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
2079 err = -EFAULT;
2080 goto out_ext_ctrl;
2082 if (err < 0)
2083 goto out;
2085 out_ext_ctrl:
2086 /* Copy results into user buffer */
2087 switch (_IOC_DIR(cmd)) {
2088 case _IOC_READ:
2089 case (_IOC_WRITE | _IOC_READ):
2090 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
2091 err = -EFAULT;
2092 break;
2095 out:
2096 kfree(mbuf);
2097 return err;
2099 EXPORT_SYMBOL(video_ioctl2);