OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [media/] [video/] [compat_ioctl32.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
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
 
15
#include <linux/compat.h>
16
#include <linux/videodev.h>
17
#include <linux/videodev2.h>
18
#include <linux/module.h>
19
#include <linux/smp_lock.h>
20
#include <media/v4l2-common.h>
21
 
22
#ifdef CONFIG_COMPAT
23
 
24
#ifdef CONFIG_VIDEO_V4L1_COMPAT
25
struct video_tuner32 {
26
        compat_int_t tuner;
27
        char name[32];
28
        compat_ulong_t rangelow, rangehigh;
29
        u32 flags;      /* It is really u32 in videodev.h */
30
        u16 mode, signal;
31
};
32
 
33
static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up)
34
{
35
        if(!access_ok(VERIFY_READ, up, sizeof(struct video_tuner32)) ||
36
                get_user(kp->tuner, &up->tuner) ||
37
                copy_from_user(kp->name, up->name, 32) ||
38
                get_user(kp->rangelow, &up->rangelow) ||
39
                get_user(kp->rangehigh, &up->rangehigh) ||
40
                get_user(kp->flags, &up->flags) ||
41
                get_user(kp->mode, &up->mode) ||
42
                get_user(kp->signal, &up->signal))
43
                return -EFAULT;
44
        return 0;
45
}
46
 
47
static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up)
48
{
49
        if(!access_ok(VERIFY_WRITE, up, sizeof(struct video_tuner32)) ||
50
                put_user(kp->tuner, &up->tuner) ||
51
                copy_to_user(up->name, kp->name, 32) ||
52
                put_user(kp->rangelow, &up->rangelow) ||
53
                put_user(kp->rangehigh, &up->rangehigh) ||
54
                put_user(kp->flags, &up->flags) ||
55
                put_user(kp->mode, &up->mode) ||
56
                put_user(kp->signal, &up->signal))
57
                        return -EFAULT;
58
        return 0;
59
}
60
 
61
 
62
struct video_buffer32 {
63
        compat_caddr_t base;
64
        compat_int_t height, width, depth, bytesperline;
65
};
66
 
67
static int get_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up)
68
{
69
        u32 tmp;
70
 
71
        if (!access_ok(VERIFY_READ, up, sizeof(struct video_buffer32)) ||
72
                get_user(tmp, &up->base) ||
73
                get_user(kp->height, &up->height) ||
74
                get_user(kp->width, &up->width) ||
75
                get_user(kp->depth, &up->depth) ||
76
                get_user(kp->bytesperline, &up->bytesperline))
77
                        return -EFAULT;
78
 
79
        /* This is actually a physical address stored
80
         * as a void pointer.
81
         */
82
        kp->base = (void *)(unsigned long) tmp;
83
 
84
        return 0;
85
}
86
 
87
static int put_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up)
88
{
89
        u32 tmp = (u32)((unsigned long)kp->base);
90
 
91
        if(!access_ok(VERIFY_WRITE, up, sizeof(struct video_buffer32)) ||
92
                put_user(tmp, &up->base) ||
93
                put_user(kp->height, &up->height) ||
94
                put_user(kp->width, &up->width) ||
95
                put_user(kp->depth, &up->depth) ||
96
                put_user(kp->bytesperline, &up->bytesperline))
97
                        return -EFAULT;
98
        return 0;
99
}
100
 
101
struct video_clip32 {
102
        s32 x, y, width, height;        /* Its really s32 in videodev.h */
103
        compat_caddr_t next;
104
};
105
 
106
struct video_window32 {
107
        u32 x, y, width, height, chromakey, flags;
108
        compat_caddr_t clips;
109
        compat_int_t clipcount;
110
};
111
#endif
112
 
113
static int native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
114
{
115
        int ret = -ENOIOCTLCMD;
116
 
117
        if (file->f_op->unlocked_ioctl)
118
                ret = file->f_op->unlocked_ioctl(file, cmd, arg);
119
        else if (file->f_op->ioctl) {
120
                lock_kernel();
121
                ret = file->f_op->ioctl(file->f_path.dentry->d_inode, file, cmd, arg);
122
                unlock_kernel();
123
        }
124
 
125
        return ret;
126
}
127
 
128
 
129
#ifdef CONFIG_VIDEO_V4L1_COMPAT
130
/* You get back everything except the clips... */
131
static int put_video_window32(struct video_window *kp, struct video_window32 __user *up)
132
{
133
        if(!access_ok(VERIFY_WRITE, up, sizeof(struct video_window32)) ||
134
                put_user(kp->x, &up->x) ||
135
                put_user(kp->y, &up->y) ||
136
                put_user(kp->width, &up->width) ||
137
                put_user(kp->height, &up->height) ||
138
                put_user(kp->chromakey, &up->chromakey) ||
139
                put_user(kp->flags, &up->flags) ||
140
                put_user(kp->clipcount, &up->clipcount))
141
                        return -EFAULT;
142
        return 0;
143
}
144
#endif
145
 
