Merge remote-tracking branch 'moduleh/module.h-split'
[linux-2.6/next.git] / drivers / media / video / v4l2-ioctl.c
blob002ce1363443338a714fca863f254968a224f6ee
1 /*
2 * Video capture interface for Linux version 2
4 * A generic framework to process V4L2 ioctl commands.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
11 * Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1)
12 * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2)
15 #include <linux/module.h>
16 #include <linux/slab.h>
17 #include <linux/types.h>
18 #include <linux/kernel.h>
19 #include <linux/version.h>
21 #include <linux/videodev2.h>
23 #include <media/v4l2-common.h>
24 #include <media/v4l2-ioctl.h>
25 #include <media/v4l2-ctrls.h>
26 #include <media/v4l2-fh.h>
27 #include <media/v4l2-event.h>
28 #include <media/v4l2-device.h>
29 #include <media/v4l2-chip-ident.h>
31 #define dbgarg(cmd, fmt, arg...) \
32 do { \
33 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { \
34 printk(KERN_DEBUG "%s: ", vfd->name); \
35 v4l_printk_ioctl(cmd); \
36 printk(" " fmt, ## arg); \
37 } \
38 } while (0)
40 #define dbgarg2(fmt, arg...) \
41 do { \
42 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \
43 printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg);\
44 } while (0)
46 #define dbgarg3(fmt, arg...) \
47 do { \
48 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \
49 printk(KERN_CONT "%s: " fmt, vfd->name, ## arg);\
50 } while (0)
52 /* Zero out the end of the struct pointed to by p. Everything after, but
53 * not including, the specified field is cleared. */
54 #define CLEAR_AFTER_FIELD(p, field) \
55 memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \
56 0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field))
58 struct std_descr {
59 v4l2_std_id std;
60 const char *descr;
63 static const struct std_descr standards[] = {
64 { V4L2_STD_NTSC, "NTSC" },
65 { V4L2_STD_NTSC_M, "NTSC-M" },
66 { V4L2_STD_NTSC_M_JP, "NTSC-M-JP" },
67 { V4L2_STD_NTSC_M_KR, "NTSC-M-KR" },
68 { V4L2_STD_NTSC_443, "NTSC-443" },
69 { V4L2_STD_PAL, "PAL" },
70 { V4L2_STD_PAL_BG, "PAL-BG" },
71 { V4L2_STD_PAL_B, "PAL-B" },
72 { V4L2_STD_PAL_B1, "PAL-B1" },
73 { V4L2_STD_PAL_G, "PAL-G" },
74 { V4L2_STD_PAL_H, "PAL-H" },
75 { V4L2_STD_PAL_I, "PAL-I" },
76 { V4L2_STD_PAL_DK, "PAL-DK" },
77 { V4L2_STD_PAL_D, "PAL-D" },
78 { V4L2_STD_PAL_D1, "PAL-D1" },
79 { V4L2_STD_PAL_K, "PAL-K" },
80 { V4L2_STD_PAL_M, "PAL-M" },
81 { V4L2_STD_PAL_N, "PAL-N" },
82 { V4L2_STD_PAL_Nc, "PAL-Nc" },
83 { V4L2_STD_PAL_60, "PAL-60" },
84 { V4L2_STD_SECAM, "SECAM" },
85 { V4L2_STD_SECAM_B, "SECAM-B" },
86 { V4L2_STD_SECAM_G, "SECAM-G" },
87 { V4L2_STD_SECAM_H, "SECAM-H" },
88 { V4L2_STD_SECAM_DK, "SECAM-DK" },
89 { V4L2_STD_SECAM_D, "SECAM-D" },
90 { V4L2_STD_SECAM_K, "SECAM-K" },
91 { V4L2_STD_SECAM_K1, "SECAM-K1" },
92 { V4L2_STD_SECAM_L, "SECAM-L" },
93 { V4L2_STD_SECAM_LC, "SECAM-Lc" },
94 { 0, "Unknown" }
97 /* video4linux standard ID conversion to standard name
99 const char *v4l2_norm_to_name(v4l2_std_id id)
101 u32 myid = id;
102 int i;
104 /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
105 64 bit comparations. So, on that architecture, with some gcc
106 variants, compilation fails. Currently, the max value is 30bit wide.
108 BUG_ON(myid != id);
110 for (i = 0; standards[i].std; i++)
111 if (myid == standards[i].std)
112 break;
113 return standards[i].descr;
115 EXPORT_SYMBOL(v4l2_norm_to_name);
117 /* Returns frame period for the given standard */
118 void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod)
120 if (id & V4L2_STD_525_60) {
121 frameperiod->numerator = 1001;
122 frameperiod->denominator = 30000;
123 } else {
124 frameperiod->numerator = 1;
125 frameperiod->denominator = 25;
128 EXPORT_SYMBOL(v4l2_video_std_frame_period);
130 /* Fill in the fields of a v4l2_standard structure according to the
131 'id' and 'transmission' parameters. Returns negative on error. */
132 int v4l2_video_std_construct(struct v4l2_standard *vs,
133 int id, const char *name)
135 vs->id = id;
136 v4l2_video_std_frame_period(id, &vs->frameperiod);
137 vs->framelines = (id & V4L2_STD_525_60) ? 525 : 625;
138 strlcpy(vs->name, name, sizeof(vs->name));
139 return 0;
141 EXPORT_SYMBOL(v4l2_video_std_construct);
143 /* ----------------------------------------------------------------- */
144 /* some arrays for pretty-printing debug messages of enum types */
146 const char *v4l2_field_names[] = {
147 [V4L2_FIELD_ANY] = "any",
148 [V4L2_FIELD_NONE] = "none",
149 [V4L2_FIELD_TOP] = "top",
150 [V4L2_FIELD_BOTTOM] = "bottom",
151 [V4L2_FIELD_INTERLACED] = "interlaced",
152 [V4L2_FIELD_SEQ_TB] = "seq-tb",
153 [V4L2_FIELD_SEQ_BT] = "seq-bt",
154 [V4L2_FIELD_ALTERNATE] = "alternate",
155 [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
156 [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
158 EXPORT_SYMBOL(v4l2_field_names);
160 const char *v4l2_type_names[] = {
161 [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "vid-cap",
162 [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "vid-overlay",
163 [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "vid-out",
164 [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
165 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
166 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
167 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
168 [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay",
169 [V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE] = "vid-cap-mplane",
170 [V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE] = "vid-out-mplane",
172 EXPORT_SYMBOL(v4l2_type_names);
174 static const char *v4l2_memory_names[] = {
175 [V4L2_MEMORY_MMAP] = "mmap",
176 [V4L2_MEMORY_USERPTR] = "userptr",
177 [V4L2_MEMORY_OVERLAY] = "overlay",
180 #define prt_names(a, arr) ((((a) >= 0) && ((a) < ARRAY_SIZE(arr))) ? \
181 arr[a] : "unknown")
183 /* ------------------------------------------------------------------ */
184 /* debug help functions */
185 static const char *v4l2_ioctls[] = {
186 [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP",
187 [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED",
188 [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT",
189 [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT",
190 [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT",
191 [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS",
192 [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF",
193 [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF",
194 [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF",
195 [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY",
196 [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF",
197 [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF",
198 [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON",
199 [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF",
200 [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM",
201 [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM",
202 [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD",
203 [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD",
204 [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD",
205 [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT",
206 [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL",
207 [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL",
208 [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER",
209 [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER",
210 [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO",
211 [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO",
212 [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL",
213 [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU",
214 [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT",
215 [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT",
216 [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT",
217 [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT",
218 [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT",
219 [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT",
220 [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT",
221 [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR",
222 [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR",
223 [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY",
224 [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY",
225 [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP",
226 [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP",
227 [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP",
228 [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP",
229 [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP",
230 [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD",
231 [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT",
232 [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO",
233 [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT",
234 [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY",
235 [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY",
236 [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
237 [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS",
238 [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS",
239 [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS",
240 [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS",
241 #if 1
242 [_IOC_NR(VIDIOC_ENUM_FRAMESIZES)] = "VIDIOC_ENUM_FRAMESIZES",
243 [_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS",
244 [_IOC_NR(VIDIOC_G_ENC_INDEX)] = "VIDIOC_G_ENC_INDEX",
245 [_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD",
246 [_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD",
248 [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER",
249 [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER",
251 [_IOC_NR(VIDIOC_DBG_G_CHIP_IDENT)] = "VIDIOC_DBG_G_CHIP_IDENT",
252 [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK",
253 #endif
254 [_IOC_NR(VIDIOC_ENUM_DV_PRESETS)] = "VIDIOC_ENUM_DV_PRESETS",
255 [_IOC_NR(VIDIOC_S_DV_PRESET)] = "VIDIOC_S_DV_PRESET",
256 [_IOC_NR(VIDIOC_G_DV_PRESET)] = "VIDIOC_G_DV_PRESET",
257 [_IOC_NR(VIDIOC_QUERY_DV_PRESET)] = "VIDIOC_QUERY_DV_PRESET",
258 [_IOC_NR(VIDIOC_S_DV_TIMINGS)] = "VIDIOC_S_DV_TIMINGS",
259 [_IOC_NR(VIDIOC_G_DV_TIMINGS)] = "VIDIOC_G_DV_TIMINGS",
260 [_IOC_NR(VIDIOC_DQEVENT)] = "VIDIOC_DQEVENT",
261 [_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)] = "VIDIOC_SUBSCRIBE_EVENT",
262 [_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT",
264 #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
266 /* Common ioctl debug function. This function can be used by
267 external ioctl messages as well as internal V4L ioctl */
268 void v4l_printk_ioctl(unsigned int cmd)
270 char *dir, *type;
272 switch (_IOC_TYPE(cmd)) {
273 case 'd':
274 type = "v4l2_int";
275 break;
276 case 'V':
277 if (_IOC_NR(cmd) >= V4L2_IOCTLS) {
278 type = "v4l2";
279 break;
281 printk("%s", v4l2_ioctls[_IOC_NR(cmd)]);
282 return;
283 default:
284 type = "unknown";
287 switch (_IOC_DIR(cmd)) {
288 case _IOC_NONE: dir = "--"; break;
289 case _IOC_READ: dir = "r-"; break;
290 case _IOC_WRITE: dir = "-w"; break;
291 case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
292 default: dir = "*ERR*"; break;
294 printk("%s ioctl '%c', dir=%s, #%d (0x%08x)",
295 type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
297 EXPORT_SYMBOL(v4l_printk_ioctl);
299 static void dbgbuf(unsigned int cmd, struct video_device *vfd,
300 struct v4l2_buffer *p)
302 struct v4l2_timecode *tc = &p->timecode;
303 struct v4l2_plane *plane;
304 int i;
306 dbgarg(cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
307 "flags=0x%08d, field=%0d, sequence=%d, memory=%s\n",
308 p->timestamp.tv_sec / 3600,
309 (int)(p->timestamp.tv_sec / 60) % 60,
310 (int)(p->timestamp.tv_sec % 60),
311 (long)p->timestamp.tv_usec,
312 p->index,
313 prt_names(p->type, v4l2_type_names),
314 p->flags, p->field, p->sequence,
315 prt_names(p->memory, v4l2_memory_names));
317 if (V4L2_TYPE_IS_MULTIPLANAR(p->type) && p->m.planes) {
318 for (i = 0; i < p->length; ++i) {
319 plane = &p->m.planes[i];
320 dbgarg2("plane %d: bytesused=%d, data_offset=0x%08x "
321 "offset/userptr=0x%08lx, length=%d\n",
322 i, plane->bytesused, plane->data_offset,
323 plane->m.userptr, plane->length);
325 } else {
326 dbgarg2("bytesused=%d, offset/userptr=0x%08lx, length=%d\n",
327 p->bytesused, p->m.userptr, p->length);
330 dbgarg2("timecode=%02d:%02d:%02d type=%d, "
331 "flags=0x%08d, frames=%d, userbits=0x%08x\n",
332 tc->hours, tc->minutes, tc->seconds,
333 tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits);
336 static inline void dbgrect(struct video_device *vfd, char *s,
337 struct v4l2_rect *r)
339 dbgarg2("%sRect start at %dx%d, size=%dx%d\n", s, r->left, r->top,
340 r->width, r->height);
343 static inline void v4l_print_pix_fmt(struct video_device *vfd,
344 struct v4l2_pix_format *fmt)
346 dbgarg2("width=%d, height=%d, format=%c%c%c%c, field=%s, "
347 "bytesperline=%d sizeimage=%d, colorspace=%d\n",
348 fmt->width, fmt->height,
349 (fmt->pixelformat & 0xff),
350 (fmt->pixelformat >> 8) & 0xff,
351 (fmt->pixelformat >> 16) & 0xff,
352 (fmt->pixelformat >> 24) & 0xff,
353 prt_names(fmt->field, v4l2_field_names),
354 fmt->bytesperline, fmt->sizeimage, fmt->colorspace);
357 static inline void v4l_print_pix_fmt_mplane(struct video_device *vfd,
358 struct v4l2_pix_format_mplane *fmt)
360 int i;
362 dbgarg2("width=%d, height=%d, format=%c%c%c%c, field=%s, "
363 "colorspace=%d, num_planes=%d\n",
364 fmt->width, fmt->height,
365 (fmt->pixelformat & 0xff),
366 (fmt->pixelformat >> 8) & 0xff,
367 (fmt->pixelformat >> 16) & 0xff,
368 (fmt->pixelformat >> 24) & 0xff,
369 prt_names(fmt->field, v4l2_field_names),
370 fmt->colorspace, fmt->num_planes);
372 for (i = 0; i < fmt->num_planes; ++i)
373 dbgarg2("plane %d: bytesperline=%d sizeimage=%d\n", i,
374 fmt->plane_fmt[i].bytesperline,
375 fmt->plane_fmt[i].sizeimage);
378 static inline void v4l_print_ext_ctrls(unsigned int cmd,
379 struct video_device *vfd, struct v4l2_ext_controls *c, int show_vals)
381 __u32 i;
383 if (!(vfd->debug & V4L2_DEBUG_IOCTL_ARG))
384 return;
385 dbgarg(cmd, "");
386 printk(KERN_CONT "class=0x%x", c->ctrl_class);
387 for (i = 0; i < c->count; i++) {
388 if (show_vals && !c->controls[i].size)
389 printk(KERN_CONT " id/val=0x%x/0x%x",
390 c->controls[i].id, c->controls[i].value);
391 else
392 printk(KERN_CONT " id=0x%x,size=%u",
393 c->controls[i].id, c->controls[i].size);
395 printk(KERN_CONT "\n");
398 static inline int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)
400 __u32 i;
402 /* zero the reserved fields */
403 c->reserved[0] = c->reserved[1] = 0;
404 for (i = 0; i < c->count; i++)
405 c->controls[i].reserved2[0] = 0;
407 /* V4L2_CID_PRIVATE_BASE cannot be used as control class
408 when using extended controls.
409 Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
410 is it allowed for backwards compatibility.
412 if (!allow_priv && c->ctrl_class == V4L2_CID_PRIVATE_BASE)
413 return 0;
414 /* Check that all controls are from the same control class. */
415 for (i = 0; i < c->count; i++) {
416 if (V4L2_CTRL_ID2CLASS(c->controls[i].id) != c->ctrl_class) {
417 c->error_idx = i;
418 return 0;
421 return 1;
424 static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type)
426 if (ops == NULL)
427 return -EINVAL;
429 switch (type) {
430 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
431 if (ops->vidioc_g_fmt_vid_cap ||
432 ops->vidioc_g_fmt_vid_cap_mplane)
433 return 0;
434 break;
435 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
436 if (ops->vidioc_g_fmt_vid_cap_mplane)
437 return 0;
438 break;
439 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
440 if (ops->vidioc_g_fmt_vid_overlay)
441 return 0;
442 break;
443 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
444 if (ops->vidioc_g_fmt_vid_out ||
445 ops->vidioc_g_fmt_vid_out_mplane)
446 return 0;
447 break;
448 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
449 if (ops->vidioc_g_fmt_vid_out_mplane)
450 return 0;
451 break;
452 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
453 if (ops->vidioc_g_fmt_vid_out_overlay)
454 return 0;
455 break;
456 case V4L2_BUF_TYPE_VBI_CAPTURE:
457 if (ops->vidioc_g_fmt_vbi_cap)
458 return 0;
459 break;
460 case V4L2_BUF_TYPE_VBI_OUTPUT:
461 if (ops->vidioc_g_fmt_vbi_out)
462 return 0;
463 break;
464 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
465 if (ops->vidioc_g_fmt_sliced_vbi_cap)
466 return 0;
467 break;
468 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
469 if (ops->vidioc_g_fmt_sliced_vbi_out)
470 return 0;
471 break;
472 case V4L2_BUF_TYPE_PRIVATE:
473 if (ops->vidioc_g_fmt_type_private)
474 return 0;
475 break;
477 return -EINVAL;
481 * fmt_sp_to_mp() - Convert a single-plane format to its multi-planar 1-plane
482 * equivalent
484 static int fmt_sp_to_mp(const struct v4l2_format *f_sp,
485 struct v4l2_format *f_mp)
487 struct v4l2_pix_format_mplane *pix_mp = &f_mp->fmt.pix_mp;
488 const struct v4l2_pix_format *pix = &f_sp->fmt.pix;
490 if (f_sp->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
491 f_mp->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
492 else if (f_sp->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
493 f_mp->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
494 else
495 return -EINVAL;
497 pix_mp->width = pix->width;
498 pix_mp->height = pix->height;
499 pix_mp->pixelformat = pix->pixelformat;
500 pix_mp->field = pix->field;
501 pix_mp->colorspace = pix->colorspace;
502 pix_mp->num_planes = 1;
503 pix_mp->plane_fmt[0].sizeimage = pix->sizeimage;
504 pix_mp->plane_fmt[0].bytesperline = pix->bytesperline;
506 return 0;
510 * fmt_mp_to_sp() - Convert a multi-planar 1-plane format to its single-planar
511 * equivalent
513 static int fmt_mp_to_sp(const struct v4l2_format *f_mp,
514 struct v4l2_format *f_sp)
516 const struct v4l2_pix_format_mplane *pix_mp = &f_mp->fmt.pix_mp;
517 struct v4l2_pix_format *pix = &f_sp->fmt.pix;
519 if (f_mp->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
520 f_sp->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
521 else if (f_mp->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
522 f_sp->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
523 else
524 return -EINVAL;
526 pix->width = pix_mp->width;
527 pix->height = pix_mp->height;
528 pix->pixelformat = pix_mp->pixelformat;
529 pix->field = pix_mp->field;
530 pix->colorspace = pix_mp->colorspace;
531 pix->sizeimage = pix_mp->plane_fmt[0].sizeimage;
532 pix->bytesperline = pix_mp->plane_fmt[0].bytesperline;
534 return 0;
537 static long __video_do_ioctl(struct file *file,
538 unsigned int cmd, void *arg)
540 struct video_device *vfd = video_devdata(file);
541 const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
542 void *fh = file->private_data;
543 struct v4l2_fh *vfh = NULL;
544 struct v4l2_format f_copy;
545 int use_fh_prio = 0;
546 long ret = -ENOTTY;
548 if (ops == NULL) {
549 printk(KERN_WARNING "videodev: \"%s\" has no ioctl_ops.\n",
550 vfd->name);
551 return ret;
554 if ((vfd->debug & V4L2_DEBUG_IOCTL) &&
555 !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) {
556 v4l_print_ioctl(vfd->name, cmd);
557 printk(KERN_CONT "\n");
560 if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) {
561 vfh = file->private_data;
562 use_fh_prio = test_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
565 if (use_fh_prio) {
566 switch (cmd) {
567 case VIDIOC_S_CTRL:
568 case VIDIOC_S_STD:
569 case VIDIOC_S_INPUT:
570 case VIDIOC_S_OUTPUT:
571 case VIDIOC_S_TUNER:
572 case VIDIOC_S_FREQUENCY:
573 case VIDIOC_S_FMT:
574 case VIDIOC_S_CROP:
575 case VIDIOC_S_AUDIO:
576 case VIDIOC_S_AUDOUT:
577 case VIDIOC_S_EXT_CTRLS:
578 case VIDIOC_S_FBUF:
579 case VIDIOC_S_PRIORITY:
580 case VIDIOC_S_DV_PRESET:
581 case VIDIOC_S_DV_TIMINGS:
582 case VIDIOC_S_JPEGCOMP:
583 case VIDIOC_S_MODULATOR:
584 case VIDIOC_S_PARM:
585 case VIDIOC_S_HW_FREQ_SEEK:
586 case VIDIOC_ENCODER_CMD:
587 case VIDIOC_OVERLAY:
588 case VIDIOC_REQBUFS:
589 case VIDIOC_STREAMON:
590 case VIDIOC_STREAMOFF:
591 ret = v4l2_prio_check(vfd->prio, vfh->prio);
592 if (ret)
593 goto exit_prio;
594 ret = -EINVAL;
595 break;
599 switch (cmd) {
601 /* --- capabilities ------------------------------------------ */
602 case VIDIOC_QUERYCAP:
604 struct v4l2_capability *cap = (struct v4l2_capability *)arg;
606 if (!ops->vidioc_querycap)
607 break;
609 cap->version = LINUX_VERSION_CODE;
610 ret = ops->vidioc_querycap(file, fh, cap);
611 if (!ret)
612 dbgarg(cmd, "driver=%s, card=%s, bus=%s, "
613 "version=0x%08x, "
614 "capabilities=0x%08x\n",
615 cap->driver, cap->card, cap->bus_info,
616 cap->version,
617 cap->capabilities);
618 break;
621 /* --- priority ------------------------------------------ */
622 case VIDIOC_G_PRIORITY:
624 enum v4l2_priority *p = arg;
626 if (ops->vidioc_g_priority) {
627 ret = ops->vidioc_g_priority(file, fh, p);
628 } else if (use_fh_prio) {
629 *p = v4l2_prio_max(&vfd->v4l2_dev->prio);
630 ret = 0;
632 if (!ret)
633 dbgarg(cmd, "priority is %d\n", *p);
634 break;
636 case VIDIOC_S_PRIORITY:
638 enum v4l2_priority *p = arg;
640 if (!ops->vidioc_s_priority && !use_fh_prio)
641 break;
642 dbgarg(cmd, "setting priority to %d\n", *p);
643 if (ops->vidioc_s_priority)
644 ret = ops->vidioc_s_priority(file, fh, *p);
645 else
646 ret = v4l2_prio_change(&vfd->v4l2_dev->prio, &vfh->prio, *p);
647 break;
650 /* --- capture ioctls ---------------------------------------- */
651 case VIDIOC_ENUM_FMT:
653 struct v4l2_fmtdesc *f = arg;
655 switch (f->type) {
656 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
657 if (ops->vidioc_enum_fmt_vid_cap)
658 ret = ops->vidioc_enum_fmt_vid_cap(file, fh, f);
659 break;
660 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
661 if (ops->vidioc_enum_fmt_vid_cap_mplane)
662 ret = ops->vidioc_enum_fmt_vid_cap_mplane(file,
663 fh, f);
664 break;
665 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
666 if (ops->vidioc_enum_fmt_vid_overlay)
667 ret = ops->vidioc_enum_fmt_vid_overlay(file,
668 fh, f);
669 break;
670 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
671 if (ops->vidioc_enum_fmt_vid_out)
672 ret = ops->vidioc_enum_fmt_vid_out(file, fh, f);
673 break;
674 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
675 if (ops->vidioc_enum_fmt_vid_out_mplane)
676 ret = ops->vidioc_enum_fmt_vid_out_mplane(file,
677 fh, f);
678 break;
679 case V4L2_BUF_TYPE_PRIVATE:
680 if (ops->vidioc_enum_fmt_type_private)
681 ret = ops->vidioc_enum_fmt_type_private(file,
682 fh, f);
683 break;
684 default:
685 break;
687 if (!ret)
688 dbgarg(cmd, "index=%d, type=%d, flags=%d, "
689 "pixelformat=%c%c%c%c, description='%s'\n",
690 f->index, f->type, f->flags,
691 (f->pixelformat & 0xff),
692 (f->pixelformat >> 8) & 0xff,
693 (f->pixelformat >> 16) & 0xff,
694 (f->pixelformat >> 24) & 0xff,
695 f->description);
696 break;
698 case VIDIOC_G_FMT:
700 struct v4l2_format *f = (struct v4l2_format *)arg;
702 /* FIXME: Should be one dump per type */
703 dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
705 switch (f->type) {
706 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
707 if (ops->vidioc_g_fmt_vid_cap) {
708 ret = ops->vidioc_g_fmt_vid_cap(file, fh, f);
709 } else if (ops->vidioc_g_fmt_vid_cap_mplane) {
710 if (fmt_sp_to_mp(f, &f_copy))
711 break;
712 ret = ops->vidioc_g_fmt_vid_cap_mplane(file, fh,
713 &f_copy);
714 if (ret)
715 break;
717 /* Driver is currently in multi-planar format,
718 * we can't return it in single-planar API*/
719 if (f_copy.fmt.pix_mp.num_planes > 1) {
720 ret = -EBUSY;
721 break;
724 ret = fmt_mp_to_sp(&f_copy, f);
726 if (!ret)
727 v4l_print_pix_fmt(vfd, &f->fmt.pix);
728 break;
729 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
730 if (ops->vidioc_g_fmt_vid_cap_mplane) {
731 ret = ops->vidioc_g_fmt_vid_cap_mplane(file,
732 fh, f);
733 } else if (ops->vidioc_g_fmt_vid_cap) {
734 if (fmt_mp_to_sp(f, &f_copy))
735 break;
736 ret = ops->vidioc_g_fmt_vid_cap(file,
737 fh, &f_copy);
738 if (ret)
739 break;
741 ret = fmt_sp_to_mp(&f_copy, f);
743 if (!ret)
744 v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp);
745 break;
746 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
747 if (ops->vidioc_g_fmt_vid_overlay)
748 ret = ops->vidioc_g_fmt_vid_overlay(file,
749 fh, f);
750 break;
751 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
752 if (ops->vidioc_g_fmt_vid_out) {
753 ret = ops->vidioc_g_fmt_vid_out(file, fh, f);
754 } else if (ops->vidioc_g_fmt_vid_out_mplane) {
755 if (fmt_sp_to_mp(f, &f_copy))
756 break;
757 ret = ops->vidioc_g_fmt_vid_out_mplane(file, fh,
758 &f_copy);
759 if (ret)
760 break;
762 /* Driver is currently in multi-planar format,
763 * we can't return it in single-planar API*/
764 if (f_copy.fmt.pix_mp.num_planes > 1) {
765 ret = -EBUSY;
766 break;
769 ret = fmt_mp_to_sp(&f_copy, f);
771 if (!ret)
772 v4l_print_pix_fmt(vfd, &f->fmt.pix);
773 break;
774 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
775 if (ops->vidioc_g_fmt_vid_out_mplane) {
776 ret = ops->vidioc_g_fmt_vid_out_mplane(file,
777 fh, f);
778 } else if (ops->vidioc_g_fmt_vid_out) {
779 if (fmt_mp_to_sp(f, &f_copy))
780 break;
781 ret = ops->vidioc_g_fmt_vid_out(file,
782 fh, &f_copy);
783 if (ret)
784 break;
786 ret = fmt_sp_to_mp(&f_copy, f);
788 if (!ret)
789 v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp);
790 break;
791 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
792 if (ops->vidioc_g_fmt_vid_out_overlay)
793 ret = ops->vidioc_g_fmt_vid_out_overlay(file,
794 fh, f);
795 break;
796 case V4L2_BUF_TYPE_VBI_CAPTURE:
797 if (ops->vidioc_g_fmt_vbi_cap)
798 ret = ops->vidioc_g_fmt_vbi_cap(file, fh, f);
799 break;
800 case V4L2_BUF_TYPE_VBI_OUTPUT:
801 if (ops->vidioc_g_fmt_vbi_out)
802 ret = ops->vidioc_g_fmt_vbi_out(file, fh, f);
803 break;
804 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
805 if (ops->vidioc_g_fmt_sliced_vbi_cap)
806 ret = ops->vidioc_g_fmt_sliced_vbi_cap(file,
807 fh, f);
808 break;
809 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
810 if (ops->vidioc_g_fmt_sliced_vbi_out)
811 ret = ops->vidioc_g_fmt_sliced_vbi_out(file,
812 fh, f);
813 break;
814 case V4L2_BUF_TYPE_PRIVATE:
815 if (ops->vidioc_g_fmt_type_private)
816 ret = ops->vidioc_g_fmt_type_private(file,
817 fh, f);
818 break;
821 break;
823 case VIDIOC_S_FMT:
825 struct v4l2_format *f = (struct v4l2_format *)arg;
827 /* FIXME: Should be one dump per type */
828 dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
830 switch (f->type) {
831 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
832 CLEAR_AFTER_FIELD(f, fmt.pix);
833 v4l_print_pix_fmt(vfd, &f->fmt.pix);
834 if (ops->vidioc_s_fmt_vid_cap) {
835 ret = ops->vidioc_s_fmt_vid_cap(file, fh, f);
836 } else if (ops->vidioc_s_fmt_vid_cap_mplane) {
837 if (fmt_sp_to_mp(f, &f_copy))
838 break;
839 ret = ops->vidioc_s_fmt_vid_cap_mplane(file, fh,
840 &f_copy);
841 if (ret)
842 break;
844 if (f_copy.fmt.pix_mp.num_planes > 1) {
845 /* Drivers shouldn't adjust from 1-plane
846 * to more than 1-plane formats */
847 ret = -EBUSY;
848 WARN_ON(1);
849 break;
852 ret = fmt_mp_to_sp(&f_copy, f);
854 break;
855 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
856 CLEAR_AFTER_FIELD(f, fmt.pix_mp);
857 v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp);
858 if (ops->vidioc_s_fmt_vid_cap_mplane) {
859 ret = ops->vidioc_s_fmt_vid_cap_mplane(file,
860 fh, f);
861 } else if (ops->vidioc_s_fmt_vid_cap &&
862 f->fmt.pix_mp.num_planes == 1) {
863 if (fmt_mp_to_sp(f, &f_copy))
864 break;
865 ret = ops->vidioc_s_fmt_vid_cap(file,
866 fh, &f_copy);
867 if (ret)
868 break;
870 ret = fmt_sp_to_mp(&f_copy, f);
872 break;
873 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
874 CLEAR_AFTER_FIELD(f, fmt.win);
875 if (ops->vidioc_s_fmt_vid_overlay)
876 ret = ops->vidioc_s_fmt_vid_overlay(file,
877 fh, f);
878 break;
879 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
880 CLEAR_AFTER_FIELD(f, fmt.pix);
881 v4l_print_pix_fmt(vfd, &f->fmt.pix);
882 if (ops->vidioc_s_fmt_vid_out) {
883 ret = ops->vidioc_s_fmt_vid_out(file, fh, f);
884 } else if (ops->vidioc_s_fmt_vid_out_mplane) {
885 if (fmt_sp_to_mp(f, &f_copy))
886 break;
887 ret = ops->vidioc_s_fmt_vid_out_mplane(file, fh,
888 &f_copy);
889 if (ret)
890 break;
892 if (f_copy.fmt.pix_mp.num_planes > 1) {
893 /* Drivers shouldn't adjust from 1-plane
894 * to more than 1-plane formats */
895 ret = -EBUSY;
896 WARN_ON(1);
897 break;
900 ret = fmt_mp_to_sp(&f_copy, f);
902 break;
903 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
904 CLEAR_AFTER_FIELD(f, fmt.pix_mp);
905 v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp);
906 if (ops->vidioc_s_fmt_vid_out_mplane) {
907 ret = ops->vidioc_s_fmt_vid_out_mplane(file,
908 fh, f);
909 } else if (ops->vidioc_s_fmt_vid_out &&
910 f->fmt.pix_mp.num_planes == 1) {
911 if (fmt_mp_to_sp(f, &f_copy))
912 break;
913 ret = ops->vidioc_s_fmt_vid_out(file,
914 fh, &f_copy);
915 if (ret)
916 break;
918 ret = fmt_mp_to_sp(&f_copy, f);
920 break;
921 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
922 CLEAR_AFTER_FIELD(f, fmt.win);
923 if (ops->vidioc_s_fmt_vid_out_overlay)
924 ret = ops->vidioc_s_fmt_vid_out_overlay(file,
925 fh, f);
926 break;
927 case V4L2_BUF_TYPE_VBI_CAPTURE:
928 CLEAR_AFTER_FIELD(f, fmt.vbi);
929 if (ops->vidioc_s_fmt_vbi_cap)
930 ret = ops->vidioc_s_fmt_vbi_cap(file, fh, f);
931 break;
932 case V4L2_BUF_TYPE_VBI_OUTPUT:
933 CLEAR_AFTER_FIELD(f, fmt.vbi);
934 if (ops->vidioc_s_fmt_vbi_out)
935 ret = ops->vidioc_s_fmt_vbi_out(file, fh, f);
936 break;
937 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
938 CLEAR_AFTER_FIELD(f, fmt.sliced);
939 if (ops->vidioc_s_fmt_sliced_vbi_cap)
940 ret = ops->vidioc_s_fmt_sliced_vbi_cap(file,
941 fh, f);
942 break;
943 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
944 CLEAR_AFTER_FIELD(f, fmt.sliced);
945 if (ops->vidioc_s_fmt_sliced_vbi_out)
946 ret = ops->vidioc_s_fmt_sliced_vbi_out(file,
947 fh, f);
948 break;
949 case V4L2_BUF_TYPE_PRIVATE:
950 /* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */
951 if (ops->vidioc_s_fmt_type_private)
952 ret = ops->vidioc_s_fmt_type_private(file,
953 fh, f);
954 break;
956 break;
958 case VIDIOC_TRY_FMT:
960 struct v4l2_format *f = (struct v4l2_format *)arg;
962 /* FIXME: Should be one dump per type */
963 dbgarg(cmd, "type=%s\n", prt_names(f->type,
964 v4l2_type_names));
965 switch (f->type) {
966 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
967 CLEAR_AFTER_FIELD(f, fmt.pix);
968 if (ops->vidioc_try_fmt_vid_cap) {
969 ret = ops->vidioc_try_fmt_vid_cap(file, fh, f);
970 } else if (ops->vidioc_try_fmt_vid_cap_mplane) {
971 if (fmt_sp_to_mp(f, &f_copy))
972 break;
973 ret = ops->vidioc_try_fmt_vid_cap_mplane(file,
974 fh, &f_copy);
975 if (ret)
976 break;
978 if (f_copy.fmt.pix_mp.num_planes > 1) {
979 /* Drivers shouldn't adjust from 1-plane
980 * to more than 1-plane formats */
981 ret = -EBUSY;
982 WARN_ON(1);
983 break;
985 ret = fmt_mp_to_sp(&f_copy, f);
987 if (!ret)
988 v4l_print_pix_fmt(vfd, &f->fmt.pix);
989 break;
990 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
991 CLEAR_AFTER_FIELD(f, fmt.pix_mp);
992 if (ops->vidioc_try_fmt_vid_cap_mplane) {
993 ret = ops->vidioc_try_fmt_vid_cap_mplane(file,
994 fh, f);
995 } else if (ops->vidioc_try_fmt_vid_cap &&
996 f->fmt.pix_mp.num_planes == 1) {
997 if (fmt_mp_to_sp(f, &f_copy))
998 break;
999 ret = ops->vidioc_try_fmt_vid_cap(file,
1000 fh, &f_copy);
1001 if (ret)
1002 break;
1004 ret = fmt_sp_to_mp(&f_copy, f);
1006 if (!ret)
1007 v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp);
1008 break;
1009 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1010 CLEAR_AFTER_FIELD(f, fmt.win);
1011 if (ops->vidioc_try_fmt_vid_overlay)
1012 ret = ops->vidioc_try_fmt_vid_overlay(file,
1013 fh, f);
1014 break;
1015 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1016 CLEAR_AFTER_FIELD(f, fmt.pix);
1017 if (ops->vidioc_try_fmt_vid_out) {
1018 ret = ops->vidioc_try_fmt_vid_out(file, fh, f);
1019 } else if (ops->vidioc_try_fmt_vid_out_mplane) {
1020 if (fmt_sp_to_mp(f, &f_copy))
1021 break;
1022 ret = ops->vidioc_try_fmt_vid_out_mplane(file,
1023 fh, &f_copy);
1024 if (ret)
1025 break;
1027 if (f_copy.fmt.pix_mp.num_planes > 1) {
1028 /* Drivers shouldn't adjust from 1-plane
1029 * to more than 1-plane formats */
1030 ret = -EBUSY;
1031 WARN_ON(1);
1032 break;
1034 ret = fmt_mp_to_sp(&f_copy, f);
1036 if (!ret)
1037 v4l_print_pix_fmt(vfd, &f->fmt.pix);
1038 break;
1039 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1040 CLEAR_AFTER_FIELD(f, fmt.pix_mp);
1041 if (ops->vidioc_try_fmt_vid_out_mplane) {
1042 ret = ops->vidioc_try_fmt_vid_out_mplane(file,
1043 fh, f);
1044 } else if (ops->vidioc_try_fmt_vid_out &&
1045 f->fmt.pix_mp.num_planes == 1) {
1046 if (fmt_mp_to_sp(f, &f_copy))
1047 break;
1048 ret = ops->vidioc_try_fmt_vid_out(file,
1049 fh, &f_copy);
1050 if (ret)
1051 break;
1053 ret = fmt_sp_to_mp(&f_copy, f);
1055 if (!ret)
1056 v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp);
1057 break;
1058 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
1059 CLEAR_AFTER_FIELD(f, fmt.win);
1060 if (ops->vidioc_try_fmt_vid_out_overlay)
1061 ret = ops->vidioc_try_fmt_vid_out_overlay(file,
1062 fh, f);
1063 break;
1064 case V4L2_BUF_TYPE_VBI_CAPTURE:
1065 CLEAR_AFTER_FIELD(f, fmt.vbi);
1066 if (ops->vidioc_try_fmt_vbi_cap)
1067 ret = ops->vidioc_try_fmt_vbi_cap(file, fh, f);
1068 break;
1069 case V4L2_BUF_TYPE_VBI_OUTPUT:
1070 CLEAR_AFTER_FIELD(f, fmt.vbi);
1071 if (ops->vidioc_try_fmt_vbi_out)
1072 ret = ops->vidioc_try_fmt_vbi_out(file, fh, f);
1073 break;
1074 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1075 CLEAR_AFTER_FIELD(f, fmt.sliced);
1076 if (ops->vidioc_try_fmt_sliced_vbi_cap)
1077 ret = ops->vidioc_try_fmt_sliced_vbi_cap(file,
1078 fh, f);
1079 break;
1080 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1081 CLEAR_AFTER_FIELD(f, fmt.sliced);
1082 if (ops->vidioc_try_fmt_sliced_vbi_out)
1083 ret = ops->vidioc_try_fmt_sliced_vbi_out(file,
1084 fh, f);
1085 break;
1086 case V4L2_BUF_TYPE_PRIVATE:
1087 /* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */
1088 if (ops->vidioc_try_fmt_type_private)
1089 ret = ops->vidioc_try_fmt_type_private(file,
1090 fh, f);
1091 break;
1094 break;
1096 /* FIXME: Those buf reqs could be handled here,
1097 with some changes on videobuf to allow its header to be included at
1098 videodev2.h or being merged at videodev2.
1100 case VIDIOC_REQBUFS:
1102 struct v4l2_requestbuffers *p = arg;
1104 if (!ops->vidioc_reqbufs)
1105 break;
1106 ret = check_fmt(ops, p->type);
1107 if (ret)
1108 break;
1110 if (p->type < V4L2_BUF_TYPE_PRIVATE)
1111 CLEAR_AFTER_FIELD(p, memory);
1113 ret = ops->vidioc_reqbufs(file, fh, p);
1114 dbgarg(cmd, "count=%d, type=%s, memory=%s\n",
1115 p->count,
1116 prt_names(p->type, v4l2_type_names),
1117 prt_names(p->memory, v4l2_memory_names));
1118 break;
1120 case VIDIOC_QUERYBUF:
1122 struct v4l2_buffer *p = arg;
1124 if (!ops->vidioc_querybuf)
1125 break;
1126 ret = check_fmt(ops, p->type);
1127 if (ret)
1128 break;
1130 ret = ops->vidioc_querybuf(file, fh, p);
1131 if (!ret)
1132 dbgbuf(cmd, vfd, p);
1133 break;
1135 case VIDIOC_QBUF:
1137 struct v4l2_buffer *p = arg;
1139 if (!ops->vidioc_qbuf)
1140 break;
1141 ret = check_fmt(ops, p->type);
1142 if (ret)
1143 break;
1145 ret = ops->vidioc_qbuf(file, fh, p);
1146 if (!ret)
1147 dbgbuf(cmd, vfd, p);
1148 break;
1150 case VIDIOC_DQBUF:
1152 struct v4l2_buffer *p = arg;
1154 if (!ops->vidioc_dqbuf)
1155 break;
1156 ret = check_fmt(ops, p->type);
1157 if (ret)
1158 break;
1160 ret = ops->vidioc_dqbuf(file, fh, p);
1161 if (!ret)
1162 dbgbuf(cmd, vfd, p);
1163 break;
1165 case VIDIOC_OVERLAY:
1167 int *i = arg;
1169 if (!ops->vidioc_overlay)
1170 break;
1171 dbgarg(cmd, "value=%d\n", *i);
1172 ret = ops->vidioc_overlay(file, fh, *i);
1173 break;
1175 case VIDIOC_G_FBUF:
1177 struct v4l2_framebuffer *p = arg;
1179 if (!ops->vidioc_g_fbuf)
1180 break;
1181 ret = ops->vidioc_g_fbuf(file, fh, arg);
1182 if (!ret) {
1183 dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
1184 p->capability, p->flags,
1185 (unsigned long)p->base);
1186 v4l_print_pix_fmt(vfd, &p->fmt);
1188 break;
1190 case VIDIOC_S_FBUF:
1192 struct v4l2_framebuffer *p = arg;
1194 if (!ops->vidioc_s_fbuf)
1195 break;
1196 dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
1197 p->capability, p->flags, (unsigned long)p->base);
1198 v4l_print_pix_fmt(vfd, &p->fmt);
1199 ret = ops->vidioc_s_fbuf(file, fh, arg);
1200 break;
1202 case VIDIOC_STREAMON:
1204 enum v4l2_buf_type i = *(int *)arg;
1206 if (!ops->vidioc_streamon)
1207 break;
1208 dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
1209 ret = ops->vidioc_streamon(file, fh, i);
1210 break;
1212 case VIDIOC_STREAMOFF:
1214 enum v4l2_buf_type i = *(int *)arg;
1216 if (!ops->vidioc_streamoff)
1217 break;
1218 dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
1219 ret = ops->vidioc_streamoff(file, fh, i);
1220 break;
1222 /* ---------- tv norms ---------- */
1223 case VIDIOC_ENUMSTD:
1225 struct v4l2_standard *p = arg;
1226 v4l2_std_id id = vfd->tvnorms, curr_id = 0;
1227 unsigned int index = p->index, i, j = 0;
1228 const char *descr = "";
1230 /* Return norm array in a canonical way */
1231 for (i = 0; i <= index && id; i++) {
1232 /* last std value in the standards array is 0, so this
1233 while always ends there since (id & 0) == 0. */
1234 while ((id & standards[j].std) != standards[j].std)
1235 j++;
1236 curr_id = standards[j].std;
1237 descr = standards[j].descr;
1238 j++;
1239 if (curr_id == 0)
1240 break;
1241 if (curr_id != V4L2_STD_PAL &&
1242 curr_id != V4L2_STD_SECAM &&
1243 curr_id != V4L2_STD_NTSC)
1244 id &= ~curr_id;
1246 if (i <= index)
1247 break;
1249 v4l2_video_std_construct(p, curr_id, descr);
1251 dbgarg(cmd, "index=%d, id=0x%Lx, name=%s, fps=%d/%d, "
1252 "framelines=%d\n", p->index,
1253 (unsigned long long)p->id, p->name,
1254 p->frameperiod.numerator,
1255 p->frameperiod.denominator,
1256 p->framelines);
1258 ret = 0;
1259 break;
1261 case VIDIOC_G_STD:
1263 v4l2_std_id *id = arg;
1265 ret = 0;
1266 /* Calls the specific handler */
1267 if (ops->vidioc_g_std)
1268 ret = ops->vidioc_g_std(file, fh, id);
1269 else if (vfd->current_norm)
1270 *id = vfd->current_norm;
1271 else
1272 ret = -EINVAL;
1274 if (!ret)
1275 dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id);
1276 break;
1278 case VIDIOC_S_STD:
1280 v4l2_std_id *id = arg, norm;
1282 dbgarg(cmd, "std=%08Lx\n", (long long unsigned)*id);
1284 norm = (*id) & vfd->tvnorms;
1285 if (vfd->tvnorms && !norm) /* Check if std is supported */
1286 break;
1288 /* Calls the specific handler */
1289 if (ops->vidioc_s_std)
1290 ret = ops->vidioc_s_std(file, fh, &norm);
1291 else
1292 ret = -EINVAL;
1294 /* Updates standard information */
1295 if (ret >= 0)
1296 vfd->current_norm = norm;
1297 break;
1299 case VIDIOC_QUERYSTD:
1301 v4l2_std_id *p = arg;
1303 if (!ops->vidioc_querystd)
1304 break;
1305 ret = ops->vidioc_querystd(file, fh, arg);
1306 if (!ret)
1307 dbgarg(cmd, "detected std=%08Lx\n",
1308 (unsigned long long)*p);
1309 break;
1311 /* ------ input switching ---------- */
1312 /* FIXME: Inputs can be handled inside videodev2 */
1313 case VIDIOC_ENUMINPUT:
1315 struct v4l2_input *p = arg;
1318 * We set the flags for CAP_PRESETS, CAP_CUSTOM_TIMINGS &
1319 * CAP_STD here based on ioctl handler provided by the
1320 * driver. If the driver doesn't support these
1321 * for a specific input, it must override these flags.
1323 if (ops->vidioc_s_std)
1324 p->capabilities |= V4L2_IN_CAP_STD;
1325 if (ops->vidioc_s_dv_preset)
1326 p->capabilities |= V4L2_IN_CAP_PRESETS;
1327 if (ops->vidioc_s_dv_timings)
1328 p->capabilities |= V4L2_IN_CAP_CUSTOM_TIMINGS;
1330 if (!ops->vidioc_enum_input)
1331 break;
1333 ret = ops->vidioc_enum_input(file, fh, p);
1334 if (!ret)
1335 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1336 "audioset=%d, "
1337 "tuner=%d, std=%08Lx, status=%d\n",
1338 p->index, p->name, p->type, p->audioset,
1339 p->tuner,
1340 (unsigned long long)p->std,
1341 p->status);
1342 break;
1344 case VIDIOC_G_INPUT:
1346 unsigned int *i = arg;
1348 if (!ops->vidioc_g_input)
1349 break;
1350 ret = ops->vidioc_g_input(file, fh, i);
1351 if (!ret)
1352 dbgarg(cmd, "value=%d\n", *i);
1353 break;
1355 case VIDIOC_S_INPUT:
1357 unsigned int *i = arg;
1359 if (!ops->vidioc_s_input)
1360 break;
1361 dbgarg(cmd, "value=%d\n", *i);
1362 ret = ops->vidioc_s_input(file, fh, *i);
1363 break;
1366 /* ------ output switching ---------- */
1367 case VIDIOC_ENUMOUTPUT:
1369 struct v4l2_output *p = arg;
1371 if (!ops->vidioc_enum_output)
1372 break;
1375 * We set the flags for CAP_PRESETS, CAP_CUSTOM_TIMINGS &
1376 * CAP_STD here based on ioctl handler provided by the
1377 * driver. If the driver doesn't support these
1378 * for a specific output, it must override these flags.
1380 if (ops->vidioc_s_std)
1381 p->capabilities |= V4L2_OUT_CAP_STD;
1382 if (ops->vidioc_s_dv_preset)
1383 p->capabilities |= V4L2_OUT_CAP_PRESETS;
1384 if (ops->vidioc_s_dv_timings)
1385 p->capabilities |= V4L2_OUT_CAP_CUSTOM_TIMINGS;
1387 ret = ops->vidioc_enum_output(file, fh, p);
1388 if (!ret)
1389 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1390 "audioset=0x%x, "
1391 "modulator=%d, std=0x%08Lx\n",
1392 p->index, p->name, p->type, p->audioset,
1393 p->modulator, (unsigned long long)p->std);
1394 break;
1396 case VIDIOC_G_OUTPUT:
1398 unsigned int *i = arg;
1400 if (!ops->vidioc_g_output)
1401 break;
1402 ret = ops->vidioc_g_output(file, fh, i);
1403 if (!ret)
1404 dbgarg(cmd, "value=%d\n", *i);
1405 break;
1407 case VIDIOC_S_OUTPUT:
1409 unsigned int *i = arg;
1411 if (!ops->vidioc_s_output)
1412 break;
1413 dbgarg(cmd, "value=%d\n", *i);
1414 ret = ops->vidioc_s_output(file, fh, *i);
1415 break;
1418 /* --- controls ---------------------------------------------- */
1419 case VIDIOC_QUERYCTRL:
1421 struct v4l2_queryctrl *p = arg;
1423 if (vfh && vfh->ctrl_handler)
1424 ret = v4l2_queryctrl(vfh->ctrl_handler, p);
1425 else if (vfd->ctrl_handler)
1426 ret = v4l2_queryctrl(vfd->ctrl_handler, p);
1427 else if (ops->vidioc_queryctrl)
1428 ret = ops->vidioc_queryctrl(file, fh, p);
1429 else
1430 break;
1431 if (!ret)
1432 dbgarg(cmd, "id=0x%x, type=%d, name=%s, min/max=%d/%d, "
1433 "step=%d, default=%d, flags=0x%08x\n",
1434 p->id, p->type, p->name,
1435 p->minimum, p->maximum,
1436 p->step, p->default_value, p->flags);
1437 else
1438 dbgarg(cmd, "id=0x%x\n", p->id);
1439 break;
1441 case VIDIOC_G_CTRL:
1443 struct v4l2_control *p = arg;
1445 if (vfh && vfh->ctrl_handler)
1446 ret = v4l2_g_ctrl(vfh->ctrl_handler, p);
1447 else if (vfd->ctrl_handler)
1448 ret = v4l2_g_ctrl(vfd->ctrl_handler, p);
1449 else if (ops->vidioc_g_ctrl)
1450 ret = ops->vidioc_g_ctrl(file, fh, p);
1451 else if (ops->vidioc_g_ext_ctrls) {
1452 struct v4l2_ext_controls ctrls;
1453 struct v4l2_ext_control ctrl;
1455 ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
1456 ctrls.count = 1;
1457 ctrls.controls = &ctrl;
1458 ctrl.id = p->id;
1459 ctrl.value = p->value;
1460 if (check_ext_ctrls(&ctrls, 1)) {
1461 ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls);
1462 if (ret == 0)
1463 p->value = ctrl.value;
1465 } else
1466 break;
1467 if (!ret)
1468 dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
1469 else
1470 dbgarg(cmd, "id=0x%x\n", p->id);
1471 break;
1473 case VIDIOC_S_CTRL:
1475 struct v4l2_control *p = arg;
1476 struct v4l2_ext_controls ctrls;
1477 struct v4l2_ext_control ctrl;
1479 if (!(vfh && vfh->ctrl_handler) && !vfd->ctrl_handler &&
1480 !ops->vidioc_s_ctrl && !ops->vidioc_s_ext_ctrls)
1481 break;
1483 dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
1485 if (vfh && vfh->ctrl_handler) {
1486 ret = v4l2_s_ctrl(vfh, vfh->ctrl_handler, p);
1487 break;
1489 if (vfd->ctrl_handler) {
1490 ret = v4l2_s_ctrl(NULL, vfd->ctrl_handler, p);
1491 break;
1493 if (ops->vidioc_s_ctrl) {
1494 ret = ops->vidioc_s_ctrl(file, fh, p);
1495 break;
1497 if (!ops->vidioc_s_ext_ctrls)
1498 break;
1500 ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
1501 ctrls.count = 1;
1502 ctrls.controls = &ctrl;
1503 ctrl.id = p->id;
1504 ctrl.value = p->value;
1505 if (check_ext_ctrls(&ctrls, 1))
1506 ret = ops->vidioc_s_ext_ctrls(file, fh, &ctrls);
1507 break;
1509 case VIDIOC_G_EXT_CTRLS:
1511 struct v4l2_ext_controls *p = arg;
1513 p->error_idx = p->count;
1514 if (vfh && vfh->ctrl_handler)
1515 ret = v4l2_g_ext_ctrls(vfh->ctrl_handler, p);
1516 else if (vfd->ctrl_handler)
1517 ret = v4l2_g_ext_ctrls(vfd->ctrl_handler, p);
1518 else if (ops->vidioc_g_ext_ctrls && check_ext_ctrls(p, 0))
1519 ret = ops->vidioc_g_ext_ctrls(file, fh, p);
1520 else
1521 break;
1522 v4l_print_ext_ctrls(cmd, vfd, p, !ret);
1523 break;
1525 case VIDIOC_S_EXT_CTRLS:
1527 struct v4l2_ext_controls *p = arg;
1529 p->error_idx = p->count;
1530 if (!(vfh && vfh->ctrl_handler) && !vfd->ctrl_handler &&
1531 !ops->vidioc_s_ext_ctrls)
1532 break;
1533 v4l_print_ext_ctrls(cmd, vfd, p, 1);
1534 if (vfh && vfh->ctrl_handler)
1535 ret = v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, p);
1536 else if (vfd->ctrl_handler)
1537 ret = v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler, p);
1538 else if (check_ext_ctrls(p, 0))
1539 ret = ops->vidioc_s_ext_ctrls(file, fh, p);
1540 break;
1542 case VIDIOC_TRY_EXT_CTRLS:
1544 struct v4l2_ext_controls *p = arg;
1546 p->error_idx = p->count;
1547 if (!(vfh && vfh->ctrl_handler) && !vfd->ctrl_handler &&
1548 !ops->vidioc_try_ext_ctrls)
1549 break;
1550 v4l_print_ext_ctrls(cmd, vfd, p, 1);
1551 if (vfh && vfh->ctrl_handler)
1552 ret = v4l2_try_ext_ctrls(vfh->ctrl_handler, p);
1553 else if (vfd->ctrl_handler)
1554 ret = v4l2_try_ext_ctrls(vfd->ctrl_handler, p);
1555 else if (check_ext_ctrls(p, 0))
1556 ret = ops->vidioc_try_ext_ctrls(file, fh, p);
1557 break;
1559 case VIDIOC_QUERYMENU:
1561 struct v4l2_querymenu *p = arg;
1563 if (vfh && vfh->ctrl_handler)
1564 ret = v4l2_querymenu(vfh->ctrl_handler, p);
1565 else if (vfd->ctrl_handler)
1566 ret = v4l2_querymenu(vfd->ctrl_handler, p);
1567 else if (ops->vidioc_querymenu)
1568 ret = ops->vidioc_querymenu(file, fh, p);
1569 else
1570 break;
1571 if (!ret)
1572 dbgarg(cmd, "id=0x%x, index=%d, name=%s\n",
1573 p->id, p->index, p->name);
1574 else
1575 dbgarg(cmd, "id=0x%x, index=%d\n",
1576 p->id, p->index);
1577 break;
1579 /* --- audio ---------------------------------------------- */
1580 case VIDIOC_ENUMAUDIO:
1582 struct v4l2_audio *p = arg;
1584 if (!ops->vidioc_enumaudio)
1585 break;
1586 ret = ops->vidioc_enumaudio(file, fh, p);
1587 if (!ret)
1588 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
1589 "mode=0x%x\n", p->index, p->name,
1590 p->capability, p->mode);
1591 else
1592 dbgarg(cmd, "index=%d\n", p->index);
1593 break;
1595 case VIDIOC_G_AUDIO:
1597 struct v4l2_audio *p = arg;
1599 if (!ops->vidioc_g_audio)
1600 break;
1602 ret = ops->vidioc_g_audio(file, fh, p);
1603 if (!ret)
1604 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
1605 "mode=0x%x\n", p->index,
1606 p->name, p->capability, p->mode);
1607 else
1608 dbgarg(cmd, "index=%d\n", p->index);
1609 break;
1611 case VIDIOC_S_AUDIO:
1613 struct v4l2_audio *p = arg;
1615 if (!ops->vidioc_s_audio)
1616 break;
1617 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
1618 "mode=0x%x\n", p->index, p->name,
1619 p->capability, p->mode);
1620 ret = ops->vidioc_s_audio(file, fh, p);
1621 break;
1623 case VIDIOC_ENUMAUDOUT:
1625 struct v4l2_audioout *p = arg;
1627 if (!ops->vidioc_enumaudout)
1628 break;
1629 dbgarg(cmd, "Enum for index=%d\n", p->index);
1630 ret = ops->vidioc_enumaudout(file, fh, p);
1631 if (!ret)
1632 dbgarg2("index=%d, name=%s, capability=%d, "
1633 "mode=%d\n", p->index, p->name,
1634 p->capability, p->mode);
1635 break;
1637 case VIDIOC_G_AUDOUT:
1639 struct v4l2_audioout *p = arg;
1641 if (!ops->vidioc_g_audout)
1642 break;
1644 ret = ops->vidioc_g_audout(file, fh, p);
1645 if (!ret)
1646 dbgarg2("index=%d, name=%s, capability=%d, "
1647 "mode=%d\n", p->index, p->name,
1648 p->capability, p->mode);
1649 break;
1651 case VIDIOC_S_AUDOUT:
1653 struct v4l2_audioout *p = arg;
1655 if (!ops->vidioc_s_audout)
1656 break;
1657 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1658 "mode=%d\n", p->index, p->name,
1659 p->capability, p->mode);
1661 ret = ops->vidioc_s_audout(file, fh, p);
1662 break;
1664 case VIDIOC_G_MODULATOR:
1666 struct v4l2_modulator *p = arg;
1668 if (!ops->vidioc_g_modulator)
1669 break;
1670 ret = ops->vidioc_g_modulator(file, fh, p);
1671 if (!ret)
1672 dbgarg(cmd, "index=%d, name=%s, "
1673 "capability=%d, rangelow=%d,"
1674 " rangehigh=%d, txsubchans=%d\n",
1675 p->index, p->name, p->capability,
1676 p->rangelow, p->rangehigh,
1677 p->txsubchans);
1678 break;
1680 case VIDIOC_S_MODULATOR:
1682 struct v4l2_modulator *p = arg;
1684 if (!ops->vidioc_s_modulator)
1685 break;
1686 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1687 "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
1688 p->index, p->name, p->capability, p->rangelow,
1689 p->rangehigh, p->txsubchans);
1690 ret = ops->vidioc_s_modulator(file, fh, p);
1691 break;
1693 case VIDIOC_G_CROP:
1695 struct v4l2_crop *p = arg;
1697 if (!ops->vidioc_g_crop)
1698 break;
1700 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1701 ret = ops->vidioc_g_crop(file, fh, p);
1702 if (!ret)
1703 dbgrect(vfd, "", &p->c);
1704 break;
1706 case VIDIOC_S_CROP:
1708 struct v4l2_crop *p = arg;
1710 if (!ops->vidioc_s_crop)
1711 break;
1712 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1713 dbgrect(vfd, "", &p->c);
1714 ret = ops->vidioc_s_crop(file, fh, p);
1715 break;
1717 case VIDIOC_CROPCAP:
1719 struct v4l2_cropcap *p = arg;
1721 /*FIXME: Should also show v4l2_fract pixelaspect */
1722 if (!ops->vidioc_cropcap)
1723 break;
1725 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1726 ret = ops->vidioc_cropcap(file, fh, p);
1727 if (!ret) {
1728 dbgrect(vfd, "bounds ", &p->bounds);
1729 dbgrect(vfd, "defrect ", &p->defrect);
1731 break;
1733 case VIDIOC_G_JPEGCOMP:
1735 struct v4l2_jpegcompression *p = arg;
1737 if (!ops->vidioc_g_jpegcomp)
1738 break;
1740 ret = ops->vidioc_g_jpegcomp(file, fh, p);
1741 if (!ret)
1742 dbgarg(cmd, "quality=%d, APPn=%d, "
1743 "APP_len=%d, COM_len=%d, "
1744 "jpeg_markers=%d\n",
1745 p->quality, p->APPn, p->APP_len,
1746 p->COM_len, p->jpeg_markers);
1747 break;
1749 case VIDIOC_S_JPEGCOMP:
1751 struct v4l2_jpegcompression *p = arg;
1753 if (!ops->vidioc_g_jpegcomp)
1754 break;
1755 dbgarg(cmd, "quality=%d, APPn=%d, APP_len=%d, "
1756 "COM_len=%d, jpeg_markers=%d\n",
1757 p->quality, p->APPn, p->APP_len,
1758 p->COM_len, p->jpeg_markers);
1759 ret = ops->vidioc_s_jpegcomp(file, fh, p);
1760 break;
1762 case VIDIOC_G_ENC_INDEX:
1764 struct v4l2_enc_idx *p = arg;
1766 if (!ops->vidioc_g_enc_index)
1767 break;
1768 ret = ops->vidioc_g_enc_index(file, fh, p);
1769 if (!ret)
1770 dbgarg(cmd, "entries=%d, entries_cap=%d\n",
1771 p->entries, p->entries_cap);
1772 break;
1774 case VIDIOC_ENCODER_CMD:
1776 struct v4l2_encoder_cmd *p = arg;
1778 if (!ops->vidioc_encoder_cmd)
1779 break;
1780 ret = ops->vidioc_encoder_cmd(file, fh, p);
1781 if (!ret)
1782 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
1783 break;
1785 case VIDIOC_TRY_ENCODER_CMD:
1787 struct v4l2_encoder_cmd *p = arg;
1789 if (!ops->vidioc_try_encoder_cmd)
1790 break;
1791 ret = ops->vidioc_try_encoder_cmd(file, fh, p);
1792 if (!ret)
1793 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
1794 break;
1796 case VIDIOC_G_PARM:
1798 struct v4l2_streamparm *p = arg;
1800 if (ops->vidioc_g_parm) {
1801 ret = check_fmt(ops, p->type);
1802 if (ret)
1803 break;
1804 ret = ops->vidioc_g_parm(file, fh, p);
1805 } else {
1806 v4l2_std_id std = vfd->current_norm;
1808 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1809 break;
1811 ret = 0;
1812 if (ops->vidioc_g_std)
1813 ret = ops->vidioc_g_std(file, fh, &std);
1814 else if (std == 0)
1815 ret = -EINVAL;
1816 if (ret == 0)
1817 v4l2_video_std_frame_period(std,
1818 &p->parm.capture.timeperframe);
1821 dbgarg(cmd, "type=%d\n", p->type);
1822 break;
1824 case VIDIOC_S_PARM:
1826 struct v4l2_streamparm *p = arg;
1828 if (!ops->vidioc_s_parm)
1829 break;
1830 ret = check_fmt(ops, p->type);
1831 if (ret)
1832 break;
1834 dbgarg(cmd, "type=%d\n", p->type);
1835 ret = ops->vidioc_s_parm(file, fh, p);
1836 break;
1838 case VIDIOC_G_TUNER:
1840 struct v4l2_tuner *p = arg;
1842 if (!ops->vidioc_g_tuner)
1843 break;
1845 p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
1846 V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1847 ret = ops->vidioc_g_tuner(file, fh, p);
1848 if (!ret)
1849 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1850 "capability=0x%x, rangelow=%d, "
1851 "rangehigh=%d, signal=%d, afc=%d, "
1852 "rxsubchans=0x%x, audmode=%d\n",
1853 p->index, p->name, p->type,
1854 p->capability, p->rangelow,
1855 p->rangehigh, p->signal, p->afc,
1856 p->rxsubchans, p->audmode);
1857 break;
1859 case VIDIOC_S_TUNER:
1861 struct v4l2_tuner *p = arg;
1863 if (!ops->vidioc_s_tuner)
1864 break;
1865 p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
1866 V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1867 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1868 "capability=0x%x, rangelow=%d, "
1869 "rangehigh=%d, signal=%d, afc=%d, "
1870 "rxsubchans=0x%x, audmode=%d\n",
1871 p->index, p->name, p->type,
1872 p->capability, p->rangelow,
1873 p->rangehigh, p->signal, p->afc,
1874 p->rxsubchans, p->audmode);
1875 ret = ops->vidioc_s_tuner(file, fh, p);
1876 break;
1878 case VIDIOC_G_FREQUENCY:
1880 struct v4l2_frequency *p = arg;
1882 if (!ops->vidioc_g_frequency)
1883 break;
1885 p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
1886 V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1887 ret = ops->vidioc_g_frequency(file, fh, p);
1888 if (!ret)
1889 dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
1890 p->tuner, p->type, p->frequency);
1891 break;
1893 case VIDIOC_S_FREQUENCY:
1895 struct v4l2_frequency *p = arg;
1897 if (!ops->vidioc_s_frequency)
1898 break;
1899 dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
1900 p->tuner, p->type, p->frequency);
1901 ret = ops->vidioc_s_frequency(file, fh, p);
1902 break;
1904 case VIDIOC_G_SLICED_VBI_CAP:
1906 struct v4l2_sliced_vbi_cap *p = arg;
1908 if (!ops->vidioc_g_sliced_vbi_cap)
1909 break;
1911 /* Clear up to type, everything after type is zerod already */
1912 memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type));
1914 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1915 ret = ops->vidioc_g_sliced_vbi_cap(file, fh, p);
1916 if (!ret)
1917 dbgarg2("service_set=%d\n", p->service_set);
1918 break;
1920 case VIDIOC_LOG_STATUS:
1922 if (!ops->vidioc_log_status)
1923 break;
1924 ret = ops->vidioc_log_status(file, fh);
1925 break;
1927 #ifdef CONFIG_VIDEO_ADV_DEBUG
1928 case VIDIOC_DBG_G_REGISTER:
1930 struct v4l2_dbg_register *p = arg;
1932 if (ops->vidioc_g_register) {
1933 if (!capable(CAP_SYS_ADMIN))
1934 ret = -EPERM;
1935 else
1936 ret = ops->vidioc_g_register(file, fh, p);
1938 break;
1940 case VIDIOC_DBG_S_REGISTER:
1942 struct v4l2_dbg_register *p = arg;
1944 if (ops->vidioc_s_register) {
1945 if (!capable(CAP_SYS_ADMIN))
1946 ret = -EPERM;
1947 else
1948 ret = ops->vidioc_s_register(file, fh, p);
1950 break;
1952 #endif
1953 case VIDIOC_DBG_G_CHIP_IDENT:
1955 struct v4l2_dbg_chip_ident *p = arg;
1957 if (!ops->vidioc_g_chip_ident)
1958 break;
1959 p->ident = V4L2_IDENT_NONE;
1960 p->revision = 0;
1961 ret = ops->vidioc_g_chip_ident(file, fh, p);
1962 if (!ret)
1963 dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
1964 break;
1966 case VIDIOC_S_HW_FREQ_SEEK:
1968 struct v4l2_hw_freq_seek *p = arg;
1969 enum v4l2_tuner_type type;
1971 if (!ops->vidioc_s_hw_freq_seek)
1972 break;
1973 type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
1974 V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1975 dbgarg(cmd,
1976 "tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u\n",
1977 p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing);
1978 if (p->type != type)
1979 ret = -EINVAL;
1980 else
1981 ret = ops->vidioc_s_hw_freq_seek(file, fh, p);
1982 break;
1984 case VIDIOC_ENUM_FRAMESIZES:
1986 struct v4l2_frmsizeenum *p = arg;
1988 if (!ops->vidioc_enum_framesizes)
1989 break;
1991 ret = ops->vidioc_enum_framesizes(file, fh, p);
1992 dbgarg(cmd,
1993 "index=%d, pixelformat=%c%c%c%c, type=%d ",
1994 p->index,
1995 (p->pixel_format & 0xff),
1996 (p->pixel_format >> 8) & 0xff,
1997 (p->pixel_format >> 16) & 0xff,
1998 (p->pixel_format >> 24) & 0xff,
1999 p->type);
2000 switch (p->type) {
2001 case V4L2_FRMSIZE_TYPE_DISCRETE:
2002 dbgarg3("width = %d, height=%d\n",
2003 p->discrete.width, p->discrete.height);
2004 break;
2005 case V4L2_FRMSIZE_TYPE_STEPWISE:
2006 dbgarg3("min %dx%d, max %dx%d, step %dx%d\n",
2007 p->stepwise.min_width, p->stepwise.min_height,
2008 p->stepwise.step_width, p->stepwise.step_height,
2009 p->stepwise.max_width, p->stepwise.max_height);
2010 break;
2011 case V4L2_FRMSIZE_TYPE_CONTINUOUS:
2012 dbgarg3("continuous\n");
2013 break;
2014 default:
2015 dbgarg3("- Unknown type!\n");
2018 break;
2020 case VIDIOC_ENUM_FRAMEINTERVALS:
2022 struct v4l2_frmivalenum *p = arg;
2024 if (!ops->vidioc_enum_frameintervals)
2025 break;
2027 ret = ops->vidioc_enum_frameintervals(file, fh, p);
2028 dbgarg(cmd,
2029 "index=%d, pixelformat=%d, width=%d, height=%d, type=%d ",
2030 p->index, p->pixel_format,
2031 p->width, p->height, p->type);
2032 switch (p->type) {
2033 case V4L2_FRMIVAL_TYPE_DISCRETE:
2034 dbgarg2("fps=%d/%d\n",
2035 p->discrete.numerator,
2036 p->discrete.denominator);
2037 break;
2038 case V4L2_FRMIVAL_TYPE_STEPWISE:
2039 dbgarg2("min=%d/%d, max=%d/%d, step=%d/%d\n",
2040 p->stepwise.min.numerator,
2041 p->stepwise.min.denominator,
2042 p->stepwise.max.numerator,
2043 p->stepwise.max.denominator,
2044 p->stepwise.step.numerator,
2045 p->stepwise.step.denominator);
2046 break;
2047 case V4L2_FRMIVAL_TYPE_CONTINUOUS:
2048 dbgarg2("continuous\n");
2049 break;
2050 default:
2051 dbgarg2("- Unknown type!\n");
2053 break;
2055 case VIDIOC_ENUM_DV_PRESETS:
2057 struct v4l2_dv_enum_preset *p = arg;
2059 if (!ops->vidioc_enum_dv_presets)
2060 break;
2062 ret = ops->vidioc_enum_dv_presets(file, fh, p);
2063 if (!ret)
2064 dbgarg(cmd,
2065 "index=%d, preset=%d, name=%s, width=%d,"
2066 " height=%d ",
2067 p->index, p->preset, p->name, p->width,
2068 p->height);
2069 break;
2071 case VIDIOC_S_DV_PRESET:
2073 struct v4l2_dv_preset *p = arg;
2075 if (!ops->vidioc_s_dv_preset)
2076 break;
2078 dbgarg(cmd, "preset=%d\n", p->preset);
2079 ret = ops->vidioc_s_dv_preset(file, fh, p);
2080 break;
2082 case VIDIOC_G_DV_PRESET:
2084 struct v4l2_dv_preset *p = arg;
2086 if (!ops->vidioc_g_dv_preset)
2087 break;
2089 ret = ops->vidioc_g_dv_preset(file, fh, p);
2090 if (!ret)
2091 dbgarg(cmd, "preset=%d\n", p->preset);
2092 break;
2094 case VIDIOC_QUERY_DV_PRESET:
2096 struct v4l2_dv_preset *p = arg;
2098 if (!ops->vidioc_query_dv_preset)
2099 break;
2101 ret = ops->vidioc_query_dv_preset(file, fh, p);
2102 if (!ret)
2103 dbgarg(cmd, "preset=%d\n", p->preset);
2104 break;
2106 case VIDIOC_S_DV_TIMINGS:
2108 struct v4l2_dv_timings *p = arg;
2110 if (!ops->vidioc_s_dv_timings)
2111 break;
2113 switch (p->type) {
2114 case V4L2_DV_BT_656_1120:
2115 dbgarg2("bt-656/1120:interlaced=%d, pixelclock=%lld,"
2116 " width=%d, height=%d, polarities=%x,"
2117 " hfrontporch=%d, hsync=%d, hbackporch=%d,"
2118 " vfrontporch=%d, vsync=%d, vbackporch=%d,"
2119 " il_vfrontporch=%d, il_vsync=%d,"
2120 " il_vbackporch=%d\n",
2121 p->bt.interlaced, p->bt.pixelclock,
2122 p->bt.width, p->bt.height, p->bt.polarities,
2123 p->bt.hfrontporch, p->bt.hsync,
2124 p->bt.hbackporch, p->bt.vfrontporch,
2125 p->bt.vsync, p->bt.vbackporch,
2126 p->bt.il_vfrontporch, p->bt.il_vsync,
2127 p->bt.il_vbackporch);
2128 ret = ops->vidioc_s_dv_timings(file, fh, p);
2129 break;
2130 default:
2131 dbgarg2("Unknown type %d!\n", p->type);
2132 break;
2134 break;
2136 case VIDIOC_G_DV_TIMINGS:
2138 struct v4l2_dv_timings *p = arg;
2140 if (!ops->vidioc_g_dv_timings)
2141 break;
2143 ret = ops->vidioc_g_dv_timings(file, fh, p);
2144 if (!ret) {
2145 switch (p->type) {
2146 case V4L2_DV_BT_656_1120:
2147 dbgarg2("bt-656/1120:interlaced=%d,"
2148 " pixelclock=%lld,"
2149 " width=%d, height=%d, polarities=%x,"
2150 " hfrontporch=%d, hsync=%d,"
2151 " hbackporch=%d, vfrontporch=%d,"
2152 " vsync=%d, vbackporch=%d,"
2153 " il_vfrontporch=%d, il_vsync=%d,"
2154 " il_vbackporch=%d\n",
2155 p->bt.interlaced, p->bt.pixelclock,
2156 p->bt.width, p->bt.height,
2157 p->bt.polarities, p->bt.hfrontporch,
2158 p->bt.hsync, p->bt.hbackporch,
2159 p->bt.vfrontporch, p->bt.vsync,
2160 p->bt.vbackporch, p->bt.il_vfrontporch,
2161 p->bt.il_vsync, p->bt.il_vbackporch);
2162 break;
2163 default:
2164 dbgarg2("Unknown type %d!\n", p->type);
2165 break;
2168 break;
2170 case VIDIOC_DQEVENT:
2172 struct v4l2_event *ev = arg;
2174 if (!ops->vidioc_subscribe_event)
2175 break;
2177 ret = v4l2_event_dequeue(fh, ev, file->f_flags & O_NONBLOCK);
2178 if (ret < 0) {
2179 dbgarg(cmd, "no pending events?");
2180 break;
2182 dbgarg(cmd,
2183 "pending=%d, type=0x%8.8x, sequence=%d, "
2184 "timestamp=%lu.%9.9lu ",
2185 ev->pending, ev->type, ev->sequence,
2186 ev->timestamp.tv_sec, ev->timestamp.tv_nsec);
2187 break;
2189 case VIDIOC_SUBSCRIBE_EVENT:
2191 struct v4l2_event_subscription *sub = arg;
2193 if (!ops->vidioc_subscribe_event)
2194 break;
2196 ret = ops->vidioc_subscribe_event(fh, sub);
2197 if (ret < 0) {
2198 dbgarg(cmd, "failed, ret=%ld", ret);
2199 break;
2201 dbgarg(cmd, "type=0x%8.8x", sub->type);
2202 break;
2204 case VIDIOC_UNSUBSCRIBE_EVENT:
2206 struct v4l2_event_subscription *sub = arg;
2208 if (!ops->vidioc_unsubscribe_event)
2209 break;
2211 ret = ops->vidioc_unsubscribe_event(fh, sub);
2212 if (ret < 0) {
2213 dbgarg(cmd, "failed, ret=%ld", ret);
2214 break;
2216 dbgarg(cmd, "type=0x%8.8x", sub->type);
2217 break;
2219 default:
2221 bool valid_prio = true;
2223 if (!ops->vidioc_default)
2224 break;
2225 if (use_fh_prio)
2226 valid_prio = v4l2_prio_check(vfd->prio, vfh->prio) >= 0;
2227 ret = ops->vidioc_default(file, fh, valid_prio, cmd, arg);
2228 break;
2230 } /* switch */
2232 exit_prio:
2233 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
2234 if (ret < 0) {
2235 v4l_print_ioctl(vfd->name, cmd);
2236 printk(KERN_CONT " error %ld\n", ret);
2240 return ret;
2243 /* In some cases, only a few fields are used as input, i.e. when the app sets
2244 * "index" and then the driver fills in the rest of the structure for the thing
2245 * with that index. We only need to copy up the first non-input field. */
2246 static unsigned long cmd_input_size(unsigned int cmd)
2248 /* Size of structure up to and including 'field' */
2249 #define CMDINSIZE(cmd, type, field) \
2250 case VIDIOC_##cmd: \
2251 return offsetof(struct v4l2_##type, field) + \
2252 sizeof(((struct v4l2_##type *)0)->field);
2254 switch (cmd) {
2255 CMDINSIZE(ENUM_FMT, fmtdesc, type);
2256 CMDINSIZE(G_FMT, format, type);
2257 CMDINSIZE(QUERYBUF, buffer, length);
2258 CMDINSIZE(G_PARM, streamparm, type);
2259 CMDINSIZE(ENUMSTD, standard, index);
2260 CMDINSIZE(ENUMINPUT, input, index);
2261 CMDINSIZE(G_CTRL, control, id);
2262 CMDINSIZE(G_TUNER, tuner, index);
2263 CMDINSIZE(QUERYCTRL, queryctrl, id);
2264 CMDINSIZE(QUERYMENU, querymenu, index);
2265 CMDINSIZE(ENUMOUTPUT, output, index);
2266 CMDINSIZE(G_MODULATOR, modulator, index);
2267 CMDINSIZE(G_FREQUENCY, frequency, tuner);
2268 CMDINSIZE(CROPCAP, cropcap, type);
2269 CMDINSIZE(G_CROP, crop, type);
2270 CMDINSIZE(ENUMAUDIO, audio, index);
2271 CMDINSIZE(ENUMAUDOUT, audioout, index);
2272 CMDINSIZE(ENCODER_CMD, encoder_cmd, flags);
2273 CMDINSIZE(TRY_ENCODER_CMD, encoder_cmd, flags);
2274 CMDINSIZE(G_SLICED_VBI_CAP, sliced_vbi_cap, type);
2275 CMDINSIZE(ENUM_FRAMESIZES, frmsizeenum, pixel_format);
2276 CMDINSIZE(ENUM_FRAMEINTERVALS, frmivalenum, height);
2277 default:
2278 return _IOC_SIZE(cmd);
2282 static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
2283 void * __user *user_ptr, void ***kernel_ptr)
2285 int ret = 0;
2287 switch (cmd) {
2288 case VIDIOC_QUERYBUF:
2289 case VIDIOC_QBUF:
2290 case VIDIOC_DQBUF: {
2291 struct v4l2_buffer *buf = parg;
2293 if (V4L2_TYPE_IS_MULTIPLANAR(buf->type) && buf->length > 0) {
2294 if (buf->length > VIDEO_MAX_PLANES) {
2295 ret = -EINVAL;
2296 break;
2298 *user_ptr = (void __user *)buf->m.planes;
2299 *kernel_ptr = (void *)&buf->m.planes;
2300 *array_size = sizeof(struct v4l2_plane) * buf->length;
2301 ret = 1;
2303 break;
2306 case VIDIOC_S_EXT_CTRLS:
2307 case VIDIOC_G_EXT_CTRLS:
2308 case VIDIOC_TRY_EXT_CTRLS: {
2309 struct v4l2_ext_controls *ctrls = parg;
2311 if (ctrls->count != 0) {
2312 *user_ptr = (void __user *)ctrls->controls;
2313 *kernel_ptr = (void *)&ctrls->controls;
2314 *array_size = sizeof(struct v4l2_ext_control)
2315 * ctrls->count;
2316 ret = 1;
2318 break;
2322 return ret;
2325 long
2326 video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
2327 v4l2_kioctl func)
2329 char sbuf[128];
2330 void *mbuf = NULL;
2331 void *parg = (void *)arg;
2332 long err = -EINVAL;
2333 bool has_array_args;
2334 size_t array_size = 0;
2335 void __user *user_ptr = NULL;
2336 void **kernel_ptr = NULL;
2338 /* Copy arguments into temp kernel buffer */
2339 if (_IOC_DIR(cmd) != _IOC_NONE) {
2340 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
2341 parg = sbuf;
2342 } else {
2343 /* too big to allocate from stack */
2344 mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
2345 if (NULL == mbuf)
2346 return -ENOMEM;
2347 parg = mbuf;
2350 err = -EFAULT;
2351 if (_IOC_DIR(cmd) & _IOC_WRITE) {
2352 unsigned long n = cmd_input_size(cmd);
2354 if (copy_from_user(parg, (void __user *)arg, n))
2355 goto out;
2357 /* zero out anything we don't copy from userspace */
2358 if (n < _IOC_SIZE(cmd))
2359 memset((u8 *)parg + n, 0, _IOC_SIZE(cmd) - n);
2360 } else {
2361 /* read-only ioctl */
2362 memset(parg, 0, _IOC_SIZE(cmd));
2366 err = check_array_args(cmd, parg, &array_size, &user_ptr, &kernel_ptr);
2367 if (err < 0)
2368 goto out;
2369 has_array_args = err;
2371 if (has_array_args) {
2373 * When adding new types of array args, make sure that the
2374 * parent argument to ioctl (which contains the pointer to the
2375 * array) fits into sbuf (so that mbuf will still remain
2376 * unused up to here).
2378 mbuf = kmalloc(array_size, GFP_KERNEL);
2379 err = -ENOMEM;
2380 if (NULL == mbuf)
2381 goto out_array_args;
2382 err = -EFAULT;
2383 if (copy_from_user(mbuf, user_ptr, array_size))
2384 goto out_array_args;
2385 *kernel_ptr = mbuf;
2388 /* Handles IOCTL */
2389 err = func(file, cmd, parg);
2390 if (err == -ENOIOCTLCMD)
2391 err = -EINVAL;
2393 if (has_array_args) {
2394 *kernel_ptr = user_ptr;
2395 if (copy_to_user(user_ptr, mbuf, array_size))
2396 err = -EFAULT;
2397 goto out_array_args;
2399 if (err < 0)
2400 goto out;
2402 out_array_args:
2403 /* Copy results into user buffer */
2404 switch (_IOC_DIR(cmd)) {
2405 case _IOC_READ:
2406 case (_IOC_WRITE | _IOC_READ):
2407 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
2408 err = -EFAULT;
2409 break;
2412 out:
2413 kfree(mbuf);
2414 return err;
2416 EXPORT_SYMBOL(video_usercopy);
2418 long video_ioctl2(struct file *file,
2419 unsigned int cmd, unsigned long arg)
2421 return video_usercopy(file, cmd, arg, __video_do_ioctl);
2423 EXPORT_SYMBOL(video_ioctl2);