diff options
Diffstat (limited to 'drivers/media/video')
-rw-r--r-- | drivers/media/video/Makefile | 3 | ||||
-rw-r--r-- | drivers/media/video/arv.c | 1 | ||||
-rw-r--r-- | drivers/media/video/bttv-driver.c | 1 | ||||
-rw-r--r-- | drivers/media/video/bw-qcam.c | 1 | ||||
-rw-r--r-- | drivers/media/video/c-qcam.c | 1 | ||||
-rw-r--r-- | drivers/media/video/compat_ioctl32.c | 318 | ||||
-rw-r--r-- | drivers/media/video/cpia.c | 1 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-video.c | 2 | ||||
-rw-r--r-- | drivers/media/video/meye.c | 1 | ||||
-rw-r--r-- | drivers/media/video/pms.c | 1 | ||||
-rw-r--r-- | drivers/media/video/saa5249.c | 1 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-video.c | 2 | ||||
-rw-r--r-- | drivers/media/video/stradis.c | 1 | ||||
-rw-r--r-- | drivers/media/video/w9966.c | 1 | ||||
-rw-r--r-- | drivers/media/video/zoran_driver.c | 1 | ||||
-rw-r--r-- | drivers/media/video/zr36120.c | 1 |
16 files changed, 336 insertions, 1 deletions
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 82060f9909d8..618a08ab940a 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -8,7 +8,8 @@ zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o zr36067-objs := zoran_procfs.o zoran_device.o \ zoran_driver.o zoran_card.o tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o -obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o + +obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o compat_ioctl32.o obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \ tda7432.o tda9875.o ir-kbd-i2c.o ir-kbd-gpio.o diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c index 881cdcb1875d..7d5a068353f2 100644 --- a/drivers/media/video/arv.c +++ b/drivers/media/video/arv.c @@ -749,6 +749,7 @@ static struct file_operations ar_fops = { .release = video_exclusive_release, .read = ar_read, .ioctl = ar_ioctl, + .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c index 1ddf9ba613ef..03f925724ce9 100644 --- a/drivers/media/video/bttv-driver.c +++ b/drivers/media/video/bttv-driver.c @@ -3120,6 +3120,7 @@ static struct file_operations bttv_fops = .open = bttv_open, .release = bttv_release, .ioctl = bttv_ioctl, + .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, .read = bttv_read, .mmap = bttv_mmap, diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c index 0065d0c240d1..6bad93ef969f 100644 --- a/drivers/media/video/bw-qcam.c +++ b/drivers/media/video/bw-qcam.c @@ -875,6 +875,7 @@ static struct file_operations qcam_fops = { .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = qcam_ioctl, + .compat_ioctl = v4l_compat_ioctl32, .read = qcam_read, .llseek = no_llseek, }; diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c index 75442ec49f35..9976db4f6da8 100644 --- a/drivers/media/video/c-qcam.c +++ b/drivers/media/video/c-qcam.c @@ -687,6 +687,7 @@ static struct file_operations qcam_fops = { .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = qcam_ioctl, + .compat_ioctl = v4l_compat_ioctl32, .read = qcam_read, .llseek = no_llseek, }; diff --git a/drivers/media/video/compat_ioctl32.c b/drivers/media/video/compat_ioctl32.c new file mode 100644 index 000000000000..42dc11c63c0d --- /dev/null +++ b/drivers/media/video/compat_ioctl32.c @@ -0,0 +1,318 @@ +#include <linux/config.h> +#include <linux/compat.h> +#include <linux/videodev.h> + +#ifdef CONFIG_COMPAT +struct video_tuner32 { + compat_int_t tuner; + char name[32]; + compat_ulong_t rangelow, rangehigh; + u32 flags; /* It is really u32 in videodev.h */ + u16 mode, signal; +}; + +static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up) +{ + int i; + + if(get_user(kp->tuner, &up->tuner)) + return -EFAULT; + for(i = 0; i < 32; i++) + __get_user(kp->name[i], &up->name[i]); + __get_user(kp->rangelow, &up->rangelow); + __get_user(kp->rangehigh, &up->rangehigh); + __get_user(kp->flags, &up->flags); + __get_user(kp->mode, &up->mode); + __get_user(kp->signal, &up->signal); + return 0; +} + +static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up) +{ + int i; + + if(put_user(kp->tuner, &up->tuner)) + return -EFAULT; + for(i = 0; i < 32; i++) + __put_user(kp->name[i], &up->name[i]); + __put_user(kp->rangelow, &up->rangelow); + __put_user(kp->rangehigh, &up->rangehigh); + __put_user(kp->flags, &up->flags); + __put_user(kp->mode, &up->mode); + __put_user(kp->signal, &up->signal); + return 0; +} + +struct video_buffer32 { + compat_caddr_t base; + compat_int_t height, width, depth, bytesperline; +}; + +static int get_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up) +{ + u32 tmp; + + if (get_user(tmp, &up->base)) + return -EFAULT; + + /* This is actually a physical address stored + * as a void pointer. + */ + kp->base = (void *)(unsigned long) tmp; + + __get_user(kp->height, &up->height); + __get_user(kp->width, &up->width); + __get_user(kp->depth, &up->depth); + __get_user(kp->bytesperline, &up->bytesperline); + return 0; +} + +static int put_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up) +{ + u32 tmp = (u32)((unsigned long)kp->base); + + if(put_user(tmp, &up->base)) + return -EFAULT; + __put_user(kp->height, &up->height); + __put_user(kp->width, &up->width); + __put_user(kp->depth, &up->depth); + __put_user(kp->bytesperline, &up->bytesperline); + return 0; +} + +struct video_clip32 { + s32 x, y, width, height; /* Its really s32 in videodev.h */ + compat_caddr_t next; +}; + +struct video_window32 { + u32 x, y, width, height, chromakey, flags; + compat_caddr_t clips; + compat_int_t clipcount; +}; + +static int native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret = -ENOIOCTLCMD; + + if (file->f_ops->unlocked_ioctl) + ret = file->f_ops->unlocked_ioctl(file, cmd, arg); + else if (file->f_ops->ioctl) { + lock_kernel(); + ret = file->f_ops->ioctl(file->f_dentry->d_inode, file, cmd, arg); + unlock_kernel(); + } + + return ret; +} + + +/* You get back everything except the clips... */ +static int put_video_window32(struct video_window *kp, struct video_window32 __user *up) +{ + if(put_user(kp->x, &up->x)) + return -EFAULT; + __put_user(kp->y, &up->y); + __put_user(kp->width, &up->width); + __put_user(kp->height, &up->height); + __put_user(kp->chromakey, &up->chromakey); + __put_user(kp->flags, &up->flags); + __put_user(kp->clipcount, &up->clipcount); + return 0; +} + +#define VIDIOCGTUNER32 _IOWR('v',4, struct video_tuner32) +#define VIDIOCSTUNER32 _IOW('v',5, struct video_tuner32) +#define VIDIOCGWIN32 _IOR('v',9, struct video_window32) +#define VIDIOCSWIN32 _IOW('v',10, struct video_window32) +#define VIDIOCGFBUF32 _IOR('v',11, struct video_buffer32) +#define VIDIOCSFBUF32 _IOW('v',12, struct video_buffer32) +#define VIDIOCGFREQ32 _IOR('v',14, u32) +#define VIDIOCSFREQ32 _IOW('v',15, u32) + +enum { + MaxClips = (~0U-sizeof(struct video_window))/sizeof(struct video_clip) +}; + +static int do_set_window(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct video_window32 __user *up = compat_ptr(arg); + struct video_window __user *vw; + struct video_clip __user *p; + int nclips; + u32 n; + + if (get_user(nclips, &up->clipcount)) + return -EFAULT; + + /* Peculiar interface... */ + if (nclips < 0) + nclips = VIDEO_CLIPMAP_SIZE; + + if (nclips > MaxClips) + return -ENOMEM; + + vw = compat_alloc_user_space(sizeof(struct video_window) + + nclips * sizeof(struct video_clip)); + + p = nclips ? (struct video_clip __user *)(vw + 1) : NULL; + + if (get_user(n, &up->x) || put_user(n, &vw->x) || + get_user(n, &up->y) || put_user(n, &vw->y) || + get_user(n, &up->width) || put_user(n, &vw->width) || + get_user(n, &up->height) || put_user(n, &vw->height) || + get_user(n, &up->chromakey) || put_user(n, &vw->chromakey) || + get_user(n, &up->flags) || put_user(n, &vw->flags) || + get_user(n, &up->clipcount) || put_user(n, &vw->clipcount) || + get_user(n, &up->clips) || put_user(p, &vw->clips)) + return -EFAULT; + + if (nclips) { + struct video_clip32 __user *u = compat_ptr(n); + int i; + if (!u) + return -EINVAL; + for (i = 0; i < nclips; i++, u++, p++) { + s32 v; + if (get_user(v, &u->x) || + put_user(v, &p->x) || + get_user(v, &u->y) || + put_user(v, &p->y) || + get_user(v, &u->width) || + put_user(v, &p->width) || + get_user(v, &u->height) || + put_user(v, &p->height) || + put_user(NULL, &p->next)) + return -EFAULT; + } + } + + return native_ioctl(file, VIDIOCSWIN, (unsigned long)p); +} + +static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + union { + struct video_tuner vt; + struct video_buffer vb; + struct video_window vw; + unsigned long vx; + } karg; + mm_segment_t old_fs = get_fs(); + void __user *up = compat_ptr(arg); + int err = 0; + + /* First, convert the command. */ + switch(cmd) { + case VIDIOCGTUNER32: cmd = VIDIOCGTUNER; break; + case VIDIOCSTUNER32: cmd = VIDIOCSTUNER; break; + case VIDIOCGWIN32: cmd = VIDIOCGWIN; break; + case VIDIOCGFBUF32: cmd = VIDIOCGFBUF; break; + case VIDIOCSFBUF32: cmd = VIDIOCSFBUF; break; + case VIDIOCGFREQ32: cmd = VIDIOCGFREQ; break; + case VIDIOCSFREQ32: cmd = VIDIOCSFREQ; break; + }; + + switch(cmd) { + case VIDIOCSTUNER: + case VIDIOCGTUNER: + err = get_video_tuner32(&karg.vt, up); + break; + + case VIDIOCSFBUF: + err = get_video_buffer32(&karg.vb, up); + break; + + case VIDIOCSFREQ: + err = get_user(karg.vx, (u32 __user *)up); + break; + }; + if(err) + goto out; + + set_fs(KERNEL_DS); + err = native_ioctl(file, cmd, (unsigned long)&karg); + set_fs(old_fs); + + if(err == 0) { + switch(cmd) { + case VIDIOCGTUNER: + err = put_video_tuner32(&karg.vt, up); + break; + + case VIDIOCGWIN: + err = put_video_window32(&karg.vw, up); + break; + + case VIDIOCGFBUF: + err = put_video_buffer32(&karg.vb, up); + break; + + case VIDIOCGFREQ: + err = put_user(((u32)karg.vx), (u32 __user *)up); + break; + }; + } +out: + return err; +} + +long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret = -ENOIOCTLCMD; + + if (!file->f_ops->ioctl) + return ret; + + switch (cmd) { + case VIDIOCSWIN32: + ret = do_set_window(file, cmd, arg); + break; + case VIDIOCGTUNER32: + case VIDIOCSTUNER32: + case VIDIOCGWIN32: + case VIDIOCGFBUF32: + case VIDIOCSFBUF32: + case VIDIOCGFREQ32: + case VIDIOCSFREQ32 + ret = do_video_ioctl(file, cmd, arg); + break; + + /* Little v, the video4linux ioctls (conflict?) */ + case VIDIOCGCAP: + case VIDIOCGCHAN: + case VIDIOCSCHAN: + case VIDIOCGPICT: + case VIDIOCSPICT: + case VIDIOCCAPTURE: + case VIDIOCKEY: + case VIDIOCGAUDIO: + case VIDIOCSAUDIO: + case VIDIOCSYNC: + case VIDIOCMCAPTURE: + case VIDIOCGMBUF: + case VIDIOCGUNIT: + case VIDIOCGCAPTURE: + case VIDIOCSCAPTURE: + + /* BTTV specific... */ + case _IOW('v', BASE_VIDIOCPRIVATE+0, char [256]): + case _IOR('v', BASE_VIDIOCPRIVATE+1, char [256]): + case _IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int): + case _IOW('v' , BASE_VIDIOCPRIVATE+3, char [16]): /* struct bttv_pll_info */ + case _IOR('v' , BASE_VIDIOCPRIVATE+4, int): + case _IOR('v' , BASE_VIDIOCPRIVATE+5, int): + case _IOR('v' , BASE_VIDIOCPRIVATE+6, int): + case _IOR('v' , BASE_VIDIOCPRIVATE+7, int): + ret = native_ioctl(file, cmd, (unsigned long)compat_ptr(arg)); + break; + + return ret; +} +#else +long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) +{ + return -ENOIOCTLCMD; +} +#endif +EXPORT_SYMBOL_GPL(v4l_compat_ioctl32); diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c index b7ec9bf45085..9f59541155d9 100644 --- a/drivers/media/video/cpia.c +++ b/drivers/media/video/cpia.c @@ -3807,6 +3807,7 @@ static struct file_operations cpia_fops = { .read = cpia_read, .mmap = cpia_mmap, .ioctl = cpia_ioctl, + .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 24a48f8a48c1..bc025c46aedf 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c @@ -1740,6 +1740,7 @@ static struct file_operations video_fops = .poll = video_poll, .mmap = video_mmap, .ioctl = video_ioctl, + .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; @@ -1767,6 +1768,7 @@ static struct file_operations radio_fops = .open = video_open, .release = video_release, .ioctl = radio_ioctl, + .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index 3f2a882bc20a..2869464aee0d 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c @@ -1754,6 +1754,7 @@ static struct file_operations meye_fops = { .release = meye_release, .mmap = meye_mmap, .ioctl = meye_ioctl, + .compat_ioctl = v4l_compat_ioctl32, .poll = meye_poll, .llseek = no_llseek, }; diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index 2504207b2e3d..9e6448639480 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c @@ -883,6 +883,7 @@ static struct file_operations pms_fops = { .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = pms_ioctl, + .compat_ioctl = v4l_compat_ioctl32, .read = pms_read, .llseek = no_llseek, }; diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c index a51c7bd96618..73b4f0e2abf0 100644 --- a/drivers/media/video/saa5249.c +++ b/drivers/media/video/saa5249.c @@ -702,6 +702,7 @@ static struct file_operations saa_fops = { .open = saa5249_open, .release = saa5249_release, .ioctl = saa5249_ioctl, + .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index 45c852df13ed..9b9e1e7f05ef 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c @@ -2262,6 +2262,7 @@ static struct file_operations video_fops = .poll = video_poll, .mmap = video_mmap, .ioctl = video_ioctl, + .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; @@ -2271,6 +2272,7 @@ static struct file_operations radio_fops = .open = video_open, .release = video_release, .ioctl = radio_ioctl, + .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c index d4497dbae05c..6ee54a45411f 100644 --- a/drivers/media/video/stradis.c +++ b/drivers/media/video/stradis.c @@ -1974,6 +1974,7 @@ static struct file_operations saa_fops = .open = saa_open, .release = saa_release, .ioctl = saa_ioctl, + .compat_ioctl = v4l_compat_ioctl32, .read = saa_read, .llseek = no_llseek, .write = saa_write, diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c index c318ba32fbaf..b7b0afffd214 100644 --- a/drivers/media/video/w9966.c +++ b/drivers/media/video/w9966.c @@ -187,6 +187,7 @@ static struct file_operations w9966_fops = { .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = w9966_v4l_ioctl, + .compat_ioctl = v4l_compat_ioctl32, .read = w9966_v4l_read, .llseek = no_llseek, }; diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c index 4034f1b45366..15283f44e79f 100644 --- a/drivers/media/video/zoran_driver.c +++ b/drivers/media/video/zoran_driver.c @@ -4678,6 +4678,7 @@ static struct file_operations zoran_fops = { .open = zoran_open, .release = zoran_close, .ioctl = zoran_ioctl, + .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, .read = zoran_read, .write = zoran_write, diff --git a/drivers/media/video/zr36120.c b/drivers/media/video/zr36120.c index 07286816d7df..d4c633b8a7f5 100644 --- a/drivers/media/video/zr36120.c +++ b/drivers/media/video/zr36120.c @@ -1490,6 +1490,7 @@ static struct video_device zr36120_template= .write = zoran_write, .poll = zoran_poll, .ioctl = zoran_ioctl, + .compat_ioctl = v4l_compat_ioctl32, .mmap = zoran_mmap, .minor = -1, }; |