146
struct v4l2_clip32
147
{
148
        struct v4l2_rect        c;
149
        compat_caddr_t          next;
150
};
151
 
152
struct v4l2_window32
153
{
154
        struct v4l2_rect        w;
155
        enum v4l2_field         field;
156
        __u32                   chromakey;
157
        compat_caddr_t          clips; /* actually struct v4l2_clip32 * */
158
        __u32                   clipcount;
159
        compat_caddr_t          bitmap;
160
};
161
 
162
static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up)
163
{
164
        if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_window32)) ||
165
                copy_from_user(&kp->w, &up->w, sizeof(up->w)) ||
166
                get_user(kp->field, &up->field) ||
167
                get_user(kp->chromakey, &up->chromakey) ||
168
                get_user(kp->clipcount, &up->clipcount))
169
                        return -EFAULT;
170
        if (kp->clipcount > 2048)
171
                return -EINVAL;
172
        if (kp->clipcount) {
173
                struct v4l2_clip32 __user *uclips;
174
                struct v4l2_clip __user *kclips;
175
                int n = kp->clipcount;
176
                compat_caddr_t p;
177
 
178
                if (get_user(p, &up->clips))
179
                        return -EFAULT;
180
                uclips = compat_ptr(p);
181
                kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip));
182
                kp->clips = kclips;
183
                while (--n >= 0) {
184
                        if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c)))
185
                                return -EFAULT;
186
                        if (put_user(n ? kclips + 1 : NULL, &kclips->next))
187
                                return -EFAULT;
188
                        uclips += 1;
189
                        kclips += 1;
190
                }
191
        } else
192
                kp->clips = NULL;
193
        return 0;
194
}
195
 
196
static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up)
197
{
198
        if (copy_to_user(&up->w, &kp->w, sizeof(up->w)) ||
199
                put_user(kp->field, &up->field) ||
200
                put_user(kp->chromakey, &up->chromakey) ||
201
                put_user(kp->clipcount, &up->clipcount))
202
                        return -EFAULT;
203
        return 0;
204
}
205
 
206
static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up)
207
{
208
        if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format)))
209
                return -EFAULT;
210
        return 0;
211
}
212
 
213
static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up)
214
{
215
        if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format)))
216
                return -EFAULT;
217
        return 0;
218
}
219
 
220
static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up)
221
{
222
        if (copy_from_user(kp, up, sizeof(struct v4l2_vbi_format)))
223
                return -EFAULT;
224
        return 0;
225
}
226
 
227
static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up)
228
{
229
        if (copy_to_user(up, kp, sizeof(struct v4l2_vbi_format)))
230
                return -EFAULT;
231
        return 0;
232
}
233
 
234
struct v4l2_format32
235
{
236
        enum v4l2_buf_type type;
237
        union
238
        {
239
                struct v4l2_pix_format  pix;  // V4L2_BUF_TYPE_VIDEO_CAPTURE
240
                struct v4l2_window32    win;  // V4L2_BUF_TYPE_VIDEO_OVERLAY
241
                struct v4l2_vbi_format  vbi;  // V4L2_BUF_TYPE_VBI_CAPTURE
242
                __u8    raw_data[200];        // user-defined
243
        } fmt;
244
};
245
 
246
static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
247
{
248
        if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
249
                        get_user(kp->type, &up->type))
250
                        return -EFAULT;
251
        switch (kp->type) {
252
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
253
                return get_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix);
254
        case V4L2_BUF_TYPE_VIDEO_OVERLAY:
255
                return get_v4l2_window32(&kp->fmt.win, &up->fmt.win);
256
        case V4L2_BUF_TYPE_VBI_CAPTURE:
257
                return get_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi);
258
        default:
259
                printk("compat_ioctl : unexpected VIDIOC_FMT type %d\n",
260
                                                                kp->type);
261
                return -ENXIO;
262
        }
263
}
264
 
265
static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
266
{
267
        if(!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
268
                put_user(kp->type, &up->type))
269
                return -EFAULT;
270
        switch (kp->type) {
271
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
272
                return put_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix);
273
        case V4L2_BUF_TYPE_VIDEO_OVERLAY:
274
                return put_v4l2_window32(&kp->fmt.win, &up->fmt.win);
275
        case V4L2_BUF_TYPE_VBI_CAPTURE:
276
                return put_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi);
277
        default:
278
                return -ENXIO;
279
        }
280
}
281
 
282
static inline int get_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up)
283
{
284
        if (copy_from_user(kp, up, sizeof(struct v4l2_standard)))
285
                return -EFAULT;
286
        return 0;
287
 
288
}
289
 
290
static inline int put_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up)
291
{
292
        if (copy_to_user(up, kp, sizeof(struct v4l2_standard)))
293
                return -EFAULT;
294
        return 0;
295
}
296
 
297
struct v4l2_standard32
298
{
299
        __u32                index;
300
        __u32                id[2]; /* __u64 would get the alignment wrong */
301
        __u8                 name[24];
302
        struct v4l2_fract    frameperiod; /* Frames, not fields */
303
        __u32                framelines;
304
        __u32                reserved[4];
305
};
306
 
307
static int get_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up)
308
{
309
        /* other fields are not set by the user, nor used by the driver */
310
        if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_standard32)) ||
311
                get_user(kp->index, &up->index))
312
                return -EFAULT;
313
        return 0;
314
}
315
 
316
static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up)
317
{
318
        if(!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard32)) ||
319
                put_user(kp->index, &up->index) ||
320
                copy_to_user(up->id, &kp->id, sizeof(__u64)) ||
321
                copy_to_user(up->name, kp->name, 24) ||
322
                copy_to_user(&up->frameperiod, &kp->frameperiod, sizeof(kp->frameperiod)) ||
323
                put_user(kp->framelines, &up->framelines) ||
324
                copy_to_user(up->reserved, kp->reserved, 4 * sizeof(__u32)))
325
                        return -EFAULT;
326
        return 0;
327
}
328
 
329
static inline int get_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up)
330
{
331
        if (copy_from_user(kp, up, sizeof(struct v4l2_tuner)))
332
                return -EFAULT;
333
        return 0;
334
 
335
}
336
 
337
static inline int put_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up)
338
{
339
        if (copy_to_user(up, kp, sizeof(struct v4l2_tuner)))
340
                return -EFAULT;
341
        return 0;
342
}
343
 
344
struct v4l2_buffer32
345
{
346
        __u32                   index;
347
        enum v4l2_buf_type      type;
348
        __u32                   bytesused;
349
        __u32                   flags;
350
        enum v4l2_field         field;
351
        struct compat_timeval   timestamp;
352
        struct v4l2_timecode    timecode;
353
        __u32                   sequence;
354
 
355
        /* memory location */
356
        enum v4l2_memory        memory;
357
        union {
358
                __u32           offset;
359
                compat_long_t   userptr;
360
        } m;
361
        __u32                   length;
362
        __u32                   input;
363
        __u32                   reserved;
364
};
365
 
366
static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up)
367
{
368
 
369
        if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_buffer32)) ||
370
                get_user(kp->index, &up->index) ||
371
                get_user(kp->type, &up->type) ||
372
                get_user(kp->flags, &up->flags) ||
373
                get_user(kp->memory, &up->memory) ||
374
                get_user(kp->input, &up->input))
375
                        return -EFAULT;
376
        switch(kp->memory) {
377
        case V4L2_MEMORY_MMAP:
378
                break;
379
        case V4L2_MEMORY_USERPTR:
380
                {
381
                compat_long_t tmp;
382
 
383
                if (get_user(kp->length, &up->length) ||
384
                    get_user(tmp, &up->m.userptr))
385
                        return -EFAULT;
386
 
387
                kp->m.userptr = (unsigned long)compat_ptr(tmp);
388
                }
389
                break;
390
        case V4L2_MEMORY_OVERLAY:
391
                if(get_user(kp->m.offset, &up->m.offset))
392
                        return -EFAULT;
393
                break;
394
        }
395
        return 0;
396
}
397
 
398
static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up)
399
{
400
        if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_buffer32)) ||
401
                put_user(kp->index, &up->index) ||
402
                put_user(kp->type, &up->type) ||
403
                put_user(kp->flags, &up->flags) ||
404
                put_user(kp->memory, &up->memory) ||
405
                put_user(kp->input, &up->input))
406
                        return -EFAULT;
407
        switch(kp->memory) {
408
        case V4L2_MEMORY_MMAP:
409
                if (put_user(kp->length, &up->length) ||
410
                        put_user(kp->m.offset, &up->m.offset))
411
                        return -EFAULT;
412
                break;
413
        case V4L2_MEMORY_USERPTR:
414
                if (put_user(kp->length, &up->length) ||
415
                        put_user(kp->m.userptr, &up->m.userptr))
416
                        return -EFAULT;
417
                break;
418
        case V4L2_MEMORY_OVERLAY:
419
                if (put_user(kp->m.offset, &up->m.offset))
420
                        return -EFAULT;
421
                break;
422
        }
