aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/v4l2-ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/v4l2-ioctl.c')
-rw-r--r--drivers/media/video/v4l2-ioctl.c1865
1 files changed, 1865 insertions, 0 deletions
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
new file mode 100644
index 000000000000..56a4fdee9160
--- /dev/null
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -0,0 +1,1865 @@
1/*
2 * Video capture interface for Linux version 2
3 *
4 * A generic framework to process V4L2 ioctl commands.
5 *
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.
10 *
11 * Authors: Alan Cox, <alan@redhat.com> (version 1)
12 * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2)
13 */
14
15#include <linux/module.h>
16#include <linux/types.h>
17#include <linux/kernel.h>
18
19#define __OLD_VIDIOC_ /* To allow fixing old calls */
20#include <linux/videodev2.h>
21
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>
28
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)
37
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)
43
44struct std_descr {
45 v4l2_std_id std;
46 const char *descr;
47};
48
49static 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" }
81};
82
83/* video4linux standard ID conversion to standard name
84 */
85const char *v4l2_norm_to_name(v4l2_std_id id)
86{
87 u32 myid = id;
88 int i;
89
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.
93 */
94 BUG_ON(myid != id);
95
96 for (i = 0; standards[i].std; i++)
97 if (myid == standards[i].std)
98 break;
99 return standards[i].descr;
100}
101EXPORT_SYMBOL(v4l2_norm_to_name);
102
103/* Fill in the fields of a v4l2_standard structure according to the
104 'id' and 'transmission' parameters. Returns negative on error. */
105int v4l2_video_std_construct(struct v4l2_standard *vs,
106 int id, const char *name)
107{
108 u32 index = vs->index;
109
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;
121 }
122 strlcpy(vs->name, name, sizeof(vs->name));
123 return 0;
124}
125EXPORT_SYMBOL(v4l2_video_std_construct);
126
127/* ----------------------------------------------------------------- */
128/* some arrays for pretty-printing debug messages of enum types */
129
130const 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",
141};
142EXPORT_SYMBOL(v4l2_field_names);
143
144const 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",
153};
154EXPORT_SYMBOL(v4l2_type_names);
155
156static const char *v4l2_memory_names[] = {
157 [V4L2_MEMORY_MMAP] = "mmap",
158 [V4L2_MEMORY_USERPTR] = "userptr",
159 [V4L2_MEMORY_OVERLAY] = "overlay",
160};
161
162#define prt_names(a, arr) ((((a) >= 0) && ((a) < ARRAY_SIZE(arr))) ? \
163 arr[a] : "unknown")
164
165/* ------------------------------------------------------------------ */
166/* debug help functions */
167
168#ifdef CONFIG_VIDEO_V4L1_COMPAT
169static 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"
199};
200#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
201#endif
202
203static 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",
265
266 [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER",
267 [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER",
268
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
272};
273#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
274
275static 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",
290
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",
294
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",
311};
312#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)
313
314/* Common ioctl debug function. This function can be used by
315 external ioctl messages as well as internal V4L ioctl */
316void v4l_printk_ioctl(unsigned int cmd)
317{
318 char *dir, *type;
319
320 switch (_IOC_TYPE(cmd)) {
321 case 'd':
322 if (_IOC_NR(cmd) >= V4L2_INT_IOCTLS) {
323 type = "v4l2_int";
324 break;
325 }
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;
333 }
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;
341 }
342 printk("%s", v4l2_ioctls[_IOC_NR(cmd)]);
343 return;
344 default:
345 type = "unknown";
346 }
347
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;
354 }
355 printk("%s ioctl '%c', dir=%s, #%d (0x%08x)",
356 type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
357}
358EXPORT_SYMBOL(v4l_printk_ioctl);
359
360/*
361 * helper function -- handles userspace copying for ioctl arguments
362 */
363
364#ifdef __OLD_VIDIOC_
365static unsigned int
366video_fix_command(unsigned int cmd)
367{
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;
387 }
388 return cmd;
389}
390#endif
391
392/*
393 * Obsolete usercopy function - Should be removed soon
394 */
395int
396video_usercopy(struct inode *inode, struct file *file,
397 unsigned int cmd, unsigned long arg,
398 int (*func)(struct inode *inode, struct file *file,
399 unsigned int cmd, void *arg))
400{
401 char sbuf[128];
402 void *mbuf = NULL;
403 void *parg = NULL;
404 int err = -EINVAL;
405 int is_ext_ctrl;
406 size_t ctrls_size = 0;
407 void __user *user_ptr = NULL;
408
409#ifdef __OLD_VIDIOC_
410 cmd = video_fix_command(cmd);
411#endif
412 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
413 cmd == VIDIOC_TRY_EXT_CTRLS);
414
415 /* Copy arguments into temp kernel buffer */
416 switch (_IOC_DIR(cmd)) {
417 case _IOC_NONE:
418 parg = NULL;
419 break;
420 case _IOC_READ:
421 case _IOC_WRITE:
422 case (_IOC_WRITE | _IOC_READ):
423 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
424 parg = sbuf;
425 } else {
426 /* too big to allocate from stack */
427 mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
428 if (NULL == mbuf)
429 return -ENOMEM;
430 parg = mbuf;
431 }
432
433 err = -EFAULT;
434 if (_IOC_DIR(cmd) & _IOC_WRITE)
435 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
436 goto out;
437 break;
438 }
439 if (is_ext_ctrl) {
440 struct v4l2_ext_controls *p = parg;
441
442 /* In case of an error, tell the caller that it wasn't
443 a specific control that caused it. */
444 p->error_idx = p->count;
445 user_ptr = (void __user *)p->controls;
446 if (p->count) {
447 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
448 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
449 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
450 err = -ENOMEM;
451 if (NULL == mbuf)
452 goto out_ext_ctrl;
453 err = -EFAULT;
454 if (copy_from_user(mbuf, user_ptr, ctrls_size))
455 goto out_ext_ctrl;
456 p->controls = mbuf;
457 }
458 }
459
460 /* call driver */
461 err = func(inode, file, cmd, parg);
462 if (err == -ENOIOCTLCMD)
463 err = -EINVAL;
464 if (is_ext_ctrl) {
465 struct v4l2_ext_controls *p = parg;
466
467 p->controls = (void *)user_ptr;
468 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
469 err = -EFAULT;
470 goto out_ext_ctrl;
471 }
472 if (err < 0)
473 goto out;
474
475out_ext_ctrl:
476 /* Copy results into user buffer */
477 switch (_IOC_DIR(cmd)) {
478 case _IOC_READ:
479 case (_IOC_WRITE | _IOC_READ):
480 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
481 err = -EFAULT;
482 break;
483 }
484
485out:
486 kfree(mbuf);
487 return err;
488}
489EXPORT_SYMBOL(video_usercopy);
490
491static void dbgbuf(unsigned int cmd, struct video_device *vfd,
492 struct v4l2_buffer *p)
493{
494 struct v4l2_timecode *tc = &p->timecode;
495
496 dbgarg(cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
497 "bytesused=%d, flags=0x%08d, "
498 "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n",
499 p->timestamp.tv_sec / 3600,
500 (int)(p->timestamp.tv_sec / 60) % 60,
501 (int)(p->timestamp.tv_sec % 60),
502 p->timestamp.tv_usec,
503 p->index,
504 prt_names(p->type, v4l2_type_names),
505 p->bytesused, p->flags,
506 p->field, p->sequence,
507 prt_names(p->memory, v4l2_memory_names),
508 p->m.userptr, p->length);
509 dbgarg2("timecode=%02d:%02d:%02d type=%d, "
510 "flags=0x%08d, frames=%d, userbits=0x%08x\n",
511 tc->hours, tc->minutes, tc->seconds,
512 tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits);
513}
514
515static inline void dbgrect(struct video_device *vfd, char *s,
516 struct v4l2_rect *r)
517{
518 dbgarg2("%sRect start at %dx%d, size=%dx%d\n", s, r->left, r->top,
519 r->width, r->height);
520};
521
522static inline void v4l_print_pix_fmt(struct video_device *vfd,
523 struct v4l2_pix_format *fmt)
524{
525 dbgarg2("width=%d, height=%d, format=%c%c%c%c, field=%s, "
526 "bytesperline=%d sizeimage=%d, colorspace=%d\n",
527 fmt->width, fmt->height,
528 (fmt->pixelformat & 0xff),
529 (fmt->pixelformat >> 8) & 0xff,
530 (fmt->pixelformat >> 16) & 0xff,
531 (fmt->pixelformat >> 24) & 0xff,
532 prt_names(fmt->field, v4l2_field_names),
533 fmt->bytesperline, fmt->sizeimage, fmt->colorspace);
534};
535
536static inline void v4l_print_ext_ctrls(unsigned int cmd,
537 struct video_device *vfd, struct v4l2_ext_controls *c, int show_vals)
538{
539 __u32 i;
540
541 if (!(vfd->debug & V4L2_DEBUG_IOCTL_ARG))
542 return;
543 dbgarg(cmd, "");
544 printk(KERN_CONT "class=0x%x", c->ctrl_class);
545 for (i = 0; i < c->count; i++) {
546 if (show_vals)
547 printk(KERN_CONT " id/val=0x%x/0x%x",
548 c->controls[i].id, c->controls[i].value);
549 else
550 printk(KERN_CONT " id=0x%x", c->controls[i].id);
551 }
552 printk(KERN_CONT "\n");
553};
554
555static inline int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)
556{
557 __u32 i;
558
559 /* zero the reserved fields */
560 c->reserved[0] = c->reserved[1] = 0;
561 for (i = 0; i < c->count; i++) {
562 c->controls[i].reserved2[0] = 0;
563 c->controls[i].reserved2[1] = 0;
564 }
565 /* V4L2_CID_PRIVATE_BASE cannot be used as control class
566 when using extended controls.
567 Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
568 is it allowed for backwards compatibility.
569 */
570 if (!allow_priv && c->ctrl_class == V4L2_CID_PRIVATE_BASE)
571 return 0;
572 /* Check that all controls are from the same control class. */
573 for (i = 0; i < c->count; i++) {
574 if (V4L2_CTRL_ID2CLASS(c->controls[i].id) != c->ctrl_class) {
575 c->error_idx = i;
576 return 0;
577 }
578 }
579 return 1;
580}
581
582static int check_fmt(struct video_device *vfd, enum v4l2_buf_type type)
583{
584 switch (type) {
585 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
586 if (vfd->vidioc_try_fmt_vid_cap)
587 return 0;
588 break;
589 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
590 if (vfd->vidioc_try_fmt_vid_overlay)
591 return 0;
592 break;
593 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
594 if (vfd->vidioc_try_fmt_vid_out)
595 return 0;
596 break;
597 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
598 if (vfd->vidioc_try_fmt_vid_out_overlay)
599 return 0;
600 break;
601 case V4L2_BUF_TYPE_VBI_CAPTURE:
602 if (vfd->vidioc_try_fmt_vbi_cap)
603 return 0;
604 break;
605 case V4L2_BUF_TYPE_VBI_OUTPUT:
606 if (vfd->vidioc_try_fmt_vbi_out)
607 return 0;
608 break;
609 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
610 if (vfd->vidioc_try_fmt_sliced_vbi_cap)
611 return 0;
612 break;
613 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
614 if (vfd->vidioc_try_fmt_sliced_vbi_out)
615 return 0;
616 break;
617 case V4L2_BUF_TYPE_PRIVATE:
618 if (vfd->vidioc_try_fmt_type_private)
619 return 0;
620 break;
621 }
622 return -EINVAL;
623}
624
625static int __video_do_ioctl(struct inode *inode, struct file *file,
626 unsigned int cmd, void *arg)
627{
628 struct video_device *vfd = video_devdata(file);
629 void *fh = file->private_data;
630 int ret = -EINVAL;
631
632 if ((vfd->debug & V4L2_DEBUG_IOCTL) &&
633 !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) {
634 v4l_print_ioctl(vfd->name, cmd);
635 printk(KERN_CONT "\n");
636 }
637
638#ifdef CONFIG_VIDEO_V4L1_COMPAT
639 /***********************************************************
640 Handles calls to the obsoleted V4L1 API
641 Due to the nature of VIDIOCGMBUF, each driver that supports
642 V4L1 should implement its own handler for this ioctl.
643 ***********************************************************/
644
645 /* --- streaming capture ------------------------------------- */
646 if (cmd == VIDIOCGMBUF) {
647 struct video_mbuf *p = arg;
648
649 memset(p, 0, sizeof(*p));
650
651 if (!vfd->vidiocgmbuf)
652 return ret;
653 ret = vfd->vidiocgmbuf(file, fh, p);
654 if (!ret)
655 dbgarg(cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
656 p->size, p->frames,
657 (unsigned long)p->offsets);
658 return ret;
659 }
660
661 /********************************************************
662 All other V4L1 calls are handled by v4l1_compat module.
663 Those calls will be translated into V4L2 calls, and
664 __video_do_ioctl will be called again, with one or more
665 V4L2 ioctls.
666 ********************************************************/
667 if (_IOC_TYPE(cmd) == 'v')
668 return v4l_compat_translate_ioctl(inode, file, cmd, arg,
669 __video_do_ioctl);
670#endif
671
672 switch (cmd) {
673 /* --- capabilities ------------------------------------------ */
674 case VIDIOC_QUERYCAP:
675 {
676 struct v4l2_capability *cap = (struct v4l2_capability *)arg;
677 memset(cap, 0, sizeof(*cap));
678
679 if (!vfd->vidioc_querycap)
680 break;
681
682 ret = vfd->vidioc_querycap(file, fh, cap);
683 if (!ret)
684 dbgarg(cmd, "driver=%s, card=%s, bus=%s, "
685 "version=0x%08x, "
686 "capabilities=0x%08x\n",
687 cap->driver, cap->card, cap->bus_info,
688 cap->version,
689 cap->capabilities);
690 break;
691 }
692
693 /* --- priority ------------------------------------------ */
694 case VIDIOC_G_PRIORITY:
695 {
696 enum v4l2_priority *p = arg;
697
698 if (!vfd->vidioc_g_priority)
699 break;
700 ret = vfd->vidioc_g_priority(file, fh, p);
701 if (!ret)
702 dbgarg(cmd, "priority is %d\n", *p);
703 break;
704 }
705 case VIDIOC_S_PRIORITY:
706 {
707 enum v4l2_priority *p = arg;
708
709 if (!vfd->vidioc_s_priority)
710 break;
711 dbgarg(cmd, "setting priority to %d\n", *p);
712 ret = vfd->vidioc_s_priority(file, fh, *p);
713 break;
714 }
715
716 /* --- capture ioctls ---------------------------------------- */
717 case VIDIOC_ENUM_FMT:
718 {
719 struct v4l2_fmtdesc *f = arg;
720 enum v4l2_buf_type type;
721 unsigned int index;
722
723 index = f->index;
724 type = f->type;
725 memset(f, 0, sizeof(*f));
726 f->index = index;
727 f->type = type;
728
729 switch (type) {
730 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
731 if (vfd->vidioc_enum_fmt_vid_cap)
732 ret = vfd->vidioc_enum_fmt_vid_cap(file, fh, f);
733 break;
734 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
735 if (vfd->vidioc_enum_fmt_vid_overlay)
736 ret = vfd->vidioc_enum_fmt_vid_overlay(file,
737 fh, f);
738 break;
739#if 1
740 /* V4L2_BUF_TYPE_VBI_CAPTURE should not support VIDIOC_ENUM_FMT
741 * according to the spec. The bttv and saa7134 drivers support
742 * it though, so just warn that this is deprecated and will be
743 * removed in the near future. */
744 case V4L2_BUF_TYPE_VBI_CAPTURE:
745 if (vfd->vidioc_enum_fmt_vbi_cap) {
746 printk(KERN_WARNING "vidioc_enum_fmt_vbi_cap will be removed in 2.6.28!\n");
747 ret = vfd->vidioc_enum_fmt_vbi_cap(file, fh, f);
748 }
749 break;
750#endif
751 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
752 if (vfd->vidioc_enum_fmt_vid_out)
753 ret = vfd->vidioc_enum_fmt_vid_out(file, fh, f);
754 break;
755 case V4L2_BUF_TYPE_PRIVATE:
756 if (vfd->vidioc_enum_fmt_type_private)
757 ret = vfd->vidioc_enum_fmt_type_private(file,
758 fh, f);
759 break;
760 default:
761 break;
762 }
763 if (!ret)
764 dbgarg(cmd, "index=%d, type=%d, flags=%d, "
765 "pixelformat=%c%c%c%c, description='%s'\n",
766 f->index, f->type, f->flags,
767 (f->pixelformat & 0xff),
768 (f->pixelformat >> 8) & 0xff,
769 (f->pixelformat >> 16) & 0xff,
770 (f->pixelformat >> 24) & 0xff,
771 f->description);
772 break;
773 }
774 case VIDIOC_G_FMT:
775 {
776 struct v4l2_format *f = (struct v4l2_format *)arg;
777
778 memset(f->fmt.raw_data, 0, sizeof(f->fmt.raw_data));
779
780 /* FIXME: Should be one dump per type */
781 dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
782
783 switch (f->type) {
784 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
785 if (vfd->vidioc_g_fmt_vid_cap)
786 ret = vfd->vidioc_g_fmt_vid_cap(file, fh, f);
787 if (!ret)
788 v4l_print_pix_fmt(vfd, &f->fmt.pix);
789 break;
790 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
791 if (vfd->vidioc_g_fmt_vid_overlay)
792 ret = vfd->vidioc_g_fmt_vid_overlay(file,
793 fh, f);
794 break;
795 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
796 if (vfd->vidioc_g_fmt_vid_out)
797 ret = vfd->vidioc_g_fmt_vid_out(file, fh, f);
798 if (!ret)
799 v4l_print_pix_fmt(vfd, &f->fmt.pix);
800 break;
801 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
802 if (vfd->vidioc_g_fmt_vid_out_overlay)
803 ret = vfd->vidioc_g_fmt_vid_out_overlay(file,
804 fh, f);
805 break;
806 case V4L2_BUF_TYPE_VBI_CAPTURE:
807 if (vfd->vidioc_g_fmt_vbi_cap)
808 ret = vfd->vidioc_g_fmt_vbi_cap(file, fh, f);
809 break;
810 case V4L2_BUF_TYPE_VBI_OUTPUT:
811 if (vfd->vidioc_g_fmt_vbi_out)
812 ret = vfd->vidioc_g_fmt_vbi_out(file, fh, f);
813 break;
814 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
815 if (vfd->vidioc_g_fmt_sliced_vbi_cap)
816 ret = vfd->vidioc_g_fmt_sliced_vbi_cap(file,
817 fh, f);
818 break;
819 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
820 if (vfd->vidioc_g_fmt_sliced_vbi_out)
821 ret = vfd->vidioc_g_fmt_sliced_vbi_out(file,
822 fh, f);
823 break;
824 case V4L2_BUF_TYPE_PRIVATE:
825 if (vfd->vidioc_g_fmt_type_private)
826 ret = vfd->vidioc_g_fmt_type_private(file,
827 fh, f);
828 break;
829 }
830
831 break;
832 }
833 case VIDIOC_S_FMT:
834 {
835 struct v4l2_format *f = (struct v4l2_format *)arg;
836
837 /* FIXME: Should be one dump per type */
838 dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
839
840 switch (f->type) {
841 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
842 v4l_print_pix_fmt(vfd, &f->fmt.pix);
843 if (vfd->vidioc_s_fmt_vid_cap)
844 ret = vfd->vidioc_s_fmt_vid_cap(file, fh, f);
845 break;
846 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
847 if (vfd->vidioc_s_fmt_vid_overlay)
848 ret = vfd->vidioc_s_fmt_vid_overlay(file,
849 fh, f);
850 break;
851 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
852 v4l_print_pix_fmt(vfd, &f->fmt.pix);
853 if (vfd->vidioc_s_fmt_vid_out)
854 ret = vfd->vidioc_s_fmt_vid_out(file, fh, f);
855 break;
856 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
857 if (vfd->vidioc_s_fmt_vid_out_overlay)
858 ret = vfd->vidioc_s_fmt_vid_out_overlay(file,
859 fh, f);
860 break;
861 case V4L2_BUF_TYPE_VBI_CAPTURE:
862 if (vfd->vidioc_s_fmt_vbi_cap)
863 ret = vfd->vidioc_s_fmt_vbi_cap(file, fh, f);
864 break;
865 case V4L2_BUF_TYPE_VBI_OUTPUT:
866 if (vfd->vidioc_s_fmt_vbi_out)
867 ret = vfd->vidioc_s_fmt_vbi_out(file, fh, f);
868 break;
869 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
870 if (vfd->vidioc_s_fmt_sliced_vbi_cap)
871 ret = vfd->vidioc_s_fmt_sliced_vbi_cap(file,
872 fh, f);
873 break;
874 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
875 if (vfd->vidioc_s_fmt_sliced_vbi_out)
876 ret = vfd->vidioc_s_fmt_sliced_vbi_out(file,
877 fh, f);
878 break;
879 case V4L2_BUF_TYPE_PRIVATE:
880 if (vfd->vidioc_s_fmt_type_private)
881 ret = vfd->vidioc_s_fmt_type_private(file,
882 fh, f);
883 break;
884 }
885 break;
886 }
887 case VIDIOC_TRY_FMT:
888 {
889 struct v4l2_format *f = (struct v4l2_format *)arg;
890
891 /* FIXME: Should be one dump per type */
892 dbgarg(cmd, "type=%s\n", prt_names(f->type,
893 v4l2_type_names));
894 switch (f->type) {
895 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
896 if (vfd->vidioc_try_fmt_vid_cap)
897 ret = vfd->vidioc_try_fmt_vid_cap(file, fh, f);
898 if (!ret)
899 v4l_print_pix_fmt(vfd, &f->fmt.pix);
900 break;
901 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
902 if (vfd->vidioc_try_fmt_vid_overlay)
903 ret = vfd->vidioc_try_fmt_vid_overlay(file,
904 fh, f);
905 break;
906 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
907 if (vfd->vidioc_try_fmt_vid_out)
908 ret = vfd->vidioc_try_fmt_vid_out(file, fh, f);
909 if (!ret)
910 v4l_print_pix_fmt(vfd, &f->fmt.pix);
911 break;
912 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
913 if (vfd->vidioc_try_fmt_vid_out_overlay)
914 ret = vfd->vidioc_try_fmt_vid_out_overlay(file,
915 fh, f);
916 break;
917 case V4L2_BUF_TYPE_VBI_CAPTURE:
918 if (vfd->vidioc_try_fmt_vbi_cap)
919 ret = vfd->vidioc_try_fmt_vbi_cap(file, fh, f);
920 break;
921 case V4L2_BUF_TYPE_VBI_OUTPUT:
922 if (vfd->vidioc_try_fmt_vbi_out)
923 ret = vfd->vidioc_try_fmt_vbi_out(file, fh, f);
924 break;
925 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
926 if (vfd->vidioc_try_fmt_sliced_vbi_cap)
927 ret = vfd->vidioc_try_fmt_sliced_vbi_cap(file,
928 fh, f);
929 break;
930 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
931 if (vfd->vidioc_try_fmt_sliced_vbi_out)
932 ret = vfd->vidioc_try_fmt_sliced_vbi_out(file,
933 fh, f);
934 break;
935 case V4L2_BUF_TYPE_PRIVATE:
936 if (vfd->vidioc_try_fmt_type_private)
937 ret = vfd->vidioc_try_fmt_type_private(file,
938 fh, f);
939 break;
940 }
941
942 break;
943 }
944 /* FIXME: Those buf reqs could be handled here,
945 with some changes on videobuf to allow its header to be included at
946 videodev2.h or being merged at videodev2.
947 */
948 case VIDIOC_REQBUFS:
949 {
950 struct v4l2_requestbuffers *p = arg;
951
952 if (!vfd->vidioc_reqbufs)
953 break;
954 ret = check_fmt(vfd, p->type);
955 if (ret)
956 break;
957
958 ret = vfd->vidioc_reqbufs(file, fh, p);
959 dbgarg(cmd, "count=%d, type=%s, memory=%s\n",
960 p->count,
961 prt_names(p->type, v4l2_type_names),
962 prt_names(p->memory, v4l2_memory_names));
963 break;
964 }
965 case VIDIOC_QUERYBUF:
966 {
967 struct v4l2_buffer *p = arg;
968
969 if (!vfd->vidioc_querybuf)
970 break;
971 ret = check_fmt(vfd, p->type);
972 if (ret)
973 break;
974
975 ret = vfd->vidioc_querybuf(file, fh, p);
976 if (!ret)
977 dbgbuf(cmd, vfd, p);
978 break;
979 }
980 case VIDIOC_QBUF:
981 {
982 struct v4l2_buffer *p = arg;
983
984 if (!vfd->vidioc_qbuf)
985 break;
986 ret = check_fmt(vfd, p->type);
987 if (ret)
988 break;
989
990 ret = vfd->vidioc_qbuf(file, fh, p);
991 if (!ret)
992 dbgbuf(cmd, vfd, p);
993 break;
994 }
995 case VIDIOC_DQBUF:
996 {
997 struct v4l2_buffer *p = arg;
998
999 if (!vfd->vidioc_dqbuf)
1000 break;
1001 ret = check_fmt(vfd, p->type);
1002 if (ret)
1003 break;
1004
1005 ret = vfd->vidioc_dqbuf(file, fh, p);
1006 if (!ret)
1007 dbgbuf(cmd, vfd, p);
1008 break;
1009 }
1010 case VIDIOC_OVERLAY:
1011 {
1012 int *i = arg;
1013
1014 if (!vfd->vidioc_overlay)
1015 break;
1016 dbgarg(cmd, "value=%d\n", *i);
1017 ret = vfd->vidioc_overlay(file, fh, *i);
1018 break;
1019 }
1020 case VIDIOC_G_FBUF:
1021 {
1022 struct v4l2_framebuffer *p = arg;
1023
1024 if (!vfd->vidioc_g_fbuf)
1025 break;
1026 ret = vfd->vidioc_g_fbuf(file, fh, arg);
1027 if (!ret) {
1028 dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
1029 p->capability, p->flags,
1030 (unsigned long)p->base);
1031 v4l_print_pix_fmt(vfd, &p->fmt);
1032 }
1033 break;
1034 }
1035 case VIDIOC_S_FBUF:
1036 {
1037 struct v4l2_framebuffer *p = arg;
1038
1039 if (!vfd->vidioc_s_fbuf)
1040 break;
1041 dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
1042 p->capability, p->flags, (unsigned long)p->base);
1043 v4l_print_pix_fmt(vfd, &p->fmt);
1044 ret = vfd->vidioc_s_fbuf(file, fh, arg);
1045 break;
1046 }
1047 case VIDIOC_STREAMON:
1048 {
1049 enum v4l2_buf_type i = *(int *)arg;
1050
1051 if (!vfd->vidioc_streamon)
1052 break;
1053 dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
1054 ret = vfd->vidioc_streamon(file, fh, i);
1055 break;
1056 }
1057 case VIDIOC_STREAMOFF:
1058 {
1059 enum v4l2_buf_type i = *(int *)arg;
1060
1061 if (!vfd->vidioc_streamoff)
1062 break;
1063 dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
1064 ret = vfd->vidioc_streamoff(file, fh, i);
1065 break;
1066 }
1067 /* ---------- tv norms ---------- */
1068 case VIDIOC_ENUMSTD:
1069 {
1070 struct v4l2_standard *p = arg;
1071 v4l2_std_id id = vfd->tvnorms, curr_id = 0;
1072 unsigned int index = p->index, i, j = 0;
1073 const char *descr = "";
1074
1075 /* Return norm array in a canonical way */
1076 for (i = 0; i <= index && id; i++) {
1077 /* last std value in the standards array is 0, so this
1078 while always ends there since (id & 0) == 0. */
1079 while ((id & standards[j].std) != standards[j].std)
1080 j++;
1081 curr_id = standards[j].std;
1082 descr = standards[j].descr;
1083 j++;
1084 if (curr_id == 0)
1085 break;
1086 if (curr_id != V4L2_STD_PAL &&
1087 curr_id != V4L2_STD_SECAM &&
1088 curr_id != V4L2_STD_NTSC)
1089 id &= ~curr_id;
1090 }
1091 if (i <= index)
1092 return -EINVAL;
1093
1094 v4l2_video_std_construct(p, curr_id, descr);
1095 p->index = index;
1096
1097 dbgarg(cmd, "index=%d, id=0x%Lx, name=%s, fps=%d/%d, "
1098 "framelines=%d\n", p->index,
1099 (unsigned long long)p->id, p->name,
1100 p->frameperiod.numerator,
1101 p->frameperiod.denominator,
1102 p->framelines);
1103
1104 ret = 0;
1105 break;
1106 }
1107 case VIDIOC_G_STD:
1108 {
1109 v4l2_std_id *id = arg;
1110
1111 ret = 0;
1112 /* Calls the specific handler */
1113 if (vfd->vidioc_g_std)
1114 ret = vfd->vidioc_g_std(file, fh, id);
1115 else
1116 *id = vfd->current_norm;
1117
1118 if (!ret)
1119 dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id);
1120 break;
1121 }
1122 case VIDIOC_S_STD:
1123 {
1124 v4l2_std_id *id = arg, norm;
1125
1126 dbgarg(cmd, "std=%08Lx\n", (long long unsigned)*id);
1127
1128 norm = (*id) & vfd->tvnorms;
1129 if (vfd->tvnorms && !norm) /* Check if std is supported */
1130 break;
1131
1132 /* Calls the specific handler */
1133 if (vfd->vidioc_s_std)
1134 ret = vfd->vidioc_s_std(file, fh, &norm);
1135 else
1136 ret = -EINVAL;
1137
1138 /* Updates standard information */
1139 if (ret >= 0)
1140 vfd->current_norm = norm;
1141 break;
1142 }
1143 case VIDIOC_QUERYSTD:
1144 {
1145 v4l2_std_id *p = arg;
1146
1147 if (!vfd->vidioc_querystd)
1148 break;
1149 ret = vfd->vidioc_querystd(file, fh, arg);
1150 if (!ret)
1151 dbgarg(cmd, "detected std=%08Lx\n",
1152 (unsigned long long)*p);
1153 break;
1154 }
1155 /* ------ input switching ---------- */
1156 /* FIXME: Inputs can be handled inside videodev2 */
1157 case VIDIOC_ENUMINPUT:
1158 {
1159 struct v4l2_input *p = arg;
1160 int i = p->index;
1161
1162 if (!vfd->vidioc_enum_input)
1163 break;
1164 memset(p, 0, sizeof(*p));
1165 p->index = i;
1166
1167 ret = vfd->vidioc_enum_input(file, fh, p);
1168 if (!ret)
1169 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1170 "audioset=%d, "
1171 "tuner=%d, std=%08Lx, status=%d\n",
1172 p->index, p->name, p->type, p->audioset,
1173 p->tuner,
1174 (unsigned long long)p->std,
1175 p->status);
1176 break;
1177 }
1178 case VIDIOC_G_INPUT:
1179 {
1180 unsigned int *i = arg;
1181
1182 if (!vfd->vidioc_g_input)
1183 break;
1184 ret = vfd->vidioc_g_input(file, fh, i);
1185 if (!ret)
1186 dbgarg(cmd, "value=%d\n", *i);
1187 break;
1188 }
1189 case VIDIOC_S_INPUT:
1190 {
1191 unsigned int *i = arg;
1192
1193 if (!vfd->vidioc_s_input)
1194 break;
1195 dbgarg(cmd, "value=%d\n", *i);
1196 ret = vfd->vidioc_s_input(file, fh, *i);
1197 break;
1198 }
1199
1200 /* ------ output switching ---------- */
1201 case VIDIOC_ENUMOUTPUT:
1202 {
1203 struct v4l2_output *p = arg;
1204 int i = p->index;
1205
1206 if (!vfd->vidioc_enum_output)
1207 break;
1208 memset(p, 0, sizeof(*p));
1209 p->index = i;
1210
1211 ret = vfd->vidioc_enum_output(file, fh, p);
1212 if (!ret)
1213 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1214 "audioset=0x%x, "
1215 "modulator=%d, std=0x%08Lx\n",
1216 p->index, p->name, p->type, p->audioset,
1217 p->modulator, (unsigned long long)p->std);
1218 break;
1219 }
1220 case VIDIOC_G_OUTPUT:
1221 {
1222 unsigned int *i = arg;
1223
1224 if (!vfd->vidioc_g_output)
1225 break;
1226 ret = vfd->vidioc_g_output(file, fh, i);
1227 if (!ret)
1228 dbgarg(cmd, "value=%d\n", *i);
1229 break;
1230 }
1231 case VIDIOC_S_OUTPUT:
1232 {
1233 unsigned int *i = arg;
1234
1235 if (!vfd->vidioc_s_output)
1236 break;
1237 dbgarg(cmd, "value=%d\n", *i);
1238 ret = vfd->vidioc_s_output(file, fh, *i);
1239 break;
1240 }
1241
1242 /* --- controls ---------------------------------------------- */
1243 case VIDIOC_QUERYCTRL:
1244 {
1245 struct v4l2_queryctrl *p = arg;
1246
1247 if (!vfd->vidioc_queryctrl)
1248 break;
1249 ret = vfd->vidioc_queryctrl(file, fh, p);
1250 if (!ret)
1251 dbgarg(cmd, "id=0x%x, type=%d, name=%s, min/max=%d/%d, "
1252 "step=%d, default=%d, flags=0x%08x\n",
1253 p->id, p->type, p->name,
1254 p->minimum, p->maximum,
1255 p->step, p->default_value, p->flags);
1256 else
1257 dbgarg(cmd, "id=0x%x\n", p->id);
1258 break;
1259 }
1260 case VIDIOC_G_CTRL:
1261 {
1262 struct v4l2_control *p = arg;
1263
1264 if (vfd->vidioc_g_ctrl)
1265 ret = vfd->vidioc_g_ctrl(file, fh, p);
1266 else if (vfd->vidioc_g_ext_ctrls) {
1267 struct v4l2_ext_controls ctrls;
1268 struct v4l2_ext_control ctrl;
1269
1270 ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
1271 ctrls.count = 1;
1272 ctrls.controls = &ctrl;
1273 ctrl.id = p->id;
1274 ctrl.value = p->value;
1275 if (check_ext_ctrls(&ctrls, 1)) {
1276 ret = vfd->vidioc_g_ext_ctrls(file, fh, &ctrls);
1277 if (ret == 0)
1278 p->value = ctrl.value;
1279 }
1280 } else
1281 break;
1282 if (!ret)
1283 dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
1284 else
1285 dbgarg(cmd, "id=0x%x\n", p->id);
1286 break;
1287 }
1288 case VIDIOC_S_CTRL:
1289 {
1290 struct v4l2_control *p = arg;
1291 struct v4l2_ext_controls ctrls;
1292 struct v4l2_ext_control ctrl;
1293
1294 if (!vfd->vidioc_s_ctrl && !vfd->vidioc_s_ext_ctrls)
1295 break;
1296
1297 dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
1298
1299 if (vfd->vidioc_s_ctrl) {
1300 ret = vfd->vidioc_s_ctrl(file, fh, p);
1301 break;
1302 }
1303 if (!vfd->vidioc_s_ext_ctrls)
1304 break;
1305
1306 ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
1307 ctrls.count = 1;
1308 ctrls.controls = &ctrl;
1309 ctrl.id = p->id;
1310 ctrl.value = p->value;
1311 if (check_ext_ctrls(&ctrls, 1))
1312 ret = vfd->vidioc_s_ext_ctrls(file, fh, &ctrls);
1313 break;
1314 }
1315 case VIDIOC_G_EXT_CTRLS:
1316 {
1317 struct v4l2_ext_controls *p = arg;
1318
1319 p->error_idx = p->count;
1320 if (!vfd->vidioc_g_ext_ctrls)
1321 break;
1322 if (check_ext_ctrls(p, 0))
1323 ret = vfd->vidioc_g_ext_ctrls(file, fh, p);
1324 v4l_print_ext_ctrls(cmd, vfd, p, !ret);
1325 break;
1326 }
1327 case VIDIOC_S_EXT_CTRLS:
1328 {
1329 struct v4l2_ext_controls *p = arg;
1330
1331 p->error_idx = p->count;
1332 if (!vfd->vidioc_s_ext_ctrls)
1333 break;
1334 v4l_print_ext_ctrls(cmd, vfd, p, 1);
1335 if (check_ext_ctrls(p, 0))
1336 ret = vfd->vidioc_s_ext_ctrls(file, fh, p);
1337 break;
1338 }
1339 case VIDIOC_TRY_EXT_CTRLS:
1340 {
1341 struct v4l2_ext_controls *p = arg;
1342
1343 p->error_idx = p->count;
1344 if (!vfd->vidioc_try_ext_ctrls)
1345 break;
1346 v4l_print_ext_ctrls(cmd, vfd, p, 1);
1347 if (check_ext_ctrls(p, 0))
1348 ret = vfd->vidioc_try_ext_ctrls(file, fh, p);
1349 break;
1350 }
1351 case VIDIOC_QUERYMENU:
1352 {
1353 struct v4l2_querymenu *p = arg;
1354
1355 if (!vfd->vidioc_querymenu)
1356 break;
1357 ret = vfd->vidioc_querymenu(file, fh, p);
1358 if (!ret)
1359 dbgarg(cmd, "id=0x%x, index=%d, name=%s\n",
1360 p->id, p->index, p->name);
1361 else
1362 dbgarg(cmd, "id=0x%x, index=%d\n",
1363 p->id, p->index);
1364 break;
1365 }
1366 /* --- audio ---------------------------------------------- */
1367 case VIDIOC_ENUMAUDIO:
1368 {
1369 struct v4l2_audio *p = arg;
1370
1371 if (!vfd->vidioc_enumaudio)
1372 break;
1373 ret = vfd->vidioc_enumaudio(file, fh, p);
1374 if (!ret)
1375 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
1376 "mode=0x%x\n", p->index, p->name,
1377 p->capability, p->mode);
1378 else
1379 dbgarg(cmd, "index=%d\n", p->index);
1380 break;
1381 }
1382 case VIDIOC_G_AUDIO:
1383 {
1384 struct v4l2_audio *p = arg;
1385 __u32 index = p->index;
1386
1387 if (!vfd->vidioc_g_audio)
1388 break;
1389
1390 memset(p, 0, sizeof(*p));
1391 p->index = index;
1392 ret = vfd->vidioc_g_audio(file, fh, p);
1393 if (!ret)
1394 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
1395 "mode=0x%x\n", p->index,
1396 p->name, p->capability, p->mode);
1397 else
1398 dbgarg(cmd, "index=%d\n", p->index);
1399 break;
1400 }
1401 case VIDIOC_S_AUDIO:
1402 {
1403 struct v4l2_audio *p = arg;
1404
1405 if (!vfd->vidioc_s_audio)
1406 break;
1407 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
1408 "mode=0x%x\n", p->index, p->name,
1409 p->capability, p->mode);
1410 ret = vfd->vidioc_s_audio(file, fh, p);
1411 break;
1412 }
1413 case VIDIOC_ENUMAUDOUT:
1414 {
1415 struct v4l2_audioout *p = arg;
1416
1417 if (!vfd->vidioc_enumaudout)
1418 break;
1419 dbgarg(cmd, "Enum for index=%d\n", p->index);
1420 ret = vfd->vidioc_enumaudout(file, fh, p);
1421 if (!ret)
1422 dbgarg2("index=%d, name=%s, capability=%d, "
1423 "mode=%d\n", p->index, p->name,
1424 p->capability, p->mode);
1425 break;
1426 }
1427 case VIDIOC_G_AUDOUT:
1428 {
1429 struct v4l2_audioout *p = arg;
1430
1431 if (!vfd->vidioc_g_audout)
1432 break;
1433 dbgarg(cmd, "Enum for index=%d\n", p->index);
1434 ret = vfd->vidioc_g_audout(file, fh, p);
1435 if (!ret)
1436 dbgarg2("index=%d, name=%s, capability=%d, "
1437 "mode=%d\n", p->index, p->name,
1438 p->capability, p->mode);
1439 break;
1440 }
1441 case VIDIOC_S_AUDOUT:
1442 {
1443 struct v4l2_audioout *p = arg;
1444
1445 if (!vfd->vidioc_s_audout)
1446 break;
1447 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1448 "mode=%d\n", p->index, p->name,
1449 p->capability, p->mode);
1450
1451 ret = vfd->vidioc_s_audout(file, fh, p);
1452 break;
1453 }
1454 case VIDIOC_G_MODULATOR:
1455 {
1456 struct v4l2_modulator *p = arg;
1457
1458 if (!vfd->vidioc_g_modulator)
1459 break;
1460 ret = vfd->vidioc_g_modulator(file, fh, p);
1461 if (!ret)
1462 dbgarg(cmd, "index=%d, name=%s, "
1463 "capability=%d, rangelow=%d,"
1464 " rangehigh=%d, txsubchans=%d\n",
1465 p->index, p->name, p->capability,
1466 p->rangelow, p->rangehigh,
1467 p->txsubchans);
1468 break;
1469 }
1470 case VIDIOC_S_MODULATOR:
1471 {
1472 struct v4l2_modulator *p = arg;
1473
1474 if (!vfd->vidioc_s_modulator)
1475 break;
1476 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1477 "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
1478 p->index, p->name, p->capability, p->rangelow,
1479 p->rangehigh, p->txsubchans);
1480 ret = vfd->vidioc_s_modulator(file, fh, p);
1481 break;
1482 }
1483 case VIDIOC_G_CROP:
1484 {
1485 struct v4l2_crop *p = arg;
1486
1487 if (!vfd->vidioc_g_crop)
1488 break;
1489 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1490 ret = vfd->vidioc_g_crop(file, fh, p);
1491 if (!ret)
1492 dbgrect(vfd, "", &p->c);
1493 break;
1494 }
1495 case VIDIOC_S_CROP:
1496 {
1497 struct v4l2_crop *p = arg;
1498
1499 if (!vfd->vidioc_s_crop)
1500 break;
1501 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1502 dbgrect(vfd, "", &p->c);
1503 ret = vfd->vidioc_s_crop(file, fh, p);
1504 break;
1505 }
1506 case VIDIOC_CROPCAP:
1507 {
1508 struct v4l2_cropcap *p = arg;
1509
1510 /*FIXME: Should also show v4l2_fract pixelaspect */
1511 if (!vfd->vidioc_cropcap)
1512 break;
1513 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1514 ret = vfd->vidioc_cropcap(file, fh, p);
1515 if (!ret) {
1516 dbgrect(vfd, "bounds ", &p->bounds);
1517 dbgrect(vfd, "defrect ", &p->defrect);
1518 }
1519 break;
1520 }
1521 case VIDIOC_G_JPEGCOMP:
1522 {
1523 struct v4l2_jpegcompression *p = arg;
1524
1525 if (!vfd->vidioc_g_jpegcomp)
1526 break;
1527 ret = vfd->vidioc_g_jpegcomp(file, fh, p);
1528 if (!ret)
1529 dbgarg(cmd, "quality=%d, APPn=%d, "
1530 "APP_len=%d, COM_len=%d, "
1531 "jpeg_markers=%d\n",
1532 p->quality, p->APPn, p->APP_len,
1533 p->COM_len, p->jpeg_markers);
1534 break;
1535 }
1536 case VIDIOC_S_JPEGCOMP:
1537 {
1538 struct v4l2_jpegcompression *p = arg;
1539
1540 if (!vfd->vidioc_g_jpegcomp)
1541 break;
1542 dbgarg(cmd, "quality=%d, APPn=%d, APP_len=%d, "
1543 "COM_len=%d, jpeg_markers=%d\n",
1544 p->quality, p->APPn, p->APP_len,
1545 p->COM_len, p->jpeg_markers);
1546 ret = vfd->vidioc_s_jpegcomp(file, fh, p);
1547 break;
1548 }
1549 case VIDIOC_G_ENC_INDEX:
1550 {
1551 struct v4l2_enc_idx *p = arg;
1552
1553 if (!vfd->vidioc_g_enc_index)
1554 break;
1555 ret = vfd->vidioc_g_enc_index(file, fh, p);
1556 if (!ret)
1557 dbgarg(cmd, "entries=%d, entries_cap=%d\n",
1558 p->entries, p->entries_cap);
1559 break;
1560 }
1561 case VIDIOC_ENCODER_CMD:
1562 {
1563 struct v4l2_encoder_cmd *p = arg;
1564
1565 if (!vfd->vidioc_encoder_cmd)
1566 break;
1567 memset(&p->raw, 0, sizeof(p->raw));
1568 ret = vfd->vidioc_encoder_cmd(file, fh, p);
1569 if (!ret)
1570 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
1571 break;
1572 }
1573 case VIDIOC_TRY_ENCODER_CMD:
1574 {
1575 struct v4l2_encoder_cmd *p = arg;
1576
1577 if (!vfd->vidioc_try_encoder_cmd)
1578 break;
1579 memset(&p->raw, 0, sizeof(p->raw));
1580 ret = vfd->vidioc_try_encoder_cmd(file, fh, p);
1581 if (!ret)
1582 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
1583 break;
1584 }
1585 case VIDIOC_G_PARM:
1586 {
1587 struct v4l2_streamparm *p = arg;
1588 __u32 type = p->type;
1589
1590 memset(p, 0, sizeof(*p));
1591 p->type = type;
1592
1593 if (vfd->vidioc_g_parm) {
1594 ret = vfd->vidioc_g_parm(file, fh, p);
1595 } else {
1596 struct v4l2_standard s;
1597
1598 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1599 return -EINVAL;
1600
1601 v4l2_video_std_construct(&s, vfd->current_norm,
1602 v4l2_norm_to_name(vfd->current_norm));
1603
1604 p->parm.capture.timeperframe = s.frameperiod;
1605 ret = 0;
1606 }
1607
1608 dbgarg(cmd, "type=%d\n", p->type);
1609 break;
1610 }
1611 case VIDIOC_S_PARM:
1612 {
1613 struct v4l2_streamparm *p = arg;
1614
1615 if (!vfd->vidioc_s_parm)
1616 break;
1617 dbgarg(cmd, "type=%d\n", p->type);
1618 ret = vfd->vidioc_s_parm(file, fh, p);
1619 break;
1620 }
1621 case VIDIOC_G_TUNER:
1622 {
1623 struct v4l2_tuner *p = arg;
1624 __u32 index = p->index;
1625
1626 if (!vfd->vidioc_g_tuner)
1627 break;
1628
1629 memset(p, 0, sizeof(*p));
1630 p->index = index;
1631
1632 ret = vfd->vidioc_g_tuner(file, fh, p);
1633 if (!ret)
1634 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1635 "capability=0x%x, rangelow=%d, "
1636 "rangehigh=%d, signal=%d, afc=%d, "
1637 "rxsubchans=0x%x, audmode=%d\n",
1638 p->index, p->name, p->type,
1639 p->capability, p->rangelow,
1640 p->rangehigh, p->signal, p->afc,
1641 p->rxsubchans, p->audmode);
1642 break;
1643 }
1644 case VIDIOC_S_TUNER:
1645 {
1646 struct v4l2_tuner *p = arg;
1647
1648 if (!vfd->vidioc_s_tuner)
1649 break;
1650 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1651 "capability=0x%x, rangelow=%d, "
1652 "rangehigh=%d, signal=%d, afc=%d, "
1653 "rxsubchans=0x%x, audmode=%d\n",
1654 p->index, p->name, p->type,
1655 p->capability, p->rangelow,
1656 p->rangehigh, p->signal, p->afc,
1657 p->rxsubchans, p->audmode);
1658 ret = vfd->vidioc_s_tuner(file, fh, p);
1659 break;
1660 }
1661 case VIDIOC_G_FREQUENCY:
1662 {
1663 struct v4l2_frequency *p = arg;
1664
1665 if (!vfd->vidioc_g_frequency)
1666 break;
1667
1668 memset(p->reserved, 0, sizeof(p->reserved));
1669
1670 ret = vfd->vidioc_g_frequency(file, fh, p);
1671 if (!ret)
1672 dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
1673 p->tuner, p->type, p->frequency);
1674 break;
1675 }
1676 case VIDIOC_S_FREQUENCY:
1677 {
1678 struct v4l2_frequency *p = arg;
1679
1680 if (!vfd->vidioc_s_frequency)
1681 break;
1682 dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
1683 p->tuner, p->type, p->frequency);
1684 ret = vfd->vidioc_s_frequency(file, fh, p);
1685 break;
1686 }
1687 case VIDIOC_G_SLICED_VBI_CAP:
1688 {
1689 struct v4l2_sliced_vbi_cap *p = arg;
1690 __u32 type = p->type;
1691
1692 if (!vfd->vidioc_g_sliced_vbi_cap)
1693 break;
1694 memset(p, 0, sizeof(*p));
1695 p->type = type;
1696 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1697 ret = vfd->vidioc_g_sliced_vbi_cap(file, fh, p);
1698 if (!ret)
1699 dbgarg2("service_set=%d\n", p->service_set);
1700 break;
1701 }
1702 case VIDIOC_LOG_STATUS:
1703 {
1704 if (!vfd->vidioc_log_status)
1705 break;
1706 ret = vfd->vidioc_log_status(file, fh);
1707 break;
1708 }
1709#ifdef CONFIG_VIDEO_ADV_DEBUG
1710 case VIDIOC_DBG_G_REGISTER:
1711 {
1712 struct v4l2_register *p = arg;
1713
1714 if (!capable(CAP_SYS_ADMIN))
1715 ret = -EPERM;
1716 else if (vfd->vidioc_g_register)
1717 ret = vfd->vidioc_g_register(file, fh, p);
1718 break;
1719 }
1720 case VIDIOC_DBG_S_REGISTER:
1721 {
1722 struct v4l2_register *p = arg;
1723
1724 if (!capable(CAP_SYS_ADMIN))
1725 ret = -EPERM;
1726 else if (vfd->vidioc_s_register)
1727 ret = vfd->vidioc_s_register(file, fh, p);
1728 break;
1729 }
1730#endif
1731 case VIDIOC_G_CHIP_IDENT:
1732 {
1733 struct v4l2_chip_ident *p = arg;
1734
1735 if (!vfd->vidioc_g_chip_ident)
1736 break;
1737 ret = vfd->vidioc_g_chip_ident(file, fh, p);
1738 if (!ret)
1739 dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
1740 break;
1741 }
1742 default:
1743 {
1744 if (!vfd->vidioc_default)
1745 break;
1746 ret = vfd->vidioc_default(file, fh, cmd, arg);
1747 break;
1748 }
1749 case VIDIOC_S_HW_FREQ_SEEK:
1750 {
1751 struct v4l2_hw_freq_seek *p = arg;
1752
1753 if (!vfd->vidioc_s_hw_freq_seek)
1754 break;
1755 dbgarg(cmd,
1756 "tuner=%d, type=%d, seek_upward=%d, wrap_around=%d\n",
1757 p->tuner, p->type, p->seek_upward, p->wrap_around);
1758 ret = vfd->vidioc_s_hw_freq_seek(file, fh, p);
1759 break;
1760 }
1761 } /* switch */
1762
1763 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1764 if (ret < 0) {
1765 v4l_print_ioctl(vfd->name, cmd);
1766 printk(KERN_CONT " error %d\n", ret);
1767 }
1768 }
1769
1770 return ret;
1771}
1772
1773int video_ioctl2(struct inode *inode, struct file *file,
1774 unsigned int cmd, unsigned long arg)
1775{
1776 char sbuf[128];
1777 void *mbuf = NULL;
1778 void *parg = NULL;
1779 int err = -EINVAL;
1780 int is_ext_ctrl;
1781 size_t ctrls_size = 0;
1782 void __user *user_ptr = NULL;
1783
1784#ifdef __OLD_VIDIOC_
1785 cmd = video_fix_command(cmd);
1786#endif
1787 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
1788 cmd == VIDIOC_TRY_EXT_CTRLS);
1789
1790 /* Copy arguments into temp kernel buffer */
1791 switch (_IOC_DIR(cmd)) {
1792 case _IOC_NONE:
1793 parg = NULL;
1794 break;
1795 case _IOC_READ:
1796 case _IOC_WRITE:
1797 case (_IOC_WRITE | _IOC_READ):
1798 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
1799 parg = sbuf;
1800 } else {
1801 /* too big to allocate from stack */
1802 mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
1803 if (NULL == mbuf)
1804 return -ENOMEM;
1805 parg = mbuf;
1806 }
1807
1808 err = -EFAULT;
1809 if (_IOC_DIR(cmd) & _IOC_WRITE)
1810 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
1811 goto out;
1812 break;
1813 }
1814
1815 if (is_ext_ctrl) {
1816 struct v4l2_ext_controls *p = parg;
1817
1818 /* In case of an error, tell the caller that it wasn't
1819 a specific control that caused it. */
1820 p->error_idx = p->count;
1821 user_ptr = (void __user *)p->controls;
1822 if (p->count) {
1823 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
1824 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
1825 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
1826 err = -ENOMEM;
1827 if (NULL == mbuf)
1828 goto out_ext_ctrl;
1829 err = -EFAULT;
1830 if (copy_from_user(mbuf, user_ptr, ctrls_size))
1831 goto out_ext_ctrl;
1832 p->controls = mbuf;
1833 }
1834 }
1835
1836 /* Handles IOCTL */
1837 err = __video_do_ioctl(inode, file, cmd, parg);
1838 if (err == -ENOIOCTLCMD)
1839 err = -EINVAL;
1840 if (is_ext_ctrl) {
1841 struct v4l2_ext_controls *p = parg;
1842
1843 p->controls = (void *)user_ptr;
1844 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
1845 err = -EFAULT;
1846 goto out_ext_ctrl;
1847 }
1848 if (err < 0)
1849 goto out;
1850
1851out_ext_ctrl:
1852 /* Copy results into user buffer */
1853 switch (_IOC_DIR(cmd)) {
1854 case _IOC_READ:
1855 case (_IOC_WRITE | _IOC_READ):
1856 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
1857 err = -EFAULT;
1858 break;
1859 }
1860
1861out:
1862 kfree(mbuf);
1863 return err;
1864}
1865EXPORT_SYMBOL(video_ioctl2);