diff options
-rw-r--r-- | drivers/media/video/compat_ioctl32.c | 388 |
1 files changed, 376 insertions, 12 deletions
diff --git a/drivers/media/video/compat_ioctl32.c b/drivers/media/video/compat_ioctl32.c index 5472d36d73ff..4b14942dd91c 100644 --- a/drivers/media/video/compat_ioctl32.c +++ b/drivers/media/video/compat_ioctl32.c | |||
@@ -1,6 +1,21 @@ | |||
1 | /* | ||
2 | * ioctl32.c: Conversion between 32bit and 64bit native ioctls. | ||
3 | * Separated from fs stuff by Arnd Bergmann <arnd@arndb.de> | ||
4 | * | ||
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 | * | ||
11 | * These routines maintain argument size conversion between 32bit and 64bit | ||
12 | * ioctls. | ||
13 | */ | ||
14 | |||
1 | #include <linux/config.h> | 15 | #include <linux/config.h> |
2 | #include <linux/compat.h> | 16 | #include <linux/compat.h> |
3 | #include <linux/videodev.h> | 17 | #include <linux/videodev.h> |
18 | #include <linux/videodev2.h> | ||
4 | #include <linux/module.h> | 19 | #include <linux/module.h> |
5 | #include <linux/smp_lock.h> | 20 | #include <linux/smp_lock.h> |
6 | 21 | ||
@@ -15,12 +30,9 @@ struct video_tuner32 { | |||
15 | 30 | ||
16 | static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up) | 31 | static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up) |
17 | { | 32 | { |
18 | int i; | ||
19 | |||
20 | if(get_user(kp->tuner, &up->tuner)) | 33 | if(get_user(kp->tuner, &up->tuner)) |
21 | return -EFAULT; | 34 | return -EFAULT; |
22 | for(i = 0; i < 32; i++) | 35 | __copy_from_user(kp->name, up->name, 32); |
23 | __get_user(kp->name[i], &up->name[i]); | ||
24 | __get_user(kp->rangelow, &up->rangelow); | 36 | __get_user(kp->rangelow, &up->rangelow); |
25 | __get_user(kp->rangehigh, &up->rangehigh); | 37 | __get_user(kp->rangehigh, &up->rangehigh); |
26 | __get_user(kp->flags, &up->flags); | 38 | __get_user(kp->flags, &up->flags); |
@@ -31,12 +43,9 @@ static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user | |||
31 | 43 | ||
32 | static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up) | 44 | static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up) |
33 | { | 45 | { |
34 | int i; | ||
35 | |||
36 | if(put_user(kp->tuner, &up->tuner)) | 46 | if(put_user(kp->tuner, &up->tuner)) |
37 | return -EFAULT; | 47 | return -EFAULT; |
38 | for(i = 0; i < 32; i++) | 48 | __copy_to_user(up->name, kp->name, 32); |
39 | __put_user(kp->name[i], &up->name[i]); | ||
40 | __put_user(kp->rangelow, &up->rangelow); | 49 | __put_user(kp->rangelow, &up->rangelow); |
41 | __put_user(kp->rangehigh, &up->rangehigh); | 50 | __put_user(kp->rangehigh, &up->rangehigh); |
42 | __put_user(kp->flags, &up->flags); | 51 | __put_user(kp->flags, &up->flags); |
@@ -123,6 +132,265 @@ static int put_video_window32(struct video_window *kp, struct video_window32 __u | |||
123 | return 0; | 132 | return 0; |
124 | } | 133 | } |
125 | 134 | ||
135 | struct v4l2_clip32 | ||
136 | { | ||
137 | struct v4l2_rect c; | ||
138 | compat_caddr_t next; | ||
139 | }; | ||
140 | |||
141 | struct v4l2_window32 | ||
142 | { | ||
143 | struct v4l2_rect w; | ||
144 | enum v4l2_field field; | ||
145 | __u32 chromakey; | ||
146 | compat_caddr_t clips; /* actually struct v4l2_clip32 * */ | ||
147 | __u32 clipcount; | ||
148 | compat_caddr_t bitmap; | ||
149 | }; | ||
150 | |||
151 | static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up) | ||
152 | { | ||
153 | if (copy_from_user(&kp->w, &up->w, sizeof(up->w))) | ||
154 | return -EFAULT; | ||
155 | __get_user(kp->field, &up->field); | ||
156 | __get_user(kp->chromakey, &up->chromakey); | ||
157 | __get_user(kp->clipcount, &up->clipcount); | ||
158 | if (kp->clipcount > 2048) | ||
159 | return -EINVAL; | ||
160 | if (kp->clipcount) { | ||
161 | struct v4l2_clip32 *uclips = compat_ptr(up->clips); | ||
162 | struct v4l2_clip *kclips; | ||
163 | int n = kp->clipcount; | ||
164 | |||
165 | kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip)); | ||
166 | kp->clips = kclips; | ||
167 | while (--n >= 0) { | ||
168 | copy_from_user(&kclips->c, &uclips->c, sizeof(uclips->c)); | ||
169 | kclips->next = n ? kclips + 1 : 0; | ||
170 | uclips += 1; | ||
171 | kclips += 1; | ||
172 | } | ||
173 | } else | ||
174 | kp->clips = 0; | ||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up) | ||
179 | { | ||
180 | if (copy_to_user(&up->w, &kp->w, sizeof(up->w))) | ||
181 | return -EFAULT; | ||
182 | __put_user(kp->field, &up->field); | ||
183 | __put_user(kp->chromakey, &up->chromakey); | ||
184 | __put_user(kp->clipcount, &up->clipcount); | ||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) | ||
189 | { | ||
190 | return copy_from_user(kp, up, sizeof(struct v4l2_pix_format)); | ||
191 | } | ||
192 | |||
193 | static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) | ||
194 | { | ||
195 | return copy_to_user(up, kp, sizeof(struct v4l2_pix_format)); | ||
196 | } | ||
197 | |||
198 | static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) | ||
199 | { | ||
200 | return copy_from_user(kp, up, sizeof(struct v4l2_vbi_format)); | ||
201 | } | ||
202 | |||
203 | static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) | ||
204 | { | ||
205 | return copy_to_user(up, kp, sizeof(struct v4l2_vbi_format)); | ||
206 | } | ||
207 | |||
208 | struct v4l2_format32 | ||
209 | { | ||
210 | enum v4l2_buf_type type; | ||
211 | union | ||
212 | { | ||
213 | struct v4l2_pix_format pix; // V4L2_BUF_TYPE_VIDEO_CAPTURE | ||
214 | struct v4l2_window32 win; // V4L2_BUF_TYPE_VIDEO_OVERLAY | ||
215 | struct v4l2_vbi_format vbi; // V4L2_BUF_TYPE_VBI_CAPTURE | ||
216 | __u8 raw_data[200]; // user-defined | ||
217 | } fmt; | ||
218 | }; | ||
219 | |||
220 | static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up) | ||
221 | { | ||
222 | if(get_user(kp->type, &up->type)) | ||
223 | return -EFAULT; | ||
224 | switch (kp->type) { | ||
225 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
226 | return get_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix); | ||
227 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | ||
228 | return get_v4l2_window32(&kp->fmt.win, &up->fmt.win); | ||
229 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
230 | return get_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi); | ||
231 | default: | ||
232 | printk("compat_ioctl : unexpected VIDIOC_FMT type %d\n", | ||
233 | kp->type); | ||
234 | return -ENXIO; | ||
235 | } | ||
236 | } | ||
237 | |||
238 | static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up) | ||
239 | { | ||
240 | if(put_user(kp->type, &up->type)) | ||
241 | return -EFAULT; | ||
242 | switch (kp->type) { | ||
243 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
244 | return put_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix); | ||
245 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | ||
246 | return put_v4l2_window32(&kp->fmt.win, &up->fmt.win); | ||
247 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
248 | return put_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi); | ||
249 | default: | ||
250 | return -ENXIO; | ||
251 | } | ||
252 | } | ||
253 | |||
254 | struct v4l2_standard32 | ||
255 | { | ||
256 | __u32 index; | ||
257 | __u32 id[2]; /* __u64 would get the alignment wrong */ | ||
258 | __u8 name[24]; | ||
259 | struct v4l2_fract frameperiod; /* Frames, not fields */ | ||
260 | __u32 framelines; | ||
261 | __u32 reserved[4]; | ||
262 | }; | ||
263 | |||
264 | static int get_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up) | ||
265 | { | ||
266 | /* other fields are not set by the user, nor used by the driver */ | ||
267 | return get_user(kp->index, &up->index); | ||
268 | } | ||
269 | |||
270 | static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up) | ||
271 | { | ||
272 | if(put_user(kp->index, &up->index)) | ||
273 | return -EFAULT; | ||
274 | __copy_to_user(up->id, &kp->id, sizeof(__u64)); | ||
275 | __copy_to_user(up->name, kp->name, 24); | ||
276 | __put_user(kp->frameperiod, &up->frameperiod); | ||
277 | __put_user(kp->framelines, &up->framelines); | ||
278 | __copy_to_user(up->reserved, kp->reserved, 4 * sizeof(__u32)); | ||
279 | return 0; | ||
280 | } | ||
281 | |||
282 | struct v4l2_buffer32 | ||
283 | { | ||
284 | __u32 index; | ||
285 | enum v4l2_buf_type type; | ||
286 | __u32 bytesused; | ||
287 | __u32 flags; | ||
288 | enum v4l2_field field; | ||
289 | struct compat_timeval timestamp; | ||
290 | struct v4l2_timecode timecode; | ||
291 | __u32 sequence; | ||
292 | |||
293 | /* memory location */ | ||
294 | enum v4l2_memory memory; | ||
295 | union { | ||
296 | __u32 offset; | ||
297 | compat_long_t userptr; | ||
298 | } m; | ||
299 | __u32 length; | ||
300 | __u32 input; | ||
301 | __u32 reserved; | ||
302 | }; | ||
303 | |||
304 | static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up) | ||
305 | { | ||
306 | |||
307 | if (get_user(kp->index, &up->index)) | ||
308 | return -EFAULT; | ||
309 | __get_user(kp->type, &up->type); | ||
310 | __get_user(kp->flags, &up->flags); | ||
311 | __get_user(kp->memory, &up->memory); | ||
312 | __get_user(kp->input, &up->input); | ||
313 | switch(kp->memory) { | ||
314 | case V4L2_MEMORY_MMAP: | ||
315 | break; | ||
316 | case V4L2_MEMORY_USERPTR: | ||
317 | { | ||
318 | unsigned long tmp = (unsigned long)compat_ptr(up->m.userptr); | ||
319 | |||
320 | __get_user(kp->length, &up->length); | ||
321 | __get_user(kp->m.userptr, &tmp); | ||
322 | } | ||
323 | break; | ||
324 | case V4L2_MEMORY_OVERLAY: | ||
325 | __get_user(kp->m.offset, &up->m.offset); | ||
326 | break; | ||
327 | } | ||
328 | return 0; | ||
329 | } | ||
330 | |||
331 | static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up) | ||
332 | { | ||
333 | if (put_user(kp->index, &up->index)) | ||
334 | return -EFAULT; | ||
335 | __put_user(kp->type, &up->type); | ||
336 | __put_user(kp->flags, &up->flags); | ||
337 | __put_user(kp->memory, &up->memory); | ||
338 | __put_user(kp->input, &up->input); | ||
339 | switch(kp->memory) { | ||
340 | case V4L2_MEMORY_MMAP: | ||
341 | __put_user(kp->length, &up->length); | ||
342 | __put_user(kp->m.offset, &up->m.offset); | ||
343 | break; | ||
344 | case V4L2_MEMORY_USERPTR: | ||
345 | __put_user(kp->length, &up->length); | ||
346 | __put_user(kp->m.userptr, &up->m.userptr); | ||
347 | break; | ||
348 | case V4L2_MEMORY_OVERLAY: | ||
349 | __put_user(kp->m.offset, &up->m.offset); | ||
350 | break; | ||
351 | } | ||
352 | __put_user(kp->bytesused, &up->bytesused); | ||
353 | __put_user(kp->field, &up->field); | ||
354 | __put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec); | ||
355 | __put_user(kp->timestamp.tv_usec, &up->timestamp.tv_usec); | ||
356 | __copy_to_user(&up->timecode, &kp->timecode, sizeof(struct v4l2_timecode)); | ||
357 | __put_user(kp->sequence, &up->sequence); | ||
358 | __put_user(kp->reserved, &up->reserved); | ||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | struct v4l2_framebuffer32 | ||
363 | { | ||
364 | __u32 capability; | ||
365 | __u32 flags; | ||
366 | compat_caddr_t base; | ||
367 | struct v4l2_pix_format fmt; | ||
368 | }; | ||
369 | |||
370 | static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up) | ||
371 | { | ||
372 | u32 tmp = (u32)((unsigned long)kp->base); | ||
373 | |||
374 | if(put_user(tmp, &up->base)) | ||
375 | return -EFAULT; | ||
376 | __put_user(kp->capability, &up->capability); | ||
377 | __put_user(kp->flags, &up->flags); | ||
378 | put_v4l2_pix_format(&kp->fmt, &up->fmt); | ||
379 | return 0; | ||
380 | } | ||
381 | |||
382 | struct v4l2_input32 /* identical layout, but different size */ | ||
383 | { | ||
384 | __u32 index; /* Which input */ | ||
385 | __u8 name[32]; /* Label */ | ||
386 | __u32 type; /* Type of input */ | ||
387 | __u32 audioset; /* Associated audios (bitfield) */ | ||
388 | __u32 tuner; /* Associated tuner */ | ||
389 | __u32 std[2]; /* __u64 would get the padding wrong */ | ||
390 | __u32 status; | ||
391 | __u32 reserved[4]; | ||
392 | }; | ||
393 | |||
126 | #define VIDIOCGTUNER32 _IOWR('v',4, struct video_tuner32) | 394 | #define VIDIOCGTUNER32 _IOWR('v',4, struct video_tuner32) |
127 | #define VIDIOCSTUNER32 _IOW('v',5, struct video_tuner32) | 395 | #define VIDIOCSTUNER32 _IOW('v',5, struct video_tuner32) |
128 | #define VIDIOCGWIN32 _IOR('v',9, struct video_window32) | 396 | #define VIDIOCGWIN32 _IOR('v',9, struct video_window32) |
@@ -132,6 +400,24 @@ static int put_video_window32(struct video_window *kp, struct video_window32 __u | |||
132 | #define VIDIOCGFREQ32 _IOR('v',14, u32) | 400 | #define VIDIOCGFREQ32 _IOR('v',14, u32) |
133 | #define VIDIOCSFREQ32 _IOW('v',15, u32) | 401 | #define VIDIOCSFREQ32 _IOW('v',15, u32) |
134 | 402 | ||
403 | #define VIDIOC_G_FMT32 _IOWR ('V', 4, struct v4l2_format32) | ||
404 | #define VIDIOC_S_FMT32 _IOWR ('V', 5, struct v4l2_format32) | ||
405 | #define VIDIOC_QUERYBUF32 _IOWR ('V', 9, struct v4l2_buffer32) | ||
406 | #define VIDIOC_G_FBUF32 _IOR ('V', 10, struct v4l2_framebuffer32) | ||
407 | /* VIDIOC_OVERLAY is now _IOW, but was _IOWR */ | ||
408 | #define VIDIOC_OVERLAY32 _IOWR ('V', 14, compat_int_t) | ||
409 | #define VIDIOC_QBUF32 _IOWR ('V', 15, struct v4l2_buffer32) | ||
410 | #define VIDIOC_DQBUF32 _IOWR ('V', 17, struct v4l2_buffer32) | ||
411 | #define VIDIOC_STREAMON32 _IOW ('V', 18, compat_int_t) | ||
412 | #define VIDIOC_STREAMOFF32 _IOW ('V', 19, compat_int_t) | ||
413 | #define VIDIOC_ENUMSTD32 _IOWR ('V', 25, struct v4l2_standard32) | ||
414 | #define VIDIOC_ENUMINPUT32 _IOWR ('V', 26, struct v4l2_input32) | ||
415 | /* VIDIOC_S_CTRL is now _IOWR, but was _IOW */ | ||
416 | #define VIDIOC_S_CTRL32 _IOW ('V', 28, struct v4l2_control) | ||
417 | #define VIDIOC_G_INPUT32 _IOR ('V', 38, compat_int_t) | ||
418 | #define VIDIOC_S_INPUT32 _IOWR ('V', 39, compat_int_t) | ||
419 | #define VIDIOC_TRY_FMT32 _IOWR ('V', 64, struct v4l2_format32) | ||
420 | |||
135 | enum { | 421 | enum { |
136 | MaxClips = (~0U-sizeof(struct video_window))/sizeof(struct video_clip) | 422 | MaxClips = (~0U-sizeof(struct video_window))/sizeof(struct video_clip) |
137 | }; | 423 | }; |
@@ -198,10 +484,14 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg | |||
198 | struct video_tuner vt; | 484 | struct video_tuner vt; |
199 | struct video_buffer vb; | 485 | struct video_buffer vb; |
200 | struct video_window vw; | 486 | struct video_window vw; |
487 | struct v4l2_format v2f; | ||
488 | struct v4l2_buffer v2b; | ||
489 | struct v4l2_framebuffer v2fb; | ||
490 | struct v4l2_standard v2s; | ||
201 | unsigned long vx; | 491 | unsigned long vx; |
202 | } karg; | 492 | } karg; |
203 | mm_segment_t old_fs = get_fs(); | ||
204 | void __user *up = compat_ptr(arg); | 493 | void __user *up = compat_ptr(arg); |
494 | int compatible_arg = 1; | ||
205 | int err = 0; | 495 | int err = 0; |
206 | 496 | ||
207 | /* First, convert the command. */ | 497 | /* First, convert the command. */ |
@@ -213,29 +503,82 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg | |||
213 | case VIDIOCSFBUF32: cmd = VIDIOCSFBUF; break; | 503 | case VIDIOCSFBUF32: cmd = VIDIOCSFBUF; break; |
214 | case VIDIOCGFREQ32: cmd = VIDIOCGFREQ; break; | 504 | case VIDIOCGFREQ32: cmd = VIDIOCGFREQ; break; |
215 | case VIDIOCSFREQ32: cmd = VIDIOCSFREQ; break; | 505 | case VIDIOCSFREQ32: cmd = VIDIOCSFREQ; break; |
506 | case VIDIOC_G_FMT32: cmd = VIDIOC_G_FMT; break; | ||
507 | case VIDIOC_S_FMT32: cmd = VIDIOC_S_FMT; break; | ||
508 | case VIDIOC_QUERYBUF32: cmd = VIDIOC_QUERYBUF; break; | ||
509 | case VIDIOC_QBUF32: cmd = VIDIOC_QBUF; break; | ||
510 | case VIDIOC_DQBUF32: cmd = VIDIOC_DQBUF; break; | ||
511 | case VIDIOC_STREAMON32: cmd = VIDIOC_STREAMON; break; | ||
512 | case VIDIOC_STREAMOFF32: cmd = VIDIOC_STREAMOFF; break; | ||
513 | case VIDIOC_G_FBUF32: cmd = VIDIOC_G_FBUF; break; | ||
514 | case VIDIOC_OVERLAY32: cmd = VIDIOC_OVERLAY; break; | ||
515 | case VIDIOC_ENUMSTD32: cmd = VIDIOC_ENUMSTD; break; | ||
516 | case VIDIOC_ENUMINPUT32: cmd = VIDIOC_ENUMINPUT; break; | ||
517 | case VIDIOC_S_CTRL32: cmd = VIDIOC_S_CTRL; break; | ||
518 | case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break; | ||
519 | case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break; | ||
520 | case VIDIOC_TRY_FMT32: cmd = VIDIOC_TRY_FMT; break; | ||
216 | }; | 521 | }; |
217 | 522 | ||
218 | switch(cmd) { | 523 | switch(cmd) { |
219 | case VIDIOCSTUNER: | 524 | case VIDIOCSTUNER: |
220 | case VIDIOCGTUNER: | 525 | case VIDIOCGTUNER: |
221 | err = get_video_tuner32(&karg.vt, up); | 526 | err = get_video_tuner32(&karg.vt, up); |
527 | compatible_arg = 0; | ||
528 | |||
222 | break; | 529 | break; |
223 | 530 | ||
224 | case VIDIOCSFBUF: | 531 | case VIDIOCSFBUF: |
225 | err = get_video_buffer32(&karg.vb, up); | 532 | err = get_video_buffer32(&karg.vb, up); |
533 | compatible_arg = 0; | ||
226 | break; | 534 | break; |
227 | 535 | ||
228 | case VIDIOCSFREQ: | 536 | case VIDIOCSFREQ: |
537 | case VIDIOC_S_INPUT: | ||
538 | case VIDIOC_OVERLAY: | ||
229 | err = get_user(karg.vx, (u32 __user *)up); | 539 | err = get_user(karg.vx, (u32 __user *)up); |
540 | compatible_arg = 0; | ||
230 | break; | 541 | break; |
231 | }; | 542 | }; |
543 | |||
544 | case VIDIOC_G_FMT: | ||
545 | case VIDIOC_S_FMT: | ||
546 | case VIDIOC_TRY_FMT: | ||
547 | err = get_v4l2_format32(&karg.v2f, up); | ||
548 | compatible_arg = 0; | ||
549 | break; | ||
550 | |||
551 | case VIDIOC_QUERYBUF: | ||
552 | case VIDIOC_QBUF: | ||
553 | case VIDIOC_DQBUF: | ||
554 | err = get_v4l2_buffer32(&karg.v2b, up); | ||
555 | compatible_arg = 0; | ||
556 | break; | ||
557 | |||
558 | case VIDIOC_ENUMSTD: | ||
559 | err = get_v4l2_standard32(&karg.v2s, up); | ||
560 | compatible_arg = 0; | ||
561 | break; | ||
562 | |||
563 | case VIDIOCGWIN: | ||
564 | case VIDIOCGFBUF: | ||
565 | case VIDIOCGFREQ: | ||
566 | case VIDIOC_G_FBUF: | ||
567 | case VIDIOC_G_INPUT: | ||
568 | compatible_arg = 0; | ||
569 | |||
232 | if(err) | 570 | if(err) |
233 | goto out; | 571 | goto out; |
234 | 572 | ||
235 | set_fs(KERNEL_DS); | 573 | if(compatible_arg) |
236 | err = native_ioctl(file, cmd, (unsigned long)&karg); | 574 | err = sys_ioctl(fd, cmd, (unsigned long)up); |
237 | set_fs(old_fs); | 575 | else { |
576 | mm_segment_t old_fs = get_fs(); | ||
238 | 577 | ||
578 | set_fs(KERNEL_DS); | ||
579 | err = sys_ioctl(fd, cmd, (unsigned long)&karg); | ||
580 | set_fs(old_fs); | ||
581 | } | ||
239 | if(err == 0) { | 582 | if(err == 0) { |
240 | switch(cmd) { | 583 | switch(cmd) { |
241 | case VIDIOCGTUNER: | 584 | case VIDIOCGTUNER: |
@@ -250,7 +593,28 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg | |||
250 | err = put_video_buffer32(&karg.vb, up); | 593 | err = put_video_buffer32(&karg.vb, up); |
251 | break; | 594 | break; |
252 | 595 | ||
596 | case VIDIOC_G_FBUF: | ||
597 | err = put_v4l2_framebuffer32(&karg.v2fb, up); | ||
598 | break; | ||
599 | |||
600 | case VIDIOC_G_FMT: | ||
601 | case VIDIOC_S_FMT: | ||
602 | case VIDIOC_TRY_FMT: | ||
603 | err = put_v4l2_format32(&karg.v2f, up); | ||
604 | break; | ||
605 | |||
606 | case VIDIOC_QUERYBUF: | ||
607 | case VIDIOC_QBUF: | ||
608 | case VIDIOC_DQBUF: | ||
609 | err = put_v4l2_buffer32(&karg.v2b, up); | ||
610 | break; | ||
611 | |||
612 | case VIDIOC_ENUMSTD: | ||
613 | err = put_v4l2_standard32(&karg.v2s, up); | ||
614 | break; | ||
615 | |||
253 | case VIDIOCGFREQ: | 616 | case VIDIOCGFREQ: |
617 | case VIDIOC_G_INPUT: | ||
254 | err = put_user(((u32)karg.vx), (u32 __user *)up); | 618 | err = put_user(((u32)karg.vx), (u32 __user *)up); |
255 | break; | 619 | break; |
256 | }; | 620 | }; |