[media] v4l: Add custom compat_ioctl32 operation
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Sun, 18 Dec 2011 23:41:19 +0000 (20:41 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Mon, 19 Mar 2012 17:06:12 +0000 (14:06 -0300)
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: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/Makefile
drivers/media/video/v4l2-compat-ioctl32.c
include/media/v4l2-dev.h

index 2a572bca3895a90860217e45631b4b4a14221b4c..d70dd0dc1f90bda162d73dddc75eb693b42a143e 100644 (file)
@@ -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 \
                        v4l2-event.o v4l2-ctrls.o v4l2-subdev.o
+ifeq ($(CONFIG_COMPAT),y)
+  videodev-objs += v4l2-compat-ioctl32.o
+endif
 
 # V4L2 core modules
 
 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
 
 # All i2c modules must come first:
index e6f67aa5b4c075fd8be254e53b3281d5e1ec6281..2829d256e4b7f2ed68905afb30bd44414e1b0ffe 100644 (file)
  */
 
 #include <linux/compat.h>
-#include <linux/videodev2.h>
 #include <linux/module.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-dev.h>
 #include <media/v4l2-ioctl.h>
 
-#ifdef CONFIG_COMPAT
-
 static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        long ret = -ENOIOCTLCMD;
@@ -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)
 {
+       struct video_device *vdev = video_devdata(file);
        long ret = -ENOIOCTLCMD;
 
        if (!file->f_op->unlocked_ioctl)
@@ -1027,14 +1027,16 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
                break;
 
        default:
-               printk(KERN_WARNING "compat_ioctl32: "
-                       "unknown ioctl '%c', dir=%d, #%d (0x%08x)\n",
-                       _IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd), cmd);
+               if (vdev->fops->compat_ioctl32)
+                       ret = vdev->fops->compat_ioctl32(file, cmd, arg);
+
+               if (ret == -ENOIOCTLCMD)
+                       printk(KERN_WARNING "compat_ioctl32: "
+                               "unknown ioctl '%c', dir=%d, #%d (0x%08x)\n",
+                               _IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd),
+                               cmd);
                break;
        }
        return ret;
 }
 EXPORT_SYMBOL_GPL(v4l2_compat_ioctl32);
-#endif
-
-MODULE_LICENSE("GPL");
index c7c40f1d2624a7eb7988ee376e324904b54c1d39..96d22215cc881a1d8a836c8312e86378efb7a51d 100644 (file)
@@ -62,6 +62,9 @@ struct v4l2_file_operations {
        unsigned int (*poll) (struct file *, struct poll_table_struct *);
        long (*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, unsigned long, unsigned long);
        int (*mmap) (struct file *, struct vm_area_struct *);