2 * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
3 * Separated from fs stuff by Arnd Bergmann <arnd@arndb.de>
5 * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com)
6 * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
7 * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs
8 * Copyright (C) 2003 Pavel Machek (pavel@suse.cz)
9 * Copyright (C) 2005 Philippe De Muyter (phdm@macqel.be)
10 * Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl>
12 * These routines maintain argument size conversion between 32bit and 64bit
16 #include <linux/compat.h>
17 #define __OLD_VIDIOC_ /* To allow fixing old calls*/
18 #include <linux/videodev.h>
19 #include <linux/videodev2.h>
20 #include <linux/module.h>
21 #include <linux/smp_lock.h>
22 #include <media/v4l2-ioctl.h>
26 #ifdef CONFIG_VIDEO_V4L1_COMPAT
27 struct video_tuner32
{
30 compat_ulong_t rangelow
, rangehigh
;
31 u32 flags
; /* It is really u32 in videodev.h */
35 static int get_video_tuner32(struct video_tuner
*kp
, struct video_tuner32 __user
*up
)
37 if (!access_ok(VERIFY_READ
, up
, sizeof(struct video_tuner32
)) ||
38 get_user(kp
->tuner
, &up
->tuner
) ||
39 copy_from_user(kp
->name
, up
->name
, 32) ||
40 get_user(kp
->rangelow
, &up
->rangelow
) ||
41 get_user(kp
->rangehigh
, &up
->rangehigh
) ||
42 get_user(kp
->flags
, &up
->flags
) ||
43 get_user(kp
->mode
, &up
->mode
) ||
44 get_user(kp
->signal
, &up
->signal
))
49 static int put_video_tuner32(struct video_tuner
*kp
, struct video_tuner32 __user
*up
)
51 if (!access_ok(VERIFY_WRITE
, up
, sizeof(struct video_tuner32
)) ||
52 put_user(kp
->tuner
, &up
->tuner
) ||
53 copy_to_user(up
->name
, kp
->name
, 32) ||
54 put_user(kp
->rangelow
, &up
->rangelow
) ||
55 put_user(kp
->rangehigh
, &up
->rangehigh
) ||
56 put_user(kp
->flags
, &up
->flags
) ||
57 put_user(kp
->mode
, &up
->mode
) ||
58 put_user(kp
->signal
, &up
->signal
))
63 struct video_buffer32
{
65 compat_int_t height
, width
, depth
, bytesperline
;
68 static int get_video_buffer32(struct video_buffer
*kp
, struct video_buffer32 __user
*up
)
72 if (!access_ok(VERIFY_READ
, up
, sizeof(struct video_buffer32
)) ||
73 get_user(tmp
, &up
->base
) ||
74 get_user(kp
->height
, &up
->height
) ||
75 get_user(kp
->width
, &up
->width
) ||
76 get_user(kp
->depth
, &up
->depth
) ||
77 get_user(kp
->bytesperline
, &up
->bytesperline
))
80 /* This is actually a physical address stored
83 kp
->base
= (void *)(unsigned long) tmp
;
88 static int put_video_buffer32(struct video_buffer
*kp
, struct video_buffer32 __user
*up
)
90 u32 tmp
= (u32
)((unsigned long)kp
->base
);
92 if (!access_ok(VERIFY_WRITE
, up
, sizeof(struct video_buffer32
)) ||
93 put_user(tmp
, &up
->base
) ||
94 put_user(kp
->height
, &up
->height
) ||
95 put_user(kp
->width
, &up
->width
) ||
96 put_user(kp
->depth
, &up
->depth
) ||
97 put_user(kp
->bytesperline
, &up
->bytesperline
))
102 struct video_clip32
{
103 s32 x
, y
, width
, height
; /* It's really s32 in videodev.h */
107 struct video_window32
{
108 u32 x
, y
, width
, height
, chromakey
, flags
;
109 compat_caddr_t clips
;
110 compat_int_t clipcount
;
113 static int get_video_window32(struct video_window
*kp
, struct video_window32 __user
*up
)
115 struct video_clip __user
*uclips
;
116 struct video_clip __user
*kclips
;
120 if (!access_ok(VERIFY_READ
, up
, sizeof(struct video_window32
)))
123 if (get_user(nclips
, &up
->clipcount
))
126 if (!access_ok(VERIFY_READ
, up
, sizeof(struct video_window32
)) ||
127 get_user(kp
->x
, &up
->x
) ||
128 get_user(kp
->y
, &up
->y
) ||
129 get_user(kp
->width
, &up
->width
) ||
130 get_user(kp
->height
, &up
->height
) ||
131 get_user(kp
->chromakey
, &up
->chromakey
) ||
132 get_user(kp
->flags
, &up
->flags
) ||
133 get_user(kp
->clipcount
, &up
->clipcount
))
136 nclips
= kp
->clipcount
;
141 if (get_user(p
, &up
->clips
))
143 uclips
= compat_ptr(p
);
145 /* If nclips < 0, then it is a clipping bitmap of size
146 VIDEO_CLIPMAP_SIZE */
148 if (!access_ok(VERIFY_READ
, uclips
, VIDEO_CLIPMAP_SIZE
))
150 kp
->clips
= compat_alloc_user_space(VIDEO_CLIPMAP_SIZE
);
151 if (copy_in_user(kp
->clips
, uclips
, VIDEO_CLIPMAP_SIZE
))
156 /* Otherwise it is an array of video_clip structs. */
157 if (!access_ok(VERIFY_READ
, uclips
, nclips
* sizeof(struct video_clip
)))
160 kp
->clips
= compat_alloc_user_space(nclips
* sizeof(struct video_clip
));
165 err
= copy_in_user(&kclips
->x
, &uclips
->x
, sizeof(kclips
->x
));
166 err
|= copy_in_user(&kclips
->y
, &uclips
->y
, sizeof(kclips
->y
));
167 err
|= copy_in_user(&kclips
->width
, &uclips
->width
, sizeof(kclips
->width
));
168 err
|= copy_in_user(&kclips
->height
, &uclips
->height
, sizeof(kclips
->height
));
178 /* You get back everything except the clips... */
179 static int put_video_window32(struct video_window
*kp
, struct video_window32 __user
*up
)
181 if (!access_ok(VERIFY_WRITE
, up
, sizeof(struct video_window32
)) ||
182 put_user(kp
->x
, &up
->x
) ||
183 put_user(kp
->y
, &up
->y
) ||
184 put_user(kp
->width
, &up
->width
) ||
185 put_user(kp
->height
, &up
->height
) ||
186 put_user(kp
->chromakey
, &up
->chromakey
) ||
187 put_user(kp
->flags
, &up
->flags
) ||
188 put_user(kp
->clipcount
, &up
->clipcount
))
193 struct video_code32
{
194 char loadwhat
[16]; /* name or tag of file being passed */
195 compat_int_t datasize
;
199 static int get_microcode32(struct video_code
*kp
, struct video_code32 __user
*up
)
201 if (!access_ok(VERIFY_READ
, up
, sizeof(struct video_code32
)) ||
202 copy_from_user(kp
->loadwhat
, up
->loadwhat
, sizeof(up
->loadwhat
)) ||
203 get_user(kp
->datasize
, &up
->datasize
) ||
204 copy_from_user(kp
->data
, up
->data
, up
->datasize
))
209 #define VIDIOCGTUNER32 _IOWR('v', 4, struct video_tuner32)
210 #define VIDIOCSTUNER32 _IOW('v', 5, struct video_tuner32)
211 #define VIDIOCGWIN32 _IOR('v', 9, struct video_window32)
212 #define VIDIOCSWIN32 _IOW('v', 10, struct video_window32)
213 #define VIDIOCGFBUF32 _IOR('v', 11, struct video_buffer32)
214 #define VIDIOCSFBUF32 _IOW('v', 12, struct video_buffer32)
215 #define VIDIOCGFREQ32 _IOR('v', 14, u32)
216 #define VIDIOCSFREQ32 _IOW('v', 15, u32)
217 #define VIDIOCSMICROCODE32 _IOW('v', 27, struct video_code32)
219 #define VIDIOCCAPTURE32 _IOW('v', 8, s32)
220 #define VIDIOCSYNC32 _IOW('v', 18, s32)
221 #define VIDIOCSWRITEMODE32 _IOW('v', 25, s32)
225 static long native_ioctl(struct file
*file
, unsigned int cmd
, unsigned long arg
)
227 long ret
= -ENOIOCTLCMD
;
229 if (file
->f_op
->unlocked_ioctl
)
230 ret
= file
->f_op
->unlocked_ioctl(file
, cmd
, arg
);
231 else if (file
->f_op
->ioctl
) {
233 ret
= file
->f_op
->ioctl(file
->f_path
.dentry
->d_inode
, file
, cmd
, arg
);
246 struct v4l2_window32
{
248 enum v4l2_field field
;
250 compat_caddr_t clips
; /* actually struct v4l2_clip32 * */
252 compat_caddr_t bitmap
;
255 static int get_v4l2_window32(struct v4l2_window
*kp
, struct v4l2_window32 __user
*up
)
257 if (!access_ok(VERIFY_READ
, up
, sizeof(struct v4l2_window32
)) ||
258 copy_from_user(&kp
->w
, &up
->w
, sizeof(up
->w
)) ||
259 get_user(kp
->field
, &up
->field
) ||
260 get_user(kp
->chromakey
, &up
->chromakey
) ||
261 get_user(kp
->clipcount
, &up
->clipcount
))
263 if (kp
->clipcount
> 2048)
266 struct v4l2_clip32 __user
*uclips
;
267 struct v4l2_clip __user
*kclips
;
268 int n
= kp
->clipcount
;
271 if (get_user(p
, &up
->clips
))
273 uclips
= compat_ptr(p
);
274 kclips
= compat_alloc_user_space(n
* sizeof(struct v4l2_clip
));
277 if (copy_in_user(&kclips
->c
, &uclips
->c
, sizeof(uclips
->c
)))
279 if (put_user(n
? kclips
+ 1 : NULL
, &kclips
->next
))
289 static int put_v4l2_window32(struct v4l2_window
*kp
, struct v4l2_window32 __user
*up
)
291 if (copy_to_user(&up
->w
, &kp
->w
, sizeof(up
->w
)) ||
292 put_user(kp
->field
, &up
->field
) ||
293 put_user(kp
->chromakey
, &up
->chromakey
) ||
294 put_user(kp
->clipcount
, &up
->clipcount
))
299 static inline int get_v4l2_pix_format(struct v4l2_pix_format
*kp
, struct v4l2_pix_format __user
*up
)
301 if (copy_from_user(kp
, up
, sizeof(struct v4l2_pix_format
)))
306 static inline int put_v4l2_pix_format(struct v4l2_pix_format
*kp
, struct v4l2_pix_format __user
*up
)
308 if (copy_to_user(up
, kp
, sizeof(struct v4l2_pix_format
)))
313 static inline int get_v4l2_vbi_format(struct v4l2_vbi_format
*kp
, struct v4l2_vbi_format __user
*up
)
315 if (copy_from_user(kp
, up
, sizeof(struct v4l2_vbi_format
)))
320 static inline int put_v4l2_vbi_format(struct v4l2_vbi_format
*kp
, struct v4l2_vbi_format __user
*up
)
322 if (copy_to_user(up
, kp
, sizeof(struct v4l2_vbi_format
)))
327 static inline int get_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format
*kp
, struct v4l2_sliced_vbi_format __user
*up
)
329 if (copy_from_user(kp
, up
, sizeof(struct v4l2_sliced_vbi_format
)))
334 static inline int put_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format
*kp
, struct v4l2_sliced_vbi_format __user
*up
)
336 if (copy_to_user(up
, kp
, sizeof(struct v4l2_sliced_vbi_format
)))
341 struct v4l2_format32
{
342 enum v4l2_buf_type type
;
344 struct v4l2_pix_format pix
;
345 struct v4l2_window32 win
;
346 struct v4l2_vbi_format vbi
;
347 struct v4l2_sliced_vbi_format sliced
;
348 __u8 raw_data
[200]; /* user-defined */
352 static int get_v4l2_format32(struct v4l2_format
*kp
, struct v4l2_format32 __user
*up
)
354 if (!access_ok(VERIFY_READ
, up
, sizeof(struct v4l2_format32
)) ||
355 get_user(kp
->type
, &up
->type
))
358 case V4L2_BUF_TYPE_VIDEO_CAPTURE
:
359 case V4L2_BUF_TYPE_VIDEO_OUTPUT
:
360 return get_v4l2_pix_format(&kp
->fmt
.pix
, &up
->fmt
.pix
);
361 case V4L2_BUF_TYPE_VIDEO_OVERLAY
:
362 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY
:
363 return get_v4l2_window32(&kp
->fmt
.win
, &up
->fmt
.win
);
364 case V4L2_BUF_TYPE_VBI_CAPTURE
:
365 case V4L2_BUF_TYPE_VBI_OUTPUT
:
366 return get_v4l2_vbi_format(&kp
->fmt
.vbi
, &up
->fmt
.vbi
);
367 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE
:
368 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT
:
369 return get_v4l2_sliced_vbi_format(&kp
->fmt
.sliced
, &up
->fmt
.sliced
);
370 case V4L2_BUF_TYPE_PRIVATE
:
371 if (copy_from_user(kp
, up
, sizeof(kp
->fmt
.raw_data
)))
377 printk(KERN_INFO
"compat_ioctl32: unexpected VIDIOC_FMT type %d\n",
383 static int put_v4l2_format32(struct v4l2_format
*kp
, struct v4l2_format32 __user
*up
)
385 if (!access_ok(VERIFY_WRITE
, up
, sizeof(struct v4l2_format32
)) ||
386 put_user(kp
->type
, &up
->type
))
389 case V4L2_BUF_TYPE_VIDEO_CAPTURE
:
390 case V4L2_BUF_TYPE_VIDEO_OUTPUT
:
391 return put_v4l2_pix_format(&kp
->fmt
.pix
, &up
->fmt
.pix
);
392 case V4L2_BUF_TYPE_VIDEO_OVERLAY
:
393 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY
:
394 return put_v4l2_window32(&kp
->fmt
.win
, &up
->fmt
.win
);
395 case V4L2_BUF_TYPE_VBI_CAPTURE
:
396 case V4L2_BUF_TYPE_VBI_OUTPUT
:
397 return put_v4l2_vbi_format(&kp
->fmt
.vbi
, &up
->fmt
.vbi
);
398 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE
:
399 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT
:
400 return put_v4l2_sliced_vbi_format(&kp
->fmt
.sliced
, &up
->fmt
.sliced
);
401 case V4L2_BUF_TYPE_PRIVATE
:
402 if (copy_to_user(up
, kp
, sizeof(up
->fmt
.raw_data
)))
408 printk(KERN_INFO
"compat_ioctl32: unexpected VIDIOC_FMT type %d\n",
414 struct v4l2_standard32
{
416 __u32 id
[2]; /* __u64 would get the alignment wrong */
418 struct v4l2_fract frameperiod
; /* Frames, not fields */
423 static int get_v4l2_standard32(struct v4l2_standard
*kp
, struct v4l2_standard32 __user
*up
)
425 /* other fields are not set by the user, nor used by the driver */
426 if (!access_ok(VERIFY_READ
, up
, sizeof(struct v4l2_standard32
)) ||
427 get_user(kp
->index
, &up
->index
))
432 static int put_v4l2_standard32(struct v4l2_standard
*kp
, struct v4l2_standard32 __user
*up
)
434 if (!access_ok(VERIFY_WRITE
, up
, sizeof(struct v4l2_standard32
)) ||
435 put_user(kp
->index
, &up
->index
) ||
436 copy_to_user(up
->id
, &kp
->id
, sizeof(__u64
)) ||
437 copy_to_user(up
->name
, kp
->name
, 24) ||
438 copy_to_user(&up
->frameperiod
, &kp
->frameperiod
, sizeof(kp
->frameperiod
)) ||
439 put_user(kp
->framelines
, &up
->framelines
) ||
440 copy_to_user(up
->reserved
, kp
->reserved
, 4 * sizeof(__u32
)))
445 struct v4l2_buffer32
{
447 enum v4l2_buf_type type
;
450 enum v4l2_field field
;
451 struct compat_timeval timestamp
;
452 struct v4l2_timecode timecode
;
455 /* memory location */
456 enum v4l2_memory memory
;
459 compat_long_t userptr
;
466 static int get_v4l2_buffer32(struct v4l2_buffer
*kp
, struct v4l2_buffer32 __user
*up
)
469 if (!access_ok(VERIFY_READ
, up
, sizeof(struct v4l2_buffer32
)) ||
470 get_user(kp
->index
, &up
->index
) ||
471 get_user(kp
->type
, &up
->type
) ||
472 get_user(kp
->flags
, &up
->flags
) ||
473 get_user(kp
->memory
, &up
->memory
) ||
474 get_user(kp
->input
, &up
->input
))
476 switch (kp
->memory
) {
477 case V4L2_MEMORY_MMAP
:
479 case V4L2_MEMORY_USERPTR
:
483 if (get_user(kp
->length
, &up
->length
) ||
484 get_user(tmp
, &up
->m
.userptr
))
487 kp
->m
.userptr
= (unsigned long)compat_ptr(tmp
);
490 case V4L2_MEMORY_OVERLAY
:
491 if (get_user(kp
->m
.offset
, &up
->m
.offset
))
498 static int put_v4l2_buffer32(struct v4l2_buffer
*kp
, struct v4l2_buffer32 __user
*up
)
500 if (!access_ok(VERIFY_WRITE
, up
, sizeof(struct v4l2_buffer32
)) ||
501 put_user(kp
->index
, &up
->index
) ||
502 put_user(kp
->type
, &up
->type
) ||
503 put_user(kp
->flags
, &up
->flags
) ||
504 put_user(kp
->memory
, &up
->memory
) ||
505 put_user(kp
->input
, &up
->input
))
507 switch (kp
->memory
) {
508 case V4L2_MEMORY_MMAP
:
509 if (put_user(kp
->length
, &up
->length
) ||
510 put_user(kp
->m
.offset
, &up
->m
.offset
))
513 case V4L2_MEMORY_USERPTR
:
514 if (put_user(kp
->length
, &up
->length
) ||
515 put_user(kp
->m
.userptr
, &up
->m
.userptr
))
518 case V4L2_MEMORY_OVERLAY
:
519 if (put_user(kp
->m
.offset
, &up
->m
.offset
))
523 if (put_user(kp
->bytesused
, &up
->bytesused
) ||
524 put_user(kp
->field
, &up
->field
) ||
525 put_user(kp
->timestamp
.tv_sec
, &up
->timestamp
.tv_sec
) ||
526 put_user(kp
->timestamp
.tv_usec
, &up
->timestamp
.tv_usec
) ||
527 copy_to_user(&up
->timecode
, &kp
->timecode
, sizeof(struct v4l2_timecode
)) ||
528 put_user(kp
->sequence
, &up
->sequence
) ||
529 put_user(kp
->reserved
, &up
->reserved
))
534 struct v4l2_framebuffer32
{
538 struct v4l2_pix_format fmt
;
541 static int get_v4l2_framebuffer32(struct v4l2_framebuffer
*kp
, struct v4l2_framebuffer32 __user
*up
)
545 if (!access_ok(VERIFY_READ
, up
, sizeof(struct v4l2_framebuffer32
)) ||
546 get_user(tmp
, &up
->base
) ||
547 get_user(kp
->capability
, &up
->capability
) ||
548 get_user(kp
->flags
, &up
->flags
))
550 kp
->base
= compat_ptr(tmp
);
551 get_v4l2_pix_format(&kp
->fmt
, &up
->fmt
);
555 static int put_v4l2_framebuffer32(struct v4l2_framebuffer
*kp
, struct v4l2_framebuffer32 __user
*up
)
557 u32 tmp
= (u32
)((unsigned long)kp
->base
);
559 if (!access_ok(VERIFY_WRITE
, up
, sizeof(struct v4l2_framebuffer32
)) ||
560 put_user(tmp
, &up
->base
) ||
561 put_user(kp
->capability
, &up
->capability
) ||
562 put_user(kp
->flags
, &up
->flags
))
564 put_v4l2_pix_format(&kp
->fmt
, &up
->fmt
);
568 struct v4l2_input32
{
569 __u32 index
; /* Which input */
570 __u8 name
[32]; /* Label */
571 __u32 type
; /* Type of input */
572 __u32 audioset
; /* Associated audios (bitfield) */
573 __u32 tuner
; /* Associated tuner */
577 } __attribute__ ((packed
));
579 /* The 64-bit v4l2_input struct has extra padding at the end of the struct.
580 Otherwise it is identical to the 32-bit version. */
581 static inline int get_v4l2_input32(struct v4l2_input
*kp
, struct v4l2_input32 __user
*up
)
583 if (copy_from_user(kp
, up
, sizeof(struct v4l2_input32
)))
588 static inline int put_v4l2_input32(struct v4l2_input
*kp
, struct v4l2_input32 __user
*up
)
590 if (copy_to_user(up
, kp
, sizeof(struct v4l2_input32
)))
595 struct v4l2_ext_controls32
{
600 compat_caddr_t controls
; /* actually struct v4l2_ext_control32 * */
603 static int get_v4l2_ext_controls32(struct v4l2_ext_controls
*kp
, struct v4l2_ext_controls32 __user
*up
)
605 struct v4l2_ext_control __user
*ucontrols
;
606 struct v4l2_ext_control __user
*kcontrols
;
610 if (!access_ok(VERIFY_READ
, up
, sizeof(struct v4l2_ext_controls32
)) ||
611 get_user(kp
->ctrl_class
, &up
->ctrl_class
) ||
612 get_user(kp
->count
, &up
->count
) ||
613 get_user(kp
->error_idx
, &up
->error_idx
) ||
614 copy_from_user(kp
->reserved
, up
->reserved
, sizeof(kp
->reserved
)))
621 if (get_user(p
, &up
->controls
))
623 ucontrols
= compat_ptr(p
);
624 if (!access_ok(VERIFY_READ
, ucontrols
, n
* sizeof(struct v4l2_ext_control
)))
626 kcontrols
= compat_alloc_user_space(n
* sizeof(struct v4l2_ext_control
));
627 kp
->controls
= kcontrols
;
629 if (copy_in_user(&kcontrols
->id
, &ucontrols
->id
, sizeof(__u32
)))
631 if (copy_in_user(&kcontrols
->reserved2
, &ucontrols
->reserved2
, sizeof(ucontrols
->reserved2
)))
633 /* Note: if the void * part of the union ever becomes relevant
634 then we need to know the type of the control in order to do
635 the right thing here. Luckily, that is not yet an issue. */
636 if (copy_in_user(&kcontrols
->value
, &ucontrols
->value
, sizeof(ucontrols
->value
)))
644 static int put_v4l2_ext_controls32(struct v4l2_ext_controls
*kp
, struct v4l2_ext_controls32 __user
*up
)
646 struct v4l2_ext_control __user
*ucontrols
;
647 struct v4l2_ext_control __user
*kcontrols
= kp
->controls
;
651 if (!access_ok(VERIFY_WRITE
, up
, sizeof(struct v4l2_ext_controls32
)) ||
652 put_user(kp
->ctrl_class
, &up
->ctrl_class
) ||
653 put_user(kp
->count
, &up
->count
) ||
654 put_user(kp
->error_idx
, &up
->error_idx
) ||
655 copy_to_user(up
->reserved
, kp
->reserved
, sizeof(up
->reserved
)))
660 if (get_user(p
, &up
->controls
))
662 ucontrols
= compat_ptr(p
);
663 if (!access_ok(VERIFY_WRITE
, ucontrols
, n
* sizeof(struct v4l2_ext_control
)))
667 if (copy_in_user(&ucontrols
->id
, &kcontrols
->id
, sizeof(__u32
)))
669 if (copy_in_user(&ucontrols
->reserved2
, &kcontrols
->reserved2
,
670 sizeof(ucontrols
->reserved2
)))
672 /* Note: if the void * part of the union ever becomes relevant
673 then we need to know the type of the control in order to do
674 the right thing here. Luckily, that is not yet an issue. */
675 if (copy_in_user(&ucontrols
->value
, &kcontrols
->value
, sizeof(ucontrols
->value
)))
683 #define VIDIOC_G_FMT32 _IOWR('V', 4, struct v4l2_format32)
684 #define VIDIOC_S_FMT32 _IOWR('V', 5, struct v4l2_format32)
685 #define VIDIOC_QUERYBUF32 _IOWR('V', 9, struct v4l2_buffer32)
686 #define VIDIOC_G_FBUF32 _IOR ('V', 10, struct v4l2_framebuffer32)
687 #define VIDIOC_S_FBUF32 _IOW ('V', 11, struct v4l2_framebuffer32)
688 #define VIDIOC_QBUF32 _IOWR('V', 15, struct v4l2_buffer32)
689 #define VIDIOC_DQBUF32 _IOWR('V', 17, struct v4l2_buffer32)
690 #define VIDIOC_ENUMSTD32 _IOWR('V', 25, struct v4l2_standard32)
691 #define VIDIOC_ENUMINPUT32 _IOWR('V', 26, struct v4l2_input32)
692 #define VIDIOC_TRY_FMT32 _IOWR('V', 64, struct v4l2_format32)
693 #define VIDIOC_G_EXT_CTRLS32 _IOWR('V', 71, struct v4l2_ext_controls32)
694 #define VIDIOC_S_EXT_CTRLS32 _IOWR('V', 72, struct v4l2_ext_controls32)
695 #define VIDIOC_TRY_EXT_CTRLS32 _IOWR('V', 73, struct v4l2_ext_controls32)
697 #define VIDIOC_OVERLAY32 _IOW ('V', 14, s32)
699 #define VIDIOC_OVERLAY32_OLD _IOWR('V', 14, s32)
701 #define VIDIOC_STREAMON32 _IOW ('V', 18, s32)
702 #define VIDIOC_STREAMOFF32 _IOW ('V', 19, s32)
703 #define VIDIOC_G_INPUT32 _IOR ('V', 38, s32)
704 #define VIDIOC_S_INPUT32 _IOWR('V', 39, s32)
705 #define VIDIOC_G_OUTPUT32 _IOR ('V', 46, s32)
706 #define VIDIOC_S_OUTPUT32 _IOWR('V', 47, s32)
708 static long do_video_ioctl(struct file
*file
, unsigned int cmd
, unsigned long arg
)
711 #ifdef CONFIG_VIDEO_V4L1_COMPAT
712 struct video_tuner vt
;
713 struct video_buffer vb
;
714 struct video_window vw
;
715 struct video_code vc
;
716 struct video_audio va
;
718 struct v4l2_format v2f
;
719 struct v4l2_buffer v2b
;
720 struct v4l2_framebuffer v2fb
;
721 struct v4l2_input v2i
;
722 struct v4l2_standard v2s
;
723 struct v4l2_ext_controls v2ecs
;
727 void __user
*up
= compat_ptr(arg
);
728 int compatible_arg
= 1;
731 /* First, convert the command. */
733 #ifdef CONFIG_VIDEO_V4L1_COMPAT
734 case VIDIOCGTUNER32
: cmd
= VIDIOCGTUNER
; break;
735 case VIDIOCSTUNER32
: cmd
= VIDIOCSTUNER
; break;
736 case VIDIOCGWIN32
: cmd
= VIDIOCGWIN
; break;
737 case VIDIOCSWIN32
: cmd
= VIDIOCSWIN
; break;
738 case VIDIOCGFBUF32
: cmd
= VIDIOCGFBUF
; break;
739 case VIDIOCSFBUF32
: cmd
= VIDIOCSFBUF
; break;
740 case VIDIOCGFREQ32
: cmd
= VIDIOCGFREQ
; break;
741 case VIDIOCSFREQ32
: cmd
= VIDIOCSFREQ
; break;
742 case VIDIOCSMICROCODE32
: cmd
= VIDIOCSMICROCODE
; break;
744 case VIDIOC_G_FMT32
: cmd
= VIDIOC_G_FMT
; break;
745 case VIDIOC_S_FMT32
: cmd
= VIDIOC_S_FMT
; break;
746 case VIDIOC_QUERYBUF32
: cmd
= VIDIOC_QUERYBUF
; break;
747 case VIDIOC_G_FBUF32
: cmd
= VIDIOC_G_FBUF
; break;
748 case VIDIOC_S_FBUF32
: cmd
= VIDIOC_S_FBUF
; break;
749 case VIDIOC_QBUF32
: cmd
= VIDIOC_QBUF
; break;
750 case VIDIOC_DQBUF32
: cmd
= VIDIOC_DQBUF
; break;
751 case VIDIOC_ENUMSTD32
: cmd
= VIDIOC_ENUMSTD
; break;
752 case VIDIOC_ENUMINPUT32
: cmd
= VIDIOC_ENUMINPUT
; break;
753 case VIDIOC_TRY_FMT32
: cmd
= VIDIOC_TRY_FMT
; break;
754 case VIDIOC_G_EXT_CTRLS32
: cmd
= VIDIOC_G_EXT_CTRLS
; break;
755 case VIDIOC_S_EXT_CTRLS32
: cmd
= VIDIOC_S_EXT_CTRLS
; break;
756 case VIDIOC_TRY_EXT_CTRLS32
: cmd
= VIDIOC_TRY_EXT_CTRLS
; break;
757 case VIDIOC_OVERLAY32
: cmd
= VIDIOC_OVERLAY
; break;
759 case VIDIOC_OVERLAY32_OLD
: cmd
= VIDIOC_OVERLAY
; break;
761 case VIDIOC_STREAMON32
: cmd
= VIDIOC_STREAMON
; break;
762 case VIDIOC_STREAMOFF32
: cmd
= VIDIOC_STREAMOFF
; break;
763 case VIDIOC_G_INPUT32
: cmd
= VIDIOC_G_INPUT
; break;
764 case VIDIOC_S_INPUT32
: cmd
= VIDIOC_S_INPUT
; break;
765 case VIDIOC_G_OUTPUT32
: cmd
= VIDIOC_G_OUTPUT
; break;
766 case VIDIOC_S_OUTPUT32
: cmd
= VIDIOC_S_OUTPUT
; break;
770 #ifdef CONFIG_VIDEO_V4L1_COMPAT
773 err
= get_video_tuner32(&karg
.vt
, up
);
778 err
= get_video_buffer32(&karg
.vb
, up
);
783 err
= get_video_window32(&karg
.vw
, up
);
793 case VIDIOCSMICROCODE
:
794 err
= get_microcode32(&karg
.vc
, up
);
799 err
= get_user(karg
.vx
, (u32 __user
*)up
);
805 case VIDIOCSWRITEMODE
:
808 case VIDIOC_STREAMON
:
809 case VIDIOC_STREAMOFF
:
811 case VIDIOC_S_OUTPUT
:
812 err
= get_user(karg
.vi
, (s32 __user
*)up
);
817 case VIDIOC_G_OUTPUT
:
824 err
= get_v4l2_format32(&karg
.v2f
, up
);
828 case VIDIOC_QUERYBUF
:
831 err
= get_v4l2_buffer32(&karg
.v2b
, up
);
836 err
= get_v4l2_framebuffer32(&karg
.v2fb
, up
);
845 err
= get_v4l2_standard32(&karg
.v2s
, up
);
849 case VIDIOC_ENUMINPUT
:
850 err
= get_v4l2_input32(&karg
.v2i
, up
);
854 case VIDIOC_G_EXT_CTRLS
:
855 case VIDIOC_S_EXT_CTRLS
:
856 case VIDIOC_TRY_EXT_CTRLS
:
857 err
= get_v4l2_ext_controls32(&karg
.v2ecs
, up
);
865 err
= native_ioctl(file
, cmd
, (unsigned long)up
);
867 mm_segment_t old_fs
= get_fs();
870 err
= native_ioctl(file
, cmd
, (unsigned long)&karg
);
874 /* Special case: even after an error we need to put the
875 results back for these ioctls since the error_idx will
876 contain information on which control failed. */
878 case VIDIOC_G_EXT_CTRLS
:
879 case VIDIOC_S_EXT_CTRLS
:
880 case VIDIOC_TRY_EXT_CTRLS
:
881 if (put_v4l2_ext_controls32(&karg
.v2ecs
, up
))
889 #ifdef CONFIG_VIDEO_V4L1_COMPAT
891 err
= put_video_tuner32(&karg
.vt
, up
);
895 err
= put_video_window32(&karg
.vw
, up
);
899 err
= put_video_buffer32(&karg
.vb
, up
);
903 err
= put_user(((u32
)karg
.vx
), (u32 __user
*)up
);
907 case VIDIOC_S_OUTPUT
:
909 case VIDIOC_G_OUTPUT
:
910 err
= put_user(((s32
)karg
.vi
), (s32 __user
*)up
);
914 err
= put_v4l2_framebuffer32(&karg
.v2fb
, up
);
920 err
= put_v4l2_format32(&karg
.v2f
, up
);
923 case VIDIOC_QUERYBUF
:
926 err
= put_v4l2_buffer32(&karg
.v2b
, up
);
930 err
= put_v4l2_standard32(&karg
.v2s
, up
);
933 case VIDIOC_ENUMINPUT
:
934 err
= put_v4l2_input32(&karg
.v2i
, up
);
940 long v4l2_compat_ioctl32(struct file
*file
, unsigned int cmd
, unsigned long arg
)
942 long ret
= -ENOIOCTLCMD
;
944 if (!file
->f_op
->ioctl
&& !file
->f_op
->unlocked_ioctl
)
948 #ifdef CONFIG_VIDEO_V4L1_COMPAT
956 case VIDIOCCAPTURE32
:
972 case VIDIOCSPLAYMODE
:
973 case VIDIOCSWRITEMODE32
:
974 case VIDIOCGPLAYINFO
:
975 case VIDIOCSMICROCODE32
:
980 case VIDIOC_OVERLAY32_OLD
:
981 case VIDIOC_S_PARM_OLD
:
982 case VIDIOC_S_CTRL_OLD
:
983 case VIDIOC_G_AUDIO_OLD
:
984 case VIDIOC_G_AUDOUT_OLD
:
985 case VIDIOC_CROPCAP_OLD
:
987 case VIDIOC_QUERYCAP
:
988 case VIDIOC_RESERVED
:
989 case VIDIOC_ENUM_FMT
:
993 case VIDIOC_QUERYBUF32
:
994 case VIDIOC_G_FBUF32
:
995 case VIDIOC_S_FBUF32
:
996 case VIDIOC_OVERLAY32
:
999 case VIDIOC_STREAMON32
:
1000 case VIDIOC_STREAMOFF32
:
1005 case VIDIOC_ENUMSTD32
:
1006 case VIDIOC_ENUMINPUT32
:
1009 case VIDIOC_G_TUNER
:
1010 case VIDIOC_S_TUNER
:
1011 case VIDIOC_G_AUDIO
:
1012 case VIDIOC_S_AUDIO
:
1013 case VIDIOC_QUERYCTRL
:
1014 case VIDIOC_QUERYMENU
:
1015 case VIDIOC_G_INPUT32
:
1016 case VIDIOC_S_INPUT32
:
1017 case VIDIOC_G_OUTPUT32
:
1018 case VIDIOC_S_OUTPUT32
:
1019 case VIDIOC_ENUMOUTPUT
:
1020 case VIDIOC_G_AUDOUT
:
1021 case VIDIOC_S_AUDOUT
:
1022 case VIDIOC_G_MODULATOR
:
1023 case VIDIOC_S_MODULATOR
:
1024 case VIDIOC_S_FREQUENCY
:
1025 case VIDIOC_G_FREQUENCY
:
1026 case VIDIOC_CROPCAP
:
1029 case VIDIOC_G_JPEGCOMP
:
1030 case VIDIOC_S_JPEGCOMP
:
1031 case VIDIOC_QUERYSTD
:
1032 case VIDIOC_TRY_FMT32
:
1033 case VIDIOC_ENUMAUDIO
:
1034 case VIDIOC_ENUMAUDOUT
:
1035 case VIDIOC_G_PRIORITY
:
1036 case VIDIOC_S_PRIORITY
:
1037 case VIDIOC_G_SLICED_VBI_CAP
:
1038 case VIDIOC_LOG_STATUS
:
1039 case VIDIOC_G_EXT_CTRLS32
:
1040 case VIDIOC_S_EXT_CTRLS32
:
1041 case VIDIOC_TRY_EXT_CTRLS32
:
1042 case VIDIOC_ENUM_FRAMESIZES
:
1043 case VIDIOC_ENUM_FRAMEINTERVALS
:
1044 case VIDIOC_G_ENC_INDEX
:
1045 case VIDIOC_ENCODER_CMD
:
1046 case VIDIOC_TRY_ENCODER_CMD
:
1047 case VIDIOC_DBG_S_REGISTER
:
1048 case VIDIOC_DBG_G_REGISTER
:
1049 case VIDIOC_DBG_G_CHIP_IDENT
:
1050 case VIDIOC_S_HW_FREQ_SEEK
:
1051 ret
= do_video_ioctl(file
, cmd
, arg
);
1054 #ifdef CONFIG_VIDEO_V4L1_COMPAT
1055 /* BTTV specific... */
1056 case _IOW('v', BASE_VIDIOCPRIVATE
+0, char [256]):
1057 case _IOR('v', BASE_VIDIOCPRIVATE
+1, char [256]):
1058 case _IOR('v' , BASE_VIDIOCPRIVATE
+2, unsigned int):
1059 case _IOW('v' , BASE_VIDIOCPRIVATE
+3, char [16]): /* struct bttv_pll_info */
1060 case _IOR('v' , BASE_VIDIOCPRIVATE
+4, int):
1061 case _IOR('v' , BASE_VIDIOCPRIVATE
+5, int):
1062 case _IOR('v' , BASE_VIDIOCPRIVATE
+6, int):
1063 case _IOR('v' , BASE_VIDIOCPRIVATE
+7, int):
1064 ret
= native_ioctl(file
, cmd
, (unsigned long)compat_ptr(arg
));
1068 printk(KERN_WARNING
"compat_ioctl32: "
1069 "unknown ioctl '%c', dir=%d, #%d (0x%08x)\n",
1070 _IOC_TYPE(cmd
), _IOC_DIR(cmd
), _IOC_NR(cmd
), cmd
);
1075 EXPORT_SYMBOL_GPL(v4l2_compat_ioctl32
);
1078 MODULE_LICENSE("GPL");