423
        if (put_user(kp->bytesused, &up->bytesused) ||
424
                put_user(kp->field, &up->field) ||
425
                put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
426
                put_user(kp->timestamp.tv_usec, &up->timestamp.tv_usec) ||
427
                copy_to_user(&up->timecode, &kp->timecode, sizeof(struct v4l2_timecode)) ||
428
                put_user(kp->sequence, &up->sequence) ||
429
                put_user(kp->reserved, &up->reserved))
430
                        return -EFAULT;
431
        return 0;
432
}
433
 
434
struct v4l2_framebuffer32
435
{
436
        __u32                   capability;
437
        __u32                   flags;
438
        compat_caddr_t          base;
439
        struct v4l2_pix_format  fmt;
440
};
441
 
442
static int get_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up)
443
{
444
        u32 tmp;
445
 
446
        if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_framebuffer32)) ||
447
                get_user(tmp, &up->base) ||
448
                get_user(kp->capability, &up->capability) ||
449
                get_user(kp->flags, &up->flags))
450
                        return -EFAULT;
451
        kp->base = compat_ptr(tmp);
452
        get_v4l2_pix_format(&kp->fmt, &up->fmt);
453
        return 0;
454
}
455
 
456
static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up)
457
{
458
        u32 tmp = (u32)((unsigned long)kp->base);
459
 
460
        if(!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_framebuffer32)) ||
461
                put_user(tmp, &up->base) ||
462
                put_user(kp->capability, &up->capability) ||
463
                put_user(kp->flags, &up->flags))
464
                        return -EFAULT;
465
        put_v4l2_pix_format(&kp->fmt, &up->fmt);
466
        return 0;
467
}
468
 
469
static inline int get_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up)
470
{
471
        if (copy_from_user(kp, up, sizeof(struct v4l2_input) - 4))
472
                return -EFAULT;
473
        return 0;
474
}
475
 
476
static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up)
477
{
478
        if (copy_to_user(up, kp, sizeof(struct v4l2_input) - 4))
479
                return -EFAULT;
480
        return 0;
481
}
482
 
483
static inline int get_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up)
484
{
485
        if (copy_from_user(kp, up, sizeof(struct v4l2_input)))
486
                return -EFAULT;
487
        return 0;
488
}
489
 
490
static inline int put_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up)
491
{
492
        if (copy_to_user(up, kp, sizeof(struct v4l2_input)))
493
                return -EFAULT;
494
        return 0;
495
}
496
 
497
#ifdef CONFIG_VIDEO_V4L1_COMPAT
498
struct video_code32
499
{
500
        char            loadwhat[16];   /* name or tag of file being passed */
501
        compat_int_t    datasize;
502
        unsigned char   *data;
503
};
504
 
505
static inline int microcode32(struct video_code *kp, struct video_code32 __user *up)
506
{
507
        if(!access_ok(VERIFY_READ, up, sizeof(struct video_code32)) ||
508
                copy_from_user(kp->loadwhat, up->loadwhat, sizeof (up->loadwhat)) ||
509
                get_user(kp->datasize, &up->datasize) ||
510
                copy_from_user(kp->data, up->data, up->datasize))
511
                        return -EFAULT;
512
        return 0;
513
}
514
 
515
#define VIDIOCGTUNER32          _IOWR('v',4, struct video_tuner32)
516
#define VIDIOCSTUNER32          _IOW('v',5, struct video_tuner32)
517
#define VIDIOCGWIN32            _IOR('v',9, struct video_window32)
518
#define VIDIOCSWIN32            _IOW('v',10, struct video_window32)
519
#define VIDIOCGFBUF32           _IOR('v',11, struct video_buffer32)
520
#define VIDIOCSFBUF32           _IOW('v',12, struct video_buffer32)
521
#define VIDIOCGFREQ32           _IOR('v',14, u32)
522
#define VIDIOCSFREQ32           _IOW('v',15, u32)
523
#define VIDIOCSMICROCODE32      _IOW('v',27, struct video_code32)
524
 
525
#endif
526
 
