⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compat_ioctl32.c

📁 V4l driver for DVB HD
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * ioctl32.c: Conversion between 32bit and 64bit native ioctls. *	Separated from fs stuff by Arnd Bergmann <arnd@arndb.de> * * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com) * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be) * Copyright (C) 2001,2002  Andi Kleen, SuSE Labs * Copyright (C) 2003       Pavel Machek (pavel@suse.cz) * Copyright (C) 2005       Philippe De Muyter (phdm@macqel.be) * * These routines maintain argument size conversion between 32bit and 64bit * ioctls. */#include "compat.h"#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11)#include <linux/config.h>#include <linux/compat.h>#include <linux/videodev.h>#include <linux/videodev2.h>#include <linux/module.h>#include <linux/smp_lock.h>#include <media/v4l2-common.h>#ifdef CONFIG_COMPATstruct 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){	if(!access_ok(VERIFY_READ, up, sizeof(struct video_tuner32)) ||		get_user(kp->tuner, &up->tuner) ||		copy_from_user(kp->name, up->name, 32) ||		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 -EFAULT;	return 0;}static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up){	if(!access_ok(VERIFY_WRITE, up, sizeof(struct video_tuner32)) ||		put_user(kp->tuner, &up->tuner) ||		copy_to_user(up->name, kp->name, 32) ||		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 -EFAULT;	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 (!access_ok(VERIFY_READ, up, sizeof(struct video_buffer32)) ||		get_user(tmp, &up->base) ||		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 -EFAULT;	/* This is actually a physical address stored	 * as a void pointer.	 */	kp->base = (void *)(unsigned long) tmp;	return 0;}static int put_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up){	u32 tmp = (u32)((unsigned long)kp->base);	if(!access_ok(VERIFY_WRITE, up, sizeof(struct video_buffer32)) ||		put_user(tmp, &up->base) ||		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 -EFAULT;	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_op->unlocked_ioctl)		ret = file->f_op->unlocked_ioctl(file, cmd, arg);	else if (file->f_op->ioctl) {		lock_kernel();		ret = file->f_op->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(!access_ok(VERIFY_WRITE, up, sizeof(struct video_window32)) ||		put_user(kp->x, &up->x) ||		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 -EFAULT;	return 0;}struct v4l2_clip32{	struct v4l2_rect        c;	compat_caddr_t 		next;};struct v4l2_window32{	struct v4l2_rect        w;	enum v4l2_field  	field;	__u32			chromakey;	compat_caddr_t		clips; /* actually struct v4l2_clip32 * */	__u32			clipcount;	compat_caddr_t		bitmap;};static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up){	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_window32)) ||		copy_from_user(&kp->w, &up->w, sizeof(up->w)) ||		get_user(kp->field, &up->field) ||		get_user(kp->chromakey, &up->chromakey) ||		get_user(kp->clipcount, &up->clipcount))			return -EFAULT;	if (kp->clipcount > 2048)		return -EINVAL;	if (kp->clipcount) {		struct v4l2_clip32 __user *uclips;		struct v4l2_clip __user *kclips;		int n = kp->clipcount;		compat_caddr_t p;		if (get_user(p, &up->clips))			return -EFAULT;		uclips = compat_ptr(p);		kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip));		kp->clips = kclips;		while (--n >= 0) {			if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c)))				return -EFAULT;			if (put_user(n ? kclips + 1 : NULL, &kclips->next))				return -EFAULT;			uclips += 1;			kclips += 1;		}	} else		kp->clips = NULL;	return 0;}static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up){	if (copy_to_user(&up->w, &kp->w, sizeof(up->w)) ||		put_user(kp->field, &up->field) ||		put_user(kp->chromakey, &up->chromakey) ||		put_user(kp->clipcount, &up->clipcount))			return -EFAULT;	return 0;}static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up){	if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format)))		return -EFAULT;	return 0;}static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up){	if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format)))		return -EFAULT;	return 0;}static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up){	if (copy_from_user(kp, up, sizeof(struct v4l2_vbi_format)))		return -EFAULT;	return 0;}static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up){	if (copy_to_user(up, kp, sizeof(struct v4l2_vbi_format)))		return -EFAULT;	return 0;}struct v4l2_format32{	enum v4l2_buf_type type;	union	{		struct v4l2_pix_format	pix;  // V4L2_BUF_TYPE_VIDEO_CAPTURE		struct v4l2_window32	win;  // V4L2_BUF_TYPE_VIDEO_OVERLAY		struct v4l2_vbi_format	vbi;  // V4L2_BUF_TYPE_VBI_CAPTURE		__u8	raw_data[200];        // user-defined	} fmt;};static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up){	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||			get_user(kp->type, &up->type))			return -EFAULT;	switch (kp->type) {	case V4L2_BUF_TYPE_VIDEO_CAPTURE:		return get_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix);	case V4L2_BUF_TYPE_VIDEO_OVERLAY:		return get_v4l2_window32(&kp->fmt.win, &up->fmt.win);	case V4L2_BUF_TYPE_VBI_CAPTURE:		return get_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi);	default:		printk("compat_ioctl : unexpected VIDIOC_FMT type %d\n",								kp->type);		return -ENXIO;	}}static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up){	if(!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||		put_user(kp->type, &up->type))		return -EFAULT;	switch (kp->type) {	case V4L2_BUF_TYPE_VIDEO_CAPTURE:		return put_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix);	case V4L2_BUF_TYPE_VIDEO_OVERLAY:		return put_v4l2_window32(&kp->fmt.win, &up->fmt.win);	case V4L2_BUF_TYPE_VBI_CAPTURE:		return put_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi);	default:		return -ENXIO;	}}static inline int get_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up){	if (copy_from_user(kp, up, sizeof(struct v4l2_standard)))		return -EFAULT;	return 0;}static inline int put_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up){	if (copy_to_user(up, kp, sizeof(struct v4l2_standard)))		return -EFAULT;	return 0;}struct v4l2_standard32{	__u32		     index;	__u32		     id[2]; /* __u64 would get the alignment wrong */	__u8		     name[24];	struct v4l2_fract    frameperiod; /* Frames, not fields */	__u32		     framelines;	__u32		     reserved[4];};static int get_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up){	/* other fields are not set by the user, nor used by the driver */	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_standard32)) ||		get_user(kp->index, &up->index))		return -EFAULT;	return 0;}static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up){	if(!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard32)) ||		put_user(kp->index, &up->index) ||		copy_to_user(up->id, &kp->id, sizeof(__u64)) ||		copy_to_user(up->name, kp->name, 24) ||		copy_to_user(&up->frameperiod, &kp->frameperiod, sizeof(kp->frameperiod)) ||		put_user(kp->framelines, &up->framelines) ||		copy_to_user(up->reserved, kp->reserved, 4 * sizeof(__u32)))			return -EFAULT;	return 0;}static inline int get_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up){	if (copy_from_user(kp, up, sizeof(struct v4l2_tuner)))		return -EFAULT;	return 0;}static inline int put_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up){	if (copy_to_user(up, kp, sizeof(struct v4l2_tuner)))		return -EFAULT;	return 0;}struct v4l2_buffer32{	__u32			index;	enum v4l2_buf_type      type;	__u32			bytesused;	__u32			flags;	enum v4l2_field		field;	struct compat_timeval	timestamp;	struct v4l2_timecode	timecode;	__u32			sequence;	/* memory location */	enum v4l2_memory        memory;	union {		__u32           offset;		compat_long_t   userptr;	} m;	__u32			length;	__u32			input;	__u32			reserved;};static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up){	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_buffer32)) ||		get_user(kp->index, &up->index) ||		get_user(kp->type, &up->type) ||		get_user(kp->flags, &up->flags) ||		get_user(kp->memory, &up->memory) ||		get_user(kp->input, &up->input))			return -EFAULT;	switch(kp->memory) {	case V4L2_MEMORY_MMAP:		break;	case V4L2_MEMORY_USERPTR:		{		compat_long_t tmp;		if (get_user(kp->length, &up->length) ||		    get_user(tmp, &up->m.userptr))			return -EFAULT;		kp->m.userptr = (unsigned long)compat_ptr(tmp);		}		break;	case V4L2_MEMORY_OVERLAY:		if(get_user(kp->m.offset, &up->m.offset))			return -EFAULT;		break;	}	return 0;}static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up){	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_buffer32)) ||		put_user(kp->index, &up->index) ||		put_user(kp->type, &up->type) ||		put_user(kp->flags, &up->flags) ||		put_user(kp->memory, &up->memory) ||		put_user(kp->input, &up->input))			return -EFAULT;	switch(kp->memory) {	case V4L2_MEMORY_MMAP:		if (put_user(kp->length, &up->length) ||			put_user(kp->m.offset, &up->m.offset))			return -EFAULT;		break;	case V4L2_MEMORY_USERPTR:		if (put_user(kp->length, &up->length) ||			put_user(kp->m.userptr, &up->m.userptr))			return -EFAULT;		break;	case V4L2_MEMORY_OVERLAY:		if (put_user(kp->m.offset, &up->m.offset))			return -EFAULT;		break;	}	if (put_user(kp->bytesused, &up->bytesused) ||		put_user(kp->field, &up->field) ||		put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||		put_user(kp->timestamp.tv_usec, &up->timestamp.tv_usec) ||		copy_to_user(&up->timecode, &kp->timecode, sizeof(struct v4l2_timecode)) ||		put_user(kp->sequence, &up->sequence) ||		put_user(kp->reserved, &up->reserved))			return -EFAULT;	return 0;}struct v4l2_framebuffer32{	__u32			capability;	__u32			flags;	compat_caddr_t 		base;	struct v4l2_pix_format	fmt;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -