powerpc: use consistent types in mktree
[zen-stable.git] / drivers / media / video / v4l2-ioctl.c
blobf2afc4e08379a1cee0c77201190dd698db576fbb
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 /* Zero out the end of the struct pointed to by p. Everthing after, but
46 * not including, the specified field is cleared. */
47 #define CLEAR_AFTER_FIELD(p, field) \
48 memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \
49 0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field))
51 struct std_descr {
52 v4l2_std_id std;
53 const char *descr;
56 static const struct std_descr standards[] = {
57 { V4L2_STD_NTSC, "NTSC" },
58 { V4L2_STD_NTSC_M, "NTSC-M" },
59 { V4L2_STD_NTSC_M_JP, "NTSC-M-JP" },
60 { V4L2_STD_NTSC_M_KR, "NTSC-M-KR" },
61 { V4L2_STD_NTSC_443, "NTSC-443" },
62 { V4L2_STD_PAL, "PAL" },
63 { V4L2_STD_PAL_BG, "PAL-BG" },
64 { V4L2_STD_PAL_B, "PAL-B" },
65 { V4L2_STD_PAL_B1, "PAL-B1" },
66 { V4L2_STD_PAL_G, "PAL-G" },
67 { V4L2_STD_PAL_H, "PAL-H" },
68 { V4L2_STD_PAL_I, "PAL-I" },
69 { V4L2_STD_PAL_DK, "PAL-DK" },
70 { V4L2_STD_PAL_D, "PAL-D" },
71 { V4L2_STD_PAL_D1, "PAL-D1" },
72 { V4L2_STD_PAL_K, "PAL-K" },
73 { V4L2_STD_PAL_M, "PAL-M" },
74 { V4L2_STD_PAL_N, "PAL-N" },
75 { V4L2_STD_PAL_Nc, "PAL-Nc" },
76 { V4L2_STD_PAL_60, "PAL-60" },
77 { V4L2_STD_SECAM, "SECAM" },
78 { V4L2_STD_SECAM_B, "SECAM-B" },
79 { V4L2_STD_SECAM_G, "SECAM-G" },
80 { V4L2_STD_SECAM_H, "SECAM-H" },
81 { V4L2_STD_SECAM_DK, "SECAM-DK" },
82 { V4L2_STD_SECAM_D, "SECAM-D" },
83 { V4L2_STD_SECAM_K, "SECAM-K" },
84 { V4L2_STD_SECAM_K1, "SECAM-K1" },
85 { V4L2_STD_SECAM_L, "SECAM-L" },
86 { V4L2_STD_SECAM_LC, "SECAM-Lc" },
87 { 0, "Unknown" }
90 /* video4linux standard ID conversion to standard name
92 const char *v4l2_norm_to_name(v4l2_std_id id)
94 u32 myid = id;
95 int i;
97 /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
98 64 bit comparations. So, on that architecture, with some gcc
99 variants, compilation fails. Currently, the max value is 30bit wide.
101 BUG_ON(myid != id);
103 for (i = 0; standards[i].std; i++)
104 if (myid == standards[i].std)
105 break;
106 return standards[i].descr;
108 EXPORT_SYMBOL(v4l2_norm_to_name);
110 /* Returns frame period for the given standard */
111 void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod)
113 if (id & V4L2_STD_525_60) {
114 frameperiod->numerator = 1001;
115 frameperiod->denominator = 30000;
116 } else {
117 frameperiod->numerator = 1;
118 frameperiod->denominator = 25;
121 EXPORT_SYMBOL(v4l2_video_std_frame_period);
123 /* Fill in the fields of a v4l2_standard structure according to the
124 'id' and 'transmission' parameters. Returns negative on error. */
125 int v4l2_video_std_construct(struct v4l2_standard *vs,
126 int id, const char *name)
128 vs->id = id;
129 v4l2_video_std_frame_period(id, &vs->frameperiod);
130 vs->framelines = (id & V4L2_STD_525_60) ? 525 : 625;
131 strlcpy(vs->name, name, sizeof(vs->name));
132 return 0;
134 EXPORT_SYMBOL(v4l2_video_std_construct);
136 /* ----------------------------------------------------------------- */
137 /* some arrays for pretty-printing debug messages of enum types */
139 const char *v4l2_field_names[] = {
140 [V4L2_FIELD_ANY] = "any",
141 [V4L2_FIELD_NONE] = "none",
142 [V4L2_FIELD_TOP] = "top",
143 [V4L2_FIELD_BOTTOM] = "bottom",
144 [V4L2_FIELD_INTERLACED] = "interlaced",
145 [V4L2_FIELD_SEQ_TB] = "seq-tb",
146 [V4L2_FIELD_SEQ_BT] = "seq-bt",
147 [V4L2_FIELD_ALTERNATE] = "alternate",
148 [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
149 [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
151 EXPORT_SYMBOL(v4l2_field_names);
153 const char *v4l2_type_names[] = {
154 [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "vid-cap",
155 [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "vid-overlay",
156 [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "vid-out",
157 [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
158 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
159 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
160 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
161 [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay",
163 EXPORT_SYMBOL(v4l2_type_names);
165 static const char *v4l2_memory_names[] = {
166 [V4L2_MEMORY_MMAP] = "mmap",
167 [V4L2_MEMORY_USERPTR] = "userptr",
168 [V4L2_MEMORY_OVERLAY] = "overlay",
171 #define prt_names(a, arr) ((((a) >= 0) && ((a) < ARRAY_SIZE(arr))) ? \
172 arr[a] : "unknown")
174 /* ------------------------------------------------------------------ */
175 /* debug help functions */
177 #ifdef CONFIG_VIDEO_V4L1_COMPAT
178 static const char *v4l1_ioctls[] = {
179 [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP",
180 [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN",
181 [_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN",
182 [_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER",
183 [_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER",
184 [_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT",
185 [_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT",
186 [_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE",
187 [_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN",
188 [_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN",
189 [_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF",
190 [_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF",
191 [_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY",
192 [_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ",
193 [_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ",
194 [_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO",
195 [_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO",
196 [_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC",
197 [_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE",
198 [_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF",
199 [_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT",
200 [_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE",
201 [_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE",
202 [_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE",
203 [_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE",
204 [_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO",
205 [_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE",
206 [_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT",
207 [_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT"
209 #define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
210 #endif
212 static const char *v4l2_ioctls[] = {
213 [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP",
214 [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED",
215 [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT",
216 [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT",
217 [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT",
218 [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS",
219 [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF",
220 [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF",
221 [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF",
222 [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY",
223 [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF",
224 [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF",
225 [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON",
226 [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF",
227 [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM",
228 [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM",
229 [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD",
230 [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD",
231 [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD",
232 [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT",
233 [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL",
234 [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL",
235 [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER",
236 [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER",
237 [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO",
238 [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO",
239 [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL",
240 [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU",
241 [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT",
242 [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT",
243 [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT",
244 [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT",
245 [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT",
246 [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT",
247 [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT",
248 [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR",
249 [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR",
250 [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY",
251 [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY",
252 [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP",
253 [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP",
254 [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP",
255 [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP",
256 [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP",
257 [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD",
258 [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT",
259 [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO",
260 [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT",
261 [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY",
262 [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY",
263 [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
264 [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS",
265 [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS",
266 [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS",
267 [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS",
268 #if 1
269 [_IOC_NR(VIDIOC_ENUM_FRAMESIZES)] = "VIDIOC_ENUM_FRAMESIZES",
270 [_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS",
271 [_IOC_NR(VIDIOC_G_ENC_INDEX)] = "VIDIOC_G_ENC_INDEX",
272 [_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD",
273 [_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD",
275 [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER",
276 [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER",
278 [_IOC_NR(VIDIOC_DBG_G_CHIP_IDENT)] = "VIDIOC_DBG_G_CHIP_IDENT",
279 [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK",
280 #endif
282 #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
284 /* Common ioctl debug function. This function can be used by
285 external ioctl messages as well as internal V4L ioctl */
286 void v4l_printk_ioctl(unsigned int cmd)
288 char *dir, *type;
290 switch (_IOC_TYPE(cmd)) {
291 case 'd':
292 type = "v4l2_int";
293 break;
294 #ifdef CONFIG_VIDEO_V4L1_COMPAT
295 case 'v':
296 if (_IOC_NR(cmd) >= V4L1_IOCTLS) {
297 type = "v4l1";
298 break;
300 printk("%s", v4l1_ioctls[_IOC_NR(cmd)]);
301 return;
302 #endif
303 case 'V':
304 if (_IOC_NR(cmd) >= V4L2_IOCTLS) {
305 type = "v4l2";
306 break;
308 printk("%s", v4l2_ioctls[_IOC_NR(cmd)]);
309 return;
310 default:
311 type = "unknown";
314 switch (_IOC_DIR(cmd)) {
315 case _IOC_NONE: dir = "--"; break;
316 case _IOC_READ: dir = "r-"; break;
317 case _IOC_WRITE: dir = "-w"; break;
318 case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
319 default: dir = "*ERR*"; break;
321 printk("%s ioctl '%c', dir=%s, #%d (0x%08x)",
322 type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
324 EXPORT_SYMBOL(v4l_printk_ioctl);
327 * helper function -- handles userspace copying for ioctl arguments
330 #ifdef __OLD_VIDIOC_
331 static unsigned int
332 video_fix_command(unsigned int cmd)
334 switch (cmd) {
335 case VIDIOC_OVERLAY_OLD:
336 cmd = VIDIOC_OVERLAY;
337 break;
338 case VIDIOC_S_PARM_OLD:
339 cmd = VIDIOC_S_PARM;
340 break;
341 case VIDIOC_S_CTRL_OLD:
342 cmd = VIDIOC_S_CTRL;
343 break;
344 case VIDIOC_G_AUDIO_OLD:
345 cmd = VIDIOC_G_AUDIO;
346 break;
347 case VIDIOC_G_AUDOUT_OLD:
348 cmd = VIDIOC_G_AUDOUT;
349 break;
350 case VIDIOC_CROPCAP_OLD:
351 cmd = VIDIOC_CROPCAP;
352 break;
354 return cmd;
356 #endif
359 * Obsolete usercopy function - Should be removed soon
361 long
362 video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
363 v4l2_kioctl func)
365 char sbuf[128];
366 void *mbuf = NULL;
367 void *parg = NULL;
368 long err = -EINVAL;
369 int is_ext_ctrl;
370 size_t ctrls_size = 0;
371 void __user *user_ptr = NULL;
373 #ifdef __OLD_VIDIOC_
374 cmd = video_fix_command(cmd);
375 #endif
376 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
377 cmd == VIDIOC_TRY_EXT_CTRLS);
379 /* Copy arguments into temp kernel buffer */
380 switch (_IOC_DIR(cmd)) {
381 case _IOC_NONE:
382 parg = NULL;
383 break;
384 case _IOC_READ:
385 case _IOC_WRITE:
386 case (_IOC_WRITE | _IOC_READ):
387 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
388 parg = sbuf;
389 } else {
390 /* too big to allocate from stack */
391 mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
392 if (NULL == mbuf)
393 return -ENOMEM;
394 parg = mbuf;
397 err = -EFAULT;
398 if (_IOC_DIR(cmd) & _IOC_WRITE)
399 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
400 goto out;
401 break;
403 if (is_ext_ctrl) {
404 struct v4l2_ext_controls *p = parg;
406 /* In case of an error, tell the caller that it wasn't
407 a specific control that caused it. */
408 p->error_idx = p->count;
409 user_ptr = (void __user *)p->controls;
410 if (p->count) {
411 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
412 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
413 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
414 err = -ENOMEM;
415 if (NULL == mbuf)
416 goto out_ext_ctrl;
417 err = -EFAULT;
418 if (copy_from_user(mbuf, user_ptr, ctrls_size))
419 goto out_ext_ctrl;
420 p->controls = mbuf;
424 /* call driver */
425 err = func(file, cmd, parg);
426 if (err == -ENOIOCTLCMD)
427 err = -EINVAL;
428 if (is_ext_ctrl) {
429 struct v4l2_ext_controls *p = parg;
431 p->controls = (void *)user_ptr;
432 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
433 err = -EFAULT;
434 goto out_ext_ctrl;
436 if (err < 0)
437 goto out;
439 out_ext_ctrl:
440 /* Copy results into user buffer */
441 switch (_IOC_DIR(cmd)) {
442 case _IOC_READ:
443 case (_IOC_WRITE | _IOC_READ):
444 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
445 err = -EFAULT;
446 break;
449 out:
450 kfree(mbuf);
451 return err;
453 EXPORT_SYMBOL(video_usercopy);
455 static void dbgbuf(unsigned int cmd, struct video_device *vfd,
456 struct v4l2_buffer *p)
458 struct v4l2_timecode *tc = &p->timecode;
460 dbgarg(cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
461 "bytesused=%d, flags=0x%08d, "
462 "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n",
463 p->timestamp.tv_sec / 3600,
464 (int)(p->timestamp.tv_sec / 60) % 60,
465 (int)(p->timestamp.tv_sec % 60),
466 (long)p->timestamp.tv_usec,
467 p->index,
468 prt_names(p->type, v4l2_type_names),
469 p->bytesused, p->flags,
470 p->field, p->sequence,
471 prt_names(p->memory, v4l2_memory_names),
472 p->m.userptr, p->length);
473 dbgarg2("timecode=%02d:%02d:%02d type=%d, "
474 "flags=0x%08d, frames=%d, userbits=0x%08x\n",
475 tc->hours, tc->minutes, tc->seconds,
476 tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits);
479 static inline void dbgrect(struct video_device *vfd, char *s,
480 struct v4l2_rect *r)
482 dbgarg2("%sRect start at %dx%d, size=%dx%d\n", s, r->left, r->top,
483 r->width, r->height);
486 static inline void v4l_print_pix_fmt(struct video_device *vfd,
487 struct v4l2_pix_format *fmt)
489 dbgarg2("width=%d, height=%d, format=%c%c%c%c, field=%s, "
490 "bytesperline=%d sizeimage=%d, colorspace=%d\n",
491 fmt->width, fmt->height,
492 (fmt->pixelformat & 0xff),
493 (fmt->pixelformat >> 8) & 0xff,
494 (fmt->pixelformat >> 16) & 0xff,
495 (fmt->pixelformat >> 24) & 0xff,
496 prt_names(fmt->field, v4l2_field_names),
497 fmt->bytesperline, fmt->sizeimage, fmt->colorspace);
500 static inline void v4l_print_ext_ctrls(unsigned int cmd,
501 struct video_device *vfd, struct v4l2_ext_controls *c, int show_vals)
503 __u32 i;
505 if (!(vfd->debug & V4L2_DEBUG_IOCTL_ARG))
506 return;
507 dbgarg(cmd, "");
508 printk(KERN_CONT "class=0x%x", c->ctrl_class);
509 for (i = 0; i < c->count; i++) {
510 if (show_vals)
511 printk(KERN_CONT " id/val=0x%x/0x%x",
512 c->controls[i].id, c->controls[i].value);
513 else
514 printk(KERN_CONT " id=0x%x", c->controls[i].id);
516 printk(KERN_CONT "\n");
519 static inline int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)
521 __u32 i;
523 /* zero the reserved fields */
524 c->reserved[0] = c->reserved[1] = 0;
525 for (i = 0; i < c->count; i++) {
526 c->controls[i].reserved2[0] = 0;
527 c->controls[i].reserved2[1] = 0;
529 /* V4L2_CID_PRIVATE_BASE cannot be used as control class
530 when using extended controls.
531 Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
532 is it allowed for backwards compatibility.
534 if (!allow_priv && c->ctrl_class == V4L2_CID_PRIVATE_BASE)
535 return 0;
536 /* Check that all controls are from the same control class. */
537 for (i = 0; i < c->count; i++) {
538 if (V4L2_CTRL_ID2CLASS(c->controls[i].id) != c->ctrl_class) {
539 c->error_idx = i;
540 return 0;
543 return 1;
546 static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type)
548 if (ops == NULL)
549 return -EINVAL;
551 switch (type) {
552 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
553 if (ops->vidioc_g_fmt_vid_cap)
554 return 0;
555 break;
556 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
557 if (ops->vidioc_g_fmt_vid_overlay)
558 return 0;
559 break;
560 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
561 if (ops->vidioc_g_fmt_vid_out)
562 return 0;
563 break;
564 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
565 if (ops->vidioc_g_fmt_vid_out_overlay)
566 return 0;
567 break;
568 case V4L2_BUF_TYPE_VBI_CAPTURE:
569 if (ops->vidioc_g_fmt_vbi_cap)
570 return 0;
571 break;
572 case V4L2_BUF_TYPE_VBI_OUTPUT:
573 if (ops->vidioc_g_fmt_vbi_out)
574 return 0;
575 break;
576 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
577 if (ops->vidioc_g_fmt_sliced_vbi_cap)
578 return 0;
579 break;
580 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
581 if (ops->vidioc_g_fmt_sliced_vbi_out)
582 return 0;
583 break;
584 case V4L2_BUF_TYPE_PRIVATE:
585 if (ops->vidioc_g_fmt_type_private)
586 return 0;
587 break;
589 return -EINVAL;
592 static long __video_do_ioctl(struct file *file,
593 unsigned int cmd, void *arg)
595 struct video_device *vfd = video_devdata(file);
596 const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
597 void *fh = file->private_data;
598 long ret = -EINVAL;
600 if ((vfd->debug & V4L2_DEBUG_IOCTL) &&
601 !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) {
602 v4l_print_ioctl(vfd->name, cmd);
603 printk(KERN_CONT "\n");
606 if (ops == NULL) {
607 printk(KERN_WARNING "videodev: \"%s\" has no ioctl_ops.\n",
608 vfd->name);
609 return -EINVAL;
612 #ifdef CONFIG_VIDEO_V4L1_COMPAT
613 /***********************************************************
614 Handles calls to the obsoleted V4L1 API
615 Due to the nature of VIDIOCGMBUF, each driver that supports
616 V4L1 should implement its own handler for this ioctl.
617 ***********************************************************/
619 /* --- streaming capture ------------------------------------- */
620 if (cmd == VIDIOCGMBUF) {
621 struct video_mbuf *p = arg;
623 if (!ops->vidiocgmbuf)
624 return ret;
625 ret = ops->vidiocgmbuf(file, fh, p);
626 if (!ret)
627 dbgarg(cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
628 p->size, p->frames,
629 (unsigned long)p->offsets);
630 return ret;
633 /********************************************************
634 All other V4L1 calls are handled by v4l1_compat module.
635 Those calls will be translated into V4L2 calls, and
636 __video_do_ioctl will be called again, with one or more
637 V4L2 ioctls.
638 ********************************************************/
639 if (_IOC_TYPE(cmd) == 'v' && _IOC_NR(cmd) < BASE_VIDIOCPRIVATE)
640 return v4l_compat_translate_ioctl(file, cmd, arg,
641 __video_do_ioctl);
642 #endif
644 switch (cmd) {
645 /* --- capabilities ------------------------------------------ */
646 case VIDIOC_QUERYCAP:
648 struct v4l2_capability *cap = (struct v4l2_capability *)arg;
650 if (!ops->vidioc_querycap)
651 break;
653 ret = ops->vidioc_querycap(file, fh, cap);
654 if (!ret)
655 dbgarg(cmd, "driver=%s, card=%s, bus=%s, "
656 "version=0x%08x, "
657 "capabilities=0x%08x\n",
658 cap->driver, cap->card, cap->bus_info,
659 cap->version,
660 cap->capabilities);
661 break;
664 /* --- priority ------------------------------------------ */
665 case VIDIOC_G_PRIORITY:
667 enum v4l2_priority *p = arg;
669 if (!ops->vidioc_g_priority)
670 break;
671 ret = ops->vidioc_g_priority(file, fh, p);
672 if (!ret)
673 dbgarg(cmd, "priority is %d\n", *p);
674 break;
676 case VIDIOC_S_PRIORITY:
678 enum v4l2_priority *p = arg;
680 if (!ops->vidioc_s_priority)
681 break;
682 dbgarg(cmd, "setting priority to %d\n", *p);
683 ret = ops->vidioc_s_priority(file, fh, *p);
684 break;
687 /* --- capture ioctls ---------------------------------------- */
688 case VIDIOC_ENUM_FMT:
690 struct v4l2_fmtdesc *f = arg;
692 switch (f->type) {
693 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
694 if (ops->vidioc_enum_fmt_vid_cap)
695 ret = ops->vidioc_enum_fmt_vid_cap(file, fh, f);
696 break;
697 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
698 if (ops->vidioc_enum_fmt_vid_overlay)
699 ret = ops->vidioc_enum_fmt_vid_overlay(file,
700 fh, f);
701 break;
702 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
703 if (ops->vidioc_enum_fmt_vid_out)
704 ret = ops->vidioc_enum_fmt_vid_out(file, fh, f);
705 break;
706 case V4L2_BUF_TYPE_PRIVATE:
707 if (ops->vidioc_enum_fmt_type_private)
708 ret = ops->vidioc_enum_fmt_type_private(file,
709 fh, f);
710 break;
711 default:
712 break;
714 if (!ret)
715 dbgarg(cmd, "index=%d, type=%d, flags=%d, "
716 "pixelformat=%c%c%c%c, description='%s'\n",
717 f->index, f->type, f->flags,
718 (f->pixelformat & 0xff),
719 (f->pixelformat >> 8) & 0xff,
720 (f->pixelformat >> 16) & 0xff,
721 (f->pixelformat >> 24) & 0xff,
722 f->description);
723 break;
725 case VIDIOC_G_FMT:
727 struct v4l2_format *f = (struct v4l2_format *)arg;
729 /* FIXME: Should be one dump per type */
730 dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
732 switch (f->type) {
733 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
734 if (ops->vidioc_g_fmt_vid_cap)
735 ret = ops->vidioc_g_fmt_vid_cap(file, fh, f);
736 if (!ret)
737 v4l_print_pix_fmt(vfd, &f->fmt.pix);
738 break;
739 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
740 if (ops->vidioc_g_fmt_vid_overlay)
741 ret = ops->vidioc_g_fmt_vid_overlay(file,
742 fh, f);
743 break;
744 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
745 if (ops->vidioc_g_fmt_vid_out)
746 ret = ops->vidioc_g_fmt_vid_out(file, fh, f);
747 if (!ret)
748 v4l_print_pix_fmt(vfd, &f->fmt.pix);
749 break;
750 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
751 if (ops->vidioc_g_fmt_vid_out_overlay)
752 ret = ops->vidioc_g_fmt_vid_out_overlay(file,
753 fh, f);
754 break;
755 case V4L2_BUF_TYPE_VBI_CAPTURE:
756 if (ops->vidioc_g_fmt_vbi_cap)
757 ret = ops->vidioc_g_fmt_vbi_cap(file, fh, f);
758 break;
759 case V4L2_BUF_TYPE_VBI_OUTPUT:
760 if (ops->vidioc_g_fmt_vbi_out)
761 ret = ops->vidioc_g_fmt_vbi_out(file, fh, f);
762 break;
763 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
764 if (ops->vidioc_g_fmt_sliced_vbi_cap)
765 ret = ops->vidioc_g_fmt_sliced_vbi_cap(file,
766 fh, f);
767 break;
768 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
769 if (ops->vidioc_g_fmt_sliced_vbi_out)
770 ret = ops->vidioc_g_fmt_sliced_vbi_out(file,
771 fh, f);
772 break;
773 case V4L2_BUF_TYPE_PRIVATE:
774 if (ops->vidioc_g_fmt_type_private)
775 ret = ops->vidioc_g_fmt_type_private(file,
776 fh, f);
777 break;
780 break;
782 case VIDIOC_S_FMT:
784 struct v4l2_format *f = (struct v4l2_format *)arg;
786 /* FIXME: Should be one dump per type */
787 dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
789 switch (f->type) {
790 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
791 CLEAR_AFTER_FIELD(f, fmt.pix);
792 v4l_print_pix_fmt(vfd, &f->fmt.pix);
793 if (ops->vidioc_s_fmt_vid_cap)
794 ret = ops->vidioc_s_fmt_vid_cap(file, fh, f);
795 break;
796 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
797 CLEAR_AFTER_FIELD(f, fmt.win);
798 if (ops->vidioc_s_fmt_vid_overlay)
799 ret = ops->vidioc_s_fmt_vid_overlay(file,
800 fh, f);
801 break;
802 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
803 CLEAR_AFTER_FIELD(f, fmt.pix);
804 v4l_print_pix_fmt(vfd, &f->fmt.pix);
805 if (ops->vidioc_s_fmt_vid_out)
806 ret = ops->vidioc_s_fmt_vid_out(file, fh, f);
807 break;
808 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
809 CLEAR_AFTER_FIELD(f, fmt.win);
810 if (ops->vidioc_s_fmt_vid_out_overlay)
811 ret = ops->vidioc_s_fmt_vid_out_overlay(file,
812 fh, f);
813 break;
814 case V4L2_BUF_TYPE_VBI_CAPTURE:
815 CLEAR_AFTER_FIELD(f, fmt.vbi);
816 if (ops->vidioc_s_fmt_vbi_cap)
817 ret = ops->vidioc_s_fmt_vbi_cap(file, fh, f);
818 break;
819 case V4L2_BUF_TYPE_VBI_OUTPUT:
820 CLEAR_AFTER_FIELD(f, fmt.vbi);
821 if (ops->vidioc_s_fmt_vbi_out)
822 ret = ops->vidioc_s_fmt_vbi_out(file, fh, f);
823 break;
824 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
825 CLEAR_AFTER_FIELD(f, fmt.sliced);
826 if (ops->vidioc_s_fmt_sliced_vbi_cap)
827 ret = ops->vidioc_s_fmt_sliced_vbi_cap(file,
828 fh, f);
829 break;
830 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
831 CLEAR_AFTER_FIELD(f, fmt.sliced);
832 if (ops->vidioc_s_fmt_sliced_vbi_out)
833 ret = ops->vidioc_s_fmt_sliced_vbi_out(file,
834 fh, f);
835 break;
836 case V4L2_BUF_TYPE_PRIVATE:
837 /* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */
838 if (ops->vidioc_s_fmt_type_private)
839 ret = ops->vidioc_s_fmt_type_private(file,
840 fh, f);
841 break;
843 break;
845 case VIDIOC_TRY_FMT:
847 struct v4l2_format *f = (struct v4l2_format *)arg;
849 /* FIXME: Should be one dump per type */
850 dbgarg(cmd, "type=%s\n", prt_names(f->type,
851 v4l2_type_names));
852 switch (f->type) {
853 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
854 CLEAR_AFTER_FIELD(f, fmt.pix);
855 if (ops->vidioc_try_fmt_vid_cap)
856 ret = ops->vidioc_try_fmt_vid_cap(file, fh, f);
857 if (!ret)
858 v4l_print_pix_fmt(vfd, &f->fmt.pix);
859 break;
860 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
861 CLEAR_AFTER_FIELD(f, fmt.win);
862 if (ops->vidioc_try_fmt_vid_overlay)
863 ret = ops->vidioc_try_fmt_vid_overlay(file,
864 fh, f);
865 break;
866 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
867 CLEAR_AFTER_FIELD(f, fmt.pix);
868 if (ops->vidioc_try_fmt_vid_out)
869 ret = ops->vidioc_try_fmt_vid_out(file, fh, f);
870 if (!ret)
871 v4l_print_pix_fmt(vfd, &f->fmt.pix);
872 break;
873 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
874 CLEAR_AFTER_FIELD(f, fmt.win);
875 if (ops->vidioc_try_fmt_vid_out_overlay)
876 ret = ops->vidioc_try_fmt_vid_out_overlay(file,
877 fh, f);
878 break;
879 case V4L2_BUF_TYPE_VBI_CAPTURE:
880 CLEAR_AFTER_FIELD(f, fmt.vbi);
881 if (ops->vidioc_try_fmt_vbi_cap)
882 ret = ops->vidioc_try_fmt_vbi_cap(file, fh, f);
883 break;
884 case V4L2_BUF_TYPE_VBI_OUTPUT:
885 CLEAR_AFTER_FIELD(f, fmt.vbi);
886 if (ops->vidioc_try_fmt_vbi_out)
887 ret = ops->vidioc_try_fmt_vbi_out(file, fh, f);
888 break;
889 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
890 CLEAR_AFTER_FIELD(f, fmt.sliced);
891 if (ops->vidioc_try_fmt_sliced_vbi_cap)
892 ret = ops->vidioc_try_fmt_sliced_vbi_cap(file,
893 fh, f);
894 break;
895 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
896 CLEAR_AFTER_FIELD(f, fmt.sliced);
897 if (ops->vidioc_try_fmt_sliced_vbi_out)
898 ret = ops->vidioc_try_fmt_sliced_vbi_out(file,
899 fh, f);
900 break;
901 case V4L2_BUF_TYPE_PRIVATE:
902 /* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */
903 if (ops->vidioc_try_fmt_type_private)
904 ret = ops->vidioc_try_fmt_type_private(file,
905 fh, f);
906 break;
909 break;
911 /* FIXME: Those buf reqs could be handled here,
912 with some changes on videobuf to allow its header to be included at
913 videodev2.h or being merged at videodev2.
915 case VIDIOC_REQBUFS:
917 struct v4l2_requestbuffers *p = arg;
919 if (!ops->vidioc_reqbufs)
920 break;
921 ret = check_fmt(ops, p->type);
922 if (ret)
923 break;
925 if (p->type < V4L2_BUF_TYPE_PRIVATE)
926 CLEAR_AFTER_FIELD(p, memory);
928 ret = ops->vidioc_reqbufs(file, fh, p);
929 dbgarg(cmd, "count=%d, type=%s, memory=%s\n",
930 p->count,
931 prt_names(p->type, v4l2_type_names),
932 prt_names(p->memory, v4l2_memory_names));
933 break;
935 case VIDIOC_QUERYBUF:
937 struct v4l2_buffer *p = arg;
939 if (!ops->vidioc_querybuf)
940 break;
941 ret = check_fmt(ops, p->type);
942 if (ret)
943 break;
945 ret = ops->vidioc_querybuf(file, fh, p);
946 if (!ret)
947 dbgbuf(cmd, vfd, p);
948 break;
950 case VIDIOC_QBUF:
952 struct v4l2_buffer *p = arg;
954 if (!ops->vidioc_qbuf)
955 break;
956 ret = check_fmt(ops, p->type);
957 if (ret)
958 break;
960 ret = ops->vidioc_qbuf(file, fh, p);
961 if (!ret)
962 dbgbuf(cmd, vfd, p);
963 break;
965 case VIDIOC_DQBUF:
967 struct v4l2_buffer *p = arg;
969 if (!ops->vidioc_dqbuf)
970 break;
971 ret = check_fmt(ops, p->type);
972 if (ret)
973 break;
975 ret = ops->vidioc_dqbuf(file, fh, p);
976 if (!ret)
977 dbgbuf(cmd, vfd, p);
978 break;
980 case VIDIOC_OVERLAY:
982 int *i = arg;
984 if (!ops->vidioc_overlay)
985 break;
986 dbgarg(cmd, "value=%d\n", *i);
987 ret = ops->vidioc_overlay(file, fh, *i);
988 break;
990 case VIDIOC_G_FBUF:
992 struct v4l2_framebuffer *p = arg;
994 if (!ops->vidioc_g_fbuf)
995 break;
996 ret = ops->vidioc_g_fbuf(file, fh, arg);
997 if (!ret) {
998 dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
999 p->capability, p->flags,
1000 (unsigned long)p->base);
1001 v4l_print_pix_fmt(vfd, &p->fmt);
1003 break;
1005 case VIDIOC_S_FBUF:
1007 struct v4l2_framebuffer *p = arg;
1009 if (!ops->vidioc_s_fbuf)
1010 break;
1011 dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
1012 p->capability, p->flags, (unsigned long)p->base);
1013 v4l_print_pix_fmt(vfd, &p->fmt);
1014 ret = ops->vidioc_s_fbuf(file, fh, arg);
1015 break;
1017 case VIDIOC_STREAMON:
1019 enum v4l2_buf_type i = *(int *)arg;
1021 if (!ops->vidioc_streamon)
1022 break;
1023 dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
1024 ret = ops->vidioc_streamon(file, fh, i);
1025 break;
1027 case VIDIOC_STREAMOFF:
1029 enum v4l2_buf_type i = *(int *)arg;
1031 if (!ops->vidioc_streamoff)
1032 break;
1033 dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
1034 ret = ops->vidioc_streamoff(file, fh, i);
1035 break;
1037 /* ---------- tv norms ---------- */
1038 case VIDIOC_ENUMSTD:
1040 struct v4l2_standard *p = arg;
1041 v4l2_std_id id = vfd->tvnorms, curr_id = 0;
1042 unsigned int index = p->index, i, j = 0;
1043 const char *descr = "";
1045 /* Return norm array in a canonical way */
1046 for (i = 0; i <= index && id; i++) {
1047 /* last std value in the standards array is 0, so this
1048 while always ends there since (id & 0) == 0. */
1049 while ((id & standards[j].std) != standards[j].std)
1050 j++;
1051 curr_id = standards[j].std;
1052 descr = standards[j].descr;
1053 j++;
1054 if (curr_id == 0)
1055 break;
1056 if (curr_id != V4L2_STD_PAL &&
1057 curr_id != V4L2_STD_SECAM &&
1058 curr_id != V4L2_STD_NTSC)
1059 id &= ~curr_id;
1061 if (i <= index)
1062 return -EINVAL;
1064 v4l2_video_std_construct(p, curr_id, descr);
1066 dbgarg(cmd, "index=%d, id=0x%Lx, name=%s, fps=%d/%d, "
1067 "framelines=%d\n", p->index,
1068 (unsigned long long)p->id, p->name,
1069 p->frameperiod.numerator,
1070 p->frameperiod.denominator,
1071 p->framelines);
1073 ret = 0;
1074 break;
1076 case VIDIOC_G_STD:
1078 v4l2_std_id *id = arg;
1080 ret = 0;
1081 /* Calls the specific handler */
1082 if (ops->vidioc_g_std)
1083 ret = ops->vidioc_g_std(file, fh, id);
1084 else if (vfd->current_norm)
1085 *id = vfd->current_norm;
1086 else
1087 ret = -EINVAL;
1089 if (!ret)
1090 dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id);
1091 break;
1093 case VIDIOC_S_STD:
1095 v4l2_std_id *id = arg, norm;
1097 dbgarg(cmd, "std=%08Lx\n", (long long unsigned)*id);
1099 norm = (*id) & vfd->tvnorms;
1100 if (vfd->tvnorms && !norm) /* Check if std is supported */
1101 break;
1103 /* Calls the specific handler */
1104 if (ops->vidioc_s_std)
1105 ret = ops->vidioc_s_std(file, fh, &norm);
1106 else
1107 ret = -EINVAL;
1109 /* Updates standard information */
1110 if (ret >= 0)
1111 vfd->current_norm = norm;
1112 break;
1114 case VIDIOC_QUERYSTD:
1116 v4l2_std_id *p = arg;
1118 if (!ops->vidioc_querystd)
1119 break;
1120 ret = ops->vidioc_querystd(file, fh, arg);
1121 if (!ret)
1122 dbgarg(cmd, "detected std=%08Lx\n",
1123 (unsigned long long)*p);
1124 break;
1126 /* ------ input switching ---------- */
1127 /* FIXME: Inputs can be handled inside videodev2 */
1128 case VIDIOC_ENUMINPUT:
1130 struct v4l2_input *p = arg;
1132 if (!ops->vidioc_enum_input)
1133 break;
1135 ret = ops->vidioc_enum_input(file, fh, p);
1136 if (!ret)
1137 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1138 "audioset=%d, "
1139 "tuner=%d, std=%08Lx, status=%d\n",
1140 p->index, p->name, p->type, p->audioset,
1141 p->tuner,
1142 (unsigned long long)p->std,
1143 p->status);
1144 break;
1146 case VIDIOC_G_INPUT:
1148 unsigned int *i = arg;
1150 if (!ops->vidioc_g_input)
1151 break;
1152 ret = ops->vidioc_g_input(file, fh, i);
1153 if (!ret)
1154 dbgarg(cmd, "value=%d\n", *i);
1155 break;
1157 case VIDIOC_S_INPUT:
1159 unsigned int *i = arg;
1161 if (!ops->vidioc_s_input)
1162 break;
1163 dbgarg(cmd, "value=%d\n", *i);
1164 ret = ops->vidioc_s_input(file, fh, *i);
1165 break;
1168 /* ------ output switching ---------- */
1169 case VIDIOC_ENUMOUTPUT:
1171 struct v4l2_output *p = arg;
1173 if (!ops->vidioc_enum_output)
1174 break;
1176 ret = ops->vidioc_enum_output(file, fh, p);
1177 if (!ret)
1178 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1179 "audioset=0x%x, "
1180 "modulator=%d, std=0x%08Lx\n",
1181 p->index, p->name, p->type, p->audioset,
1182 p->modulator, (unsigned long long)p->std);
1183 break;
1185 case VIDIOC_G_OUTPUT:
1187 unsigned int *i = arg;
1189 if (!ops->vidioc_g_output)
1190 break;
1191 ret = ops->vidioc_g_output(file, fh, i);
1192 if (!ret)
1193 dbgarg(cmd, "value=%d\n", *i);
1194 break;
1196 case VIDIOC_S_OUTPUT:
1198 unsigned int *i = arg;
1200 if (!ops->vidioc_s_output)
1201 break;
1202 dbgarg(cmd, "value=%d\n", *i);
1203 ret = ops->vidioc_s_output(file, fh, *i);
1204 break;
1207 /* --- controls ---------------------------------------------- */
1208 case VIDIOC_QUERYCTRL:
1210 struct v4l2_queryctrl *p = arg;
1212 if (!ops->vidioc_queryctrl)
1213 break;
1214 ret = ops->vidioc_queryctrl(file, fh, p);
1215 if (!ret)
1216 dbgarg(cmd, "id=0x%x, type=%d, name=%s, min/max=%d/%d, "
1217 "step=%d, default=%d, flags=0x%08x\n",
1218 p->id, p->type, p->name,
1219 p->minimum, p->maximum,
1220 p->step, p->default_value, p->flags);
1221 else
1222 dbgarg(cmd, "id=0x%x\n", p->id);
1223 break;
1225 case VIDIOC_G_CTRL:
1227 struct v4l2_control *p = arg;
1229 if (ops->vidioc_g_ctrl)
1230 ret = ops->vidioc_g_ctrl(file, fh, p);
1231 else if (ops->vidioc_g_ext_ctrls) {
1232 struct v4l2_ext_controls ctrls;
1233 struct v4l2_ext_control ctrl;
1235 ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
1236 ctrls.count = 1;
1237 ctrls.controls = &ctrl;
1238 ctrl.id = p->id;
1239 ctrl.value = p->value;
1240 if (check_ext_ctrls(&ctrls, 1)) {
1241 ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls);
1242 if (ret == 0)
1243 p->value = ctrl.value;
1245 } else
1246 break;
1247 if (!ret)
1248 dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
1249 else
1250 dbgarg(cmd, "id=0x%x\n", p->id);
1251 break;
1253 case VIDIOC_S_CTRL:
1255 struct v4l2_control *p = arg;
1256 struct v4l2_ext_controls ctrls;
1257 struct v4l2_ext_control ctrl;
1259 if (!ops->vidioc_s_ctrl && !ops->vidioc_s_ext_ctrls)
1260 break;
1262 dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
1264 if (ops->vidioc_s_ctrl) {
1265 ret = ops->vidioc_s_ctrl(file, fh, p);
1266 break;
1268 if (!ops->vidioc_s_ext_ctrls)
1269 break;
1271 ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
1272 ctrls.count = 1;
1273 ctrls.controls = &ctrl;
1274 ctrl.id = p->id;
1275 ctrl.value = p->value;
1276 if (check_ext_ctrls(&ctrls, 1))
1277 ret = ops->vidioc_s_ext_ctrls(file, fh, &ctrls);
1278 break;
1280 case VIDIOC_G_EXT_CTRLS:
1282 struct v4l2_ext_controls *p = arg;
1284 p->error_idx = p->count;
1285 if (!ops->vidioc_g_ext_ctrls)
1286 break;
1287 if (check_ext_ctrls(p, 0))
1288 ret = ops->vidioc_g_ext_ctrls(file, fh, p);
1289 v4l_print_ext_ctrls(cmd, vfd, p, !ret);
1290 break;
1292 case VIDIOC_S_EXT_CTRLS:
1294 struct v4l2_ext_controls *p = arg;
1296 p->error_idx = p->count;
1297 if (!ops->vidioc_s_ext_ctrls)
1298 break;
1299 v4l_print_ext_ctrls(cmd, vfd, p, 1);
1300 if (check_ext_ctrls(p, 0))
1301 ret = ops->vidioc_s_ext_ctrls(file, fh, p);
1302 break;
1304 case VIDIOC_TRY_EXT_CTRLS:
1306 struct v4l2_ext_controls *p = arg;
1308 p->error_idx = p->count;
1309 if (!ops->vidioc_try_ext_ctrls)
1310 break;
1311 v4l_print_ext_ctrls(cmd, vfd, p, 1);
1312 if (check_ext_ctrls(p, 0))
1313 ret = ops->vidioc_try_ext_ctrls(file, fh, p);
1314 break;
1316 case VIDIOC_QUERYMENU:
1318 struct v4l2_querymenu *p = arg;
1320 if (!ops->vidioc_querymenu)
1321 break;
1322 ret = ops->vidioc_querymenu(file, fh, p);
1323 if (!ret)
1324 dbgarg(cmd, "id=0x%x, index=%d, name=%s\n",
1325 p->id, p->index, p->name);
1326 else
1327 dbgarg(cmd, "id=0x%x, index=%d\n",
1328 p->id, p->index);
1329 break;
1331 /* --- audio ---------------------------------------------- */
1332 case VIDIOC_ENUMAUDIO:
1334 struct v4l2_audio *p = arg;
1336 if (!ops->vidioc_enumaudio)
1337 break;
1338 ret = ops->vidioc_enumaudio(file, fh, p);
1339 if (!ret)
1340 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
1341 "mode=0x%x\n", p->index, p->name,
1342 p->capability, p->mode);
1343 else
1344 dbgarg(cmd, "index=%d\n", p->index);
1345 break;
1347 case VIDIOC_G_AUDIO:
1349 struct v4l2_audio *p = arg;
1351 if (!ops->vidioc_g_audio)
1352 break;
1354 ret = ops->vidioc_g_audio(file, fh, p);
1355 if (!ret)
1356 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
1357 "mode=0x%x\n", p->index,
1358 p->name, p->capability, p->mode);
1359 else
1360 dbgarg(cmd, "index=%d\n", p->index);
1361 break;
1363 case VIDIOC_S_AUDIO:
1365 struct v4l2_audio *p = arg;
1367 if (!ops->vidioc_s_audio)
1368 break;
1369 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
1370 "mode=0x%x\n", p->index, p->name,
1371 p->capability, p->mode);
1372 ret = ops->vidioc_s_audio(file, fh, p);
1373 break;
1375 case VIDIOC_ENUMAUDOUT:
1377 struct v4l2_audioout *p = arg;
1379 if (!ops->vidioc_enumaudout)
1380 break;
1381 dbgarg(cmd, "Enum for index=%d\n", p->index);
1382 ret = ops->vidioc_enumaudout(file, fh, p);
1383 if (!ret)
1384 dbgarg2("index=%d, name=%s, capability=%d, "
1385 "mode=%d\n", p->index, p->name,
1386 p->capability, p->mode);
1387 break;
1389 case VIDIOC_G_AUDOUT:
1391 struct v4l2_audioout *p = arg;
1393 if (!ops->vidioc_g_audout)
1394 break;
1396 ret = ops->vidioc_g_audout(file, fh, p);
1397 if (!ret)
1398 dbgarg2("index=%d, name=%s, capability=%d, "
1399 "mode=%d\n", p->index, p->name,
1400 p->capability, p->mode);
1401 break;
1403 case VIDIOC_S_AUDOUT:
1405 struct v4l2_audioout *p = arg;
1407 if (!ops->vidioc_s_audout)
1408 break;
1409 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1410 "mode=%d\n", p->index, p->name,
1411 p->capability, p->mode);
1413 ret = ops->vidioc_s_audout(file, fh, p);
1414 break;
1416 case VIDIOC_G_MODULATOR:
1418 struct v4l2_modulator *p = arg;
1420 if (!ops->vidioc_g_modulator)
1421 break;
1422 ret = ops->vidioc_g_modulator(file, fh, p);
1423 if (!ret)
1424 dbgarg(cmd, "index=%d, name=%s, "
1425 "capability=%d, rangelow=%d,"
1426 " rangehigh=%d, txsubchans=%d\n",
1427 p->index, p->name, p->capability,
1428 p->rangelow, p->rangehigh,
1429 p->txsubchans);
1430 break;
1432 case VIDIOC_S_MODULATOR:
1434 struct v4l2_modulator *p = arg;
1436 if (!ops->vidioc_s_modulator)
1437 break;
1438 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1439 "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
1440 p->index, p->name, p->capability, p->rangelow,
1441 p->rangehigh, p->txsubchans);
1442 ret = ops->vidioc_s_modulator(file, fh, p);
1443 break;
1445 case VIDIOC_G_CROP:
1447 struct v4l2_crop *p = arg;
1449 if (!ops->vidioc_g_crop)
1450 break;
1452 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1453 ret = ops->vidioc_g_crop(file, fh, p);
1454 if (!ret)
1455 dbgrect(vfd, "", &p->c);
1456 break;
1458 case VIDIOC_S_CROP:
1460 struct v4l2_crop *p = arg;
1462 if (!ops->vidioc_s_crop)
1463 break;
1464 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1465 dbgrect(vfd, "", &p->c);
1466 ret = ops->vidioc_s_crop(file, fh, p);
1467 break;
1469 case VIDIOC_CROPCAP:
1471 struct v4l2_cropcap *p = arg;
1473 /*FIXME: Should also show v4l2_fract pixelaspect */
1474 if (!ops->vidioc_cropcap)
1475 break;
1477 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1478 ret = ops->vidioc_cropcap(file, fh, p);
1479 if (!ret) {
1480 dbgrect(vfd, "bounds ", &p->bounds);
1481 dbgrect(vfd, "defrect ", &p->defrect);
1483 break;
1485 case VIDIOC_G_JPEGCOMP:
1487 struct v4l2_jpegcompression *p = arg;
1489 if (!ops->vidioc_g_jpegcomp)
1490 break;
1492 ret = ops->vidioc_g_jpegcomp(file, fh, p);
1493 if (!ret)
1494 dbgarg(cmd, "quality=%d, APPn=%d, "
1495 "APP_len=%d, COM_len=%d, "
1496 "jpeg_markers=%d\n",
1497 p->quality, p->APPn, p->APP_len,
1498 p->COM_len, p->jpeg_markers);
1499 break;
1501 case VIDIOC_S_JPEGCOMP:
1503 struct v4l2_jpegcompression *p = arg;
1505 if (!ops->vidioc_g_jpegcomp)
1506 break;
1507 dbgarg(cmd, "quality=%d, APPn=%d, APP_len=%d, "
1508 "COM_len=%d, jpeg_markers=%d\n",
1509 p->quality, p->APPn, p->APP_len,
1510 p->COM_len, p->jpeg_markers);
1511 ret = ops->vidioc_s_jpegcomp(file, fh, p);
1512 break;
1514 case VIDIOC_G_ENC_INDEX:
1516 struct v4l2_enc_idx *p = arg;
1518 if (!ops->vidioc_g_enc_index)
1519 break;
1520 ret = ops->vidioc_g_enc_index(file, fh, p);
1521 if (!ret)
1522 dbgarg(cmd, "entries=%d, entries_cap=%d\n",
1523 p->entries, p->entries_cap);
1524 break;
1526 case VIDIOC_ENCODER_CMD:
1528 struct v4l2_encoder_cmd *p = arg;
1530 if (!ops->vidioc_encoder_cmd)
1531 break;
1532 ret = ops->vidioc_encoder_cmd(file, fh, p);
1533 if (!ret)
1534 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
1535 break;
1537 case VIDIOC_TRY_ENCODER_CMD:
1539 struct v4l2_encoder_cmd *p = arg;
1541 if (!ops->vidioc_try_encoder_cmd)
1542 break;
1543 ret = ops->vidioc_try_encoder_cmd(file, fh, p);
1544 if (!ret)
1545 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
1546 break;
1548 case VIDIOC_G_PARM:
1550 struct v4l2_streamparm *p = arg;
1552 if (ops->vidioc_g_parm) {
1553 ret = check_fmt(ops, p->type);
1554 if (ret)
1555 break;
1556 ret = ops->vidioc_g_parm(file, fh, p);
1557 } else {
1558 v4l2_std_id std = vfd->current_norm;
1560 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1561 return -EINVAL;
1563 ret = 0;
1564 if (ops->vidioc_g_std)
1565 ret = ops->vidioc_g_std(file, fh, &std);
1566 else if (std == 0)
1567 ret = -EINVAL;
1568 if (ret == 0)
1569 v4l2_video_std_frame_period(std,
1570 &p->parm.capture.timeperframe);
1573 dbgarg(cmd, "type=%d\n", p->type);
1574 break;
1576 case VIDIOC_S_PARM:
1578 struct v4l2_streamparm *p = arg;
1580 if (!ops->vidioc_s_parm)
1581 break;
1582 ret = check_fmt(ops, p->type);
1583 if (ret)
1584 break;
1586 dbgarg(cmd, "type=%d\n", p->type);
1587 ret = ops->vidioc_s_parm(file, fh, p);
1588 break;
1590 case VIDIOC_G_TUNER:
1592 struct v4l2_tuner *p = arg;
1594 if (!ops->vidioc_g_tuner)
1595 break;
1597 ret = ops->vidioc_g_tuner(file, fh, p);
1598 if (!ret)
1599 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1600 "capability=0x%x, rangelow=%d, "
1601 "rangehigh=%d, signal=%d, afc=%d, "
1602 "rxsubchans=0x%x, audmode=%d\n",
1603 p->index, p->name, p->type,
1604 p->capability, p->rangelow,
1605 p->rangehigh, p->signal, p->afc,
1606 p->rxsubchans, p->audmode);
1607 break;
1609 case VIDIOC_S_TUNER:
1611 struct v4l2_tuner *p = arg;
1613 if (!ops->vidioc_s_tuner)
1614 break;
1615 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1616 "capability=0x%x, rangelow=%d, "
1617 "rangehigh=%d, signal=%d, afc=%d, "
1618 "rxsubchans=0x%x, audmode=%d\n",
1619 p->index, p->name, p->type,
1620 p->capability, p->rangelow,
1621 p->rangehigh, p->signal, p->afc,
1622 p->rxsubchans, p->audmode);
1623 ret = ops->vidioc_s_tuner(file, fh, p);
1624 break;
1626 case VIDIOC_G_FREQUENCY:
1628 struct v4l2_frequency *p = arg;
1630 if (!ops->vidioc_g_frequency)
1631 break;
1633 ret = ops->vidioc_g_frequency(file, fh, p);
1634 if (!ret)
1635 dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
1636 p->tuner, p->type, p->frequency);
1637 break;
1639 case VIDIOC_S_FREQUENCY:
1641 struct v4l2_frequency *p = arg;
1643 if (!ops->vidioc_s_frequency)
1644 break;
1645 dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
1646 p->tuner, p->type, p->frequency);
1647 ret = ops->vidioc_s_frequency(file, fh, p);
1648 break;
1650 case VIDIOC_G_SLICED_VBI_CAP:
1652 struct v4l2_sliced_vbi_cap *p = arg;
1654 if (!ops->vidioc_g_sliced_vbi_cap)
1655 break;
1657 /* Clear up to type, everything after type is zerod already */
1658 memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type));
1660 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1661 ret = ops->vidioc_g_sliced_vbi_cap(file, fh, p);
1662 if (!ret)
1663 dbgarg2("service_set=%d\n", p->service_set);
1664 break;
1666 case VIDIOC_LOG_STATUS:
1668 if (!ops->vidioc_log_status)
1669 break;
1670 ret = ops->vidioc_log_status(file, fh);
1671 break;
1673 #ifdef CONFIG_VIDEO_ADV_DEBUG
1674 case VIDIOC_DBG_G_REGISTER:
1676 struct v4l2_dbg_register *p = arg;
1678 if (!capable(CAP_SYS_ADMIN))
1679 ret = -EPERM;
1680 else if (ops->vidioc_g_register)
1681 ret = ops->vidioc_g_register(file, fh, p);
1682 break;
1684 case VIDIOC_DBG_S_REGISTER:
1686 struct v4l2_dbg_register *p = arg;
1688 if (!capable(CAP_SYS_ADMIN))
1689 ret = -EPERM;
1690 else if (ops->vidioc_s_register)
1691 ret = ops->vidioc_s_register(file, fh, p);
1692 break;
1694 #endif
1695 case VIDIOC_DBG_G_CHIP_IDENT:
1697 struct v4l2_dbg_chip_ident *p = arg;
1699 if (!ops->vidioc_g_chip_ident)
1700 break;
1701 p->ident = V4L2_IDENT_NONE;
1702 p->revision = 0;
1703 ret = ops->vidioc_g_chip_ident(file, fh, p);
1704 if (!ret)
1705 dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
1706 break;
1708 case VIDIOC_S_HW_FREQ_SEEK:
1710 struct v4l2_hw_freq_seek *p = arg;
1712 if (!ops->vidioc_s_hw_freq_seek)
1713 break;
1714 dbgarg(cmd,
1715 "tuner=%d, type=%d, seek_upward=%d, wrap_around=%d\n",
1716 p->tuner, p->type, p->seek_upward, p->wrap_around);
1717 ret = ops->vidioc_s_hw_freq_seek(file, fh, p);
1718 break;
1720 case VIDIOC_ENUM_FRAMESIZES:
1722 struct v4l2_frmsizeenum *p = arg;
1724 if (!ops->vidioc_enum_framesizes)
1725 break;
1727 ret = ops->vidioc_enum_framesizes(file, fh, p);
1728 dbgarg(cmd,
1729 "index=%d, pixelformat=%d, type=%d ",
1730 p->index, p->pixel_format, p->type);
1731 switch (p->type) {
1732 case V4L2_FRMSIZE_TYPE_DISCRETE:
1733 dbgarg2("width = %d, height=%d\n",
1734 p->discrete.width, p->discrete.height);
1735 break;
1736 case V4L2_FRMSIZE_TYPE_STEPWISE:
1737 dbgarg2("min %dx%d, max %dx%d, step %dx%d\n",
1738 p->stepwise.min_width, p->stepwise.min_height,
1739 p->stepwise.step_width, p->stepwise.step_height,
1740 p->stepwise.max_width, p->stepwise.max_height);
1741 break;
1742 case V4L2_FRMSIZE_TYPE_CONTINUOUS:
1743 dbgarg2("continuous\n");
1744 break;
1745 default:
1746 dbgarg2("- Unknown type!\n");
1749 break;
1751 case VIDIOC_ENUM_FRAMEINTERVALS:
1753 struct v4l2_frmivalenum *p = arg;
1755 if (!ops->vidioc_enum_frameintervals)
1756 break;
1758 ret = ops->vidioc_enum_frameintervals(file, fh, p);
1759 dbgarg(cmd,
1760 "index=%d, pixelformat=%d, width=%d, height=%d, type=%d ",
1761 p->index, p->pixel_format,
1762 p->width, p->height, p->type);
1763 switch (p->type) {
1764 case V4L2_FRMIVAL_TYPE_DISCRETE:
1765 dbgarg2("fps=%d/%d\n",
1766 p->discrete.numerator,
1767 p->discrete.denominator);
1768 break;
1769 case V4L2_FRMIVAL_TYPE_STEPWISE:
1770 dbgarg2("min=%d/%d, max=%d/%d, step=%d/%d\n",
1771 p->stepwise.min.numerator,
1772 p->stepwise.min.denominator,
1773 p->stepwise.max.numerator,
1774 p->stepwise.max.denominator,
1775 p->stepwise.step.numerator,
1776 p->stepwise.step.denominator);
1777 break;
1778 case V4L2_FRMIVAL_TYPE_CONTINUOUS:
1779 dbgarg2("continuous\n");
1780 break;
1781 default:
1782 dbgarg2("- Unknown type!\n");
1784 break;
1787 default:
1789 if (!ops->vidioc_default)
1790 break;
1791 ret = ops->vidioc_default(file, fh, cmd, arg);
1792 break;
1794 } /* switch */
1796 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1797 if (ret < 0) {
1798 v4l_print_ioctl(vfd->name, cmd);
1799 printk(KERN_CONT " error %ld\n", ret);
1803 return ret;
1806 /* In some cases, only a few fields are used as input, i.e. when the app sets
1807 * "index" and then the driver fills in the rest of the structure for the thing
1808 * with that index. We only need to copy up the first non-input field. */
1809 static unsigned long cmd_input_size(unsigned int cmd)
1811 /* Size of structure up to and including 'field' */
1812 #define CMDINSIZE(cmd, type, field) \
1813 case VIDIOC_##cmd: \
1814 return offsetof(struct v4l2_##type, field) + \
1815 sizeof(((struct v4l2_##type *)0)->field);
1817 switch (cmd) {
1818 CMDINSIZE(ENUM_FMT, fmtdesc, type);
1819 CMDINSIZE(G_FMT, format, type);
1820 CMDINSIZE(QUERYBUF, buffer, type);
1821 CMDINSIZE(G_PARM, streamparm, type);
1822 CMDINSIZE(ENUMSTD, standard, index);
1823 CMDINSIZE(ENUMINPUT, input, index);
1824 CMDINSIZE(G_CTRL, control, id);
1825 CMDINSIZE(G_TUNER, tuner, index);
1826 CMDINSIZE(QUERYCTRL, queryctrl, id);
1827 CMDINSIZE(QUERYMENU, querymenu, index);
1828 CMDINSIZE(ENUMOUTPUT, output, index);
1829 CMDINSIZE(G_MODULATOR, modulator, index);
1830 CMDINSIZE(G_FREQUENCY, frequency, tuner);
1831 CMDINSIZE(CROPCAP, cropcap, type);
1832 CMDINSIZE(G_CROP, crop, type);
1833 CMDINSIZE(ENUMAUDIO, audio, index);
1834 CMDINSIZE(ENUMAUDOUT, audioout, index);
1835 CMDINSIZE(ENCODER_CMD, encoder_cmd, flags);
1836 CMDINSIZE(TRY_ENCODER_CMD, encoder_cmd, flags);
1837 CMDINSIZE(G_SLICED_VBI_CAP, sliced_vbi_cap, type);
1838 CMDINSIZE(ENUM_FRAMESIZES, frmsizeenum, pixel_format);
1839 CMDINSIZE(ENUM_FRAMEINTERVALS, frmivalenum, height);
1840 default:
1841 return _IOC_SIZE(cmd);
1845 long video_ioctl2(struct file *file,
1846 unsigned int cmd, unsigned long arg)
1848 char sbuf[128];
1849 void *mbuf = NULL;
1850 void *parg = NULL;
1851 long err = -EINVAL;
1852 int is_ext_ctrl;
1853 size_t ctrls_size = 0;
1854 void __user *user_ptr = NULL;
1856 #ifdef __OLD_VIDIOC_
1857 cmd = video_fix_command(cmd);
1858 #endif
1859 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
1860 cmd == VIDIOC_TRY_EXT_CTRLS);
1862 /* Copy arguments into temp kernel buffer */
1863 if (_IOC_DIR(cmd) != _IOC_NONE) {
1864 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
1865 parg = sbuf;
1866 } else {
1867 /* too big to allocate from stack */
1868 mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
1869 if (NULL == mbuf)
1870 return -ENOMEM;
1871 parg = mbuf;
1874 err = -EFAULT;
1875 if (_IOC_DIR(cmd) & _IOC_WRITE) {
1876 unsigned long n = cmd_input_size(cmd);
1878 if (copy_from_user(parg, (void __user *)arg, n))
1879 goto out;
1881 /* zero out anything we don't copy from userspace */
1882 if (n < _IOC_SIZE(cmd))
1883 memset((u8 *)parg + n, 0, _IOC_SIZE(cmd) - n);
1884 } else {
1885 /* read-only ioctl */
1886 memset(parg, 0, _IOC_SIZE(cmd));
1890 if (is_ext_ctrl) {
1891 struct v4l2_ext_controls *p = parg;
1893 /* In case of an error, tell the caller that it wasn't
1894 a specific control that caused it. */
1895 p->error_idx = p->count;
1896 user_ptr = (void __user *)p->controls;
1897 if (p->count) {
1898 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
1899 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
1900 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
1901 err = -ENOMEM;
1902 if (NULL == mbuf)
1903 goto out_ext_ctrl;
1904 err = -EFAULT;
1905 if (copy_from_user(mbuf, user_ptr, ctrls_size))
1906 goto out_ext_ctrl;
1907 p->controls = mbuf;
1911 /* Handles IOCTL */
1912 err = __video_do_ioctl(file, cmd, parg);
1913 if (err == -ENOIOCTLCMD)
1914 err = -EINVAL;
1915 if (is_ext_ctrl) {
1916 struct v4l2_ext_controls *p = parg;
1918 p->controls = (void *)user_ptr;
1919 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
1920 err = -EFAULT;
1921 goto out_ext_ctrl;
1923 if (err < 0)
1924 goto out;
1926 out_ext_ctrl:
1927 /* Copy results into user buffer */
1928 switch (_IOC_DIR(cmd)) {
1929 case _IOC_READ:
1930 case (_IOC_WRITE | _IOC_READ):
1931 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
1932 err = -EFAULT;
1933 break;
1936 out:
1937 kfree(mbuf);
1938 return err;
1940 EXPORT_SYMBOL(video_ioctl2);