media: dvb: move compat handlers into drivers
The VIDEO_STILLPICTURE is only implemented by one driver, while VIDEO_GET_EVENT has two users in tree. In both cases, it is fairly easy to handle the compat ioctls in the native handler rather than relying on translation in fs/compat_ioctls. In effect, this means that now the drivers implement both structure layouts in both native and compat mode, but I don't see anything wrong with that. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
This commit is contained in:
parent
8a24280b11
commit
04b72322e8
|
@ -36,6 +36,7 @@
|
|||
#include <media/tveeprom.h>
|
||||
#include <media/v4l2-event.h>
|
||||
#ifdef CONFIG_VIDEO_IVTV_DEPRECATED_IOCTLS
|
||||
#include <linux/compat.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#endif
|
||||
|
@ -1627,6 +1628,21 @@ static __inline__ void warn_deprecated_ioctl(const char *name)
|
|||
pr_warn_once("warning: the %s ioctl is deprecated. Don't use it, as it will be removed soon\n",
|
||||
name);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
struct compat_video_event {
|
||||
__s32 type;
|
||||
/* unused, make sure to use atomic time for y2038 if it ever gets used */
|
||||
compat_long_t timestamp;
|
||||
union {
|
||||
video_size_t size;
|
||||
unsigned int frame_rate; /* in frames per 1000sec */
|
||||
unsigned char vsync_field; /* unknown/odd/even/progressive */
|
||||
} u;
|
||||
};
|
||||
#define VIDEO_GET_EVENT32 _IOR('o', 28, struct compat_video_event)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
|
||||
|
@ -1749,7 +1765,13 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
|
|||
return ivtv_video_command(itv, id, dc, try);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
case VIDEO_GET_EVENT32:
|
||||
#endif
|
||||
case VIDEO_GET_EVENT: {
|
||||
#ifdef CONFIG_COMPAT
|
||||
struct compat_video_event *ev32 = arg;
|
||||
#endif
|
||||
struct video_event *ev = arg;
|
||||
DEFINE_WAIT(wait);
|
||||
|
||||
|
@ -1763,14 +1785,22 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
|
|||
if (test_and_clear_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
|
||||
ev->type = VIDEO_EVENT_DECODER_STOPPED;
|
||||
else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) {
|
||||
unsigned char vsync_field;
|
||||
|
||||
ev->type = VIDEO_EVENT_VSYNC;
|
||||
ev->u.vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ?
|
||||
vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ?
|
||||
VIDEO_VSYNC_FIELD_ODD : VIDEO_VSYNC_FIELD_EVEN;
|
||||
if (itv->output_mode == OUT_UDMA_YUV &&
|
||||
(itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) ==
|
||||
IVTV_YUV_MODE_PROGRESSIVE) {
|
||||
ev->u.vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE;
|
||||
vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE;
|
||||
}
|
||||
#ifdef CONFIG_COMPAT
|
||||
if (cmd == VIDEO_GET_EVENT32)
|
||||
ev32->u.vsync_field = vsync_field;
|
||||
else
|
||||
#endif
|
||||
ev->u.vsync_field = vsync_field;
|
||||
}
|
||||
if (ev->type)
|
||||
return 0;
|
||||
|
|
|
@ -932,7 +932,6 @@ static int dvb_video_get_event (struct av7110 *av7110, struct video_event *event
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* DVB device file operations
|
||||
******************************************************************************/
|
||||
|
@ -1095,6 +1094,42 @@ static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
struct compat_video_still_picture {
|
||||
compat_uptr_t iFrame;
|
||||
int32_t size;
|
||||
};
|
||||
#define VIDEO_STILLPICTURE32 _IOW('o', 30, struct compat_video_still_picture)
|
||||
|
||||
struct compat_video_event {
|
||||
__s32 type;
|
||||
/* unused, make sure to use atomic time for y2038 if it ever gets used */
|
||||
compat_long_t timestamp;
|
||||
union {
|
||||
video_size_t size;
|
||||
unsigned int frame_rate; /* in frames per 1000sec */
|
||||
unsigned char vsync_field; /* unknown/odd/even/progressive */
|
||||
} u;
|
||||
};
|
||||
#define VIDEO_GET_EVENT32 _IOR('o', 28, struct compat_video_event)
|
||||
|
||||
static int dvb_compat_video_get_event(struct av7110 *av7110,
|
||||
struct compat_video_event *event, int flags)
|
||||
{
|
||||
struct video_event ev;
|
||||
int ret;
|
||||
|
||||
ret = dvb_video_get_event(av7110, &ev, flags);
|
||||
|
||||
*event = (struct compat_video_event) {
|
||||
.type = ev.type,
|
||||
.timestamp = ev.timestamp,
|
||||
.u.size = ev.u.size,
|
||||
};
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int dvb_video_ioctl(struct file *file,
|
||||
unsigned int cmd, void *parg)
|
||||
|
@ -1184,6 +1219,12 @@ static int dvb_video_ioctl(struct file *file,
|
|||
memcpy(parg, &av7110->videostate, sizeof(struct video_status));
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
case VIDEO_GET_EVENT32:
|
||||
ret = dvb_compat_video_get_event(av7110, parg, file->f_flags);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case VIDEO_GET_EVENT:
|
||||
ret = dvb_video_get_event(av7110, parg, file->f_flags);
|
||||
break;
|
||||
|
@ -1226,6 +1267,19 @@ static int dvb_video_ioctl(struct file *file,
|
|||
1, (u16) arg);
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
case VIDEO_STILLPICTURE32:
|
||||
{
|
||||
struct compat_video_still_picture *pic =
|
||||
(struct compat_video_still_picture *) parg;
|
||||
av7110->videostate.stream_source = VIDEO_SOURCE_MEMORY;
|
||||
dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
|
||||
ret = play_iframe(av7110, compat_ptr(pic->iFrame),
|
||||
pic->size, file->f_flags & O_NONBLOCK);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case VIDEO_STILLPICTURE:
|
||||
{
|
||||
struct video_still_picture *pic =
|
||||
|
|
|
@ -103,11 +103,6 @@
|
|||
|
||||
#include <linux/hiddev.h>
|
||||
|
||||
#define __DVB_CORE__
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <linux/dvb/dmx.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
#include <linux/dvb/video.h>
|
||||
|
||||
#include <linux/sort.h>
|
||||
|
||||
|
@ -133,73 +128,6 @@ static int do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|||
return vfs_ioctl(file, cmd, arg);
|
||||
}
|
||||
|
||||
struct compat_video_event {
|
||||
int32_t type;
|
||||
compat_time_t timestamp;
|
||||
union {
|
||||
video_size_t size;
|
||||
unsigned int frame_rate;
|
||||
} u;
|
||||
};
|
||||
#define VIDEO_GET_EVENT32 _IOR('o', 28, struct compat_video_event)
|
||||
|
||||
static int do_video_get_event(struct file *file,
|
||||
unsigned int cmd, struct compat_video_event __user *up)
|
||||
{
|
||||
struct video_event __user *kevent =
|
||||
compat_alloc_user_space(sizeof(*kevent));
|
||||
int err;
|
||||
|
||||
if (kevent == NULL)
|
||||
return -EFAULT;
|
||||
|
||||
err = do_ioctl(file, VIDEO_GET_EVENT, (unsigned long)kevent);
|
||||
if (!err) {
|
||||
err = convert_in_user(&kevent->type, &up->type);
|
||||
err |= convert_in_user(&kevent->timestamp, &up->timestamp);
|
||||
err |= convert_in_user(&kevent->u.size.w, &up->u.size.w);
|
||||
err |= convert_in_user(&kevent->u.size.h, &up->u.size.h);
|
||||
err |= convert_in_user(&kevent->u.size.aspect_ratio,
|
||||
&up->u.size.aspect_ratio);
|
||||
if (err)
|
||||
err = -EFAULT;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
struct compat_video_still_picture {
|
||||
compat_uptr_t iFrame;
|
||||
int32_t size;
|
||||
};
|
||||
#define VIDEO_STILLPICTURE32 _IOW('o', 30, struct compat_video_still_picture)
|
||||
|
||||
static int do_video_stillpicture(struct file *file,
|
||||
unsigned int cmd, struct compat_video_still_picture __user *up)
|
||||
{
|
||||
struct video_still_picture __user *up_native;
|
||||
compat_uptr_t fp;
|
||||
int32_t size;
|
||||
int err;
|
||||
|
||||
err = get_user(fp, &up->iFrame);
|
||||
err |= get_user(size, &up->size);
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
|
||||
up_native =
|
||||
compat_alloc_user_space(sizeof(struct video_still_picture));
|
||||
|
||||
err = put_user(compat_ptr(fp), &up_native->iFrame);
|
||||
err |= put_user(size, &up_native->size);
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
|
||||
err = do_ioctl(file, VIDEO_STILLPICTURE, (unsigned long) up_native);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BLOCK
|
||||
typedef struct sg_io_hdr32 {
|
||||
compat_int_t interface_id; /* [i] 'S' for SCSI generic (required) */
|
||||
|
@ -1250,12 +1178,6 @@ static long do_ioctl_trans(unsigned int cmd,
|
|||
case RTC_EPOCH_READ32:
|
||||
case RTC_EPOCH_SET32:
|
||||
return rtc_ioctl(file, cmd, argp);
|
||||
|
||||
/* dvb */
|
||||
case VIDEO_GET_EVENT32:
|
||||
return do_video_get_event(file, cmd, argp);
|
||||
case VIDEO_STILLPICTURE32:
|
||||
return do_video_stillpicture(file, cmd, argp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue