xref: /linux/drivers/media/v4l2-core/v4l2-compat-ioctl32.c (revision 3a38ef2b3cb6b63c105247b5ea4a9cf600e673f0)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
4  *	Separated from fs stuff by Arnd Bergmann <arnd@arndb.de>
5  *
6  * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
7  * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
8  * Copyright (C) 2001,2002  Andi Kleen, SuSE Labs
9  * Copyright (C) 2003       Pavel Machek (pavel@ucw.cz)
10  * Copyright (C) 2005       Philippe De Muyter (phdm@macqel.be)
11  * Copyright (C) 2008       Hans Verkuil <hverkuil@xs4all.nl>
12  *
13  * These routines maintain argument size conversion between 32bit and 64bit
14  * ioctls.
15  */
16 
17 #include <linux/compat.h>
18 #include <linux/module.h>
19 #include <linux/videodev2.h>
20 #include <linux/v4l2-subdev.h>
21 #include <media/v4l2-dev.h>
22 #include <media/v4l2-fh.h>
23 #include <media/v4l2-ctrls.h>
24 #include <media/v4l2-ioctl.h>
25 
26 /*
27  * Per-ioctl data copy handlers.
28  *
29  * Those come in pairs, with a get_v4l2_foo() and a put_v4l2_foo() routine,
30  * where "v4l2_foo" is the name of the V4L2 struct.
31  *
32  * They basically get two __user pointers, one with a 32-bits struct that
33  * came from the userspace call and a 64-bits struct, also allocated as
34  * userspace, but filled internally by do_video_ioctl().
35  *
36  * For ioctls that have pointers inside it, the functions will also
37  * receive an ancillary buffer with extra space, used to pass extra
38  * data to the routine.
39  */
40 
41 struct v4l2_clip32 {
42 	struct v4l2_rect        c;
43 	compat_caddr_t		next;
44 };
45 
46 struct v4l2_window32 {
47 	struct v4l2_rect        w;
48 	__u32			field;	/* enum v4l2_field */
49 	__u32			chromakey;
50 	compat_caddr_t		clips; /* actually struct v4l2_clip32 * */
51 	__u32			clipcount;
52 	compat_caddr_t		bitmap;
53 	__u8                    global_alpha;
54 };
55 
56 static int get_v4l2_window32(struct v4l2_window *p64,
57 			     struct v4l2_window32 __user *p32)
58 {
59 	struct v4l2_window32 w32;
60 
61 	if (copy_from_user(&w32, p32, sizeof(w32)))
62 		return -EFAULT;
63 
64 	*p64 = (struct v4l2_window) {
65 		.w		= w32.w,
66 		.field		= w32.field,
67 		.chromakey	= w32.chromakey,
68 		.clips		= (void __force *)compat_ptr(w32.clips),
69 		.clipcount	= w32.clipcount,
70 		.bitmap		= compat_ptr(w32.bitmap),
71 		.global_alpha	= w32.global_alpha,
72 	};
73 
74 	if (p64->clipcount > 2048)
75 		return -EINVAL;
76 	if (!p64->clipcount)
77 		p64->clips = NULL;
78 
79 	return 0;
80 }
81 
82 static int put_v4l2_window32(struct v4l2_window *p64,
83 			     struct v4l2_window32 __user *p32)
84 {
85 	struct v4l2_window32 w32;
86 
87 	memset(&w32, 0, sizeof(w32));
88 	w32 = (struct v4l2_window32) {
89 		.w		= p64->w,
90 		.field		= p64->field,
91 		.chromakey	= p64->chromakey,
92 		.clips		= (uintptr_t)p64->clips,
93 		.clipcount	= p64->clipcount,
94 		.bitmap		= ptr_to_compat(p64->bitmap),
95 		.global_alpha	= p64->global_alpha,
96 	};
97 
98 	/* copy everything except the clips pointer */
99 	if (copy_to_user(p32, &w32, offsetof(struct v4l2_window32, clips)) ||
100 	    copy_to_user(&p32->clipcount, &w32.clipcount,
101 			 sizeof(w32) - offsetof(struct v4l2_window32, clipcount)))
102 		return -EFAULT;
103 
104 	return 0;
105 }
106 
107 struct v4l2_format32 {
108 	__u32	type;	/* enum v4l2_buf_type */
109 	union {
110 		struct v4l2_pix_format	pix;
111 		struct v4l2_pix_format_mplane	pix_mp;
112 		struct v4l2_window32	win;
113 		struct v4l2_vbi_format	vbi;
114 		struct v4l2_sliced_vbi_format	sliced;
115 		struct v4l2_sdr_format	sdr;
116 		struct v4l2_meta_format	meta;
117 		__u8	raw_data[200];        /* user-defined */
118 	} fmt;
119 };
120 
121 /**
122  * struct v4l2_create_buffers32 - VIDIOC_CREATE_BUFS32 argument
123  * @index:	on return, index of the first created buffer
124  * @count:	entry: number of requested buffers,
125  *		return: number of created buffers
126  * @memory:	buffer memory type
127  * @format:	frame format, for which buffers are requested
128  * @capabilities: capabilities of this buffer type.
129  * @flags:	additional buffer management attributes (ignored unless the
130  *		queue has V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS capability and
131  *		configured for MMAP streaming I/O).
132  * @reserved:	future extensions
133  */
134 struct v4l2_create_buffers32 {
135 	__u32			index;
136 	__u32			count;
137 	__u32			memory;	/* enum v4l2_memory */
138 	struct v4l2_format32	format;
139 	__u32			capabilities;
140 	__u32			flags;
141 	__u32			reserved[6];
142 };
143 
144 static int get_v4l2_format32(struct v4l2_format *p64,
145 			     struct v4l2_format32 __user *p32)
146 {
147 	if (get_user(p64->type, &p32->type))
148 		return -EFAULT;
149 
150 	switch (p64->type) {
151 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
152 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
153 		return copy_from_user(&p64->fmt.pix, &p32->fmt.pix,
154 				      sizeof(p64->fmt.pix)) ? -EFAULT : 0;
155 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
156 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
157 		return copy_from_user(&p64->fmt.pix_mp, &p32->fmt.pix_mp,
158 				      sizeof(p64->fmt.pix_mp)) ? -EFAULT : 0;
159 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
160 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
161 		return get_v4l2_window32(&p64->fmt.win, &p32->fmt.win);
162 	case V4L2_BUF_TYPE_VBI_CAPTURE:
163 	case V4L2_BUF_TYPE_VBI_OUTPUT:
164 		return copy_from_user(&p64->fmt.vbi, &p32->fmt.vbi,
165 				      sizeof(p64->fmt.vbi)) ? -EFAULT : 0;
166 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
167 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
168 		return copy_from_user(&p64->fmt.sliced, &p32->fmt.sliced,
169 				      sizeof(p64->fmt.sliced)) ? -EFAULT : 0;
170 	case V4L2_BUF_TYPE_SDR_CAPTURE:
171 	case V4L2_BUF_TYPE_SDR_OUTPUT:
172 		return copy_from_user(&p64->fmt.sdr, &p32->fmt.sdr,
173 				      sizeof(p64->fmt.sdr)) ? -EFAULT : 0;
174 	case V4L2_BUF_TYPE_META_CAPTURE:
175 	case V4L2_BUF_TYPE_META_OUTPUT:
176 		return copy_from_user(&p64->fmt.meta, &p32->fmt.meta,
177 				      sizeof(p64->fmt.meta)) ? -EFAULT : 0;
178 	default:
179 		return -EINVAL;
180 	}
181 }
182 
183 static int get_v4l2_create32(struct v4l2_create_buffers *p64,
184 			     struct v4l2_create_buffers32 __user *p32)
185 {
186 	if (copy_from_user(p64, p32,
187 			   offsetof(struct v4l2_create_buffers32, format)))
188 		return -EFAULT;
189 	if (copy_from_user(&p64->flags, &p32->flags, sizeof(p32->flags)))
190 		return -EFAULT;
191 	return get_v4l2_format32(&p64->format, &p32->format);
192 }
193 
194 static int put_v4l2_format32(struct v4l2_format *p64,
195 			     struct v4l2_format32 __user *p32)
196 {
197 	switch (p64->type) {
198 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
199 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
200 		return copy_to_user(&p32->fmt.pix, &p64->fmt.pix,
201 				    sizeof(p64->fmt.pix)) ? -EFAULT : 0;
202 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
203 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
204 		return copy_to_user(&p32->fmt.pix_mp, &p64->fmt.pix_mp,
205 				    sizeof(p64->fmt.pix_mp)) ? -EFAULT : 0;
206 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
207 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
208 		return put_v4l2_window32(&p64->fmt.win, &p32->fmt.win);
209 	case V4L2_BUF_TYPE_VBI_CAPTURE:
210 	case V4L2_BUF_TYPE_VBI_OUTPUT:
211 		return copy_to_user(&p32->fmt.vbi, &p64->fmt.vbi,
212 				    sizeof(p64->fmt.vbi)) ? -EFAULT : 0;
213 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
214 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
215 		return copy_to_user(&p32->fmt.sliced, &p64->fmt.sliced,
216 				    sizeof(p64->fmt.sliced)) ? -EFAULT : 0;
217 	case V4L2_BUF_TYPE_SDR_CAPTURE:
218 	case V4L2_BUF_TYPE_SDR_OUTPUT:
219 		return copy_to_user(&p32->fmt.sdr, &p64->fmt.sdr,
220 				    sizeof(p64->fmt.sdr)) ? -EFAULT : 0;
221 	case V4L2_BUF_TYPE_META_CAPTURE:
222 	case V4L2_BUF_TYPE_META_OUTPUT:
223 		return copy_to_user(&p32->fmt.meta, &p64->fmt.meta,
224 				    sizeof(p64->fmt.meta)) ? -EFAULT : 0;
225 	default:
226 		return -EINVAL;
227 	}
228 }
229 
230 static int put_v4l2_create32(struct v4l2_create_buffers *p64,
231 			     struct v4l2_create_buffers32 __user *p32)
232 {
233 	if (copy_to_user(p32, p64,
234 			 offsetof(struct v4l2_create_buffers32, format)) ||
235 	    put_user(p64->capabilities, &p32->capabilities) ||
236 	    put_user(p64->flags, &p32->flags) ||
237 	    copy_to_user(p32->reserved, p64->reserved, sizeof(p64->reserved)))
238 		return -EFAULT;
239 	return put_v4l2_format32(&p64->format, &p32->format);
240 }
241 
242 struct v4l2_standard32 {
243 	__u32		     index;
244 	compat_u64	     id;
245 	__u8		     name[24];
246 	struct v4l2_fract    frameperiod; /* Frames, not fields */
247 	__u32		     framelines;
248 	__u32		     reserved[4];
249 };
250 
251 static int get_v4l2_standard32(struct v4l2_standard *p64,
252 			       struct v4l2_standard32 __user *p32)
253 {
254 	/* other fields are not set by the user, nor used by the driver */
255 	return get_user(p64->index, &p32->index);
256 }
257 
258 static int put_v4l2_standard32(struct v4l2_standard *p64,
259 			       struct v4l2_standard32 __user *p32)
260 {
261 	if (put_user(p64->index, &p32->index) ||
262 	    put_user(p64->id, &p32->id) ||
263 	    copy_to_user(p32->name, p64->name, sizeof(p32->name)) ||
264 	    copy_to_user(&p32->frameperiod, &p64->frameperiod,
265 			 sizeof(p32->frameperiod)) ||
266 	    put_user(p64->framelines, &p32->framelines) ||
267 	    copy_to_user(p32->reserved, p64->reserved, sizeof(p32->reserved)))
268 		return -EFAULT;
269 	return 0;
270 }
271 
272 struct v4l2_plane32 {
273 	__u32			bytesused;
274 	__u32			length;
275 	union {
276 		__u32		mem_offset;
277 		compat_long_t	userptr;
278 		__s32		fd;
279 	} m;
280 	__u32			data_offset;
281 	__u32			reserved[11];
282 };
283 
284 /*
285  * This is correct for all architectures including i386, but not x32,
286  * which has different alignment requirements for timestamp
287  */
288 struct v4l2_buffer32 {
289 	__u32			index;
290 	__u32			type;	/* enum v4l2_buf_type */
291 	__u32			bytesused;
292 	__u32			flags;
293 	__u32			field;	/* enum v4l2_field */
294 	struct {
295 		compat_s64	tv_sec;
296 		compat_s64	tv_usec;
297 	}			timestamp;
298 	struct v4l2_timecode	timecode;
299 	__u32			sequence;
300 
301 	/* memory location */
302 	__u32			memory;	/* enum v4l2_memory */
303 	union {
304 		__u32           offset;
305 		compat_long_t   userptr;
306 		compat_caddr_t  planes;
307 		__s32		fd;
308 	} m;
309 	__u32			length;
310 	__u32			reserved2;
311 	__s32			request_fd;
312 };
313 
314 #ifdef CONFIG_COMPAT_32BIT_TIME
315 struct v4l2_buffer32_time32 {
316 	__u32			index;
317 	__u32			type;	/* enum v4l2_buf_type */
318 	__u32			bytesused;
319 	__u32			flags;
320 	__u32			field;	/* enum v4l2_field */
321 	struct old_timeval32	timestamp;
322 	struct v4l2_timecode	timecode;
323 	__u32			sequence;
324 
325 	/* memory location */
326 	__u32			memory;	/* enum v4l2_memory */
327 	union {
328 		__u32           offset;
329 		compat_long_t   userptr;
330 		compat_caddr_t  planes;
331 		__s32		fd;
332 	} m;
333 	__u32			length;
334 	__u32			reserved2;
335 	__s32			request_fd;
336 };
337 #endif
338 
339 static int get_v4l2_plane32(struct v4l2_plane *p64,
340 			    struct v4l2_plane32 __user *p32,
341 			    enum v4l2_memory memory)
342 {
343 	struct v4l2_plane32 plane32;
344 	typeof(p64->m) m = {};
345 
346 	if (copy_from_user(&plane32, p32, sizeof(plane32)))
347 		return -EFAULT;
348 
349 	switch (memory) {
350 	case V4L2_MEMORY_MMAP:
351 	case V4L2_MEMORY_OVERLAY:
352 		m.mem_offset = plane32.m.mem_offset;
353 		break;
354 	case V4L2_MEMORY_USERPTR:
355 		m.userptr = (unsigned long)compat_ptr(plane32.m.userptr);
356 		break;
357 	case V4L2_MEMORY_DMABUF:
358 		m.fd = plane32.m.fd;
359 		break;
360 	}
361 
362 	memset(p64, 0, sizeof(*p64));
363 	*p64 = (struct v4l2_plane) {
364 		.bytesused	= plane32.bytesused,
365 		.length		= plane32.length,
366 		.m		= m,
367 		.data_offset	= plane32.data_offset,
368 	};
369 
370 	return 0;
371 }
372 
373 static int put_v4l2_plane32(struct v4l2_plane *p64,
374 			    struct v4l2_plane32 __user *p32,
375 			    enum v4l2_memory memory)
376 {
377 	struct v4l2_plane32 plane32;
378 
379 	memset(&plane32, 0, sizeof(plane32));
380 	plane32 = (struct v4l2_plane32) {
381 		.bytesused	= p64->bytesused,
382 		.length		= p64->length,
383 		.data_offset	= p64->data_offset,
384 	};
385 
386 	switch (memory) {
387 	case V4L2_MEMORY_MMAP:
388 	case V4L2_MEMORY_OVERLAY:
389 		plane32.m.mem_offset = p64->m.mem_offset;
390 		break;
391 	case V4L2_MEMORY_USERPTR:
392 		plane32.m.userptr = (uintptr_t)(p64->m.userptr);
393 		break;
394 	case V4L2_MEMORY_DMABUF:
395 		plane32.m.fd = p64->m.fd;
396 		break;
397 	}
398 
399 	if (copy_to_user(p32, &plane32, sizeof(plane32)))
400 		return -EFAULT;
401 
402 	return 0;
403 }
404 
405 static int get_v4l2_buffer32(struct v4l2_buffer *vb,
406 			     struct v4l2_buffer32 __user *arg)
407 {
408 	struct v4l2_buffer32 vb32;
409 
410 	if (copy_from_user(&vb32, arg, sizeof(vb32)))
411 		return -EFAULT;
412 
413 	memset(vb, 0, sizeof(*vb));
414 	*vb = (struct v4l2_buffer) {
415 		.index		= vb32.index,
416 		.type		= vb32.type,
417 		.bytesused	= vb32.bytesused,
418 		.flags		= vb32.flags,
419 		.field		= vb32.field,
420 		.timestamp.tv_sec	= vb32.timestamp.tv_sec,
421 		.timestamp.tv_usec	= vb32.timestamp.tv_usec,
422 		.timecode	= vb32.timecode,
423 		.sequence	= vb32.sequence,
424 		.memory		= vb32.memory,
425 		.m.offset	= vb32.m.offset,
426 		.length		= vb32.length,
427 		.request_fd	= vb32.request_fd,
428 	};
429 
430 	switch (vb->memory) {
431 	case V4L2_MEMORY_MMAP:
432 	case V4L2_MEMORY_OVERLAY:
433 		vb->m.offset = vb32.m.offset;
434 		break;
435 	case V4L2_MEMORY_USERPTR:
436 		vb->m.userptr = (unsigned long)compat_ptr(vb32.m.userptr);
437 		break;
438 	case V4L2_MEMORY_DMABUF:
439 		vb->m.fd = vb32.m.fd;
440 		break;
441 	}
442 
443 	if (V4L2_TYPE_IS_MULTIPLANAR(vb->type))
444 		vb->m.planes = (void __force *)
445 				compat_ptr(vb32.m.planes);
446 
447 	return 0;
448 }
449 
450 #ifdef CONFIG_COMPAT_32BIT_TIME
451 static int get_v4l2_buffer32_time32(struct v4l2_buffer *vb,
452 				    struct v4l2_buffer32_time32 __user *arg)
453 {
454 	struct v4l2_buffer32_time32 vb32;
455 
456 	if (copy_from_user(&vb32, arg, sizeof(vb32)))
457 		return -EFAULT;
458 
459 	*vb = (struct v4l2_buffer) {
460 		.index		= vb32.index,
461 		.type		= vb32.type,
462 		.bytesused	= vb32.bytesused,
463 		.flags		= vb32.flags,
464 		.field		= vb32.field,
465 		.timestamp.tv_sec	= vb32.timestamp.tv_sec,
466 		.timestamp.tv_usec	= vb32.timestamp.tv_usec,
467 		.timecode	= vb32.timecode,
468 		.sequence	= vb32.sequence,
469 		.memory		= vb32.memory,
470 		.m.offset	= vb32.m.offset,
471 		.length		= vb32.length,
472 		.request_fd	= vb32.request_fd,
473 	};
474 	switch (vb->memory) {
475 	case V4L2_MEMORY_MMAP:
476 	case V4L2_MEMORY_OVERLAY:
477 		vb->m.offset = vb32.m.offset;
478 		break;
479 	case V4L2_MEMORY_USERPTR:
480 		vb->m.userptr = (unsigned long)compat_ptr(vb32.m.userptr);
481 		break;
482 	case V4L2_MEMORY_DMABUF:
483 		vb->m.fd = vb32.m.fd;
484 		break;
485 	}
486 
487 	if (V4L2_TYPE_IS_MULTIPLANAR(vb->type))
488 		vb->m.planes = (void __force *)
489 				compat_ptr(vb32.m.planes);
490 
491 	return 0;
492 }
493 #endif
494 
495 static int put_v4l2_buffer32(struct v4l2_buffer *vb,
496 			     struct v4l2_buffer32 __user *arg)
497 {
498 	struct v4l2_buffer32 vb32;
499 
500 	memset(&vb32, 0, sizeof(vb32));
501 	vb32 = (struct v4l2_buffer32) {
502 		.index		= vb->index,
503 		.type		= vb->type,
504 		.bytesused	= vb->bytesused,
505 		.flags		= vb->flags,
506 		.field		= vb->field,
507 		.timestamp.tv_sec	= vb->timestamp.tv_sec,
508 		.timestamp.tv_usec	= vb->timestamp.tv_usec,
509 		.timecode	= vb->timecode,
510 		.sequence	= vb->sequence,
511 		.memory		= vb->memory,
512 		.m.offset	= vb->m.offset,
513 		.length		= vb->length,
514 		.request_fd	= vb->request_fd,
515 	};
516 
517 	switch (vb->memory) {
518 	case V4L2_MEMORY_MMAP:
519 	case V4L2_MEMORY_OVERLAY:
520 		vb32.m.offset = vb->m.offset;
521 		break;
522 	case V4L2_MEMORY_USERPTR:
523 		vb32.m.userptr = (uintptr_t)(vb->m.userptr);
524 		break;
525 	case V4L2_MEMORY_DMABUF:
526 		vb32.m.fd = vb->m.fd;
527 		break;
528 	}
529 
530 	if (V4L2_TYPE_IS_MULTIPLANAR(vb->type))
531 		vb32.m.planes = (uintptr_t)vb->m.planes;
532 
533 	if (copy_to_user(arg, &vb32, sizeof(vb32)))
534 		return -EFAULT;
535 
536 	return 0;
537 }
538 
539 #ifdef CONFIG_COMPAT_32BIT_TIME
540 static int put_v4l2_buffer32_time32(struct v4l2_buffer *vb,
541 				    struct v4l2_buffer32_time32 __user *arg)
542 {
543 	struct v4l2_buffer32_time32 vb32;
544 
545 	memset(&vb32, 0, sizeof(vb32));
546 	vb32 = (struct v4l2_buffer32_time32) {
547 		.index		= vb->index,
548 		.type		= vb->type,
549 		.bytesused	= vb->bytesused,
550 		.flags		= vb->flags,
551 		.field		= vb->field,
552 		.timestamp.tv_sec	= vb->timestamp.tv_sec,
553 		.timestamp.tv_usec	= vb->timestamp.tv_usec,
554 		.timecode	= vb->timecode,
555 		.sequence	= vb->sequence,
556 		.memory		= vb->memory,
557 		.m.offset	= vb->m.offset,
558 		.length		= vb->length,
559 		.request_fd	= vb->request_fd,
560 	};
561 	switch (vb->memory) {
562 	case V4L2_MEMORY_MMAP:
563 	case V4L2_MEMORY_OVERLAY:
564 		vb32.m.offset = vb->m.offset;
565 		break;
566 	case V4L2_MEMORY_USERPTR:
567 		vb32.m.userptr = (uintptr_t)(vb->m.userptr);
568 		break;
569 	case V4L2_MEMORY_DMABUF:
570 		vb32.m.fd = vb->m.fd;
571 		break;
572 	}
573 
574 	if (V4L2_TYPE_IS_MULTIPLANAR(vb->type))
575 		vb32.m.planes = (uintptr_t)vb->m.planes;
576 
577 	if (copy_to_user(arg, &vb32, sizeof(vb32)))
578 		return -EFAULT;
579 
580 	return 0;
581 }
582 #endif
583 
584 struct v4l2_framebuffer32 {
585 	__u32			capability;
586 	__u32			flags;
587 	compat_caddr_t		base;
588 	struct {
589 		__u32		width;
590 		__u32		height;
591 		__u32		pixelformat;
592 		__u32		field;
593 		__u32		bytesperline;
594 		__u32		sizeimage;
595 		__u32		colorspace;
596 		__u32		priv;
597 	} fmt;
598 };
599 
600 static int get_v4l2_framebuffer32(struct v4l2_framebuffer *p64,
601 				  struct v4l2_framebuffer32 __user *p32)
602 {
603 	compat_caddr_t tmp;
604 
605 	if (get_user(tmp, &p32->base) ||
606 	    get_user(p64->capability, &p32->capability) ||
607 	    get_user(p64->flags, &p32->flags) ||
608 	    copy_from_user(&p64->fmt, &p32->fmt, sizeof(p64->fmt)))
609 		return -EFAULT;
610 	p64->base = (void __force *)compat_ptr(tmp);
611 
612 	return 0;
613 }
614 
615 static int put_v4l2_framebuffer32(struct v4l2_framebuffer *p64,
616 				  struct v4l2_framebuffer32 __user *p32)
617 {
618 	if (put_user((uintptr_t)p64->base, &p32->base) ||
619 	    put_user(p64->capability, &p32->capability) ||
620 	    put_user(p64->flags, &p32->flags) ||
621 	    copy_to_user(&p32->fmt, &p64->fmt, sizeof(p64->fmt)))
622 		return -EFAULT;
623 
624 	return 0;
625 }
626 
627 struct v4l2_input32 {
628 	__u32	     index;		/*  Which input */
629 	__u8	     name[32];		/*  Label */
630 	__u32	     type;		/*  Type of input */
631 	__u32	     audioset;		/*  Associated audios (bitfield) */
632 	__u32        tuner;             /*  Associated tuner */
633 	compat_u64   std;
634 	__u32	     status;
635 	__u32	     capabilities;
636 	__u32	     reserved[3];
637 };
638 
639 /*
640  * The 64-bit v4l2_input struct has extra padding at the end of the struct.
641  * Otherwise it is identical to the 32-bit version.
642  */
643 static inline int get_v4l2_input32(struct v4l2_input *p64,
644 				   struct v4l2_input32 __user *p32)
645 {
646 	if (copy_from_user(p64, p32, sizeof(*p32)))
647 		return -EFAULT;
648 	return 0;
649 }
650 
651 static inline int put_v4l2_input32(struct v4l2_input *p64,
652 				   struct v4l2_input32 __user *p32)
653 {
654 	if (copy_to_user(p32, p64, sizeof(*p32)))
655 		return -EFAULT;
656 	return 0;
657 }
658 
659 struct v4l2_ext_controls32 {
660 	__u32 which;
661 	__u32 count;
662 	__u32 error_idx;
663 	__s32 request_fd;
664 	__u32 reserved[1];
665 	compat_caddr_t controls; /* actually struct v4l2_ext_control32 * */
666 };
667 
668 struct v4l2_ext_control32 {
669 	__u32 id;
670 	__u32 size;
671 	__u32 reserved2[1];
672 	union {
673 		__s32 value;
674 		__s64 value64;
675 		compat_caddr_t string; /* actually char * */
676 	};
677 } __attribute__ ((packed));
678 
679 /* Return true if this control is a pointer type. */
680 static inline bool ctrl_is_pointer(struct file *file, u32 id)
681 {
682 	struct video_device *vdev = video_devdata(file);
683 	struct v4l2_fh *fh = NULL;
684 	struct v4l2_ctrl_handler *hdl = NULL;
685 	struct v4l2_query_ext_ctrl qec = { id };
686 	const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops;
687 
688 	if (test_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags))
689 		fh = file->private_data;
690 
691 	if (fh && fh->ctrl_handler)
692 		hdl = fh->ctrl_handler;
693 	else if (vdev->ctrl_handler)
694 		hdl = vdev->ctrl_handler;
695 
696 	if (hdl) {
697 		struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, id);
698 
699 		return ctrl && ctrl->is_ptr;
700 	}
701 
702 	if (!ops || !ops->vidioc_query_ext_ctrl)
703 		return false;
704 
705 	return !ops->vidioc_query_ext_ctrl(file, fh, &qec) &&
706 		(qec.flags & V4L2_CTRL_FLAG_HAS_PAYLOAD);
707 }
708 
709 static int get_v4l2_ext_controls32(struct v4l2_ext_controls *p64,
710 				   struct v4l2_ext_controls32 __user *p32)
711 {
712 	struct v4l2_ext_controls32 ec32;
713 
714 	if (copy_from_user(&ec32, p32, sizeof(ec32)))
715 		return -EFAULT;
716 
717 	*p64 = (struct v4l2_ext_controls) {
718 		.which		= ec32.which,
719 		.count		= ec32.count,
720 		.error_idx	= ec32.error_idx,
721 		.request_fd	= ec32.request_fd,
722 		.reserved[0]	= ec32.reserved[0],
723 		.controls	= (void __force *)compat_ptr(ec32.controls),
724 	};
725 
726 	return 0;
727 }
728 
729 static int put_v4l2_ext_controls32(struct v4l2_ext_controls *p64,
730 				   struct v4l2_ext_controls32 __user *p32)
731 {
732 	struct v4l2_ext_controls32 ec32;
733 
734 	memset(&ec32, 0, sizeof(ec32));
735 	ec32 = (struct v4l2_ext_controls32) {
736 		.which		= p64->which,
737 		.count		= p64->count,
738 		.error_idx	= p64->error_idx,
739 		.request_fd	= p64->request_fd,
740 		.reserved[0]	= p64->reserved[0],
741 		.controls	= (uintptr_t)p64->controls,
742 	};
743 
744 	if (copy_to_user(p32, &ec32, sizeof(ec32)))
745 		return -EFAULT;
746 
747 	return 0;
748 }
749 
750 #ifdef CONFIG_X86_64
751 /*
752  * x86 is the only compat architecture with different struct alignment
753  * between 32-bit and 64-bit tasks.
754  */
755 struct v4l2_event32 {
756 	__u32				type;
757 	union {
758 		compat_s64		value64;
759 		__u8			data[64];
760 	} u;
761 	__u32				pending;
762 	__u32				sequence;
763 	struct {
764 		compat_s64		tv_sec;
765 		compat_s64		tv_nsec;
766 	} timestamp;
767 	__u32				id;
768 	__u32				reserved[8];
769 };
770 
771 static int put_v4l2_event32(struct v4l2_event *p64,
772 			    struct v4l2_event32 __user *p32)
773 {
774 	if (put_user(p64->type, &p32->type) ||
775 	    copy_to_user(&p32->u, &p64->u, sizeof(p64->u)) ||
776 	    put_user(p64->pending, &p32->pending) ||
777 	    put_user(p64->sequence, &p32->sequence) ||
778 	    put_user(p64->timestamp.tv_sec, &p32->timestamp.tv_sec) ||
779 	    put_user(p64->timestamp.tv_nsec, &p32->timestamp.tv_nsec) ||
780 	    put_user(p64->id, &p32->id) ||
781 	    copy_to_user(p32->reserved, p64->reserved, sizeof(p32->reserved)))
782 		return -EFAULT;
783 	return 0;
784 }
785 
786 #endif
787 
788 #ifdef CONFIG_COMPAT_32BIT_TIME
789 struct v4l2_event32_time32 {
790 	__u32				type;
791 	union {
792 		compat_s64		value64;
793 		__u8			data[64];
794 	} u;
795 	__u32				pending;
796 	__u32				sequence;
797 	struct old_timespec32		timestamp;
798 	__u32				id;
799 	__u32				reserved[8];
800 };
801 
802 static int put_v4l2_event32_time32(struct v4l2_event *p64,
803 				   struct v4l2_event32_time32 __user *p32)
804 {
805 	if (put_user(p64->type, &p32->type) ||
806 	    copy_to_user(&p32->u, &p64->u, sizeof(p64->u)) ||
807 	    put_user(p64->pending, &p32->pending) ||
808 	    put_user(p64->sequence, &p32->sequence) ||
809 	    put_user(p64->timestamp.tv_sec, &p32->timestamp.tv_sec) ||
810 	    put_user(p64->timestamp.tv_nsec, &p32->timestamp.tv_nsec) ||
811 	    put_user(p64->id, &p32->id) ||
812 	    copy_to_user(p32->reserved, p64->reserved, sizeof(p32->reserved)))
813 		return -EFAULT;
814 	return 0;
815 }
816 #endif
817 
818 struct v4l2_edid32 {
819 	__u32 pad;
820 	__u32 start_block;
821 	__u32 blocks;
822 	__u32 reserved[5];
823 	compat_caddr_t edid;
824 };
825 
826 static int get_v4l2_edid32(struct v4l2_edid *p64,
827 			   struct v4l2_edid32 __user *p32)
828 {
829 	compat_uptr_t edid;
830 
831 	if (copy_from_user(p64, p32, offsetof(struct v4l2_edid32, edid)) ||
832 	    get_user(edid, &p32->edid))
833 		return -EFAULT;
834 
835 	p64->edid = (void __force *)compat_ptr(edid);
836 	return 0;
837 }
838 
839 static int put_v4l2_edid32(struct v4l2_edid *p64,
840 			   struct v4l2_edid32 __user *p32)
841 {
842 	if (copy_to_user(p32, p64, offsetof(struct v4l2_edid32, edid)))
843 		return -EFAULT;
844 	return 0;
845 }
846 
847 /*
848  * List of ioctls that require 32-bits/64-bits conversion
849  *
850  * The V4L2 ioctls that aren't listed there don't have pointer arguments
851  * and the struct size is identical for both 32 and 64 bits versions, so
852  * they don't need translations.
853  */
854 
855 #define VIDIOC_G_FMT32		_IOWR('V',  4, struct v4l2_format32)
856 #define VIDIOC_S_FMT32		_IOWR('V',  5, struct v4l2_format32)
857 #define VIDIOC_QUERYBUF32	_IOWR('V',  9, struct v4l2_buffer32)
858 #define VIDIOC_G_FBUF32		_IOR ('V', 10, struct v4l2_framebuffer32)
859 #define VIDIOC_S_FBUF32		_IOW ('V', 11, struct v4l2_framebuffer32)
860 #define VIDIOC_QBUF32		_IOWR('V', 15, struct v4l2_buffer32)
861 #define VIDIOC_DQBUF32		_IOWR('V', 17, struct v4l2_buffer32)
862 #define VIDIOC_ENUMSTD32	_IOWR('V', 25, struct v4l2_standard32)
863 #define VIDIOC_ENUMINPUT32	_IOWR('V', 26, struct v4l2_input32)
864 #define VIDIOC_G_EDID32		_IOWR('V', 40, struct v4l2_edid32)
865 #define VIDIOC_S_EDID32		_IOWR('V', 41, struct v4l2_edid32)
866 #define VIDIOC_TRY_FMT32	_IOWR('V', 64, struct v4l2_format32)
867 #define VIDIOC_G_EXT_CTRLS32    _IOWR('V', 71, struct v4l2_ext_controls32)
868 #define VIDIOC_S_EXT_CTRLS32    _IOWR('V', 72, struct v4l2_ext_controls32)
869 #define VIDIOC_TRY_EXT_CTRLS32  _IOWR('V', 73, struct v4l2_ext_controls32)
870 #define	VIDIOC_DQEVENT32	_IOR ('V', 89, struct v4l2_event32)
871 #define VIDIOC_CREATE_BUFS32	_IOWR('V', 92, struct v4l2_create_buffers32)
872 #define VIDIOC_PREPARE_BUF32	_IOWR('V', 93, struct v4l2_buffer32)
873 
874 #ifdef CONFIG_COMPAT_32BIT_TIME
875 #define VIDIOC_QUERYBUF32_TIME32	_IOWR('V',  9, struct v4l2_buffer32_time32)
876 #define VIDIOC_QBUF32_TIME32		_IOWR('V', 15, struct v4l2_buffer32_time32)
877 #define VIDIOC_DQBUF32_TIME32		_IOWR('V', 17, struct v4l2_buffer32_time32)
878 #define	VIDIOC_DQEVENT32_TIME32		_IOR ('V', 89, struct v4l2_event32_time32)
879 #define VIDIOC_PREPARE_BUF32_TIME32	_IOWR('V', 93, struct v4l2_buffer32_time32)
880 #endif
881 
882 unsigned int v4l2_compat_translate_cmd(unsigned int cmd)
883 {
884 	switch (cmd) {
885 	case VIDIOC_G_FMT32:
886 		return VIDIOC_G_FMT;
887 	case VIDIOC_S_FMT32:
888 		return VIDIOC_S_FMT;
889 	case VIDIOC_TRY_FMT32:
890 		return VIDIOC_TRY_FMT;
891 	case VIDIOC_G_FBUF32:
892 		return VIDIOC_G_FBUF;
893 	case VIDIOC_S_FBUF32:
894 		return VIDIOC_S_FBUF;
895 #ifdef CONFIG_COMPAT_32BIT_TIME
896 	case VIDIOC_QUERYBUF32_TIME32:
897 		return VIDIOC_QUERYBUF;
898 	case VIDIOC_QBUF32_TIME32:
899 		return VIDIOC_QBUF;
900 	case VIDIOC_DQBUF32_TIME32:
901 		return VIDIOC_DQBUF;
902 	case VIDIOC_PREPARE_BUF32_TIME32:
903 		return VIDIOC_PREPARE_BUF;
904 #endif
905 	case VIDIOC_QUERYBUF32:
906 		return VIDIOC_QUERYBUF;
907 	case VIDIOC_QBUF32:
908 		return VIDIOC_QBUF;
909 	case VIDIOC_DQBUF32:
910 		return VIDIOC_DQBUF;
911 	case VIDIOC_CREATE_BUFS32:
912 		return VIDIOC_CREATE_BUFS;
913 	case VIDIOC_G_EXT_CTRLS32:
914 		return VIDIOC_G_EXT_CTRLS;
915 	case VIDIOC_S_EXT_CTRLS32:
916 		return VIDIOC_S_EXT_CTRLS;
917 	case VIDIOC_TRY_EXT_CTRLS32:
918 		return VIDIOC_TRY_EXT_CTRLS;
919 	case VIDIOC_PREPARE_BUF32:
920 		return VIDIOC_PREPARE_BUF;
921 	case VIDIOC_ENUMSTD32:
922 		return VIDIOC_ENUMSTD;
923 	case VIDIOC_ENUMINPUT32:
924 		return VIDIOC_ENUMINPUT;
925 	case VIDIOC_G_EDID32:
926 		return VIDIOC_G_EDID;
927 	case VIDIOC_S_EDID32:
928 		return VIDIOC_S_EDID;
929 #ifdef CONFIG_X86_64
930 	case VIDIOC_DQEVENT32:
931 		return VIDIOC_DQEVENT;
932 #endif
933 #ifdef CONFIG_COMPAT_32BIT_TIME
934 	case VIDIOC_DQEVENT32_TIME32:
935 		return VIDIOC_DQEVENT;
936 #endif
937 	}
938 	return cmd;
939 }
940 
941 int v4l2_compat_get_user(void __user *arg, void *parg, unsigned int cmd)
942 {
943 	switch (cmd) {
944 	case VIDIOC_G_FMT32:
945 	case VIDIOC_S_FMT32:
946 	case VIDIOC_TRY_FMT32:
947 		return get_v4l2_format32(parg, arg);
948 
949 	case VIDIOC_S_FBUF32:
950 		return get_v4l2_framebuffer32(parg, arg);
951 #ifdef CONFIG_COMPAT_32BIT_TIME
952 	case VIDIOC_QUERYBUF32_TIME32:
953 	case VIDIOC_QBUF32_TIME32:
954 	case VIDIOC_DQBUF32_TIME32:
955 	case VIDIOC_PREPARE_BUF32_TIME32:
956 		return get_v4l2_buffer32_time32(parg, arg);
957 #endif
958 	case VIDIOC_QUERYBUF32:
959 	case VIDIOC_QBUF32:
960 	case VIDIOC_DQBUF32:
961 	case VIDIOC_PREPARE_BUF32:
962 		return get_v4l2_buffer32(parg, arg);
963 
964 	case VIDIOC_G_EXT_CTRLS32:
965 	case VIDIOC_S_EXT_CTRLS32:
966 	case VIDIOC_TRY_EXT_CTRLS32:
967 		return get_v4l2_ext_controls32(parg, arg);
968 
969 	case VIDIOC_CREATE_BUFS32:
970 		return get_v4l2_create32(parg, arg);
971 
972 	case VIDIOC_ENUMSTD32:
973 		return get_v4l2_standard32(parg, arg);
974 
975 	case VIDIOC_ENUMINPUT32:
976 		return get_v4l2_input32(parg, arg);
977 
978 	case VIDIOC_G_EDID32:
979 	case VIDIOC_S_EDID32:
980 		return get_v4l2_edid32(parg, arg);
981 	}
982 	return 0;
983 }
984 
985 int v4l2_compat_put_user(void __user *arg, void *parg, unsigned int cmd)
986 {
987 	switch (cmd) {
988 	case VIDIOC_G_FMT32:
989 	case VIDIOC_S_FMT32:
990 	case VIDIOC_TRY_FMT32:
991 		return put_v4l2_format32(parg, arg);
992 
993 	case VIDIOC_G_FBUF32:
994 		return put_v4l2_framebuffer32(parg, arg);
995 #ifdef CONFIG_COMPAT_32BIT_TIME
996 	case VIDIOC_QUERYBUF32_TIME32:
997 	case VIDIOC_QBUF32_TIME32:
998 	case VIDIOC_DQBUF32_TIME32:
999 	case VIDIOC_PREPARE_BUF32_TIME32:
1000 		return put_v4l2_buffer32_time32(parg, arg);
1001 #endif
1002 	case VIDIOC_QUERYBUF32:
1003 	case VIDIOC_QBUF32:
1004 	case VIDIOC_DQBUF32:
1005 	case VIDIOC_PREPARE_BUF32:
1006 		return put_v4l2_buffer32(parg, arg);
1007 
1008 	case VIDIOC_G_EXT_CTRLS32:
1009 	case VIDIOC_S_EXT_CTRLS32:
1010 	case VIDIOC_TRY_EXT_CTRLS32:
1011 		return put_v4l2_ext_controls32(parg, arg);
1012 
1013 	case VIDIOC_CREATE_BUFS32:
1014 		return put_v4l2_create32(parg, arg);
1015 
1016 	case VIDIOC_ENUMSTD32:
1017 		return put_v4l2_standard32(parg, arg);
1018 
1019 	case VIDIOC_ENUMINPUT32:
1020 		return put_v4l2_input32(parg, arg);
1021 
1022 	case VIDIOC_G_EDID32:
1023 	case VIDIOC_S_EDID32:
1024 		return put_v4l2_edid32(parg, arg);
1025 #ifdef CONFIG_X86_64
1026 	case VIDIOC_DQEVENT32:
1027 		return put_v4l2_event32(parg, arg);
1028 #endif
1029 #ifdef CONFIG_COMPAT_32BIT_TIME
1030 	case VIDIOC_DQEVENT32_TIME32:
1031 		return put_v4l2_event32_time32(parg, arg);
1032 #endif
1033 	}
1034 	return 0;
1035 }
1036 
1037 int v4l2_compat_get_array_args(struct file *file, void *mbuf,
1038 			       void __user *user_ptr, size_t array_size,
1039 			       unsigned int cmd, void *arg)
1040 {
1041 	int err = 0;
1042 
1043 	memset(mbuf, 0, array_size);
1044 
1045 	switch (cmd) {
1046 	case VIDIOC_G_FMT32:
1047 	case VIDIOC_S_FMT32:
1048 	case VIDIOC_TRY_FMT32: {
1049 		struct v4l2_format *f64 = arg;
1050 		struct v4l2_clip *c64 = mbuf;
1051 		struct v4l2_clip32 __user *c32 = user_ptr;
1052 		u32 clipcount = f64->fmt.win.clipcount;
1053 
1054 		if ((f64->type != V4L2_BUF_TYPE_VIDEO_OVERLAY &&
1055 		     f64->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY) ||
1056 		    clipcount == 0)
1057 			return 0;
1058 		if (clipcount > 2048)
1059 			return -EINVAL;
1060 		while (clipcount--) {
1061 			if (copy_from_user(c64, c32, sizeof(c64->c)))
1062 				return -EFAULT;
1063 			c64->next = NULL;
1064 			c64++;
1065 			c32++;
1066 		}
1067 		break;
1068 	}
1069 #ifdef CONFIG_COMPAT_32BIT_TIME
1070 	case VIDIOC_QUERYBUF32_TIME32:
1071 	case VIDIOC_QBUF32_TIME32:
1072 	case VIDIOC_DQBUF32_TIME32:
1073 	case VIDIOC_PREPARE_BUF32_TIME32:
1074 #endif
1075 	case VIDIOC_QUERYBUF32:
1076 	case VIDIOC_QBUF32:
1077 	case VIDIOC_DQBUF32:
1078 	case VIDIOC_PREPARE_BUF32: {
1079 		struct v4l2_buffer *b64 = arg;
1080 		struct v4l2_plane *p64 = mbuf;
1081 		struct v4l2_plane32 __user *p32 = user_ptr;
1082 
1083 		if (V4L2_TYPE_IS_MULTIPLANAR(b64->type)) {
1084 			u32 num_planes = b64->length;
1085 
1086 			if (num_planes == 0)
1087 				return 0;
1088 
1089 			while (num_planes--) {
1090 				err = get_v4l2_plane32(p64, p32, b64->memory);
1091 				if (err)
1092 					return err;
1093 				++p64;
1094 				++p32;
1095 			}
1096 		}
1097 		break;
1098 	}
1099 	case VIDIOC_G_EXT_CTRLS32:
1100 	case VIDIOC_S_EXT_CTRLS32:
1101 	case VIDIOC_TRY_EXT_CTRLS32: {
1102 		struct v4l2_ext_controls *ecs64 = arg;
1103 		struct v4l2_ext_control *ec64 = mbuf;
1104 		struct v4l2_ext_control32 __user *ec32 = user_ptr;
1105 		int n;
1106 
1107 		for (n = 0; n < ecs64->count; n++) {
1108 			if (copy_from_user(ec64, ec32, sizeof(*ec32)))
1109 				return -EFAULT;
1110 
1111 			if (ctrl_is_pointer(file, ec64->id)) {
1112 				compat_uptr_t p;
1113 
1114 				if (get_user(p, &ec32->string))
1115 					return -EFAULT;
1116 				ec64->string = compat_ptr(p);
1117 			}
1118 			ec32++;
1119 			ec64++;
1120 		}
1121 		break;
1122 	}
1123 	default:
1124 		if (copy_from_user(mbuf, user_ptr, array_size))
1125 			err = -EFAULT;
1126 		break;
1127 	}
1128 
1129 	return err;
1130 }
1131 
1132 int v4l2_compat_put_array_args(struct file *file, void __user *user_ptr,
1133 			       void *mbuf, size_t array_size,
1134 			       unsigned int cmd, void *arg)
1135 {
1136 	int err = 0;
1137 
1138 	switch (cmd) {
1139 	case VIDIOC_G_FMT32:
1140 	case VIDIOC_S_FMT32:
1141 	case VIDIOC_TRY_FMT32: {
1142 		struct v4l2_format *f64 = arg;
1143 		struct v4l2_clip *c64 = mbuf;
1144 		struct v4l2_clip32 __user *c32 = user_ptr;
1145 		u32 clipcount = f64->fmt.win.clipcount;
1146 
1147 		if ((f64->type != V4L2_BUF_TYPE_VIDEO_OVERLAY &&
1148 		     f64->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY) ||
1149 		    clipcount == 0)
1150 			return 0;
1151 		if (clipcount > 2048)
1152 			return -EINVAL;
1153 		while (clipcount--) {
1154 			if (copy_to_user(c32, c64, sizeof(c64->c)))
1155 				return -EFAULT;
1156 			c64++;
1157 			c32++;
1158 		}
1159 		break;
1160 	}
1161 #ifdef CONFIG_COMPAT_32BIT_TIME
1162 	case VIDIOC_QUERYBUF32_TIME32:
1163 	case VIDIOC_QBUF32_TIME32:
1164 	case VIDIOC_DQBUF32_TIME32:
1165 	case VIDIOC_PREPARE_BUF32_TIME32:
1166 #endif
1167 	case VIDIOC_QUERYBUF32:
1168 	case VIDIOC_QBUF32:
1169 	case VIDIOC_DQBUF32:
1170 	case VIDIOC_PREPARE_BUF32: {
1171 		struct v4l2_buffer *b64 = arg;
1172 		struct v4l2_plane *p64 = mbuf;
1173 		struct v4l2_plane32 __user *p32 = user_ptr;
1174 
1175 		if (V4L2_TYPE_IS_MULTIPLANAR(b64->type)) {
1176 			u32 num_planes = b64->length;
1177 
1178 			if (num_planes == 0)
1179 				return 0;
1180 
1181 			while (num_planes--) {
1182 				err = put_v4l2_plane32(p64, p32, b64->memory);
1183 				if (err)
1184 					return err;
1185 				++p64;
1186 				++p32;
1187 			}
1188 		}
1189 		break;
1190 	}
1191 	case VIDIOC_G_EXT_CTRLS32:
1192 	case VIDIOC_S_EXT_CTRLS32:
1193 	case VIDIOC_TRY_EXT_CTRLS32: {
1194 		struct v4l2_ext_controls *ecs64 = arg;
1195 		struct v4l2_ext_control *ec64 = mbuf;
1196 		struct v4l2_ext_control32 __user *ec32 = user_ptr;
1197 		int n;
1198 
1199 		for (n = 0; n < ecs64->count; n++) {
1200 			unsigned int size = sizeof(*ec32);
1201 			/*
1202 			 * Do not modify the pointer when copying a pointer
1203 			 * control.  The contents of the pointer was changed,
1204 			 * not the pointer itself.
1205 			 * The structures are otherwise compatible.
1206 			 */
1207 			if (ctrl_is_pointer(file, ec64->id))
1208 				size -= sizeof(ec32->value64);
1209 
1210 			if (copy_to_user(ec32, ec64, size))
1211 				return -EFAULT;
1212 
1213 			ec32++;
1214 			ec64++;
1215 		}
1216 		break;
1217 	}
1218 	default:
1219 		if (copy_to_user(user_ptr, mbuf, array_size))
1220 			err = -EFAULT;
1221 		break;
1222 	}
1223 
1224 	return err;
1225 }
1226 
1227 /**
1228  * v4l2_compat_ioctl32() - Handles a compat32 ioctl call
1229  *
1230  * @file: pointer to &struct file with the file handler
1231  * @cmd: ioctl to be called
1232  * @arg: arguments passed from/to the ioctl handler
1233  *
1234  * This function is meant to be used as .compat_ioctl fops at v4l2-dev.c
1235  * in order to deal with 32-bit calls on a 64-bits Kernel.
1236  *
1237  * This function calls do_video_ioctl() for non-private V4L2 ioctls.
1238  * If the function is a private one it calls vdev->fops->compat_ioctl32
1239  * instead.
1240  */
1241 long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
1242 {
1243 	struct video_device *vdev = video_devdata(file);
1244 	long ret = -ENOIOCTLCMD;
1245 
1246 	if (!file->f_op->unlocked_ioctl)
1247 		return ret;
1248 
1249 	if (!video_is_registered(vdev))
1250 		return -ENODEV;
1251 
1252 	if (_IOC_TYPE(cmd) == 'V' && _IOC_NR(cmd) < BASE_VIDIOC_PRIVATE)
1253 		ret = file->f_op->unlocked_ioctl(file, cmd,
1254 					(unsigned long)compat_ptr(arg));
1255 	else if (vdev->fops->compat_ioctl32)
1256 		ret = vdev->fops->compat_ioctl32(file, cmd, arg);
1257 
1258 	if (ret == -ENOIOCTLCMD)
1259 		pr_debug("compat_ioctl32: unknown ioctl '%c', dir=%d, #%d (0x%08x)\n",
1260 			 _IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd), cmd);
1261 	return ret;
1262 }
1263 EXPORT_SYMBOL_GPL(v4l2_compat_ioctl32);
1264