V4L/DVB (5146): Make VIDIOC_INT_[SG]_REGISTER ioctls no longer internal only
authorTrent Piepho <xyzzy@speakeasy.org>
Wed, 24 Jan 2007 01:38:13 +0000 (22:38 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Wed, 21 Feb 2007 15:34:55 +0000 (13:34 -0200)
The direct register access ioctls were defined as kernel internal only,
but they are very useful for debugging hardware from userspace and are
used as such.  Officially export them.

VIDIOC_INT_[SG]_REGISTER is renamed to VIDIOC_DBG_[SG]_REGISTER
Definition of ioctl and struct v4l2_register is moved from v4l2-common.h
to videodev2.h.

Types used in struct v4l2_register are changed to the userspace
exportable versions (u32 -> __u32, etc).

Use of VIDIOC_DBG_S_REGISTER requires CAP_SYS_ADMIN permission, so move
the check into the video_ioctl2() dispatcher so it doesn't need to be
duplicated in each driver's call-back function. CAP_SYS_ADMIN check is
added to pvrusb2 (which doesn't use video_ioctl2).

Signed-off-by: Trent Piepho <xyzzy@speakeasy.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
16 files changed:
drivers/media/video/cx25840/cx25840-core.c
drivers/media/video/cx88/cx88-video.c
drivers/media/video/pvrusb2/pvrusb2-hdw.c
drivers/media/video/pvrusb2/pvrusb2-hdw.h
drivers/media/video/pvrusb2/pvrusb2-v4l2.c
drivers/media/video/saa7115.c
drivers/media/video/saa7127.c
drivers/media/video/tvp5150.c
drivers/media/video/upd64031a.c
drivers/media/video/upd64083.c
drivers/media/video/usbvision/usbvision-video.c
drivers/media/video/v4l2-common.c
drivers/media/video/videodev.c
include/linux/videodev2.h
include/media/v4l2-common.h
include/media/v4l2-dev.h

index 7bb7589a07c30719f7796e78081d01cc0e878ee7..6515b2a784173d4e6b1c719abeba5beb3216f237 100644 (file)
@@ -628,7 +628,7 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        /* ioctls to allow direct access to the
         * cx25840 registers for testing */
-       case VIDIOC_INT_G_REGISTER:
+       case VIDIOC_DBG_G_REGISTER:
        {
                struct v4l2_register *reg = arg;
 
@@ -638,7 +638,7 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
                break;
        }
 
-       case VIDIOC_INT_S_REGISTER:
+       case VIDIOC_DBG_S_REGISTER:
        {
                struct v4l2_register *reg = arg;
 
index ee8cbd33cfc1c5b2e493f4688e64351488898f0a..f6736eb786bca66f18e96d36d67bafb6465fe3cb 100644 (file)
@@ -1405,8 +1405,6 @@ static int vidioc_s_register (struct file *file, void *fh,
 
        if (reg->i2c_id != 0)
                return -EINVAL;
-       if (!capable(CAP_SYS_ADMIN))
-               return -EPERM;
        cx_write(reg->reg&0xffffff, reg->val);
        return 0;
 }
index 5e166ed19fc5012e5066413f0234408660a8461e..2a350755bd30d58e7979a6806110225dfeeca071 100644 (file)
@@ -3277,7 +3277,7 @@ static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw)
 
 
 int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
-                            u32 chip_id,unsigned long reg_id,
+                            u32 chip_id, u32 reg_id,
                             int setFl,u32 *val_ptr)
 {
 #ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -3295,8 +3295,8 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
                        cp = list_entry(item,struct pvr2_i2c_client,list);
                        if (cp->client->driver->id != chip_id) continue;
                        stat = pvr2_i2c_client_cmd(
-                               cp,(setFl ? VIDIOC_INT_S_REGISTER :
-                                   VIDIOC_INT_G_REGISTER),&req);
+                               cp,(setFl ? VIDIOC_DBG_S_REGISTER :
+                                   VIDIOC_DBG_G_REGISTER),&req);
                        if (!setFl) *val_ptr = req.val;
                        okFl = !0;
                        break;
index dc7a3ba8dd18b4ea44b471ad213086e35a33b6f5..e6df8e4a7fe04ea9aeec3f0e95db858ddc8dd106 100644 (file)
@@ -222,7 +222,7 @@ void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *,
    setFl   - true to set the register, false to read it
    val_ptr - storage location for source / result. */
 int pvr2_hdw_register_access(struct pvr2_hdw *,
-                            u32 chip_id,unsigned long reg_id,
+                            u32 chip_id,u32 reg_id,
                             int setFl,u32 *val_ptr);
 
 /* The following entry points are all lower level things you normally don't
index 49f5d3c3614ccdb937e4b44ac9ed4ffc969807ff..cde5f5f3e8f2dab131a3e9454647d32ef02ac6af 100644 (file)
@@ -738,16 +738,20 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
                break;
        }
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-       case VIDIOC_INT_G_REGISTER:
-       case VIDIOC_INT_S_REGISTER:
+       case VIDIOC_DBG_S_REGISTER:
+               if (!capable(CAP_SYS_ADMIN)) {
+                       ret = -EPERM;
+                       break;
+               } /* fall through */
+       case VIDIOC_DBG_G_REGISTER:
        {
                u32 val;
                struct v4l2_register *req = (struct v4l2_register *)arg;
-               if (cmd == VIDIOC_INT_S_REGISTER) val = req->val;
+               if (cmd == VIDIOC_DBG_S_REGISTER) val = req->val;
                ret = pvr2_hdw_register_access(
                        hdw,req->i2c_id,req->reg,
-                       cmd == VIDIOC_INT_S_REGISTER,&val);
-               if (cmd == VIDIOC_INT_G_REGISTER) req->val = val;
+                       cmd == VIDIOC_DBG_S_REGISTER,&val);
+               if (cmd == VIDIOC_DBG_G_REGISTER) req->val = val;
                break;
        }
 #endif
