From: Gerd Knorr This patch fixes some v4l2 ioctl #defines which have wrong _IO* macros. It also adds a function which maps the old numbers to to new ones to maintain binary backward compatibility. --- drivers/media/video/videodev.c | 33 ++++++++++++++++++++++++++++++--- include/linux/videodev2.h | 19 ++++++++++++++----- 2 files changed, 44 insertions(+), 8 deletions(-) diff -puN drivers/media/video/videodev.c~v4l-01-videodev-update drivers/media/video/videodev.c --- 25/drivers/media/video/videodev.c~v4l-01-videodev-update 2004-01-15 08:27:36.000000000 -0800 +++ 25-akpm/drivers/media/video/videodev.c 2004-01-15 08:27:36.000000000 -0800 @@ -140,6 +140,30 @@ static int video_open(struct inode *inod /* * helper function -- handles userspace copying for ioctl arguments */ + +static unsigned int +video_fix_command(unsigned int cmd) +{ + switch (cmd) { + case VIDIOC_OVERLAY_OLD: + cmd = VIDIOC_OVERLAY; + break; + case VIDIOC_S_PARM_OLD: + cmd = VIDIOC_S_PARM; + break; + case VIDIOC_S_CTRL_OLD: + cmd = VIDIOC_S_CTRL; + break; + case VIDIOC_G_AUDIO_OLD: + cmd = VIDIOC_G_AUDIO; + break; + case VIDIOC_G_AUDOUT_OLD: + cmd = VIDIOC_G_AUDOUT; + break; + } + return cmd; +} + int video_usercopy(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg, @@ -151,12 +175,14 @@ video_usercopy(struct inode *inode, stru void *parg = NULL; int err = -EINVAL; + cmd = video_fix_command(cmd); + /* Copy arguments into temp kernel buffer */ switch (_IOC_DIR(cmd)) { case _IOC_NONE: parg = (void *)arg; break; - case _IOC_READ: /* some v4l ioctls are marked wrong ... */ + case _IOC_READ: case _IOC_WRITE: case (_IOC_WRITE | _IOC_READ): if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { @@ -170,8 +196,9 @@ video_usercopy(struct inode *inode, stru } err = -EFAULT; - if (copy_from_user(parg, (void *)arg, _IOC_SIZE(cmd))) - goto out; + if (_IOC_DIR(cmd) & _IOC_WRITE) + if (copy_from_user(parg, (void *)arg, _IOC_SIZE(cmd))) + goto out; break; } diff -puN include/linux/videodev2.h~v4l-01-videodev-update include/linux/videodev2.h --- 25/include/linux/videodev2.h~v4l-01-videodev-update 2004-01-15 08:27:36.000000000 -0800 +++ 25-akpm/include/linux/videodev2.h 2004-01-15 08:27:36.000000000 -0800 @@ -783,22 +783,22 @@ struct v4l2_streamparm #define VIDIOC_QUERYBUF _IOWR ('V', 9, struct v4l2_buffer) #define VIDIOC_G_FBUF _IOR ('V', 10, struct v4l2_framebuffer) #define VIDIOC_S_FBUF _IOW ('V', 11, struct v4l2_framebuffer) -#define VIDIOC_OVERLAY _IOWR ('V', 14, int) +#define VIDIOC_OVERLAY _IOW ('V', 14, int) #define VIDIOC_QBUF _IOWR ('V', 15, struct v4l2_buffer) #define VIDIOC_DQBUF _IOWR ('V', 17, struct v4l2_buffer) #define VIDIOC_STREAMON _IOW ('V', 18, int) #define VIDIOC_STREAMOFF _IOW ('V', 19, int) #define VIDIOC_G_PARM _IOWR ('V', 21, struct v4l2_streamparm) -#define VIDIOC_S_PARM _IOW ('V', 22, struct v4l2_streamparm) +#define VIDIOC_S_PARM _IOWR ('V', 22, struct v4l2_streamparm) #define VIDIOC_G_STD _IOR ('V', 23, v4l2_std_id) #define VIDIOC_S_STD _IOW ('V', 24, v4l2_std_id) #define VIDIOC_ENUMSTD _IOWR ('V', 25, struct v4l2_standard) #define VIDIOC_ENUMINPUT _IOWR ('V', 26, struct v4l2_input) #define VIDIOC_G_CTRL _IOWR ('V', 27, struct v4l2_control) -#define VIDIOC_S_CTRL _IOW ('V', 28, struct v4l2_control) +#define VIDIOC_S_CTRL _IOWR ('V', 28, struct v4l2_control) #define VIDIOC_G_TUNER _IOWR ('V', 29, struct v4l2_tuner) #define VIDIOC_S_TUNER _IOW ('V', 30, struct v4l2_tuner) -#define VIDIOC_G_AUDIO _IOWR ('V', 33, struct v4l2_audio) +#define VIDIOC_G_AUDIO _IOR ('V', 33, struct v4l2_audio) #define VIDIOC_S_AUDIO _IOW ('V', 34, struct v4l2_audio) #define VIDIOC_QUERYCTRL _IOWR ('V', 36, struct v4l2_queryctrl) #define VIDIOC_QUERYMENU _IOWR ('V', 37, struct v4l2_querymenu) @@ -807,7 +807,7 @@ struct v4l2_streamparm #define VIDIOC_G_OUTPUT _IOR ('V', 46, int) #define VIDIOC_S_OUTPUT _IOWR ('V', 47, int) #define VIDIOC_ENUMOUTPUT _IOWR ('V', 48, struct v4l2_output) -#define VIDIOC_G_AUDOUT _IOWR ('V', 49, struct v4l2_audioout) +#define VIDIOC_G_AUDOUT _IOR ('V', 49, struct v4l2_audioout) #define VIDIOC_S_AUDOUT _IOW ('V', 50, struct v4l2_audioout) #define VIDIOC_G_MODULATOR _IOWR ('V', 54, struct v4l2_modulator) #define VIDIOC_S_MODULATOR _IOW ('V', 55, struct v4l2_modulator) @@ -820,6 +820,15 @@ struct v4l2_streamparm #define VIDIOC_S_JPEGCOMP _IOW ('V', 62, struct v4l2_jpegcompression) #define VIDIOC_QUERYSTD _IOR ('V', 63, v4l2_std_id) #define VIDIOC_TRY_FMT _IOWR ('V', 64, struct v4l2_format) +#define VIDIOC_ENUMAUDIO _IOWR ('V', 65, struct v4l2_audio) +#define VIDIOC_ENUMAUDOUT _IOWR ('V', 66, struct v4l2_audioout) + +/* for compatibility, will go away some day */ +#define VIDIOC_OVERLAY_OLD _IOWR ('V', 14, int) +#define VIDIOC_S_PARM_OLD _IOW ('V', 22, struct v4l2_streamparm) +#define VIDIOC_S_CTRL_OLD _IOW ('V', 28, struct v4l2_control) +#define VIDIOC_G_AUDIO_OLD _IOWR ('V', 33, struct v4l2_audio) +#define VIDIOC_G_AUDOUT_OLD _IOWR ('V', 49, struct v4l2_audioout) #define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */ _