Commit b9d0aa6e authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab

[media] v4l: Add custom compat_ioctl32 operation

Drivers implementing custom ioctls need to handle 32-bit/64-bit
compatibility themselves. Provide them with a way to do so.

To avoid circular module dependencies, merge the v4l2-compat-ioctl32
module into videodev. There is no point in keeping them separate, as the
v4l2_compat_ioctl32() function is required by videodev if CONFIG_COMPAT
is set anyway.
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent f769c260
...@@ -12,14 +12,13 @@ omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o ...@@ -12,14 +12,13 @@ omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o
videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \ videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \
v4l2-event.o v4l2-ctrls.o v4l2-subdev.o v4l2-event.o v4l2-ctrls.o v4l2-subdev.o
ifeq ($(CONFIG_COMPAT),y)
videodev-objs += v4l2-compat-ioctl32.o
endif
# V4L2 core modules # V4L2 core modules
obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-int-device.o obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-int-device.o
ifeq ($(CONFIG_COMPAT),y)
obj-$(CONFIG_VIDEO_DEV) += v4l2-compat-ioctl32.o
endif
obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o
# All i2c modules must come first: # All i2c modules must come first:
......
...@@ -14,12 +14,11 @@ ...@@ -14,12 +14,11 @@
*/ */
#include <linux/compat.h> #include <linux/compat.h>
#include <linux/videodev2.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/videodev2.h>
#include <media/v4l2-dev.h>
#include <media/v4l2-ioctl.h> #include <media/v4l2-ioctl.h>
#ifdef CONFIG_COMPAT
static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{ {
long ret = -ENOIOCTLCMD; long ret = -ENOIOCTLCMD;
...@@ -937,6 +936,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar ...@@ -937,6 +936,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
{ {
struct video_device *vdev = video_devdata(file);
long ret = -ENOIOCTLCMD; long ret = -ENOIOCTLCMD;
if (!file->f_op->unlocked_ioctl) if (!file->f_op->unlocked_ioctl)
...@@ -1027,14 +1027,16 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) ...@@ -1027,14 +1027,16 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
break; break;
default: default:
if (vdev->fops->compat_ioctl32)
ret = vdev->fops->compat_ioctl32(file, cmd, arg);
if (ret == -ENOIOCTLCMD)
printk(KERN_WARNING "compat_ioctl32: " printk(KERN_WARNING "compat_ioctl32: "
"unknown ioctl '%c', dir=%d, #%d (0x%08x)\n", "unknown ioctl '%c', dir=%d, #%d (0x%08x)\n",
_IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd), cmd); _IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd),
cmd);
break; break;
} }
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(v4l2_compat_ioctl32); EXPORT_SYMBOL_GPL(v4l2_compat_ioctl32);
#endif
MODULE_LICENSE("GPL");
...@@ -62,6 +62,9 @@ struct v4l2_file_operations { ...@@ -62,6 +62,9 @@ struct v4l2_file_operations {
unsigned int (*poll) (struct file *, struct poll_table_struct *); unsigned int (*poll) (struct file *, struct poll_table_struct *);
long (*ioctl) (struct file *, unsigned int, unsigned long); long (*ioctl) (struct file *, unsigned int, unsigned long);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
#ifdef CONFIG_COMPAT
long (*compat_ioctl32) (struct file *, unsigned int, unsigned long);
#endif
unsigned long (*get_unmapped_area) (struct file *, unsigned long, unsigned long (*get_unmapped_area) (struct file *, unsigned long,
unsigned long, unsigned long, unsigned long); unsigned long, unsigned long, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *); int (*mmap) (struct file *, struct vm_area_struct *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment