Commit 04b72322 authored by Arnd Bergmann's avatar Arnd Bergmann Committed by Mauro Carvalho Chehab
Browse files

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: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent 8a24280b
Loading
Loading
Loading
Loading
+32 −2
Original line number Diff line number Diff line
@@ -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;
+55 −1
Original line number Diff line number Diff line
@@ -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 =
+0 −78
Original line number Diff line number Diff line
@@ -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);
	}

	/*