527
/* VIDIOC_ENUMINPUT32 is VIDIOC_ENUMINPUT minus 4 bytes of padding alignement */
528
#define VIDIOC_ENUMINPUT32      VIDIOC_ENUMINPUT - _IOC(0, 0, 0, 4)
529
#define VIDIOC_G_FMT32          _IOWR ('V',  4, struct v4l2_format32)
530
#define VIDIOC_S_FMT32          _IOWR ('V',  5, struct v4l2_format32)
531
#define VIDIOC_QUERYBUF32       _IOWR ('V',  9, struct v4l2_buffer32)
532
#define VIDIOC_G_FBUF32         _IOR  ('V', 10, struct v4l2_framebuffer32)
533
#define VIDIOC_S_FBUF32         _IOW  ('V', 11, struct v4l2_framebuffer32)
534
/* VIDIOC_OVERLAY is now _IOW, but was _IOWR */
535
#define VIDIOC_OVERLAY32        _IOWR ('V', 14, compat_int_t)
536
#define VIDIOC_QBUF32           _IOWR ('V', 15, struct v4l2_buffer32)
537
#define VIDIOC_DQBUF32          _IOWR ('V', 17, struct v4l2_buffer32)
538
#define VIDIOC_STREAMON32       _IOW  ('V', 18, compat_int_t)
539
#define VIDIOC_STREAMOFF32      _IOW  ('V', 19, compat_int_t)
540
#define VIDIOC_ENUMSTD32        _IOWR ('V', 25, struct v4l2_standard32)
541
/* VIDIOC_S_CTRL is now _IOWR, but was _IOW */
542
#define VIDIOC_S_CTRL32         _IOW  ('V', 28, struct v4l2_control)
543
#define VIDIOC_G_INPUT32        _IOR  ('V', 38, compat_int_t)
544
#define VIDIOC_S_INPUT32        _IOWR ('V', 39, compat_int_t)
545
#define VIDIOC_TRY_FMT32        _IOWR ('V', 64, struct v4l2_format32)
546
 
547
#ifdef CONFIG_VIDEO_V4L1_COMPAT
548
enum {
549
        MaxClips = (~0U-sizeof(struct video_window))/sizeof(struct video_clip)
550
};
551
 
552
static int do_set_window(struct file *file, unsigned int cmd, unsigned long arg)
553
{
554
        struct video_window32 __user *up = compat_ptr(arg);
555
        struct video_window __user *vw;
556
        struct video_clip __user *p;
557
        int nclips;
558
        u32 n;
559
 
560
        if (!access_ok(VERIFY_READ, up, sizeof(struct video_window32)))
561
                return -EFAULT;
562
 
563
        if (get_user(nclips, &up->clipcount))
564
                return -EFAULT;
565
 
566
        /* Peculiar interface... */
567
        if (nclips < 0)
568
                nclips = VIDEO_CLIPMAP_SIZE;
569
 
570
        if (nclips > MaxClips)
571
                return -ENOMEM;
572
 
573
        vw = compat_alloc_user_space(sizeof(struct video_window) +
574
                                    nclips * sizeof(struct video_clip));
575
 
576
        p = nclips ? (struct video_clip __user *)(vw + 1) : NULL;
577
 
578
        if (get_user(n, &up->x) || put_user(n, &vw->x) ||
579
            get_user(n, &up->y) || put_user(n, &vw->y) ||
580
            get_user(n, &up->width) || put_user(n, &vw->width) ||
581
            get_user(n, &up->height) || put_user(n, &vw->height) ||
582
            get_user(n, &up->chromakey) || put_user(n, &vw->chromakey) ||
583
            get_user(n, &up->flags) || put_user(n, &vw->flags) ||
584
            get_user(n, &up->clipcount) || put_user(n, &vw->clipcount) ||
585
            get_user(n, &up->clips) || put_user(p, &vw->clips))
586
                return -EFAULT;
587
 
588
        if (nclips) {
589
                struct video_clip32 __user *u = compat_ptr(n);
590
                int i;
591
                if (!u)
592
                        return -EINVAL;
593
                for (i = 0; i < nclips; i++, u++, p++) {
594
                        s32 v;
595
                        if (!access_ok(VERIFY_READ, u, sizeof(struct video_clip32)) ||
596
                            !access_ok(VERIFY_WRITE, p, sizeof(struct video_clip32)) ||
597
                            get_user(v, &u->x) ||
598
                            put_user(v, &p->x) ||
599
                            get_user(v, &u->y) ||
600
                            put_user(v, &p->y) ||
601
                            get_user(v, &u->width) ||
602
                            put_user(v, &p->width) ||
603
                            get_user(v, &u->height) ||
604
                            put_user(v, &p->height) ||
605
                            put_user(NULL, &p->next))
606
                                return -EFAULT;
607
                }
608
        }
609
 
610
        return native_ioctl(file, VIDIOCSWIN, (unsigned long)vw);
611
}
612
#endif
613
 
614
static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
615
{
616
        union {
617
#ifdef CONFIG_VIDEO_V4L1_COMPAT
618
                struct video_tuner vt;
619
                struct video_buffer vb;
620
                struct video_window vw;
621
                struct video_code vc;
622
                struct video_audio va;
623
#endif
624
                struct v4l2_format v2f;
625
                struct v4l2_buffer v2b;
626
                struct v4l2_framebuffer v2fb;
627
                struct v4l2_standard v2s;
628
                struct v4l2_input v2i;
629
                struct v4l2_tuner v2t;
630
                unsigned long vx;
631
        } karg;
632
        void __user *up = compat_ptr(arg);
633
        int compatible_arg = 1;
634
        int err = 0;
635
        int realcmd = cmd;
636
 
637
        /* First, convert the command. */
638
        switch(cmd) {
639
#ifdef CONFIG_VIDEO_V4L1_COMPAT
640
        case VIDIOCGTUNER32: realcmd = cmd = VIDIOCGTUNER; break;
641
        case VIDIOCSTUNER32: realcmd = cmd = VIDIOCSTUNER; break;
642
        case VIDIOCGWIN32: realcmd = cmd = VIDIOCGWIN; break;
643
        case VIDIOCGFBUF32: realcmd = cmd = VIDIOCGFBUF; break;
644
        case VIDIOCSFBUF32: realcmd = cmd = VIDIOCSFBUF; break;
645
        case VIDIOCGFREQ32: realcmd = cmd = VIDIOCGFREQ; break;
646
        case VIDIOCSFREQ32: realcmd = cmd = VIDIOCSFREQ; break;
647
        case VIDIOCSMICROCODE32: realcmd = cmd = VIDIOCSMICROCODE; break;
648
#endif
649
        case VIDIOC_G_FMT32: realcmd = cmd = VIDIOC_G_FMT; break;
650
        case VIDIOC_S_FMT32: realcmd = cmd = VIDIOC_S_FMT; break;
651
        case VIDIOC_QUERYBUF32: realcmd = cmd = VIDIOC_QUERYBUF; break;
652
        case VIDIOC_QBUF32: realcmd = cmd = VIDIOC_QBUF; break;
653
        case VIDIOC_DQBUF32: realcmd = cmd = VIDIOC_DQBUF; break;
654
        case VIDIOC_STREAMON32: realcmd = cmd = VIDIOC_STREAMON; break;
655
        case VIDIOC_STREAMOFF32: realcmd = cmd = VIDIOC_STREAMOFF; break;
656
        case VIDIOC_G_FBUF32: realcmd = cmd = VIDIOC_G_FBUF; break;
657
        case VIDIOC_S_FBUF32: realcmd = cmd = VIDIOC_S_FBUF; break;
658
        case VIDIOC_OVERLAY32: realcmd = cmd = VIDIOC_OVERLAY; break;
659
        case VIDIOC_ENUMSTD32: realcmd = VIDIOC_ENUMSTD; break;
660
        case VIDIOC_ENUMINPUT32: realcmd = VIDIOC_ENUMINPUT; break;
661
        case VIDIOC_S_CTRL32: realcmd = cmd = VIDIOC_S_CTRL; break;
662
        case VIDIOC_G_INPUT32: realcmd = cmd = VIDIOC_G_INPUT; break;
663
        case VIDIOC_S_INPUT32: realcmd = cmd = VIDIOC_S_INPUT; break;
664
        case VIDIOC_TRY_FMT32: realcmd = cmd = VIDIOC_TRY_FMT; break;
665
        };
666
 
667
        switch(cmd) {
668
#ifdef CONFIG_VIDEO_V4L1_COMPAT
669
        case VIDIOCSTUNER:
670
        case VIDIOCGTUNER:
671
                err = get_video_tuner32(&karg.vt, up);
672
                compatible_arg = 0;
673
 
674
                break;
675
 
676
        case VIDIOCSFBUF:
677
                err = get_video_buffer32(&karg.vb, up);
678
                compatible_arg = 0;
679
                break;
680
 
681
 
682
        case VIDIOCSFREQ:
683
#endif
684
        case VIDIOC_S_INPUT:
685
        case VIDIOC_OVERLAY:
686
        case VIDIOC_STREAMON:
687
        case VIDIOC_STREAMOFF:
688
                err = get_user(karg.vx, (u32 __user *)up);
689
                compatible_arg = 1;
690
                break;
691
 
692
        case VIDIOC_S_FBUF:
693
                err = get_v4l2_framebuffer32(&karg.v2fb, up);
694
                compatible_arg = 0;
695
                break;
696
 
697
        case VIDIOC_G_FMT:
698
        case VIDIOC_S_FMT:
699
        case VIDIOC_TRY_FMT:
700
                err = get_v4l2_format32(&karg.v2f, up);
701
                compatible_arg = 0;
702
                break;
703
 
704
        case VIDIOC_QUERYBUF:
705
        case VIDIOC_QBUF:
706
        case VIDIOC_DQBUF:
707
                err = get_v4l2_buffer32(&karg.v2b, up);
708
                compatible_arg = 0;
709
                break;
710
 
711
        case VIDIOC_ENUMSTD:
712
                err = get_v4l2_standard(&karg.v2s, up);
713
                compatible_arg = 0;
714
                break;
715
 
716
        case VIDIOC_ENUMSTD32:
717
                err = get_v4l2_standard32(&karg.v2s, up);
718
                compatible_arg = 0;
719
                break;
720
 
721
        case VIDIOC_ENUMINPUT:
722
                err = get_v4l2_input(&karg.v2i, up);
723
                compatible_arg = 0;
724
                break;
725
 
726
        case VIDIOC_ENUMINPUT32:
727
                err = get_v4l2_input32(&karg.v2i, up);
728
                compatible_arg = 0;
729
                break;
730
 
731
        case VIDIOC_G_TUNER:
732
        case VIDIOC_S_TUNER:
733
                err = get_v4l2_tuner(&karg.v2t, up);
734
                compatible_arg = 0;
735
                break;
736
 
737
#ifdef CONFIG_VIDEO_V4L1_COMPAT
738
        case VIDIOCGWIN:
739
        case VIDIOCGFBUF:
740
        case VIDIOCGFREQ:
741
#endif
742
        case VIDIOC_G_FBUF:
743
        case VIDIOC_G_INPUT:
744
                compatible_arg = 0;
745
                break;
746
#ifdef CONFIG_VIDEO_V4L1_COMPAT
747
        case VIDIOCSMICROCODE:
748
                err = microcode32(&karg.vc, up);
749
                compatible_arg = 0;
750
                break;
751
#endif
752
        };
753
        if(err)
754
                goto out;
755
 
756
        if(compatible_arg)
757
                err = native_ioctl(file, realcmd, (unsigned long)up);
758
        else {
759
                mm_segment_t old_fs = get_fs();
760
 
761
                set_fs(KERNEL_DS);
762
                err = native_ioctl(file, realcmd, (unsigned long) &karg);
763
                set_fs(old_fs);
764
        }
765
        if(err == 0) {
766
                switch(cmd) {
767
#ifdef CONFIG_VIDEO_V4L1_COMPAT
768
                case VIDIOCGTUNER:
769
                        err = put_video_tuner32(&karg.vt, up);
770
                        break;
771
 
772
                case VIDIOCGWIN:
773
                        err = put_video_window32(&karg.vw, up);
774
                        break;
775
 
776
                case VIDIOCGFBUF:
777
                        err = put_video_buffer32(&karg.vb, up);
778
                        break;
779
 
780
#endif
781
                case VIDIOC_G_FBUF:
782
                        err = put_v4l2_framebuffer32(&karg.v2fb, up);
783
                        break;
784
 
785
                case VIDIOC_G_FMT:
786
                case VIDIOC_S_FMT:
787
                case VIDIOC_TRY_FMT:
788
                        err = put_v4l2_format32(&karg.v2f, up);
789
                        break;
790
 
791
                case VIDIOC_QUERYBUF:
792
                case VIDIOC_QBUF:
793
                case VIDIOC_DQBUF:
794
                        err = put_v4l2_buffer32(&karg.v2b, up);
795
                        break;
796
 
797
                case VIDIOC_ENUMSTD:
798
                        err = put_v4l2_standard(&karg.v2s, up);
799
                        break;
800
 
801
                case VIDIOC_ENUMSTD32:
802
                        err = put_v4l2_standard32(&karg.v2s, up);
803
                        break;
804
 
805
                case VIDIOC_G_TUNER:
806
                case VIDIOC_S_TUNER:
807
                        err = put_v4l2_tuner(&karg.v2t, up);
808
                        break;
809
 
810
                case VIDIOC_ENUMINPUT:
811
                        err = put_v4l2_input(&karg.v2i, up);
812
                        break;
813
 
814
                case VIDIOC_ENUMINPUT32:
815
                        err = put_v4l2_input32(&karg.v2i, up);
816
                        break;
817
 
818
#ifdef CONFIG_VIDEO_V4L1_COMPAT
819
                case VIDIOCGFREQ:
820
#endif
821
                case VIDIOC_G_INPUT:
822
                        err = put_user(((u32)karg.vx), (u32 __user *)up);
823
                        break;
824
                };
825
        }
826
out:
827
        return err;
828
}
829
 
830
long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
831
{
832
        int ret = -ENOIOCTLCMD;
833
 
834
        if (!file->f_op->ioctl)
835
                return ret;
836
 
837
        switch (cmd) {
838
#ifdef CONFIG_VIDEO_V4L1_COMPAT
839
        case VIDIOCSWIN32:
840
                ret = do_set_window(file, cmd, arg);
841
                break;
842
        case VIDIOCGTUNER32:
843
        case VIDIOCSTUNER32:
844
        case VIDIOCGWIN32:
845
        case VIDIOCGFBUF32:
846
        case VIDIOCSFBUF32:
847
        case VIDIOCGFREQ32:
848
        case VIDIOCSFREQ32:
849
        case VIDIOCGAUDIO:
850
        case VIDIOCSAUDIO:
851
        case VIDIOCGVBIFMT:
852
        case VIDIOCSVBIFMT:
853
#endif
854
        case VIDIOC_QUERYCAP:
855
        case VIDIOC_ENUM_FMT:
856
        case VIDIOC_G_FMT32:
857
        case VIDIOC_CROPCAP:
858
        case VIDIOC_S_CROP:
859
        case VIDIOC_S_FMT32:
860
        case VIDIOC_REQBUFS:
861
        case VIDIOC_QUERYBUF32:
862
        case VIDIOC_G_FBUF32:
863
        case VIDIOC_S_FBUF32:
864
        case VIDIOC_OVERLAY32:
865
        case VIDIOC_QBUF32:
866
        case VIDIOC_DQBUF32:
867
        case VIDIOC_STREAMON32:
868
        case VIDIOC_STREAMOFF32:
869
        case VIDIOC_G_PARM:
870
        case VIDIOC_G_STD:
871
        case VIDIOC_S_STD:
872
        case VIDIOC_G_TUNER:
873
        case VIDIOC_S_TUNER:
874
        case VIDIOC_ENUMSTD:
875
        case VIDIOC_ENUMSTD32:
876
        case VIDIOC_ENUMINPUT:
877
        case VIDIOC_ENUMINPUT32:
878
        case VIDIOC_G_CTRL:
879
        case VIDIOC_S_CTRL:
880
        case VIDIOC_S_CTRL32:
881
        case VIDIOC_S_FREQUENCY:
882
        case VIDIOC_G_FREQUENCY:
883
        case VIDIOC_QUERYCTRL:
884
        case VIDIOC_G_INPUT32:
885
        case VIDIOC_S_INPUT32:
886
        case VIDIOC_TRY_FMT32:
887
                ret = do_video_ioctl(file, cmd, arg);
888
                break;
889
 
890
#ifdef CONFIG_VIDEO_V4L1_COMPAT
891
        /* Little v, the video4linux ioctls (conflict?) */
892
        case VIDIOCGCAP:
893
        case VIDIOCGCHAN:
894
        case VIDIOCSCHAN:
895
        case VIDIOCGPICT:
896
        case VIDIOCSPICT:
897
        case VIDIOCCAPTURE:
898
        case VIDIOCKEY:
899
        case VIDIOCSYNC:
900
        case VIDIOCMCAPTURE:
901
        case VIDIOCGMBUF:
902
        case VIDIOCGUNIT:
903
        case VIDIOCGCAPTURE:
904
        case VIDIOCSCAPTURE:
905
 
906
        /* BTTV specific... */
907
        case _IOW('v',  BASE_VIDIOCPRIVATE+0, char [256]):
908
        case _IOR('v',  BASE_VIDIOCPRIVATE+1, char [256]):
909
        case _IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int):
910
        case _IOW('v' , BASE_VIDIOCPRIVATE+3, char [16]): /* struct bttv_pll_info */
911
        case _IOR('v' , BASE_VIDIOCPRIVATE+4, int):
912
        case _IOR('v' , BASE_VIDIOCPRIVATE+5, int):
913
        case _IOR('v' , BASE_VIDIOCPRIVATE+6, int):
914
        case _IOR('v' , BASE_VIDIOCPRIVATE+7, int):
915
                ret = native_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
916
                break;
917
#endif
918
        default:
919
                v4l_print_ioctl("compat_ioctl32", cmd);
920
        }
921
        return ret;
922
}
923
#else
924
long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
925
{
926
        return -ENOIOCTLCMD;
927
}
928
#endif
929
EXPORT_SYMBOL_GPL(v4l_compat_ioctl32);
930
 
931
MODULE_LICENSE("GPL");

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.