V4L/DVB (5146): Make VIDIOC_INT_[SG]_REGISTER ioctls no longer internal only

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>
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 7bb7589..6515b2a 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -628,7 +628,7 @@
 #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 @@
 		break;
 	}
 
-	case VIDIOC_INT_S_REGISTER:
+	case VIDIOC_DBG_S_REGISTER:
 	{
 		struct v4l2_register *reg = arg;
 
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index ee8cbd3..f6736eb 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -1405,8 +1405,6 @@
 
 	if (reg->i2c_id != 0)
 		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	cx_write(reg->reg&0xffffff, reg->val);
 	return 0;
 }
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 5e166ed..2a35075 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -3277,7 +3277,7 @@
 
 
 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 @@
 			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;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
index dc7a3ba..e6df8e4 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -222,7 +222,7 @@
    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
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 49f5d3c..cde5f5f 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -738,16 +738,20 @@
 		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
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index 389e518..bb6aa13 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -1417,7 +1417,7 @@
 	}
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-	case VIDIOC_INT_G_REGISTER:
+	case VIDIOC_DBG_G_REGISTER:
 	{
 		struct v4l2_register *reg = arg;
 
@@ -1427,7 +1427,7 @@
 		break;
 	}
 
-	case VIDIOC_INT_S_REGISTER:
+	case VIDIOC_DBG_S_REGISTER:
 	{
 		struct v4l2_register *reg = arg;
 
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index ad401bd..304375ad 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -614,7 +614,7 @@
 		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 @@
 		break;
 	}
 
-	case VIDIOC_INT_S_REGISTER:
+	case VIDIOC_DBG_S_REGISTER:
 	{
 		struct v4l2_register *reg = arg;
 
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index bc0a4fc..65d4389 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -950,7 +950,7 @@
 	}
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-	case VIDIOC_INT_G_REGISTER:
+	case VIDIOC_DBG_G_REGISTER:
 	{
 		struct v4l2_register *reg = arg;
 
@@ -960,7 +960,7 @@
 		break;
 	}
 
-	case VIDIOC_INT_S_REGISTER:
+	case VIDIOC_DBG_S_REGISTER:
 	{
 		struct v4l2_register *reg = arg;
 
diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c
index fc52201..0eee82b 100644
--- a/drivers/media/video/upd64031a.c
+++ b/drivers/media/video/upd64031a.c
@@ -162,7 +162,7 @@
 		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 @@
 		break;
 	}
 
-	case VIDIOC_INT_S_REGISTER:
+	case VIDIOC_DBG_S_REGISTER:
 	{
 		struct v4l2_register *reg = arg;
 		u8 addr = reg->reg & 0xff;
diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c
index c3a7ffe..3f0eec0 100644
--- a/drivers/media/video/upd64083.c
+++ b/drivers/media/video/upd64083.c
@@ -139,7 +139,7 @@
 		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 @@
 		break;
 	}
 
-	case VIDIOC_INT_S_REGISTER:
+	case VIDIOC_DBG_S_REGISTER:
 	{
 		struct v4l2_register *reg = arg;
 		u8 addr = reg->reg & 0xff;
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index 82c3976..b6fabee 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -519,7 +519,7 @@
 
 #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 @@
 			/* 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 @@
 				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;
 			}
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index dab8751..d20d4ca 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -400,9 +400,10 @@
 	[_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 @@
 				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;
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
index 4b5d5f7..764a53b 100644
--- a/drivers/media/video/videodev.c
+++ b/drivers/media/video/videodev.c
@@ -1454,17 +1454,19 @@
 		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;
 	}
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 112b28c..fe6ccdf 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1271,6 +1271,17 @@
 };
 
 /*
+ *	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 @@
 #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 */
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 91b1992..959e6f6 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -99,13 +99,6 @@
 
 /* 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 @@
    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. */
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index 46eb71f..aeec569 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -77,9 +77,6 @@
 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