V4L/DVB (9579): v4l core: a few get ioctls were lacking memory clean
[linux-2.6/mini2440.git] / drivers / media / video / v4l2-ioctl.c
blob98a0bf22e43cce9db4a3fff03b0c21b0c9f262b6
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/videodev2.h>
22 #ifdef CONFIG_VIDEO_V4L1
23 #include <linux/videodev.h>
24 #endif
25 #include <media/v4l2-common.h>
26 #include <media/v4l2-ioctl.h>
27 #include <linux/video_decoder.h>
29 #define dbgarg(cmd, fmt, arg...) \
30 do { \
31 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { \
32 printk(KERN_DEBUG "%s: ", vfd->name); \
33 v4l_printk_ioctl(cmd); \
34 printk(" " fmt, ## arg); \
35 } \
36 } while (0)
38 #define dbgarg2(fmt, arg...) \
39 do { \
40 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \
41 printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg);\
42 } while (0)
44 struct std_descr {
45 v4l2_std_id std;
46 const char *descr;
49 static const struct std_descr standards[] = {
50 { V4L2_STD_NTSC, "NTSC" },
51 { V4L2_STD_NTSC_M, "NTSC-M" },
52 { V4L2_STD_NTSC_M_JP, "NTSC-M-JP" },
53 { V4L2_STD_NTSC_M_KR, "NTSC-M-KR" },
54 { V4L2_STD_NTSC_443, "NTSC-443" },
55 { V4L2_STD_PAL, "PAL" },
56 { V4L2_STD_PAL_BG, "PAL-BG" },
57 { V4L2_STD_PAL_B, "PAL-B" },
58 { V4L2_STD_PAL_B1, "PAL-B1" },
59 { V4L2_STD_PAL_G, "PAL-G" },
60 { V4L2_STD_PAL_H, "PAL-H" },
61 { V4L2_STD_PAL_I, "PAL-I" },
62 { V4L2_STD_PAL_DK, "PAL-DK" },
63 { V4L2_STD_PAL_D, "PAL-D" },
64 { V4L2_STD_PAL_D1, "PAL-D1" },
65 { V4L2_STD_PAL_K, "PAL-K" },
66 { V4L2_STD_PAL_M, "PAL-M" },
67 { V4L2_STD_PAL_N, "PAL-N" },
68 { V4L2_STD_PAL_Nc, "PAL-Nc" },
69 { V4L2_STD_PAL_60, "PAL-60" },
70 { V4L2_STD_SECAM, "SECAM" },
71 { V4L2_STD_SECAM_B, "SECAM-B" },
72 { V4L2_STD_SECAM_G, "SECAM-G" },
73 { V4L2_STD_SECAM_H, "SECAM-H" },
74 { V4L2_STD_SECAM_DK, "SECAM-DK" },
75 { V4L2_STD_SECAM_D, "SECAM-D" },
76 { V4L2_STD_SECAM_K, "SECAM-K" },
77 { V4L2_STD_SECAM_K1, "SECAM-K1" },
78 { V4L2_STD_SECAM_L, "SECAM-L" },
79 { V4L2_STD_SECAM_LC, "SECAM-Lc" },
80 { 0, "Unknown" }
83 /* video4linux standard ID conversion to standard name
85 const char *v4l2_norm_to_name(v4l2_std_id id)
87 u32 myid = id;
88 int i;
90 /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
91 64 bit comparations. So, on that architecture, with some gcc
92 variants, compilation fails. Currently, the max value is 30bit wide.
94 BUG_ON(myid != id);
96 for (i = 0; standards[i].std; i++)
97 if (myid == standards[i].std)
98 break;
99 return standards[i].descr;
101 EXPORT_SYMBOL(v4l2_norm_to_name);
103 /* Fill in the fields of a v4l2_standard structure according to the
104 'id' and 'transmission' parameters. Returns negative on error. */
105 int v4l2_video_std_construct(struct v4l2_standard *vs,
106 int id, const char *name)
108 u32 index = vs->index;
110 memset(vs, 0, sizeof(struct v4l2_standard));
111 vs->index = index;
112 vs->id = id;
113 if (id & V4L2_STD_525_60) {
114 vs->frameperiod.numerator = 1001;
115 vs->frameperiod.denominator = 30000;
116 vs->framelines = 525;
117 } else {
118 vs->frameperiod.numerator = 1;
119 vs->frameperiod.denominator = 25;
120 vs->framelines = 625;
122 strlcpy(vs->name, name, sizeof(vs->name));
123 return 0;
125 EXPORT_SYMBOL(v4l2_video_std_construct);
127 /* ----------------------------------------------------------------- */
128 /* some arrays for pretty-printing debug messages of enum types */
130 const char *v4l2_field_names[] = {
131 [V4L2_FIELD_ANY] = "any",
132 [V4L2_FIELD_NONE] = "none",
133 [V4L2_FIELD_TOP] = "top",
134 [V4L2_FIELD_BOTTOM] = "bottom",
135 [V4L2_FIELD_INTERLACED] = "interlaced",
136 [V4L2_FIELD_SEQ_TB] = "seq-tb",
137 [V4L2_FIELD_SEQ_BT] = "seq-bt",
138 [V4L2_FIELD_ALTERNATE] = "alternate",
139 [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
140 [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
142 EXPORT_SYMBOL(v4l2_field_names);
144 const char *v4l2_type_names[] = {
145 [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "vid-cap",
146 [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "vid-overlay",
147 [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "vid-out",
148 [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
149 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
150 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
151 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
152 [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay",
154 EXPORT_SYMBOL(v4l2_type_names);
156 static const char *v4l2_memory_names[] = {
157 [V4L2_MEMORY_MMAP] = "mmap",
158 [V4L2_MEMORY_USERPTR] = "userptr",
159 [V4L2_MEMORY_OVERLAY] = "overlay",
162 #define prt_names(a, arr) ((((a) >= 0) && ((a) < ARRAY_SIZE(arr))) ? \
163 arr[a] : "unknown")
165 /* ------------------------------------------------------------------ */
166 /* debug help functions */
168 #ifdef CONFIG_VIDEO_V4L1_COMPAT
169 static const char *v4l1_ioctls[] = {
170 [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP",
171 [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN",
172 [_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN",
173 [_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER",
174 [_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER",
175 [_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT",
176 [_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT",
177 [_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE",
178 [_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN",
179 [_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN",
180 [_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF",
181 [_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF",
182 [_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY",
183 [_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ",
184 [_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ",
185 [_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO",
186 [_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO",
187 [_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC",
188 [_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE",
189 [_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF",
190 [_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT",
191 [_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE",
192 [_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE",
193 [_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE",
194 [_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE",
195 [_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO",
196 [_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE",
197 [_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT",
198 [_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT"
200 #define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
201 #endif
203 static const char *v4l2_ioctls[] = {
204 [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP",
205 [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED",
206 [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT",
207 [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT",
208 [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT",
209 [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS",
210 [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF",
211 [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF",
212 [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF",
213 [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY",
214 [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF",
215 [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF",
216 [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON",
217 [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF",
218 [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM",
219 [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM",
220 [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD",
221 [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD",
222 [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD",
223 [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT",
224 [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL",
225 [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL",
226 [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER",
227 [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER",
228 [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO",
229 [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO",
230 [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL",
231 [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU",
232 [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT",
233 [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT",
234 [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT",
235 [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT",
236 [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT",
237 [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT",
238 [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT",
239 [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR",
240 [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR",
241 [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY",
242 [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY",
243 [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP",
244 [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP",
245 [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP",
246 [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP",
247 [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP",
248 [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD",
249 [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT",
250 [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO",
251 [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT",
252 [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY",
253 [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY",
254 [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
255 [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS",
256 [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS",
257 [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS",
258 [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS",
259 #if 1
260 [_IOC_NR(VIDIOC_ENUM_FRAMESIZES)] = "VIDIOC_ENUM_FRAMESIZES",
261 [_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS",
262 [_IOC_NR(VIDIOC_G_ENC_INDEX)] = "VIDIOC_G_ENC_INDEX",
263 [_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD",
264 [_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD",
266 [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER",
267 [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER",
269 [_IOC_NR(VIDIOC_G_CHIP_IDENT)] = "VIDIOC_G_CHIP_IDENT",
270 [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK",
271 #endif
273 #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
275 static const char *v4l2_int_ioctls[] = {
276 #ifdef CONFIG_VIDEO_V4L1_COMPAT
277 [_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES",
278 [_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS",
279 [_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM",
280 [_IOC_NR(DECODER_SET_INPUT)] = "DECODER_SET_INPUT",
281 [_IOC_NR(DECODER_SET_OUTPUT)] = "DECODER_SET_OUTPUT",
282 [_IOC_NR(DECODER_ENABLE_OUTPUT)] = "DECODER_ENABLE_OUTPUT",
283 [_IOC_NR(DECODER_SET_PICTURE)] = "DECODER_SET_PICTURE",
284 [_IOC_NR(DECODER_SET_GPIO)] = "DECODER_SET_GPIO",
285 [_IOC_NR(DECODER_INIT)] = "DECODER_INIT",
286 [_IOC_NR(DECODER_SET_VBI_BYPASS)] = "DECODER_SET_VBI_BYPASS",
287 [_IOC_NR(DECODER_DUMP)] = "DECODER_DUMP",
288 #endif
289 [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO",
291 [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR",
292 [_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY",
293 [_IOC_NR(TUNER_SET_CONFIG)] = "TUNER_SET_CONFIG",
295 [_IOC_NR(VIDIOC_INT_S_TUNER_MODE)] = "VIDIOC_INT_S_TUNER_MODE",
296 [_IOC_NR(VIDIOC_INT_RESET)] = "VIDIOC_INT_RESET",
297 [_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ",
298 [_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)] = "VIDIOC_INT_DECODE_VBI_LINE",
299 [_IOC_NR(VIDIOC_INT_S_VBI_DATA)] = "VIDIOC_INT_S_VBI_DATA",
300 [_IOC_NR(VIDIOC_INT_G_VBI_DATA)] = "VIDIOC_INT_G_VBI_DATA",
301 [_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ",
302 [_IOC_NR(VIDIOC_INT_S_STANDBY)] = "VIDIOC_INT_S_STANDBY",
303 [_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING",
304 [_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING",
305 [_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING",
306 [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING",
307 [_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)] = "VIDIOC_INT_S_CRYSTAL_FREQ",
308 [_IOC_NR(VIDIOC_INT_INIT)] = "VIDIOC_INT_INIT",
309 [_IOC_NR(VIDIOC_INT_G_STD_OUTPUT)] = "VIDIOC_INT_G_STD_OUTPUT",
310 [_IOC_NR(VIDIOC_INT_S_STD_OUTPUT)] = "VIDIOC_INT_S_STD_OUTPUT",
312 #define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)
314 /* Common ioctl debug function. This function can be used by
315 external ioctl messages as well as internal V4L ioctl */
316 void v4l_printk_ioctl(unsigned int cmd)
318 char *dir, *type;
320 switch (_IOC_TYPE(cmd)) {
321 case 'd':
322 if (_IOC_NR(cmd) >= V4L2_INT_IOCTLS) {
323 type = "v4l2_int";
324 break;
326 printk("%s", v4l2_int_ioctls[_IOC_NR(cmd)]);
327 return;
328 #ifdef CONFIG_VIDEO_V4L1_COMPAT
329 case 'v':
330 if (_IOC_NR(cmd) >= V4L1_IOCTLS) {
331 type = "v4l1";
332 break;
334 printk("%s", v4l1_ioctls[_IOC_NR(cmd)]);
335 return;
336 #endif
337 case 'V':
338 if (_IOC_NR(cmd) >= V4L2_IOCTLS) {
339 type = "v4l2";
340 break;
342 printk("%s", v4l2_ioctls[_IOC_NR(cmd)]);
343 return;
344 default:
345 type = "unknown";
348 switch (_IOC_DIR(cmd)) {
349 case _IOC_NONE: dir = "--"; break;
350 case _IOC_READ: dir = "r-"; break;
351 case _IOC_WRITE: dir = "-w"; break;
352 case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
353 default: dir = "*ERR*"; break;
355 printk("%s ioctl '%c', dir=%s, #%d (0x%08x)",
356 type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
358 EXPORT_SYMBOL(v4l_printk_ioctl);
361 * helper function -- handles userspace copying for ioctl arguments
364 #ifdef __OLD_VIDIOC_
365 static unsigned int
366 video_fix_command(unsigned int cmd)
368 switch (cmd) {
369 case VIDIOC_OVERLAY_OLD:
370 cmd = VIDIOC_OVERLAY;
371 break;
372 case VIDIOC_S_PARM_OLD:
373 cmd = VIDIOC_S_PARM;
374 break;
375 case VIDIOC_S_CTRL_OLD:
376 cmd = VIDIOC_S_CTRL;
377 break;
378 case VIDIOC_G_AUDIO_OLD:
379 cmd = VIDIOC_G_AUDIO;
380 break;
381 case VIDIOC_G_AUDOUT_OLD:
382 cmd = VIDIOC_G_AUDOUT;
383 break;
384 case VIDIOC_CROPCAP_OLD:
385 cmd = VIDIOC_CROPCAP;
386 break;
388 return cmd;
390 #endif
393 * Obsolete usercopy function - Should be removed soon
396 video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
397 v4l2_kioctl func)
399 char sbuf[128];
400 void *mbuf = NULL;
401 void *parg = NULL;
402 int err = -EINVAL;
403 int is_ext_ctrl;
404 size_t ctrls_size = 0;
405 void __user *user_ptr = NULL;
407 #ifdef __OLD_VIDIOC_
408 cmd = video_fix_command(cmd);
409 #endif
410 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
411 cmd == VIDIOC_TRY_EXT_CTRLS);
413 /* Copy arguments into temp kernel buffer */
414 switch (_IOC_DIR(cmd)) {
415 case _IOC_NONE:
416 parg = NULL;
417 break;
418 case _IOC_READ:
419 case _IOC_WRITE:
420 case (_IOC_WRITE | _IOC_READ):
421 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
422 parg = sbuf;
423 } else {
424 /* too big to allocate from stack */
425 mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
426 if (NULL == mbuf)
427 return -ENOMEM;
428 parg = mbuf;
431 err = -EFAULT;
432 if (_IOC_DIR(cmd) & _IOC_WRITE)
433 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
434 goto out;
435 break;
437 if (is_ext_ctrl) {
438 struct v4l2_ext_controls *p = parg;
440 /* In case of an error, tell the caller that it wasn't
441 a specific control that caused it. */
442 p->error_idx = p->count;
443 user_ptr = (void __user *)p->controls;
444 if (p->count) {
445 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
446 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
447 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
448 err = -ENOMEM;
449 if (NULL == mbuf)
450 goto out_ext_ctrl;
451 err = -EFAULT;
452 if (copy_from_user(mbuf, user_ptr, ctrls_size))
453 goto out_ext_ctrl;
454 p->controls = mbuf;
458 /* call driver */
459 err = func(file, cmd, parg);
460 if (err == -ENOIOCTLCMD)
461 err = -EINVAL;
462 if (is_ext_ctrl) {
463 struct v4l2_ext_controls *p = parg;
465 p->controls = (void *)user_ptr;
466 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
467 err = -EFAULT;
468 goto out_ext_ctrl;
470 if (err < 0)
471 goto out;
473 out_ext_ctrl:
474 /* Copy results into user buffer */
475 switch (_IOC_DIR(cmd)) {
476 case _IOC_READ:
477 case (_IOC_WRITE | _IOC_READ):
478 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
479 err = -EFAULT;
480 break;
483 out:
484 kfree(mbuf);
485 return err;
487 EXPORT_SYMBOL(video_usercopy);
489 static void dbgbuf(unsigned int cmd, struct video_device *vfd,
490 struct v4l2_buffer *p)
492 struct v4l2_timecode *tc = &p->timecode;
494 dbgarg(cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
495 "bytesused=%d, flags=0x%08d, "
496 "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n",
497 p->timestamp.tv_sec / 3600,
498 (int)(p->timestamp.tv_sec / 60) % 60,
499 (int)(p->timestamp.tv_sec % 60),
500 (long)p->timestamp.tv_usec,
501 p->index,
502 prt_names(p->type, v4l2_type_names),
503 p->bytesused, p->flags,
504 p->field, p->sequence,
505 prt_names(p->memory, v4l2_memory_names),
506 p->m.userptr, p->length);
507 dbgarg2("timecode=%02d:%02d:%02d type=%d, "
508 "flags=0x%08d, frames=%d, userbits=0x%08x\n",
509 tc->hours, tc->minutes, tc->seconds,
510 tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits);
513 static inline void dbgrect(struct video_device *vfd, char *s,
514 struct v4l2_rect *r)
516 dbgarg2("%sRect start at %dx%d, size=%dx%d\n", s, r->left, r->top,
517 r->width, r->height);
520 static inline void v4l_print_pix_fmt(struct video_device *vfd,
521 struct v4l2_pix_format *fmt)
523 dbgarg2("width=%d, height=%d, format=%c%c%c%c, field=%s, "
524 "bytesperline=%d sizeimage=%d, colorspace=%d\n",
525 fmt->width, fmt->height,
526 (fmt->pixelformat & 0xff),
527 (fmt->pixelformat >> 8) & 0xff,
528 (fmt->pixelformat >> 16) & 0xff,
529 (fmt->pixelformat >> 24) & 0xff,
530 prt_names(fmt->field, v4l2_field_names),
531 fmt->bytesperline, fmt->sizeimage, fmt->colorspace);
534 static inline void v4l_print_ext_ctrls(unsigned int cmd,
535 struct video_device *vfd, struct v4l2_ext_controls *c, int show_vals)
537 __u32 i;
539 if (!(vfd->debug & V4L2_DEBUG_IOCTL_ARG))
540 return;
541 dbgarg(cmd, "");
542 printk(KERN_CONT "class=0x%x", c->ctrl_class);
543 for (i = 0; i < c->count; i++) {
544 if (show_vals)
545 printk(KERN_CONT " id/val=0x%x/0x%x",
546 c->controls[i].id, c->controls[i].value);
547 else
548 printk(KERN_CONT " id=0x%x", c->controls[i].id);
550 printk(KERN_CONT "\n");
553 static inline int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)
555 __u32 i;
557 /* zero the reserved fields */
558 c->reserved[0] = c->reserved[1] = 0;
559 for (i = 0; i < c->count; i++) {
560 c->controls[i].reserved2[0] = 0;
561 c->controls[i].reserved2[1] = 0;
563 /* V4L2_CID_PRIVATE_BASE cannot be used as control class
564 when using extended controls.
565 Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
566 is it allowed for backwards compatibility.
568 if (!allow_priv && c->ctrl_class == V4L2_CID_PRIVATE_BASE)
569 return 0;
570 /* Check that all controls are from the same control class. */
571 for (i = 0; i < c->count; i++) {
572 if (V4L2_CTRL_ID2CLASS(c->controls[i].id) != c->ctrl_class) {
573 c->error_idx = i;
574 return 0;
577 return 1;
580 static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type)
582 if (ops == NULL)
583 return -EINVAL;
585 switch (type) {
586 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
587 if (ops->vidioc_try_fmt_vid_cap)
588 return 0;
589 break;
590 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
591 if (ops->vidioc_try_fmt_vid_overlay)
592 return 0;
593 break;
594 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
595 if (ops->vidioc_try_fmt_vid_out)
596 return 0;
597 break;
598 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
599 if (ops->vidioc_try_fmt_vid_out_overlay)
600 return 0;
601 break;
602 case V4L2_BUF_TYPE_VBI_CAPTURE:
603 if (ops->vidioc_try_fmt_vbi_cap)
604 return 0;
605 break;
606 case V4L2_BUF_TYPE_VBI_OUTPUT:
607 if (ops->vidioc_try_fmt_vbi_out)
608 return 0;
609 break;
610 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
611 if (ops->vidioc_try_fmt_sliced_vbi_cap)
612 return 0;
613 break;
614 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
615 if (ops->vidioc_try_fmt_sliced_vbi_out)
616 return 0;
617 break;
618 case V4L2_BUF_TYPE_PRIVATE:
619 if (ops->vidioc_try_fmt_type_private)
620 return 0;
621 break;
623 return -EINVAL;
626 static int __video_do_ioctl(struct file *file,
627 unsigned int cmd, void *arg)
629 struct video_device *vfd = video_devdata(file);
630 const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
631 void *fh = file->private_data;
632 int ret = -EINVAL;
634 if ((vfd->debug & V4L2_DEBUG_IOCTL) &&
635 !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) {
636 v4l_print_ioctl(vfd->name, cmd);
637 printk(KERN_CONT "\n");
640 if (ops == NULL) {
641 printk(KERN_WARNING "videodev: \"%s\" has no ioctl_ops.\n",
642 vfd->name);
643 return -EINVAL;
646 #ifdef CONFIG_VIDEO_V4L1_COMPAT
647 /***********************************************************
648 Handles calls to the obsoleted V4L1 API
649 Due to the nature of VIDIOCGMBUF, each driver that supports
650 V4L1 should implement its own handler for this ioctl.
651 ***********************************************************/
653 /* --- streaming capture ------------------------------------- */
654 if (cmd == VIDIOCGMBUF) {
655 struct video_mbuf *p = arg;
657 memset(p, 0, sizeof(*p));
659 if (!ops->vidiocgmbuf)
660 return ret;
661 ret = ops->vidiocgmbuf(file, fh, p);
662 if (!ret)
663 dbgarg(cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
664 p->size, p->frames,
665 (unsigned long)p->offsets);
666 return ret;
669 /********************************************************
670 All other V4L1 calls are handled by v4l1_compat module.
671 Those calls will be translated into V4L2 calls, and
672 __video_do_ioctl will be called again, with one or more
673 V4L2 ioctls.
674 ********************************************************/
675 if (_IOC_TYPE(cmd) == 'v' && _IOC_NR(cmd) < BASE_VIDIOCPRIVATE)
676 return v4l_compat_translate_ioctl(file, cmd, arg,
677 __video_do_ioctl);
678 #endif
680 switch (cmd) {
681 /* --- capabilities ------------------------------------------ */
682 case VIDIOC_QUERYCAP:
684 struct v4l2_capability *cap = (struct v4l2_capability *)arg;
685 memset(cap, 0, sizeof(*cap));
687 if (!ops->vidioc_querycap)
688 break;
690 ret = ops->vidioc_querycap(file, fh, cap);
691 if (!ret)
692 dbgarg(cmd, "driver=%s, card=%s, bus=%s, "
693 "version=0x%08x, "
694 "capabilities=0x%08x\n",
695 cap->driver, cap->card, cap->bus_info,
696 cap->version,
697 cap->capabilities);
698 break;
701 /* --- priority ------------------------------------------ */
702 case VIDIOC_G_PRIORITY:
704 enum v4l2_priority *p = arg;
706 if (!ops->vidioc_g_priority)
707 break;
708 ret = ops->vidioc_g_priority(file, fh, p);
709 if (!ret)
710 dbgarg(cmd, "priority is %d\n", *p);
711 break;
713 case VIDIOC_S_PRIORITY:
715 enum v4l2_priority *p = arg;
717 if (!ops->vidioc_s_priority)
718 break;
719 dbgarg(cmd, "setting priority to %d\n", *p);
720 ret = ops->vidioc_s_priority(file, fh, *p);
721 break;
724 /* --- capture ioctls ---------------------------------------- */
725 case VIDIOC_ENUM_FMT:
727 struct v4l2_fmtdesc *f = arg;
728 enum v4l2_buf_type type;
729 unsigned int index;
731 index = f->index;
732 type = f->type;
733 memset(f, 0, sizeof(*f));
734 f->index = index;
735 f->type = type;
737 switch (type) {
738 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
739 if (ops->vidioc_enum_fmt_vid_cap)
740 ret = ops->vidioc_enum_fmt_vid_cap(file, fh, f);
741 break;
742 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
743 if (ops->vidioc_enum_fmt_vid_overlay)
744 ret = ops->vidioc_enum_fmt_vid_overlay(file,
745 fh, f);
746 break;
747 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
748 if (ops->vidioc_enum_fmt_vid_out)
749 ret = ops->vidioc_enum_fmt_vid_out(file, fh, f);
750 break;
751 case V4L2_BUF_TYPE_PRIVATE:
752 if (ops->vidioc_enum_fmt_type_private)
753 ret = ops->vidioc_enum_fmt_type_private(file,
754 fh, f);
755 break;
756 default:
757 break;
759 if (!ret)
760 dbgarg(cmd, "index=%d, type=%d, flags=%d, "
761 "pixelformat=%c%c%c%c, description='%s'\n",
762 f->index, f->type, f->flags,
763 (f->pixelformat & 0xff),
764 (f->pixelformat >> 8) & 0xff,
765 (f->pixelformat >> 16) & 0xff,
766 (f->pixelformat >> 24) & 0xff,
767 f->description);
768 break;
770 case VIDIOC_G_FMT:
772 struct v4l2_format *f = (struct v4l2_format *)arg;
774 memset(f->fmt.raw_data, 0, sizeof(f->fmt.raw_data));
776 /* FIXME: Should be one dump per type */
777 dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
779 switch (f->type) {
780 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
781 if (ops->vidioc_g_fmt_vid_cap)
782 ret = ops->vidioc_g_fmt_vid_cap(file, fh, f);
783 if (!ret)
784 v4l_print_pix_fmt(vfd, &f->fmt.pix);
785 break;
786 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
787 if (ops->vidioc_g_fmt_vid_overlay)
788 ret = ops->vidioc_g_fmt_vid_overlay(file,
789 fh, f);
790 break;
791 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
792 if (ops->vidioc_g_fmt_vid_out)
793 ret = ops->vidioc_g_fmt_vid_out(file, fh, f);
794 if (!ret)
795 v4l_print_pix_fmt(vfd, &f->fmt.pix);
796 break;
797 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
798 if (ops->vidioc_g_fmt_vid_out_overlay)
799 ret = ops->vidioc_g_fmt_vid_out_overlay(file,
800 fh, f);
801 break;
802 case V4L2_BUF_TYPE_VBI_CAPTURE:
803 if (ops->vidioc_g_fmt_vbi_cap)
804 ret = ops->vidioc_g_fmt_vbi_cap(file, fh, f);
805 break;
806 case V4L2_BUF_TYPE_VBI_OUTPUT:
807 if (ops->vidioc_g_fmt_vbi_out)
808 ret = ops->vidioc_g_fmt_vbi_out(file, fh, f);
809 break;
810 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
811 if (ops->vidioc_g_fmt_sliced_vbi_cap)
812 ret = ops->vidioc_g_fmt_sliced_vbi_cap(file,
813 fh, f);
814 break;
815 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
816 if (ops->vidioc_g_fmt_sliced_vbi_out)
817 ret = ops->vidioc_g_fmt_sliced_vbi_out(file,
818 fh, f);
819 break;
820 case V4L2_BUF_TYPE_PRIVATE:
821 if (ops->vidioc_g_fmt_type_private)
822 ret = ops->vidioc_g_fmt_type_private(file,
823 fh, f);
824 break;
827 break;
829 case VIDIOC_S_FMT:
831 struct v4l2_format *f = (struct v4l2_format *)arg;
833 /* FIXME: Should be one dump per type */
834 dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
836 switch (f->type) {
837 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
838 v4l_print_pix_fmt(vfd, &f->fmt.pix);
839 if (ops->vidioc_s_fmt_vid_cap)
840 ret = ops->vidioc_s_fmt_vid_cap(file, fh, f);
841 break;
842 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
843 if (ops->vidioc_s_fmt_vid_overlay)
844 ret = ops->vidioc_s_fmt_vid_overlay(file,
845 fh, f);
846 break;
847 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
848 v4l_print_pix_fmt(vfd, &f->fmt.pix);
849 if (ops->vidioc_s_fmt_vid_out)
850 ret = ops->vidioc_s_fmt_vid_out(file, fh, f);
851 break;
852 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
853 if (ops->vidioc_s_fmt_vid_out_overlay)
854 ret = ops->vidioc_s_fmt_vid_out_overlay(file,
855 fh, f);
856 break;
857 case V4L2_BUF_TYPE_VBI_CAPTURE:
858 if (ops->vidioc_s_fmt_vbi_cap)
859 ret = ops->vidioc_s_fmt_vbi_cap(file, fh, f);
860 break;
861 case V4L2_BUF_TYPE_VBI_OUTPUT:
862 if (ops->vidioc_s_fmt_vbi_out)
863 ret = ops->vidioc_s_fmt_vbi_out(file, fh, f);
864 break;
865 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
866 if (ops->vidioc_s_fmt_sliced_vbi_cap)
867 ret = ops->vidioc_s_fmt_sliced_vbi_cap(file,
868 fh, f);
869 break;
870 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
871 if (ops->vidioc_s_fmt_sliced_vbi_out)
872 ret = ops->vidioc_s_fmt_sliced_vbi_out(file,
873 fh, f);
874 break;
875 case V4L2_BUF_TYPE_PRIVATE:
876 if (ops->vidioc_s_fmt_type_private)
877 ret = ops->vidioc_s_fmt_type_private(file,
878 fh, f);
879 break;
881 break;
883 case VIDIOC_TRY_FMT:
885 struct v4l2_format *f = (struct v4l2_format *)arg;
887 /* FIXME: Should be one dump per type */
888 dbgarg(cmd, "type=%s\n", prt_names(f->type,
889 v4l2_type_names));
890 switch (f->type) {
891 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
892 if (ops->vidioc_try_fmt_vid_cap)
893 ret = ops->vidioc_try_fmt_vid_cap(file, fh, f);
894 if (!ret)
895 v4l_print_pix_fmt(vfd, &f->fmt.pix);
896 break;
897 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
898 if (ops->vidioc_try_fmt_vid_overlay)
899 ret = ops->vidioc_try_fmt_vid_overlay(file,
900 fh, f);
901 break;
902 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
903 if (ops->vidioc_try_fmt_vid_out)
904 ret = ops->vidioc_try_fmt_vid_out(file, fh, f);
905 if (!ret)
906 v4l_print_pix_fmt(vfd, &f->fmt.pix);
907 break;
908 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
909 if (ops->vidioc_try_fmt_vid_out_overlay)
910 ret = ops->vidioc_try_fmt_vid_out_overlay(file,
911 fh, f);
912 break;
913 case V4L2_BUF_TYPE_VBI_CAPTURE:
914 if (ops->vidioc_try_fmt_vbi_cap)
915 ret = ops->vidioc_try_fmt_vbi_cap(file, fh, f);
916 break;
917 case V4L2_BUF_TYPE_VBI_OUTPUT:
918 if (ops->vidioc_try_fmt_vbi_out)
919 ret = ops->vidioc_try_fmt_vbi_out(file, fh, f);
920 break;
921 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
922 if (ops->vidioc_try_fmt_sliced_vbi_cap)
923 ret = ops->vidioc_try_fmt_sliced_vbi_cap(file,
924 fh, f);
925 break;
926 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
927 if (ops->vidioc_try_fmt_sliced_vbi_out)
928 ret = ops->vidioc_try_fmt_sliced_vbi_out(file,
929 fh, f);
930 break;
931 case V4L2_BUF_TYPE_PRIVATE:
932 if (ops->vidioc_try_fmt_type_private)
933 ret = ops->vidioc_try_fmt_type_private(file,
934 fh, f);
935 break;
938 break;
940 /* FIXME: Those buf reqs could be handled here,
941 with some changes on videobuf to allow its header to be included at
942 videodev2.h or being merged at videodev2.
944 case VIDIOC_REQBUFS:
946 struct v4l2_requestbuffers *p = arg;
948 if (!ops->vidioc_reqbufs)
949 break;
950 ret = check_fmt(ops, p->type);
951 if (ret)
952 break;
954 ret = ops->vidioc_reqbufs(file, fh, p);
955 dbgarg(cmd, "count=%d, type=%s, memory=%s\n",
956 p->count,
957 prt_names(p->type, v4l2_type_names),
958 prt_names(p->memory, v4l2_memory_names));
959 break;
961 case VIDIOC_QUERYBUF:
963 struct v4l2_buffer *p = arg;
965 if (!ops->vidioc_querybuf)
966 break;
967 ret = check_fmt(ops, p->type);
968 if (ret)
969 break;
971 ret = ops->vidioc_querybuf(file, fh, p);
972 if (!ret)
973 dbgbuf(cmd, vfd, p);
974 break;
976 case VIDIOC_QBUF:
978 struct v4l2_buffer *p = arg;
980 if (!ops->vidioc_qbuf)
981 break;
982 ret = check_fmt(ops, p->type);
983 if (ret)
984 break;
986 ret = ops->vidioc_qbuf(file, fh, p);
987 if (!ret)
988 dbgbuf(cmd, vfd, p);
989 break;
991 case VIDIOC_DQBUF:
993 struct v4l2_buffer *p = arg;
995 if (!ops->vidioc_dqbuf)
996 break;
997 ret = check_fmt(ops, p->type);
998 if (ret)
999 break;
1001 ret = ops->vidioc_dqbuf(file, fh, p);
1002 if (!ret)
1003 dbgbuf(cmd, vfd, p);
1004 break;
1006 case VIDIOC_OVERLAY:
1008 int *i = arg;
1010 if (!ops->vidioc_overlay)
1011 break;
1012 dbgarg(cmd, "value=%d\n", *i);
1013 ret = ops->vidioc_overlay(file, fh, *i);
1014 break;
1016 case VIDIOC_G_FBUF:
1018 struct v4l2_framebuffer *p = arg;
1020 if (!ops->vidioc_g_fbuf)
1021 break;
1022 ret = ops->vidioc_g_fbuf(file, fh, arg);
1023 if (!ret) {
1024 dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
1025 p->capability, p->flags,
1026 (unsigned long)p->base);
1027 v4l_print_pix_fmt(vfd, &p->fmt);
1029 break;
1031 case VIDIOC_S_FBUF:
1033 struct v4l2_framebuffer *p = arg;
1035 if (!ops->vidioc_s_fbuf)
1036 break;
1037 dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
1038 p->capability, p->flags, (unsigned long)p->base);
1039 v4l_print_pix_fmt(vfd, &p->fmt);
1040 ret = ops->vidioc_s_fbuf(file, fh, arg);
1041 break;
1043 case VIDIOC_STREAMON:
1045 enum v4l2_buf_type i = *(int *)arg;
1047 if (!ops->vidioc_streamon)
1048 break;
1049 dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
1050 ret = ops->vidioc_streamon(file, fh, i);
1051 break;
1053 case VIDIOC_STREAMOFF:
1055 enum v4l2_buf_type i = *(int *)arg;
1057 if (!ops->vidioc_streamoff)
1058 break;
1059 dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
1060 ret = ops->vidioc_streamoff(file, fh, i);
1061 break;
1063 /* ---------- tv norms ---------- */
1064 case VIDIOC_ENUMSTD:
1066 struct v4l2_standard *p = arg;
1067 v4l2_std_id id = vfd->tvnorms, curr_id = 0;
1068 unsigned int index = p->index, i, j = 0;
1069 const char *descr = "";
1071 /* Return norm array in a canonical way */
1072 for (i = 0; i <= index && id; i++) {
1073 /* last std value in the standards array is 0, so this
1074 while always ends there since (id & 0) == 0. */
1075 while ((id & standards[j].std) != standards[j].std)
1076 j++;
1077 curr_id = standards[j].std;
1078 descr = standards[j].descr;
1079 j++;
1080 if (curr_id == 0)
1081 break;
1082 if (curr_id != V4L2_STD_PAL &&
1083 curr_id != V4L2_STD_SECAM &&
1084 curr_id != V4L2_STD_NTSC)
1085 id &= ~curr_id;
1087 if (i <= index)
1088 return -EINVAL;
1090 v4l2_video_std_construct(p, curr_id, descr);
1091 p->index = index;
1093 dbgarg(cmd, "index=%d, id=0x%Lx, name=%s, fps=%d/%d, "
1094 "framelines=%d\n", p->index,
1095 (unsigned long long)p->id, p->name,
1096 p->frameperiod.numerator,
1097 p->frameperiod.denominator,
1098 p->framelines);
1100 ret = 0;
1101 break;
1103 case VIDIOC_G_STD:
1105 v4l2_std_id *id = arg;
1107 ret = 0;
1108 /* Calls the specific handler */
1109 if (ops->vidioc_g_std)
1110 ret = ops->vidioc_g_std(file, fh, id);
1111 else
1112 *id = vfd->current_norm;
1114 if (!ret)
1115 dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id);
1116 break;
1118 case VIDIOC_S_STD:
1120 v4l2_std_id *id = arg, norm;
1122 dbgarg(cmd, "std=%08Lx\n", (long long unsigned)*id);
1124 norm = (*id) & vfd->tvnorms;
1125 if (vfd->tvnorms && !norm) /* Check if std is supported */
1126 break;
1128 /* Calls the specific handler */
1129 if (ops->vidioc_s_std)
1130 ret = ops->vidioc_s_std(file, fh, &norm);
1131 else
1132 ret = -EINVAL;
1134 /* Updates standard information */
1135 if (ret >= 0)
1136 vfd->current_norm = norm;
1137 break;
1139 case VIDIOC_QUERYSTD:
1141 v4l2_std_id *p = arg;
1143 if (!ops->vidioc_querystd)
1144 break;
1145 ret = ops->vidioc_querystd(file, fh, arg);
1146 if (!ret)
1147 dbgarg(cmd, "detected std=%08Lx\n",
1148 (unsigned long long)*p);
1149 break;
1151 /* ------ input switching ---------- */
1152 /* FIXME: Inputs can be handled inside videodev2 */
1153 case VIDIOC_ENUMINPUT:
1155 struct v4l2_input *p = arg;
1156 int i = p->index;
1158 if (!ops->vidioc_enum_input)
1159 break;
1160 memset(p, 0, sizeof(*p));
1161 p->index = i;
1163 ret = ops->vidioc_enum_input(file, fh, p);
1164 if (!ret)
1165 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1166 "audioset=%d, "
1167 "tuner=%d, std=%08Lx, status=%d\n",
1168 p->index, p->name, p->type, p->audioset,
1169 p->tuner,
1170 (unsigned long long)p->std,
1171 p->status);
1172 break;
1174 case VIDIOC_G_INPUT:
1176 unsigned int *i = arg;
1178 if (!ops->vidioc_g_input)
1179 break;
1180 ret = ops->vidioc_g_input(file, fh, i);
1181 if (!ret)
1182 dbgarg(cmd, "value=%d\n", *i);
1183 break;
1185 case VIDIOC_S_INPUT:
1187 unsigned int *i = arg;
1189 if (!ops->vidioc_s_input)
1190 break;
1191 dbgarg(cmd, "value=%d\n", *i);
1192 ret = ops->vidioc_s_input(file, fh, *i);
1193 break;
1196 /* ------ output switching ---------- */
1197 case VIDIOC_ENUMOUTPUT:
1199 struct v4l2_output *p = arg;
1200 int i = p->index;
1202 if (!ops->vidioc_enum_output)
1203 break;
1204 memset(p, 0, sizeof(*p));
1205 p->index = i;
1207 ret = ops->vidioc_enum_output(file, fh, p);
1208 if (!ret)
1209 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1210 "audioset=0x%x, "
1211 "modulator=%d, std=0x%08Lx\n",
1212 p->index, p->name, p->type, p->audioset,
1213 p->modulator, (unsigned long long)p->std);
1214 break;
1216 case VIDIOC_G_OUTPUT:
1218 unsigned int *i = arg;
1220 if (!ops->vidioc_g_output)
1221 break;
1222 ret = ops->vidioc_g_output(file, fh, i);
1223 if (!ret)
1224 dbgarg(cmd, "value=%d\n", *i);
1225 break;
1227 case VIDIOC_S_OUTPUT:
1229 unsigned int *i = arg;
1231 if (!ops->vidioc_s_output)
1232 break;
1233 dbgarg(cmd, "value=%d\n", *i);
1234 ret = ops->vidioc_s_output(file, fh, *i);
1235 break;
1238 /* --- controls ---------------------------------------------- */
1239 case VIDIOC_QUERYCTRL:
1241 struct v4l2_queryctrl *p = arg;
1243 if (!ops->vidioc_queryctrl)
1244 break;
1245 ret = ops->vidioc_queryctrl(file, fh, p);
1246 if (!ret)
1247 dbgarg(cmd, "id=0x%x, type=%d, name=%s, min/max=%d/%d, "
1248 "step=%d, default=%d, flags=0x%08x\n",
1249 p->id, p->type, p->name,
1250 p->minimum, p->maximum,
1251 p->step, p->default_value, p->flags);
1252 else
1253 dbgarg(cmd, "id=0x%x\n", p->id);
1254 break;
1256 case VIDIOC_G_CTRL:
1258 struct v4l2_control *p = arg;
1260 if (ops->vidioc_g_ctrl)
1261 ret = ops->vidioc_g_ctrl(file, fh, p);
1262 else if (ops->vidioc_g_ext_ctrls) {
1263 struct v4l2_ext_controls ctrls;
1264 struct v4l2_ext_control ctrl;
1266 ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
1267 ctrls.count = 1;
1268 ctrls.controls = &ctrl;
1269 ctrl.id = p->id;
1270 ctrl.value = p->value;
1271 if (check_ext_ctrls(&ctrls, 1)) {
1272 ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls);
1273 if (ret == 0)
1274 p->value = ctrl.value;
1276 } else
1277 break;
1278 if (!ret)
1279 dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
1280 else
1281 dbgarg(cmd, "id=0x%x\n", p->id);
1282 break;
1284 case VIDIOC_S_CTRL:
1286 struct v4l2_control *p = arg;
1287 struct v4l2_ext_controls ctrls;
1288 struct v4l2_ext_control ctrl;
1290 if (!ops->vidioc_s_ctrl && !ops->vidioc_s_ext_ctrls)
1291 break;
1293 dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
1295 if (ops->vidioc_s_ctrl) {
1296 ret = ops->vidioc_s_ctrl(file, fh, p);
1297 break;
1299 if (!ops->vidioc_s_ext_ctrls)
1300 break;
1302 ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
1303 ctrls.count = 1;
1304 ctrls.controls = &ctrl;
1305 ctrl.id = p->id;
1306 ctrl.value = p->value;
1307 if (check_ext_ctrls(&ctrls, 1))
1308 ret = ops->vidioc_s_ext_ctrls(file, fh, &ctrls);
1309 break;
1311 case VIDIOC_G_EXT_CTRLS:
1313 struct v4l2_ext_controls *p = arg;
1315 p->error_idx = p->count;
1316 if (!ops->vidioc_g_ext_ctrls)
1317 break;
1318 if (check_ext_ctrls(p, 0))
1319 ret = ops->vidioc_g_ext_ctrls(file, fh, p);
1320 v4l_print_ext_ctrls(cmd, vfd, p, !ret);
1321 break;
1323 case VIDIOC_S_EXT_CTRLS:
1325 struct v4l2_ext_controls *p = arg;
1327 p->error_idx = p->count;
1328 if (!ops->vidioc_s_ext_ctrls)
1329 break;
1330 v4l_print_ext_ctrls(cmd, vfd, p, 1);
1331 if (check_ext_ctrls(p, 0))
1332 ret = ops->vidioc_s_ext_ctrls(file, fh, p);
1333 break;
1335 case VIDIOC_TRY_EXT_CTRLS:
1337 struct v4l2_ext_controls *p = arg;
1339 p->error_idx = p->count;
1340 if (!ops->vidioc_try_ext_ctrls)
1341 break;
1342 v4l_print_ext_ctrls(cmd, vfd, p, 1);
1343 if (check_ext_ctrls(p, 0))
1344 ret = ops->vidioc_try_ext_ctrls(file, fh, p);
1345 break;
1347 case VIDIOC_QUERYMENU:
1349 struct v4l2_querymenu *p = arg;
1351 if (!ops->vidioc_querymenu)
1352 break;
1353 ret = ops->vidioc_querymenu(file, fh, p);
1354 if (!ret)
1355 dbgarg(cmd, "id=0x%x, index=%d, name=%s\n",
1356 p->id, p->index, p->name);
1357 else
1358 dbgarg(cmd, "id=0x%x, index=%d\n",
1359 p->id, p->index);
1360 break;
1362 /* --- audio ---------------------------------------------- */
1363 case VIDIOC_ENUMAUDIO:
1365 struct v4l2_audio *p = arg;
1367 if (!ops->vidioc_enumaudio)
1368 break;
1369 ret = ops->vidioc_enumaudio(file, fh, p);
1370 if (!ret)
1371 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
1372 "mode=0x%x\n", p->index, p->name,
1373 p->capability, p->mode);
1374 else
1375 dbgarg(cmd, "index=%d\n", p->index);
1376 break;
1378 case VIDIOC_G_AUDIO:
1380 struct v4l2_audio *p = arg;
1381 __u32 index = p->index;
1383 if (!ops->vidioc_g_audio)
1384 break;
1386 memset(p, 0, sizeof(*p));
1387 p->index = index;
1388 ret = ops->vidioc_g_audio(file, fh, p);
1389 if (!ret)
1390 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
1391 "mode=0x%x\n", p->index,
1392 p->name, p->capability, p->mode);
1393 else
1394 dbgarg(cmd, "index=%d\n", p->index);
1395 break;
1397 case VIDIOC_S_AUDIO:
1399 struct v4l2_audio *p = arg;
1401 if (!ops->vidioc_s_audio)
1402 break;
1403 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
1404 "mode=0x%x\n", p->index, p->name,
1405 p->capability, p->mode);
1406 ret = ops->vidioc_s_audio(file, fh, p);
1407 break;
1409 case VIDIOC_ENUMAUDOUT:
1411 struct v4l2_audioout *p = arg;
1413 if (!ops->vidioc_enumaudout)
1414 break;
1415 dbgarg(cmd, "Enum for index=%d\n", p->index);
1416 ret = ops->vidioc_enumaudout(file, fh, p);
1417 if (!ret)
1418 dbgarg2("index=%d, name=%s, capability=%d, "
1419 "mode=%d\n", p->index, p->name,
1420 p->capability, p->mode);
1421 break;
1423 case VIDIOC_G_AUDOUT:
1425 struct v4l2_audioout *p = arg;
1427 if (!ops->vidioc_g_audout)
1428 break;
1429 dbgarg(cmd, "Enum for index=%d\n", p->index);
1430 ret = ops->vidioc_g_audout(file, fh, p);
1431 if (!ret)
1432 dbgarg2("index=%d, name=%s, capability=%d, "
1433 "mode=%d\n", p->index, p->name,
1434 p->capability, p->mode);
1435 break;
1437 case VIDIOC_S_AUDOUT:
1439 struct v4l2_audioout *p = arg;
1441 if (!ops->vidioc_s_audout)
1442 break;
1443 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1444 "mode=%d\n", p->index, p->name,
1445 p->capability, p->mode);
1447 ret = ops->vidioc_s_audout(file, fh, p);
1448 break;
1450 case VIDIOC_G_MODULATOR:
1452 struct v4l2_modulator *p = arg;
1454 if (!ops->vidioc_g_modulator)
1455 break;
1456 ret = ops->vidioc_g_modulator(file, fh, p);
1457 if (!ret)
1458 dbgarg(cmd, "index=%d, name=%s, "
1459 "capability=%d, rangelow=%d,"
1460 " rangehigh=%d, txsubchans=%d\n",
1461 p->index, p->name, p->capability,
1462 p->rangelow, p->rangehigh,
1463 p->txsubchans);
1464 break;
1466 case VIDIOC_S_MODULATOR:
1468 struct v4l2_modulator *p = arg;
1470 if (!ops->vidioc_s_modulator)
1471 break;
1472 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1473 "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
1474 p->index, p->name, p->capability, p->rangelow,
1475 p->rangehigh, p->txsubchans);
1476 ret = ops->vidioc_s_modulator(file, fh, p);
1477 break;
1479 case VIDIOC_G_CROP:
1481 struct v4l2_crop *p = arg;
1482 __u32 type;
1484 if (!ops->vidioc_g_crop)
1485 break;
1487 type = p->type;
1488 memset(p, 0, sizeof(*p));
1489 p->type = type;
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;
1511 __u32 type;
1513 /*FIXME: Should also show v4l2_fract pixelaspect */
1514 if (!ops->vidioc_cropcap)
1515 break;
1517 type = p->type;
1518 memset(p, 0, sizeof(*p));
1519 p->type = type;
1521 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1522 ret = ops->vidioc_cropcap(file, fh, p);
1523 if (!ret) {
1524 dbgrect(vfd, "bounds ", &p->bounds);
1525 dbgrect(vfd, "defrect ", &p->defrect);
1527 break;
1529 case VIDIOC_G_JPEGCOMP:
1531 struct v4l2_jpegcompression *p = arg;
1533 if (!ops->vidioc_g_jpegcomp)
1534 break;
1536 memset(p, 0, sizeof(*p));
1538 ret = ops->vidioc_g_jpegcomp(file, fh, p);
1539 if (!ret)
1540 dbgarg(cmd, "quality=%d, APPn=%d, "
1541 "APP_len=%d, COM_len=%d, "
1542 "jpeg_markers=%d\n",
1543 p->quality, p->APPn, p->APP_len,
1544 p->COM_len, p->jpeg_markers);
1545 break;
1547 case VIDIOC_S_JPEGCOMP:
1549 struct v4l2_jpegcompression *p = arg;
1551 if (!ops->vidioc_g_jpegcomp)
1552 break;
1553 dbgarg(cmd, "quality=%d, APPn=%d, APP_len=%d, "
1554 "COM_len=%d, jpeg_markers=%d\n",
1555 p->quality, p->APPn, p->APP_len,
1556 p->COM_len, p->jpeg_markers);
1557 ret = ops->vidioc_s_jpegcomp(file, fh, p);
1558 break;
1560 case VIDIOC_G_ENC_INDEX:
1562 struct v4l2_enc_idx *p = arg;
1564 if (!ops->vidioc_g_enc_index)
1565 break;
1566 ret = ops->vidioc_g_enc_index(file, fh, p);
1567 if (!ret)
1568 dbgarg(cmd, "entries=%d, entries_cap=%d\n",
1569 p->entries, p->entries_cap);
1570 break;
1572 case VIDIOC_ENCODER_CMD:
1574 struct v4l2_encoder_cmd *p = arg;
1576 if (!ops->vidioc_encoder_cmd)
1577 break;
1578 memset(&p->raw, 0, sizeof(p->raw));
1579 ret = ops->vidioc_encoder_cmd(file, fh, p);
1580 if (!ret)
1581 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
1582 break;
1584 case VIDIOC_TRY_ENCODER_CMD:
1586 struct v4l2_encoder_cmd *p = arg;
1588 if (!ops->vidioc_try_encoder_cmd)
1589 break;
1590 memset(&p->raw, 0, sizeof(p->raw));
1591 ret = ops->vidioc_try_encoder_cmd(file, fh, p);
1592 if (!ret)
1593 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
1594 break;
1596 case VIDIOC_G_PARM:
1598 struct v4l2_streamparm *p = arg;
1599 __u32 type = p->type;
1601 memset(p, 0, sizeof(*p));
1602 p->type = type;
1604 if (ops->vidioc_g_parm) {
1605 ret = ops->vidioc_g_parm(file, fh, p);
1606 } else {
1607 struct v4l2_standard s;
1609 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1610 return -EINVAL;
1612 v4l2_video_std_construct(&s, vfd->current_norm,
1613 v4l2_norm_to_name(vfd->current_norm));
1615 p->parm.capture.timeperframe = s.frameperiod;
1616 ret = 0;
1619 dbgarg(cmd, "type=%d\n", p->type);
1620 break;
1622 case VIDIOC_S_PARM:
1624 struct v4l2_streamparm *p = arg;
1626 if (!ops->vidioc_s_parm)
1627 break;
1628 dbgarg(cmd, "type=%d\n", p->type);
1629 ret = ops->vidioc_s_parm(file, fh, p);
1630 break;
1632 case VIDIOC_G_TUNER:
1634 struct v4l2_tuner *p = arg;
1635 __u32 index = p->index;
1637 if (!ops->vidioc_g_tuner)
1638 break;
1640 memset(p, 0, sizeof(*p));
1641 p->index = index;
1643 ret = ops->vidioc_g_tuner(file, fh, p);
1644 if (!ret)
1645 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1646 "capability=0x%x, rangelow=%d, "
1647 "rangehigh=%d, signal=%d, afc=%d, "
1648 "rxsubchans=0x%x, audmode=%d\n",
1649 p->index, p->name, p->type,
1650 p->capability, p->rangelow,
1651 p->rangehigh, p->signal, p->afc,
1652 p->rxsubchans, p->audmode);
1653 break;
1655 case VIDIOC_S_TUNER:
1657 struct v4l2_tuner *p = arg;
1659 if (!ops->vidioc_s_tuner)
1660 break;
1661 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1662 "capability=0x%x, rangelow=%d, "
1663 "rangehigh=%d, signal=%d, afc=%d, "
1664 "rxsubchans=0x%x, audmode=%d\n",
1665 p->index, p->name, p->type,
1666 p->capability, p->rangelow,
1667 p->rangehigh, p->signal, p->afc,
1668 p->rxsubchans, p->audmode);
1669 ret = ops->vidioc_s_tuner(file, fh, p);
1670 break;
1672 case VIDIOC_G_FREQUENCY:
1674 struct v4l2_frequency *p = arg;
1676 if (!ops->vidioc_g_frequency)
1677 break;
1679 memset(p->reserved, 0, sizeof(p->reserved));
1681 ret = ops->vidioc_g_frequency(file, fh, p);
1682 if (!ret)
1683 dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
1684 p->tuner, p->type, p->frequency);
1685 break;
1687 case VIDIOC_S_FREQUENCY:
1689 struct v4l2_frequency *p = arg;
1691 if (!ops->vidioc_s_frequency)
1692 break;
1693 dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
1694 p->tuner, p->type, p->frequency);
1695 ret = ops->vidioc_s_frequency(file, fh, p);
1696 break;
1698 case VIDIOC_G_SLICED_VBI_CAP:
1700 struct v4l2_sliced_vbi_cap *p = arg;
1701 __u32 type = p->type;
1703 if (!ops->vidioc_g_sliced_vbi_cap)
1704 break;
1705 memset(p, 0, sizeof(*p));
1706 p->type = type;
1707 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1708 ret = ops->vidioc_g_sliced_vbi_cap(file, fh, p);
1709 if (!ret)
1710 dbgarg2("service_set=%d\n", p->service_set);
1711 break;
1713 case VIDIOC_LOG_STATUS:
1715 if (!ops->vidioc_log_status)
1716 break;
1717 ret = ops->vidioc_log_status(file, fh);
1718 break;
1720 #ifdef CONFIG_VIDEO_ADV_DEBUG
1721 case VIDIOC_DBG_G_REGISTER:
1723 struct v4l2_register *p = arg;
1725 if (!capable(CAP_SYS_ADMIN))
1726 ret = -EPERM;
1727 else if (ops->vidioc_g_register)
1728 ret = ops->vidioc_g_register(file, fh, p);
1729 break;
1731 case VIDIOC_DBG_S_REGISTER:
1733 struct v4l2_register *p = arg;
1735 if (!capable(CAP_SYS_ADMIN))
1736 ret = -EPERM;
1737 else if (ops->vidioc_s_register)
1738 ret = ops->vidioc_s_register(file, fh, p);
1739 break;
1741 #endif
1742 case VIDIOC_G_CHIP_IDENT:
1744 struct v4l2_chip_ident *p = arg;
1746 if (!ops->vidioc_g_chip_ident)
1747 break;
1748 ret = ops->vidioc_g_chip_ident(file, fh, p);
1749 if (!ret)
1750 dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
1751 break;
1753 case VIDIOC_S_HW_FREQ_SEEK:
1755 struct v4l2_hw_freq_seek *p = arg;
1757 if (!ops->vidioc_s_hw_freq_seek)
1758 break;
1759 dbgarg(cmd,
1760 "tuner=%d, type=%d, seek_upward=%d, wrap_around=%d\n",
1761 p->tuner, p->type, p->seek_upward, p->wrap_around);
1762 ret = ops->vidioc_s_hw_freq_seek(file, fh, p);
1763 break;
1765 case VIDIOC_ENUM_FRAMESIZES:
1767 struct v4l2_frmsizeenum *p = arg;
1769 if (!ops->vidioc_enum_framesizes)
1770 break;
1772 memset(p, 0, sizeof(*p));
1774 ret = ops->vidioc_enum_framesizes(file, fh, p);
1775 dbgarg(cmd,
1776 "index=%d, pixelformat=%d, type=%d ",
1777 p->index, p->pixel_format, p->type);
1778 switch (p->type) {
1779 case V4L2_FRMSIZE_TYPE_DISCRETE:
1780 dbgarg2("width = %d, height=%d\n",
1781 p->discrete.width, p->discrete.height);
1782 break;
1783 case V4L2_FRMSIZE_TYPE_STEPWISE:
1784 dbgarg2("min %dx%d, max %dx%d, step %dx%d\n",
1785 p->stepwise.min_width, p->stepwise.min_height,
1786 p->stepwise.step_width, p->stepwise.step_height,
1787 p->stepwise.max_width, p->stepwise.max_height);
1788 break;
1789 case V4L2_FRMSIZE_TYPE_CONTINUOUS:
1790 dbgarg2("continuous\n");
1791 break;
1792 default:
1793 dbgarg2("- Unknown type!\n");
1796 break;
1798 case VIDIOC_ENUM_FRAMEINTERVALS:
1800 struct v4l2_frmivalenum *p = arg;
1802 if (!ops->vidioc_enum_frameintervals)
1803 break;
1805 memset(p, 0, sizeof(*p));
1807 ret = ops->vidioc_enum_frameintervals(file, fh, p);
1808 dbgarg(cmd,
1809 "index=%d, pixelformat=%d, width=%d, height=%d, type=%d ",
1810 p->index, p->pixel_format,
1811 p->width, p->height, p->type);
1812 switch (p->type) {
1813 case V4L2_FRMIVAL_TYPE_DISCRETE:
1814 dbgarg2("fps=%d/%d\n",
1815 p->discrete.numerator,
1816 p->discrete.denominator);
1817 break;
1818 case V4L2_FRMIVAL_TYPE_STEPWISE:
1819 dbgarg2("min=%d, max=%d, step=%d\n",
1820 p->stepwise.min, p->stepwise.max,
1821 p->stepwise.step);
1822 break;
1823 case V4L2_FRMIVAL_TYPE_CONTINUOUS:
1824 dbgarg2("continuous\n");
1825 break;
1826 default:
1827 dbgarg2("- Unknown type!\n");
1829 break;
1832 default:
1834 if (!ops->vidioc_default)
1835 break;
1836 ret = ops->vidioc_default(file, fh, cmd, arg);
1837 break;
1839 } /* switch */
1841 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1842 if (ret < 0) {
1843 v4l_print_ioctl(vfd->name, cmd);
1844 printk(KERN_CONT " error %d\n", ret);
1848 return ret;
1851 int __video_ioctl2(struct file *file,
1852 unsigned int cmd, unsigned long arg)
1854 char sbuf[128];
1855 void *mbuf = NULL;
1856 void *parg = NULL;
1857 int err = -EINVAL;
1858 int is_ext_ctrl;
1859 size_t ctrls_size = 0;
1860 void __user *user_ptr = NULL;
1862 #ifdef __OLD_VIDIOC_
1863 cmd = video_fix_command(cmd);
1864 #endif
1865 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
1866 cmd == VIDIOC_TRY_EXT_CTRLS);
1868 /* Copy arguments into temp kernel buffer */
1869 switch (_IOC_DIR(cmd)) {
1870 case _IOC_NONE:
1871 parg = NULL;
1872 break;
1873 case _IOC_READ:
1874 case _IOC_WRITE:
1875 case (_IOC_WRITE | _IOC_READ):
1876 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
1877 parg = sbuf;
1878 } else {
1879 /* too big to allocate from stack */
1880 mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
1881 if (NULL == mbuf)
1882 return -ENOMEM;
1883 parg = mbuf;
1886 err = -EFAULT;
1887 if (_IOC_DIR(cmd) & _IOC_WRITE)
1888 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
1889 goto out;
1890 break;
1893 if (is_ext_ctrl) {
1894 struct v4l2_ext_controls *p = parg;
1896 /* In case of an error, tell the caller that it wasn't
1897 a specific control that caused it. */
1898 p->error_idx = p->count;
1899 user_ptr = (void __user *)p->controls;
1900 if (p->count) {
1901 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
1902 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
1903 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
1904 err = -ENOMEM;
1905 if (NULL == mbuf)
1906 goto out_ext_ctrl;
1907 err = -EFAULT;
1908 if (copy_from_user(mbuf, user_ptr, ctrls_size))
1909 goto out_ext_ctrl;
1910 p->controls = mbuf;
1914 /* Handles IOCTL */
1915 err = __video_do_ioctl(file, cmd, parg);
1916 if (err == -ENOIOCTLCMD)
1917 err = -EINVAL;
1918 if (is_ext_ctrl) {
1919 struct v4l2_ext_controls *p = parg;
1921 p->controls = (void *)user_ptr;
1922 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
1923 err = -EFAULT;
1924 goto out_ext_ctrl;
1926 if (err < 0)
1927 goto out;
1929 out_ext_ctrl:
1930 /* Copy results into user buffer */
1931 switch (_IOC_DIR(cmd)) {
1932 case _IOC_READ:
1933 case (_IOC_WRITE | _IOC_READ):
1934 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
1935 err = -EFAULT;
1936 break;
1939 out:
1940 kfree(mbuf);
1941 return err;
1943 EXPORT_SYMBOL(__video_ioctl2);
1945 int video_ioctl2(struct inode *inode, struct file *file,
1946 unsigned int cmd, unsigned long arg)
1948 return __video_ioctl2(file, cmd, arg);
1950 EXPORT_SYMBOL(video_ioctl2);