index 389e518bc3e52e9dab7700a8af4ab0ec524dbf27..bb6aa135002a20e4636ef378f768084f5a3b53c3 100644 (file)
@@ -1417,7 +1417,7 @@ static int saa711x_command(struct i2c_client *client, unsigned int cmd, void *ar
        }
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-       case VIDIOC_INT_G_REGISTER:
+       case VIDIOC_DBG_G_REGISTER:
        {
                struct v4l2_register *reg = arg;
 
@@ -1427,7 +1427,7 @@ static int saa711x_command(struct i2c_client *client, unsigned int cmd, void *ar
                break;
        }
 
-       case VIDIOC_INT_S_REGISTER:
+       case VIDIOC_DBG_S_REGISTER:
        {
                struct v4l2_register *reg = arg;
 
index ad401bdefeaf39f30b566bffd8510f49f052925a..304375ade4a9aed6c6dc1468ceb41529af6317e0 100644 (file)
@@ -614,7 +614,7 @@ static int saa7127_command(struct i2c_client *client,
                break;
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-       case VIDIOC_INT_G_REGISTER:
+       case VIDIOC_DBG_G_REGISTER:
        {
                struct v4l2_register *reg = arg;
 
@@ -624,7 +624,7 @@ static int saa7127_command(struct i2c_client *client,
                break;
        }
 
-       case VIDIOC_INT_S_REGISTER:
+       case VIDIOC_DBG_S_REGISTER:
        {
                struct v4l2_register *reg = arg;
 
index bc0a4fc27b24452a828e971d906e1918aeff2a27..65d4389690a044a161cb7670e682987042058b35 100644 (file)
@@ -950,7 +950,7 @@ static int tvp5150_command(struct i2c_client *c,
        }
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-       case VIDIOC_INT_G_REGISTER:
+       case VIDIOC_DBG_G_REGISTER:
        {
                struct v4l2_register *reg = arg;
 
@@ -960,7 +960,7 @@ static int tvp5150_command(struct i2c_client *c,
                break;
        }
 
-       case VIDIOC_INT_S_REGISTER:
+       case VIDIOC_DBG_S_REGISTER:
        {
                struct v4l2_register *reg = arg;
 
index fc52201d607ea856da10d1584bd510dddfbe95dd..0eee82ba52bc127111f8ac32c04a2c31aae8fedf 100644 (file)
@@ -162,7 +162,7 @@ static int upd64031a_command(struct i2c_client *client, unsigned int cmd, void *
                break;
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-       case VIDIOC_INT_G_REGISTER:
+       case VIDIOC_DBG_G_REGISTER:
        {
                struct v4l2_register *reg = arg;
 
@@ -172,7 +172,7 @@ static int upd64031a_command(struct i2c_client *client, unsigned int cmd, void *
                break;
        }
 
-       case VIDIOC_INT_S_REGISTER:
+       case VIDIOC_DBG_S_REGISTER:
        {
                struct v4l2_register *reg = arg;
                u8 addr = reg->reg & 0xff;
index c3a7ffe5c2674365e1c3d47392678ce626d1806a..3f0eec0cdb45fd580bb9cc9b2948acd5551e0822 100644 (file)
@@ -139,7 +139,7 @@ static int upd64083_command(struct i2c_client *client, unsigned int cmd, void *a
                break;
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-       case VIDIOC_INT_G_REGISTER:
+       case VIDIOC_DBG_G_REGISTER:
        {
                struct v4l2_register *reg = arg;
 
@@ -149,7 +149,7 @@ static int upd64083_command(struct i2c_client *client, unsigned int cmd, void *a
                break;
        }
 
-       case VIDIOC_INT_S_REGISTER:
+       case VIDIOC_DBG_S_REGISTER:
        {
                struct v4l2_register *reg = arg;
                u8 addr = reg->reg & 0xff;
index 82c39767ba344211a9d1f56a15b27b6645d91e07..b6fabeeb8ab8c7e7e3e86c1ab8de3b714854b3c8 100644 (file)
@@ -519,7 +519,7 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file,
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
                /* ioctls to allow direct acces to the NT100x registers */
-               case VIDIOC_INT_G_REGISTER:
+               case VIDIOC_DBG_G_REGISTER:
                {
                        struct v4l2_register *reg = arg;
                        int errCode;
@@ -529,17 +529,17 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file,
                        /* NT100x has a 8-bit register space */
                        errCode = usbvision_read_reg(usbvision, reg->reg&0xff);
                        if (errCode < 0) {
-                               err("%s: VIDIOC_INT_G_REGISTER failed: error %d", __FUNCTION__, errCode);
+                               err("%s: VIDIOC_DBG_G_REGISTER failed: error %d", __FUNCTION__, errCode);
                        }
                        else {
                                reg->val=(unsigned char)errCode;
-                               PDEBUG(DBG_IOCTL, "VIDIOC_INT_G_REGISTER reg=0x%02X, value=0x%02X",
+                               PDEBUG(DBG_IOCTL, "VIDIOC_DBG_G_REGISTER reg=0x%02X, value=0x%02X",
                                                        (unsigned int)reg->reg, reg->val);
                                errCode = 0; // No error
                        }
                        return errCode;
                }
-               case VIDIOC_INT_S_REGISTER:
+               case VIDIOC_DBG_S_REGISTER:
                {
                        struct v4l2_register *reg = arg;
                        int errCode;
@@ -550,10 +550,10 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file,
                                return -EPERM;
                        errCode = usbvision_write_reg(usbvision, reg->reg&0xff, reg->val);
                        if (errCode < 0) {
-                               err("%s: VIDIOC_INT_S_REGISTER failed: error %d", __FUNCTION__, errCode);
+                               err("%s: VIDIOC_DBG_S_REGISTER failed: error %d", __FUNCTION__, errCode);
                        }
                        else {
-                               PDEBUG(DBG_IOCTL, "VIDIOC_INT_S_REGISTER reg=0x%02X, value=0x%02X",
+                               PDEBUG(DBG_IOCTL, "VIDIOC_DBG_S_REGISTER reg=0x%02X, value=0x%02X",
                                                        (unsigned int)reg->reg, reg->val);
                                errCode = 0;
                        }
index dab87512b9bdaf3c577df8d29b34a87aabd3e67a..d20d4ca5d8a32c86e8b9009194a6ac721f6e7d07 100644 (file)
@@ -400,9 +400,10 @@ static const char *v4l2_int_ioctls[] = {
        [_IOC_NR(TUNER_SET_STANDBY)]           = "TUNER_SET_STANDBY",
        [_IOC_NR(TDA9887_SET_CONFIG)]          = "TDA9887_SET_CONFIG",
 
+       [_IOC_NR(VIDIOC_DBG_S_REGISTER)]       = "VIDIOC_DBG_S_REGISTER",
+       [_IOC_NR(VIDIOC_DBG_G_REGISTER)]       = "VIDIOC_DBG_G_REGISTER",
+
        [_IOC_NR(VIDIOC_INT_S_TUNER_MODE)]     = "VIDIOC_INT_S_TUNER_MODE",
-       [_IOC_NR(VIDIOC_INT_S_REGISTER)]       = "VIDIOC_INT_S_REGISTER",
-       [_IOC_NR(VIDIOC_INT_G_REGISTER)]       = "VIDIOC_INT_G_REGISTER",
        [_IOC_NR(VIDIOC_INT_RESET)]            = "VIDIOC_INT_RESET",
        [_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ",
        [_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)]  = "VIDIOC_INT_DECODE_VBI_LINE",
@@ -753,11 +754,11 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg)
                                p->id,p->index,p->name);
                break;
        }
-       case VIDIOC_INT_G_REGISTER:
-       case VIDIOC_INT_S_REGISTER:
+       case VIDIOC_DBG_G_REGISTER:
+       case VIDIOC_DBG_S_REGISTER:
        {
                struct v4l2_register *p=arg;
-               printk ("%s: i2c_id=%d, reg=%lu, val=%d\n", s,
+               printk ("%s: i2c_id=%d, reg=%d, val=%d\n", s,
                                p->i2c_id,p->reg,p->val);
 
                break;
index 4b5d5f771e4c949eb89c1c85bffac8bd0727af39..764a53b70db24ae31b8076b969668cb195bb6235 100644 (file)
@@ -1454,17 +1454,19 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
                break;
        }
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-       case VIDIOC_INT_G_REGISTER:
+       case VIDIOC_DBG_G_REGISTER:
        {
                struct v4l2_register *p=arg;
                if (vfd->vidioc_g_register)
                        ret=vfd->vidioc_g_register(file, fh, p);
                break;
        }
-       case VIDIOC_INT_S_REGISTER:
+       case VIDIOC_DBG_S_REGISTER:
        {
                struct v4l2_register *p=arg;
-               if (vfd->vidioc_s_register)
+               if (!capable(CAP_SYS_ADMIN))
+                       ret=-EPERM;
+               else if (vfd->vidioc_s_register)
                        ret=vfd->vidioc_s_register(file, fh, p);
                break;
        }
index 112b28c1f63a8fe9c17de624584a31f61aaa17ca..fe6ccdfa9d48b6273c61bc964b3461f0ec508295 100644 (file)
@@ -1270,6 +1270,17 @@ struct v4l2_streamparm
        } parm;
 };
 
+/*
+ *     A D V A N C E D   D E B U G G I N G
+ */
+
+/* VIDIOC_DBG_G_REGISTER and VIDIOC_DBG_S_REGISTER */
+struct v4l2_register {
+       __u32 i2c_id; /* I2C driver ID of the I2C chip, or 0 for the host */
+       __u32 reg;
+       __u32 val;
+};
+
 /*
  *     I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
  *
@@ -1339,6 +1350,9 @@ struct v4l2_streamparm
 #define VIDIOC_ENUM_FRAMESIZES _IOWR ('V', 74, struct v4l2_frmsizeenum)
 #define VIDIOC_ENUM_FRAMEINTERVALS     _IOWR ('V', 75, struct v4l2_frmivalenum)
 #endif
+/* only implemented if CONFIG_VIDEO_ADV_DEBUG is defined */
+#define        VIDIOC_DBG_S_REGISTER   _IOW ('d', 100, struct v4l2_register)
+#define        VIDIOC_DBG_G_REGISTER   _IOWR('d', 101, struct v4l2_register)
 
 #ifdef __OLD_VIDIOC_
 /* for compatibility, will go away some day */
index 91b19921f958af283e5fc78521847c5b7785ca3c..959e6f6a4eff6d8fb68b5eff44eadd1630d49d9e 100644 (file)
@@ -99,13 +99,6 @@ u32 v4l2_ctrl_next(const u32 * const *ctrl_classes, u32 id);
 
 /* Internal ioctls */
 
-/* VIDIOC_INT_G_REGISTER and VIDIOC_INT_S_REGISTER */
-struct v4l2_register {
-       u32 i2c_id;             /* I2C driver ID of the I2C chip. 0 for the I2C adapter. */
-       unsigned long reg;
-       u32 val;
-};
-
 /* VIDIOC_INT_DECODE_VBI_LINE */
 struct v4l2_decode_vbi_line {
        u32 is_second_field;    /* Set to 0 for the first (odd) field,
@@ -175,9 +168,7 @@ enum v4l2_chip_ident {
    Replacement of TUNER_SET_STANDBY. */
 #define VIDIOC_INT_S_STANDBY        _IOW('d', 94, u32)
 
-/* only implemented if CONFIG_VIDEO_ADV_DEBUG is defined */
-#define        VIDIOC_INT_S_REGISTER           _IOW ('d', 100, struct v4l2_register)
-#define        VIDIOC_INT_G_REGISTER           _IOWR('d', 101, struct v4l2_register)
+/* 100, 101 used by  VIDIOC_DBG_[SG]_REGISTER */
 
 /* Generic reset command. The argument selects which subsystems to reset.
    Passing 0 will always reset the whole chip. */
index 46eb71f5653ceac859bbaf15231d6bd666bdad82..aeec56992ef5bb071b768edefab68e5f0ade6238 100644 (file)
@@ -77,9 +77,6 @@ int v4l_compat_translate_ioctl(struct inode *inode, struct file *file,
 extern long v4l_compat_ioctl32(struct file *file, unsigned int cmd,
                                unsigned long arg);
 
-/* Forward definition of v4l2-common.h defined structure */
-struct v4l2_register;
-
 /*
  * Newer version of video_device, handled by videodev2.c
  *     This version moves redundant code from video device code to