1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include <linux/compat.h>
17#include <linux/module.h>
18#include <linux/videodev2.h>
19#include <linux/v4l2-subdev.h>
20#include <media/v4l2-dev.h>
21#include <media/v4l2-ioctl.h>
22
23
24#define assign_in_user(to, from) \
25({ \
26 typeof(*from) __assign_tmp; \
27 \
28 get_user(__assign_tmp, from) || put_user(__assign_tmp, to); \
29})
30
31static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
32{
33 long ret = -ENOIOCTLCMD;
34
35 if (file->f_op->unlocked_ioctl)
36 ret = file->f_op->unlocked_ioctl(file, cmd, arg);
37
38 return ret;
39}
40
41
42struct v4l2_clip32 {
43 struct v4l2_rect c;
44 compat_caddr_t next;
45};
46
47struct v4l2_window32 {
48 struct v4l2_rect w;
49 __u32 field;
50 __u32 chromakey;
51 compat_caddr_t clips;
52 __u32 clipcount;
53 compat_caddr_t bitmap;
54};
55
56static int get_v4l2_window32(struct v4l2_window __user *kp,
57 struct v4l2_window32 __user *up,
58 void __user *aux_buf, u32 aux_space)
59{
60 u32 clipcount;
61
62 if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_window32)) ||
63 copy_in_user(&kp->w, &up->w, sizeof(up->w)) ||
64 assign_in_user(&kp->field, &up->field) ||
65 assign_in_user(&kp->chromakey, &up->chromakey) ||
66 get_user(clipcount, &up->clipcount) ||
67 put_user(clipcount, &kp->clipcount))
68 return -EFAULT;
69 if (clipcount > 2048)
70 return -EINVAL;
71 if (clipcount) {
72 struct v4l2_clip32 __user *uclips;
73 struct v4l2_clip __user *kclips;
74 compat_caddr_t p;
75
76 if (get_user(p, &up->clips))
77 return -EFAULT;
78 uclips = compat_ptr(p);
79 if (aux_space < clipcount * sizeof(*kclips))
80 return -EFAULT;
81 kclips = aux_buf;
82 if (put_user(kclips, &kp->clips))
83 return -EFAULT;
84
85 while (--clipcount >= 0) {
86 if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c)))
87 return -EFAULT;
88 if (put_user(clipcount ? kclips + 1 : NULL, &kclips->next))
89 return -EFAULT;
90 uclips += 1;
91 kclips += 1;
92 }
93 } else
94 return put_user(NULL, &kp->clips);
95 return 0;
96}
97
98static int put_v4l2_window32(struct v4l2_window __user *kp,
99 struct v4l2_window32 __user *up)
100{
101 u32 clipcount;
102
103 if (copy_in_user(&up->w, &kp->w, sizeof(kp->w)) ||
104 assign_in_user(&up->field, &kp->field) ||
105 assign_in_user(&up->chromakey, &kp->chromakey) ||
106 get_user(clipcount, &kp->clipcount) ||
107 put_user(clipcount, &up->clipcount))
108 return -EFAULT;
109 return 0;
110}
111
112static inline int get_v4l2_pix_format(struct v4l2_pix_format __user *kp,
113 struct v4l2_pix_format __user *up)
114{
115 if (copy_in_user(kp, up, sizeof(struct v4l2_pix_format)))
116 return -EFAULT;
117 return 0;
118}
119
120static inline int get_v4l2_pix_format_mplane(struct v4l2_pix_format_mplane __user *kp,
121 struct v4l2_pix_format_mplane __user *up)
122{
123 if (copy_in_user(kp, up, sizeof(struct v4l2_pix_format_mplane)))
124 return -EFAULT;
125 return 0;
126}
127
128static inline int put_v4l2_pix_format(struct v4l2_pix_format __user *kp,
129 struct v4l2_pix_format __user *up)
130{
131 if (copy_in_user(up, kp, sizeof(struct v4l2_pix_format)))
132 return -EFAULT;
133 return 0;
134}
135
136static inline int put_v4l2_pix_format_mplane(struct v4l2_pix_format_mplane __user *kp,
137 struct v4l2_pix_format_mplane __user *up)
138{
139 if (copy_in_user(up, kp, sizeof(struct v4l2_pix_format_mplane)))
140 return -EFAULT;
141 return 0;
142}
143
144static inline int get_v4l2_vbi_format(struct v4l2_vbi_format __user *kp,
145 struct v4l2_vbi_format __user *up)
146{
147 if (copy_in_user(kp, up, sizeof(struct v4l2_vbi_format)))
148 return -EFAULT;
149 return 0;
150}
151
152static inline int put_v4l2_vbi_format(struct v4l2_vbi_format __user *kp,
153 struct v4l2_vbi_format __user *up)
154{
155 if (copy_in_user(up, kp, sizeof(struct v4l2_vbi_format)))
156 return -EFAULT;
157 return 0;
158}
159
160static inline int get_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format __user *kp,
161 struct v4l2_sliced_vbi_format __user *up)
162{
163 if (copy_in_user(kp, up, sizeof(struct v4l2_sliced_vbi_format)))
164 return -EFAULT;
165 return 0;
166}
167
168static inline int put_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format __user *kp,
169 struct v4l2_sliced_vbi_format __user *up)
170{
171 if (copy_in_user(up, kp, sizeof(struct v4l2_sliced_vbi_format)))
172 return -EFAULT;
173 return 0;
174}
175
176struct v4l2_format32 {
177 __u32 type;
178 union {
179 struct v4l2_pix_format pix;
180 struct v4l2_pix_format_mplane pix_mp;
181 struct v4l2_window32 win;
182 struct v4l2_vbi_format vbi;
183 struct v4l2_sliced_vbi_format sliced;
184 __u8 raw_data[200];
185 } fmt;
186};
187
188
189
190
191
192
193
194
195
196
197struct v4l2_create_buffers32 {
198 __u32 index;
199 __u32 count;
200 __u32 memory;
201 struct v4l2_format32 format;
202 __u32 reserved[8];
203};
204
205static int __bufsize_v4l2_format(struct v4l2_format32 __user *up, u32 *size)
206{
207 u32 type;
208
209 if (get_user(type, &up->type))
210 return -EFAULT;
211
212 switch (type) {
213 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
214 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: {
215 u32 clipcount;
216
217 if (get_user(clipcount, &up->fmt.win.clipcount))
218 return -EFAULT;
219 if (clipcount > 2048)
220 return -EINVAL;
221 *size = clipcount * sizeof(struct v4l2_clip);
222 return 0;
223 }
224 default:
225 *size = 0;
226 return 0;
227 }
228}
229
230static int bufsize_v4l2_format(struct v4l2_format32 __user *up, u32 *size)
231{
232 if (!access_ok(VERIFY_READ, up, sizeof(*up)))
233 return -EFAULT;
234 return __bufsize_v4l2_format(up, size);
235}
236
237static int __get_v4l2_format32(struct v4l2_format __user *kp,
238 struct v4l2_format32 __user *up,
239 void __user *aux_buf, u32 aux_space)
240{
241 u32 type;
242
243 if (get_user(type, &up->type) || put_user(type, &kp->type))
244 return -EFAULT;
245
246 switch (type) {
247 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
248 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
249 return get_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix);
250 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
251 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
252 return get_v4l2_pix_format_mplane(&kp->fmt.pix_mp,
253 &up->fmt.pix_mp);
254 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
255 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
256 return get_v4l2_window32(&kp->fmt.win, &up->fmt.win,
257 aux_buf, aux_space);
258 case V4L2_BUF_TYPE_VBI_CAPTURE:
259 case V4L2_BUF_TYPE_VBI_OUTPUT:
260 return get_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi);
261 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
262 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
263 return get_v4l2_sliced_vbi_format(&kp->fmt.sliced, &up->fmt.sliced);
264 default:
265 printk(KERN_INFO "compat_ioctl32: unexpected VIDIOC_FMT type %d\n",
266 kp->type);
267 return -EINVAL;
268 }
269}
270
271static int get_v4l2_format32(struct v4l2_format __user *kp,
272 struct v4l2_format32 __user *up,
273 void __user *aux_buf, u32 aux_space)
274{
275 if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
276 get_user(kp->type, &up->type))
277 return -EFAULT;
278 return __get_v4l2_format32(kp, up, aux_buf, aux_space);
279}
280
281static int bufsize_v4l2_create(struct v4l2_create_buffers32 __user *up,
282 u32 *size)
283{
284 if (!access_ok(VERIFY_READ, up, sizeof(*up)))
285 return -EFAULT;
286 return __bufsize_v4l2_format(&up->format, size);
287}
288
289static int get_v4l2_create32(struct v4l2_create_buffers __user *kp,
290 struct v4l2_create_buffers32 __user *up,
291 void __user *aux_buf, u32 aux_space)
292{
293 if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)) ||
294 copy_in_user(kp, up,
295 offsetof(struct v4l2_create_buffers32, format.fmt)))
296 return -EFAULT;
297 return __get_v4l2_format32(&kp->format, &up->format,
298 aux_buf, aux_space);
299}
300
301static int __put_v4l2_format32(struct v4l2_format __user *kp,
302 struct v4l2_format32 __user *up)
303{
304 u32 type;
305
306 if (get_user(type, &kp->type))
307 return -EFAULT;
308
309 switch (type) {
310 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
311 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
312 return put_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix);
313 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
314 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
315 return put_v4l2_pix_format_mplane(&kp->fmt.pix_mp,
316 &up->fmt.pix_mp);
317 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
318 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
319 return put_v4l2_window32(&kp->fmt.win, &up->fmt.win);
320 case V4L2_BUF_TYPE_VBI_CAPTURE:
321 case V4L2_BUF_TYPE_VBI_OUTPUT:
322 return put_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi);
323 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
324 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
325 return put_v4l2_sliced_vbi_format(&kp->fmt.sliced, &up->fmt.sliced);
326 default:
327 printk(KERN_INFO "compat_ioctl32: unexpected VIDIOC_FMT type %d\n",
328 kp->type);
329 return -EINVAL;
330 }
331}
332
333static int put_v4l2_format32(struct v4l2_format __user *kp,
334 struct v4l2_format32 __user *up)
335{
336 if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)))
337 return -EFAULT;
338 return __put_v4l2_format32(kp, up);
339}
340
341static int put_v4l2_create32(struct v4l2_create_buffers __user *kp,
342 struct v4l2_create_buffers32 __user *up)
343{
344 if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_create_buffers32)) ||
345 copy_in_user(up, kp, offsetof(struct v4l2_create_buffers32, format.fmt)))
346 return -EFAULT;
347 return __put_v4l2_format32(&kp->format, &up->format);
348}
349
350struct v4l2_standard32 {
351 __u32 index;
352 compat_u64 id;
353 __u8 name[24];
354 struct v4l2_fract frameperiod;
355 __u32 framelines;
356 __u32 reserved[4];
357};
358
359static int get_v4l2_standard32(struct v4l2_standard __user *kp,
360 struct v4l2_standard32 __user *up)
361{
362
363 if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_standard32)) ||
364 assign_in_user(&kp->index, &up->index))
365 return -EFAULT;
366 return 0;
367}
368
369static int put_v4l2_standard32(struct v4l2_standard __user *kp,
370 struct v4l2_standard32 __user *up)
371{
372 if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard32)) ||
373 assign_in_user(&up->index, &kp->index) ||
374 assign_in_user(&up->id, &kp->id) ||
375 copy_in_user(up->name, kp->name, sizeof(up->name)) ||
376 copy_in_user(&up->frameperiod, &kp->frameperiod,
377 sizeof(up->frameperiod)) ||
378 assign_in_user(&up->framelines, &kp->framelines) ||
379 copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved)))
380 return -EFAULT;
381 return 0;
382}
383
384struct v4l2_plane32 {
385 __u32 bytesused;
386 __u32 length;
387 union {
388 __u32 mem_offset;
389 compat_long_t userptr;
390 __s32 fd;
391 } m;
392 __u32 data_offset;
393 __u32 reserved[11];
394};
395
396struct v4l2_buffer32 {
397 __u32 index;
398 __u32 type;
399 __u32 bytesused;
400 __u32 flags;
401 __u32 field;
402 struct compat_timeval timestamp;
403 struct v4l2_timecode timecode;
404 __u32 sequence;
405
406
407 __u32 memory;
408 union {
409 __u32 offset;
410 compat_long_t userptr;
411 compat_caddr_t planes;
412 __s32 fd;
413 } m;
414 __u32 length;
415 __u32 reserved2;
416 __u32 reserved;
417};
418
419static int get_v4l2_plane32(struct v4l2_plane __user *up,
420 struct v4l2_plane32 __user *up32,
421 enum v4l2_memory memory)
422{
423 compat_ulong_t p;
424
425 if (copy_in_user(up, up32, 2 * sizeof(__u32)) ||
426 copy_in_user(&up->data_offset, &up32->data_offset,
427 sizeof(__u32)))
428 return -EFAULT;
429
430 if (memory == V4L2_MEMORY_USERPTR) {
431 if (get_user(p, &up32->m.userptr) ||
432 put_user((unsigned long)compat_ptr(p), &up->m.userptr))
433 return -EFAULT;
434 } else if (memory == V4L2_MEMORY_DMABUF) {
435 if (copy_in_user(&up->m.fd, &up32->m.fd, sizeof(int)))
436 return -EFAULT;
437 } else {
438 if (copy_in_user(&up->m.mem_offset, &up32->m.mem_offset,
439 sizeof(__u32)))
440 return -EFAULT;
441 }
442
443 return 0;
444}
445
446static int put_v4l2_plane32(struct v4l2_plane __user *up,
447 struct v4l2_plane32 __user *up32,
448 enum v4l2_memory memory)
449{
450 if (copy_in_user(up32, up, 2 * sizeof(__u32)) ||
451 copy_in_user(&up32->data_offset, &up->data_offset,
452 sizeof(__u32)))
453 return -EFAULT;
454
455
456
457 if (memory == V4L2_MEMORY_MMAP)
458 if (copy_in_user(&up32->m.mem_offset, &up->m.mem_offset,
459 sizeof(__u32)))
460 return -EFAULT;
461
462 if (memory == V4L2_MEMORY_DMABUF)
463 if (copy_in_user(&up32->m.fd, &up->m.fd, sizeof(int)))
464 return -EFAULT;
465
466 return 0;
467}
468
469static int bufsize_v4l2_buffer(struct v4l2_buffer32 __user *up, u32 *size)
470{
471 u32 type;
472 u32 length;
473
474 if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
475 get_user(type, &up->type) ||
476 get_user(length, &up->length))
477 return -EFAULT;
478
479 if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
480 if (length > VIDEO_MAX_PLANES)
481 return -EINVAL;
482
483
484
485
486
487 *size = length * sizeof(struct v4l2_plane);
488 } else {
489 *size = 0;
490 }
491 return 0;
492}
493
494static int get_v4l2_buffer32(struct v4l2_buffer __user *kp,
495 struct v4l2_buffer32 __user *up,
496 void __user *aux_buf, u32 aux_space)
497{
498 u32 type;
499 u32 length;
500 enum v4l2_memory memory;
501 struct v4l2_plane32 __user *uplane32;
502 struct v4l2_plane __user *uplane;
503 compat_caddr_t p;
504 int ret;
505
506 if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_buffer32)) ||
507 assign_in_user(&kp->index, &up->index) ||
508 get_user(type, &up->type) ||
509 put_user(type, &kp->type) ||
510 assign_in_user(&kp->flags, &up->flags) ||
511 get_user(memory, &up->memory) ||
512 put_user(memory, &kp->memory) ||
513 get_user(length, &up->length) ||
514 put_user(length, &kp->length))
515 return -EFAULT;
516
517 if (V4L2_TYPE_IS_OUTPUT(type))
518 if (assign_in_user(&kp->bytesused, &up->bytesused) ||
519 assign_in_user(&kp->field, &up->field) ||
520 assign_in_user(&kp->timestamp.tv_sec,
521 &up->timestamp.tv_sec) ||
522 assign_in_user(&kp->timestamp.tv_usec,
523 &up->timestamp.tv_usec))
524 return -EFAULT;
525
526 if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
527 u32 num_planes = length;
528
529 if (num_planes == 0) {
530
531
532
533
534 return put_user(NULL, &kp->m.planes);
535 }
536 if (num_planes > VIDEO_MAX_PLANES)
537 return -EINVAL;
538
539 if (get_user(p, &up->m.planes))
540 return -EFAULT;
541
542 uplane32 = compat_ptr(p);
543 if (!access_ok(VERIFY_READ, uplane32,
544 num_planes * sizeof(struct v4l2_plane32)))
545 return -EFAULT;
546
547
548
549
550
551 if (aux_space < num_planes * sizeof(*uplane))
552 return -EFAULT;
553
554 uplane = aux_buf;
555 if (put_user((__force struct v4l2_plane *)uplane,
556 &kp->m.planes))
557 return -EFAULT;
558
559 while (num_planes--) {
560 ret = get_v4l2_plane32(uplane, uplane32, memory);
561 if (ret)
562 return ret;
563 uplane++;
564 uplane32++;
565 }
566 } else {
567 switch (memory) {
568 case V4L2_MEMORY_MMAP:
569 if (assign_in_user(&kp->m.offset, &up->m.offset))
570 return -EFAULT;
571 break;
572 case V4L2_MEMORY_USERPTR: {
573 compat_ulong_t userptr;
574
575 if (get_user(userptr, &up->m.userptr) ||
576 put_user((unsigned long)compat_ptr(userptr),
577 &kp->m.userptr))
578 return -EFAULT;
579 }
580 break;
581 case V4L2_MEMORY_OVERLAY:
582 if (assign_in_user(&kp->m.offset, &up->m.offset))
583 return -EFAULT;
584 break;
585 case V4L2_MEMORY_DMABUF:
586 if (assign_in_user(&kp->m.fd, &up->m.fd))
587 return -EFAULT;
588 break;
589 }
590 }
591
592 return 0;
593}
594
595static int put_v4l2_buffer32(struct v4l2_buffer __user *kp,
596 struct v4l2_buffer32 __user *up)
597{
598 u32 type;
599 u32 length;
600 enum v4l2_memory memory;
601 struct v4l2_plane32 __user *uplane32;
602 struct v4l2_plane __user *uplane;
603 compat_caddr_t p;
604 int ret;
605
606 if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_buffer32)) ||
607 assign_in_user(&up->index, &kp->index) ||
608 get_user(type, &kp->type) ||
609 put_user(type, &up->type) ||
610 assign_in_user(&up->flags, &kp->flags) ||
611 get_user(memory, &kp->memory) ||
612 put_user(memory, &up->memory))
613 return -EFAULT;
614
615 if (assign_in_user(&up->bytesused, &kp->bytesused) ||
616 assign_in_user(&up->field, &kp->field) ||
617 assign_in_user(&up->timestamp.tv_sec, &kp->timestamp.tv_sec) ||
618 assign_in_user(&up->timestamp.tv_usec, &kp->timestamp.tv_usec) ||
619 copy_in_user(&up->timecode, &kp->timecode, sizeof(kp->timecode)) ||
620 assign_in_user(&up->sequence, &kp->sequence) ||
621 assign_in_user(&up->reserved2, &kp->reserved2) ||
622 assign_in_user(&up->reserved, &kp->reserved) ||
623 get_user(length, &kp->length) ||
624 put_user(length, &up->length))
625 return -EFAULT;
626
627 if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
628 u32 num_planes = length;
629
630 if (num_planes == 0)
631 return 0;
632
633 if (get_user(uplane, ((__force struct v4l2_plane __user **)&kp->m.planes)))
634 return -EFAULT;
635 if (get_user(p, &up->m.planes))
636 return -EFAULT;
637 uplane32 = compat_ptr(p);
638
639 while (num_planes--) {
640 ret = put_v4l2_plane32(uplane, uplane32, memory);
641 if (ret)
642 return ret;
643 ++uplane;
644 ++uplane32;
645 }
646 } else {
647 switch (memory) {
648 case V4L2_MEMORY_MMAP:
649 if (assign_in_user(&up->m.offset, &kp->m.offset))
650 return -EFAULT;
651 break;
652 case V4L2_MEMORY_USERPTR:
653 if (assign_in_user(&up->m.userptr, &kp->m.userptr))
654 return -EFAULT;
655 break;
656 case V4L2_MEMORY_OVERLAY:
657 if (assign_in_user(&up->m.offset, &kp->m.offset))
658 return -EFAULT;
659 break;
660 case V4L2_MEMORY_DMABUF:
661 if (assign_in_user(&up->m.fd, &kp->m.fd))
662 return -EFAULT;
663 break;
664 }
665 }
666
667 return 0;
668}
669
670struct v4l2_framebuffer32 {
671 __u32 capability;
672 __u32 flags;
673 compat_caddr_t base;
674 struct v4l2_pix_format fmt;
675};
676
677static int get_v4l2_framebuffer32(struct v4l2_framebuffer __user *kp,
678 struct v4l2_framebuffer32 __user *up)
679{
680 compat_caddr_t tmp;
681
682 if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_framebuffer32)) ||
683 get_user(tmp, &up->base) ||
684 put_user((__force void *)compat_ptr(tmp), &kp->base) ||
685 assign_in_user(&kp->capability, &up->capability) ||
686 assign_in_user(&kp->flags, &up->flags) ||
687 copy_in_user(&kp->fmt, &up->fmt, sizeof(kp->fmt)))
688 return -EFAULT;
689 return 0;
690}
691
692static int put_v4l2_framebuffer32(struct v4l2_framebuffer __user *kp,
693 struct v4l2_framebuffer32 __user *up)
694{
695 void *base;
696
697 if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_framebuffer32)) ||
698 get_user(base, &kp->base) ||
699 put_user(ptr_to_compat(base), &up->base) ||
700 assign_in_user(&up->capability, &kp->capability) ||
701 assign_in_user(&up->flags, &kp->flags) ||
702 copy_in_user(&up->fmt, &kp->fmt, sizeof(kp->fmt)))
703 return -EFAULT;
704 return 0;
705}
706
707struct v4l2_input32 {
708 __u32 index;
709 __u8 name[32];
710 __u32 type;
711 __u32 audioset;
712 __u32 tuner;
713 v4l2_std_id std;
714 __u32 status;
715 __u32 reserved[4];
716} __attribute__ ((packed));
717
718
719
720
721
722static inline int get_v4l2_input32(struct v4l2_input __user *kp,
723 struct v4l2_input32 __user *up)
724{
725 if (copy_in_user(kp, up, sizeof(struct v4l2_input32)))
726 return -EFAULT;
727 return 0;
728}
729
730static inline int put_v4l2_input32(struct v4l2_input __user *kp,
731 struct v4l2_input32 __user *up)
732{
733 if (copy_in_user(up, kp, sizeof(struct v4l2_input32)))
734 return -EFAULT;
735 return 0;
736}
737
738struct v4l2_ext_controls32 {
739 __u32 ctrl_class;
740 __u32 count;
741 __u32 error_idx;
742 __u32 reserved[2];
743 compat_caddr_t controls;
744};
745
746struct v4l2_ext_control32 {
747 __u32 id;
748 __u32 size;
749 __u32 reserved2[1];
750 union {
751 __s32 value;
752 __s64 value64;
753 compat_caddr_t string;
754 };
755} __attribute__ ((packed));
756
757
758
759
760
761
762
763static inline int ctrl_is_pointer(u32 id)
764{
765 switch (id) {
766 case V4L2_CID_RDS_TX_PS_NAME:
767 case V4L2_CID_RDS_TX_RADIO_TEXT:
768 return 1;
769 default:
770 return 0;
771 }
772}
773
774static int bufsize_v4l2_ext_controls(struct v4l2_ext_controls32 __user *up,
775 u32 *size)
776{
777 u32 count;
778
779 if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
780 get_user(count, &up->count))
781 return -EFAULT;
782 if (count > V4L2_CID_MAX_CTRLS)
783 return -EINVAL;
784 *size = count * sizeof(struct v4l2_ext_control);
785 return 0;
786}
787
788static int get_v4l2_ext_controls32(struct v4l2_ext_controls __user *kp,
789 struct v4l2_ext_controls32 __user *up,
790 void __user *aux_buf, u32 aux_space)
791{
792 struct v4l2_ext_control32 __user *ucontrols;
793 struct v4l2_ext_control __user *kcontrols;
794 u32 count;
795 u32 n;
796 compat_caddr_t p;
797
798 if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_ext_controls32)) ||
799 assign_in_user(&kp->ctrl_class, &up->ctrl_class) ||
800 get_user(count, &up->count) ||
801 put_user(count, &kp->count) ||
802 assign_in_user(&kp->error_idx, &up->error_idx) ||
803 copy_in_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
804 return -EFAULT;
805
806 if (count == 0)
807 return put_user(NULL, &kp->controls);
808 if (count > V4L2_CID_MAX_CTRLS)
809 return -EINVAL;
810 if (get_user(p, &up->controls))
811 return -EFAULT;
812 ucontrols = compat_ptr(p);
813 if (!access_ok(VERIFY_READ, ucontrols,
814 count * sizeof(struct v4l2_ext_control32)))
815 return -EFAULT;
816 if (aux_space < count * sizeof(*kcontrols))
817 return -EFAULT;
818 kcontrols = aux_buf;
819 if (put_user((__force struct v4l2_ext_control *)kcontrols,
820 &kp->controls))
821 return -EFAULT;
822
823 for (n = 0; n < count; n++) {
824 u32 id;
825
826 if (copy_in_user(kcontrols, ucontrols, sizeof(*ucontrols)))
827 return -EFAULT;
828
829 if (get_user(id, &kcontrols->id))
830 return -EFAULT;
831
832 if (ctrl_is_pointer(id)) {
833 void __user *s;
834
835 if (get_user(p, &ucontrols->string))
836 return -EFAULT;
837 s = compat_ptr(p);
838 if (put_user(s, &kcontrols->string))
839 return -EFAULT;
840 }
841 ucontrols++;
842 kcontrols++;
843 }
844 return 0;
845}
846
847static int put_v4l2_ext_controls32(struct v4l2_ext_controls __user *kp,
848 struct v4l2_ext_controls32 __user *up)
849{
850 struct v4l2_ext_control32 __user *ucontrols;
851 struct v4l2_ext_control __user *kcontrols;
852 u32 count;
853 u32 n;
854 compat_caddr_t p;
855
856 if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_ext_controls32)) ||
857 assign_in_user(&up->ctrl_class, &kp->ctrl_class) ||
858 get_user(count, &kp->count) ||
859 put_user(count, &up->count) ||
860 assign_in_user(&up->error_idx, &kp->error_idx) ||
861 copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved)) ||
862 get_user(kcontrols, &kp->controls))
863 return -EFAULT;
864
865 if (!count)
866 return 0;
867 if (get_user(p, &up->controls))
868 return -EFAULT;
869 ucontrols = compat_ptr(p);
870 if (!access_ok(VERIFY_WRITE, ucontrols,
871 count * sizeof(struct v4l2_ext_control32)))
872 return -EFAULT;
873
874 for (n = 0; n < count; n++) {
875 unsigned int size = sizeof(*ucontrols);
876 u32 id;
877
878 if (get_user(id, &kcontrols->id) ||
879 put_user(id, &ucontrols->id) ||
880 assign_in_user(&ucontrols->size, &kcontrols->size) ||
881 copy_in_user(&ucontrols->reserved2, &kcontrols->reserved2,
882 sizeof(ucontrols->reserved2)))
883 return -EFAULT;
884
885
886
887
888
889
890 if (ctrl_is_pointer(id))
891 size -= sizeof(ucontrols->value64);
892
893 if (copy_in_user(ucontrols, kcontrols, size))
894 return -EFAULT;
895
896 ucontrols++;
897 kcontrols++;
898 }
899 return 0;
900}
901
902struct v4l2_event32 {
903 __u32 type;
904 union {
905 __u8 data[64];
906 } u;
907 __u32 pending;
908 __u32 sequence;
909 struct compat_timespec timestamp;
910 __u32 id;
911 __u32 reserved[8];
912};
913
914static int put_v4l2_event32(struct v4l2_event __user *kp,
915 struct v4l2_event32 __user *up)
916{
917 if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_event32)) ||
918 assign_in_user(&up->type, &kp->type) ||
919 copy_in_user(&up->u, &kp->u, sizeof(kp->u)) ||
920 assign_in_user(&up->pending, &kp->pending) ||
921 assign_in_user(&up->sequence, &kp->sequence) ||
922 assign_in_user(&up->timestamp.tv_sec, &kp->timestamp.tv_sec) ||
923 assign_in_user(&up->timestamp.tv_nsec, &kp->timestamp.tv_nsec) ||
924 assign_in_user(&up->id, &kp->id) ||
925 copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved)))
926 return -EFAULT;
927 return 0;
928}
929
930struct v4l2_subdev_edid32 {
931 __u32 pad;
932 __u32 start_block;
933 __u32 blocks;
934 __u32 reserved[5];
935 compat_caddr_t edid;
936};
937
938static int get_v4l2_subdev_edid32(struct v4l2_subdev_edid __user *kp,
939 struct v4l2_subdev_edid32 __user *up)
940{
941 compat_uptr_t tmp;
942
943 if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_subdev_edid32)) ||
944 assign_in_user(&kp->pad, &up->pad) ||
945 assign_in_user(&kp->start_block, &up->start_block) ||
946 assign_in_user(&kp->blocks, &up->blocks) ||
947 get_user(tmp, &up->edid) ||
948 put_user(compat_ptr(tmp), &kp->edid) ||
949 copy_in_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
950 return -EFAULT;
951 return 0;
952}
953
954static int put_v4l2_subdev_edid32(struct v4l2_subdev_edid __user *kp,
955 struct v4l2_subdev_edid32 __user *up)
956{
957 void *edid;
958
959 if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_subdev_edid32)) ||
960 assign_in_user(&up->pad, &kp->pad) ||
961 assign_in_user(&up->start_block, &kp->start_block) ||
962 assign_in_user(&up->blocks, &kp->blocks) ||
963 get_user(edid, &kp->edid) ||
964 put_user(ptr_to_compat(edid), &up->edid) ||
965 copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved)))
966 return -EFAULT;
967 return 0;
968}
969
970
971#define VIDIOC_G_FMT32 _IOWR('V', 4, struct v4l2_format32)
972#define VIDIOC_S_FMT32 _IOWR('V', 5, struct v4l2_format32)
973#define VIDIOC_QUERYBUF32 _IOWR('V', 9, struct v4l2_buffer32)
974#define VIDIOC_G_FBUF32 _IOR ('V', 10, struct v4l2_framebuffer32)
975#define VIDIOC_S_FBUF32 _IOW ('V', 11, struct v4l2_framebuffer32)
976#define VIDIOC_QBUF32 _IOWR('V', 15, struct v4l2_buffer32)
977#define VIDIOC_DQBUF32 _IOWR('V', 17, struct v4l2_buffer32)
978#define VIDIOC_ENUMSTD32 _IOWR('V', 25, struct v4l2_standard32)
979#define VIDIOC_ENUMINPUT32 _IOWR('V', 26, struct v4l2_input32)
980#define VIDIOC_SUBDEV_G_EDID32 _IOWR('V', 63, struct v4l2_subdev_edid32)
981#define VIDIOC_SUBDEV_S_EDID32 _IOWR('V', 64, struct v4l2_subdev_edid32)
982#define VIDIOC_TRY_FMT32 _IOWR('V', 64, struct v4l2_format32)
983#define VIDIOC_G_EXT_CTRLS32 _IOWR('V', 71, struct v4l2_ext_controls32)
984#define VIDIOC_S_EXT_CTRLS32 _IOWR('V', 72, struct v4l2_ext_controls32)
985#define VIDIOC_TRY_EXT_CTRLS32 _IOWR('V', 73, struct v4l2_ext_controls32)
986#define VIDIOC_DQEVENT32 _IOR ('V', 89, struct v4l2_event32)
987#define VIDIOC_CREATE_BUFS32 _IOWR('V', 92, struct v4l2_create_buffers32)
988#define VIDIOC_PREPARE_BUF32 _IOWR('V', 93, struct v4l2_buffer32)
989
990#define VIDIOC_OVERLAY32 _IOW ('V', 14, s32)
991#define VIDIOC_STREAMON32 _IOW ('V', 18, s32)
992#define VIDIOC_STREAMOFF32 _IOW ('V', 19, s32)
993#define VIDIOC_G_INPUT32 _IOR ('V', 38, s32)
994#define VIDIOC_S_INPUT32 _IOWR('V', 39, s32)
995#define VIDIOC_G_OUTPUT32 _IOR ('V', 46, s32)
996#define VIDIOC_S_OUTPUT32 _IOWR('V', 47, s32)
997
998static int alloc_userspace(unsigned int size, u32 aux_space,
999 void __user **up_native)
1000{
1001 *up_native = compat_alloc_user_space(size + aux_space);
1002 if (!*up_native)
1003 return -ENOMEM;
1004 if (clear_user(*up_native, size))
1005 return -EFAULT;
1006 return 0;
1007}
1008
1009static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1010{
1011 void __user *up = compat_ptr(arg);
1012 void __user *up_native = NULL;
1013 void __user *aux_buf;
1014 u32 aux_space;
1015 int compatible_arg = 1;
1016 long err = 0;
1017
1018
1019 switch (cmd) {
1020 case VIDIOC_G_FMT32: cmd = VIDIOC_G_FMT; break;
1021 case VIDIOC_S_FMT32: cmd = VIDIOC_S_FMT; break;
1022 case VIDIOC_QUERYBUF32: cmd = VIDIOC_QUERYBUF; break;
1023 case VIDIOC_G_FBUF32: cmd = VIDIOC_G_FBUF; break;
1024 case VIDIOC_S_FBUF32: cmd = VIDIOC_S_FBUF; break;
1025 case VIDIOC_QBUF32: cmd = VIDIOC_QBUF; break;
1026 case VIDIOC_DQBUF32: cmd = VIDIOC_DQBUF; break;
1027 case VIDIOC_ENUMSTD32: cmd = VIDIOC_ENUMSTD; break;
1028 case VIDIOC_ENUMINPUT32: cmd = VIDIOC_ENUMINPUT; break;
1029 case VIDIOC_TRY_FMT32: cmd = VIDIOC_TRY_FMT; break;
1030 case VIDIOC_G_EXT_CTRLS32: cmd = VIDIOC_G_EXT_CTRLS; break;
1031 case VIDIOC_S_EXT_CTRLS32: cmd = VIDIOC_S_EXT_CTRLS; break;
1032 case VIDIOC_TRY_EXT_CTRLS32: cmd = VIDIOC_TRY_EXT_CTRLS; break;
1033 case VIDIOC_DQEVENT32: cmd = VIDIOC_DQEVENT; break;
1034 case VIDIOC_OVERLAY32: cmd = VIDIOC_OVERLAY; break;
1035 case VIDIOC_STREAMON32: cmd = VIDIOC_STREAMON; break;
1036 case VIDIOC_STREAMOFF32: cmd = VIDIOC_STREAMOFF; break;
1037 case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break;
1038 case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break;
1039 case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break;
1040 case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break;
1041 case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break;
1042 case VIDIOC_PREPARE_BUF32: cmd = VIDIOC_PREPARE_BUF; break;
1043 case VIDIOC_SUBDEV_G_EDID32: cmd = VIDIOC_SUBDEV_G_EDID; break;
1044 case VIDIOC_SUBDEV_S_EDID32: cmd = VIDIOC_SUBDEV_S_EDID; break;
1045 }
1046
1047 switch (cmd) {
1048 case VIDIOC_OVERLAY:
1049 case VIDIOC_STREAMON:
1050 case VIDIOC_STREAMOFF:
1051 case VIDIOC_S_INPUT:
1052 case VIDIOC_S_OUTPUT:
1053 err = alloc_userspace(sizeof(unsigned int), 0, &up_native);
1054 if (!err && assign_in_user((unsigned int __user *)up_native,
1055 (compat_uint_t __user *)up))
1056 err = -EFAULT;
1057 compatible_arg = 0;
1058 break;
1059
1060 case VIDIOC_G_INPUT:
1061 case VIDIOC_G_OUTPUT:
1062 err = alloc_userspace(sizeof(unsigned int), 0, &up_native);
1063 compatible_arg = 0;
1064 break;
1065
1066 case VIDIOC_SUBDEV_G_EDID:
1067 case VIDIOC_SUBDEV_S_EDID:
1068 err = alloc_userspace(sizeof(struct v4l2_subdev_edid32), 0, &up_native);
1069 if (!err)
1070 err = get_v4l2_subdev_edid32(up_native, up);
1071 compatible_arg = 0;
1072 break;
1073
1074 case VIDIOC_G_FMT:
1075 case VIDIOC_S_FMT:
1076 case VIDIOC_TRY_FMT:
1077 err = bufsize_v4l2_format(up, &aux_space);
1078 if (!err)
1079 err = alloc_userspace(sizeof(struct v4l2_format),
1080 aux_space, &up_native);
1081 if (!err) {
1082 aux_buf = up_native + sizeof(struct v4l2_format);
1083 err = get_v4l2_format32(up_native, up,
1084 aux_buf, aux_space);
1085 }
1086 compatible_arg = 0;
1087 break;
1088
1089 case VIDIOC_CREATE_BUFS:
1090 err = bufsize_v4l2_create(up, &aux_space);
1091 if (!err)
1092 err = alloc_userspace(sizeof(struct v4l2_create_buffers),
1093 aux_space, &up_native);
1094 if (!err) {
1095 aux_buf = up_native + sizeof(struct v4l2_create_buffers);
1096 err = get_v4l2_create32(up_native, up,
1097 aux_buf, aux_space);
1098 }
1099 compatible_arg = 0;
1100 break;
1101
1102 case VIDIOC_PREPARE_BUF:
1103 case VIDIOC_QUERYBUF:
1104 case VIDIOC_QBUF:
1105 case VIDIOC_DQBUF:
1106 err = bufsize_v4l2_buffer(up, &aux_space);
1107 if (!err)
1108 err = alloc_userspace(sizeof(struct v4l2_buffer),
1109 aux_space, &up_native);
1110 if (!err) {
1111 aux_buf = up_native + sizeof(struct v4l2_buffer);
1112 err = get_v4l2_buffer32(up_native, up,
1113 aux_buf, aux_space);
1114 }
1115 compatible_arg = 0;
1116 break;
1117
1118 case VIDIOC_S_FBUF:
1119 err = alloc_userspace(sizeof(struct v4l2_framebuffer), 0,
1120 &up_native);
1121 if (!err)
1122 err = get_v4l2_framebuffer32(up_native, up);
1123 compatible_arg = 0;
1124 break;
1125
1126 case VIDIOC_G_FBUF:
1127 err = alloc_userspace(sizeof(struct v4l2_framebuffer), 0,
1128 &up_native);
1129 compatible_arg = 0;
1130 break;
1131
1132 case VIDIOC_ENUMSTD:
1133 err = alloc_userspace(sizeof(struct v4l2_standard), 0,
1134 &up_native);
1135 if (!err)
1136 err = get_v4l2_standard32(up_native, up);
1137 compatible_arg = 0;
1138 break;
1139
1140 case VIDIOC_ENUMINPUT:
1141 err = alloc_userspace(sizeof(struct v4l2_input), 0, &up_native);
1142 if (!err)
1143 err = get_v4l2_input32(up_native, up);
1144 compatible_arg = 0;
1145 break;
1146
1147 case VIDIOC_G_EXT_CTRLS:
1148 case VIDIOC_S_EXT_CTRLS:
1149 case VIDIOC_TRY_EXT_CTRLS:
1150 err = bufsize_v4l2_ext_controls(up, &aux_space);
1151 if (!err)
1152 err = alloc_userspace(sizeof(struct v4l2_ext_controls),
1153 aux_space, &up_native);
1154 if (!err) {
1155 aux_buf = up_native + sizeof(struct v4l2_ext_controls);
1156 err = get_v4l2_ext_controls32(up_native, up,
1157 aux_buf, aux_space);
1158 }
1159 compatible_arg = 0;
1160 break;
1161 case VIDIOC_DQEVENT:
1162 err = alloc_userspace(sizeof(struct v4l2_event), 0, &up_native);
1163 compatible_arg = 0;
1164 break;
1165 }
1166 if (err)
1167 return err;
1168
1169 if (compatible_arg)
1170 err = native_ioctl(file, cmd, (unsigned long)up);
1171 else
1172 err = native_ioctl(file, cmd, (unsigned long)up_native);
1173
1174 if (err == -ENOTTY)
1175 return err;
1176
1177
1178
1179
1180
1181
1182 switch (cmd) {
1183 case VIDIOC_G_EXT_CTRLS:
1184 case VIDIOC_S_EXT_CTRLS:
1185 case VIDIOC_TRY_EXT_CTRLS:
1186 if (put_v4l2_ext_controls32(up_native, up))
1187 err = -EFAULT;
1188 break;
1189 }
1190 if (err)
1191 return err;
1192
1193 switch (cmd) {
1194 case VIDIOC_S_INPUT:
1195 case VIDIOC_S_OUTPUT:
1196 case VIDIOC_G_INPUT:
1197 case VIDIOC_G_OUTPUT:
1198 if (assign_in_user((compat_uint_t __user *)up,
1199 ((unsigned int __user *)up_native)))
1200 err = -EFAULT;
1201 break;
1202
1203 case VIDIOC_G_FBUF:
1204 err = put_v4l2_framebuffer32(up_native, up);
1205 break;
1206
1207 case VIDIOC_DQEVENT:
1208 err = put_v4l2_event32(up_native, up);
1209 break;
1210
1211 case VIDIOC_SUBDEV_G_EDID:
1212 case VIDIOC_SUBDEV_S_EDID:
1213 err = put_v4l2_subdev_edid32(up_native, up);
1214 break;
1215
1216 case VIDIOC_G_FMT:
1217 case VIDIOC_S_FMT:
1218 case VIDIOC_TRY_FMT:
1219 err = put_v4l2_format32(up_native, up);
1220 break;
1221
1222 case VIDIOC_CREATE_BUFS:
1223 err = put_v4l2_create32(up_native, up);
1224 break;
1225
1226 case VIDIOC_QUERYBUF:
1227 case VIDIOC_QBUF:
1228 case VIDIOC_DQBUF:
1229 err = put_v4l2_buffer32(up_native, up);
1230 break;
1231
1232 case VIDIOC_ENUMSTD:
1233 err = put_v4l2_standard32(up_native, up);
1234 break;
1235
1236 case VIDIOC_ENUMINPUT:
1237 err = put_v4l2_input32(up_native, up);
1238 break;
1239 }
1240 return err;
1241}
1242
1243long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
1244{
1245 struct video_device *vdev = video_devdata(file);
1246 long ret = -ENOIOCTLCMD;
1247
1248 if (!file->f_op->unlocked_ioctl)
1249 return ret;
1250
1251 switch (cmd) {
1252 case VIDIOC_QUERYCAP:
1253 case VIDIOC_RESERVED:
1254 case VIDIOC_ENUM_FMT:
1255 case VIDIOC_G_FMT32:
1256 case VIDIOC_S_FMT32:
1257 case VIDIOC_REQBUFS:
1258 case VIDIOC_QUERYBUF32:
1259 case VIDIOC_G_FBUF32:
1260 case VIDIOC_S_FBUF32:
1261 case VIDIOC_OVERLAY32:
1262 case VIDIOC_QBUF32:
1263 case VIDIOC_EXPBUF:
1264 case VIDIOC_DQBUF32:
1265 case VIDIOC_STREAMON32:
1266 case VIDIOC_STREAMOFF32:
1267 case VIDIOC_G_PARM:
1268 case VIDIOC_S_PARM:
1269 case VIDIOC_G_STD:
1270 case VIDIOC_S_STD:
1271 case VIDIOC_ENUMSTD32:
1272 case VIDIOC_ENUMINPUT32:
1273 case VIDIOC_G_CTRL:
1274 case VIDIOC_S_CTRL:
1275 case VIDIOC_G_TUNER:
1276 case VIDIOC_S_TUNER:
1277 case VIDIOC_G_AUDIO:
1278 case VIDIOC_S_AUDIO:
1279 case VIDIOC_QUERYCTRL:
1280 case VIDIOC_QUERYMENU:
1281 case VIDIOC_G_INPUT32:
1282 case VIDIOC_S_INPUT32:
1283 case VIDIOC_G_OUTPUT32:
1284 case VIDIOC_S_OUTPUT32:
1285 case VIDIOC_ENUMOUTPUT:
1286 case VIDIOC_G_AUDOUT:
1287 case VIDIOC_S_AUDOUT:
1288 case VIDIOC_G_MODULATOR:
1289 case VIDIOC_S_MODULATOR:
1290 case VIDIOC_S_FREQUENCY:
1291 case VIDIOC_G_FREQUENCY:
1292 case VIDIOC_CROPCAP:
1293 case VIDIOC_G_CROP:
1294 case VIDIOC_S_CROP:
1295 case VIDIOC_G_SELECTION:
1296 case VIDIOC_S_SELECTION:
1297 case VIDIOC_G_JPEGCOMP:
1298 case VIDIOC_S_JPEGCOMP:
1299 case VIDIOC_QUERYSTD:
1300 case VIDIOC_TRY_FMT32:
1301 case VIDIOC_ENUMAUDIO:
1302 case VIDIOC_ENUMAUDOUT:
1303 case VIDIOC_G_PRIORITY:
1304 case VIDIOC_S_PRIORITY:
1305 case VIDIOC_G_SLICED_VBI_CAP:
1306 case VIDIOC_LOG_STATUS:
1307 case VIDIOC_G_EXT_CTRLS32:
1308 case VIDIOC_S_EXT_CTRLS32:
1309 case VIDIOC_TRY_EXT_CTRLS32:
1310 case VIDIOC_ENUM_FRAMESIZES:
1311 case VIDIOC_ENUM_FRAMEINTERVALS:
1312 case VIDIOC_G_ENC_INDEX:
1313 case VIDIOC_ENCODER_CMD:
1314 case VIDIOC_TRY_ENCODER_CMD:
1315 case VIDIOC_DECODER_CMD:
1316 case VIDIOC_TRY_DECODER_CMD:
1317 case VIDIOC_DBG_S_REGISTER:
1318 case VIDIOC_DBG_G_REGISTER:
1319 case VIDIOC_DBG_G_CHIP_IDENT:
1320 case VIDIOC_S_HW_FREQ_SEEK:
1321 case VIDIOC_S_DV_TIMINGS:
1322 case VIDIOC_G_DV_TIMINGS:
1323 case VIDIOC_DQEVENT:
1324 case VIDIOC_DQEVENT32:
1325 case VIDIOC_SUBSCRIBE_EVENT:
1326 case VIDIOC_UNSUBSCRIBE_EVENT:
1327 case VIDIOC_CREATE_BUFS32:
1328 case VIDIOC_PREPARE_BUF32:
1329 case VIDIOC_ENUM_DV_TIMINGS:
1330 case VIDIOC_QUERY_DV_TIMINGS:
1331 case VIDIOC_DV_TIMINGS_CAP:
1332 case VIDIOC_ENUM_FREQ_BANDS:
1333 case VIDIOC_SUBDEV_G_EDID32:
1334 case VIDIOC_SUBDEV_S_EDID32:
1335 ret = do_video_ioctl(file, cmd, arg);
1336 break;
1337
1338 default:
1339 if (vdev->fops->compat_ioctl32)
1340 ret = vdev->fops->compat_ioctl32(file, cmd, arg);
1341
1342 if (ret == -ENOIOCTLCMD)
1343 printk(KERN_WARNING "compat_ioctl32: "
1344 "unknown ioctl '%c', dir=%d, #%d (0x%08x)\n",
1345 _IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd),
1346 cmd);
1347 break;
1348 }
1349 return ret;
1350}
1351EXPORT_SYMBOL_GPL(v4l2_compat_ioctl32);
1352