Add basic support for ioctl operations on the rc chardev. Only two ioctl's are defined for now: one to get the rc-core version and one to get the driver type of a given chardev. Userspace is expected to make sure that both match the expected values before proceeding with any ioctl/read/write ops. Signed-off-by: David Härdeman <david@xxxxxxxxxxx> --- Documentation/ioctl/ioctl-number.txt | 1 + drivers/media/rc/rc-main.c | 65 ++++++++++++++++++++++++++++++++++ include/media/rc-core.h | 19 ++++++++++ 3 files changed, 85 insertions(+) diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt index d7e43fa..2868bc8 100644 --- a/Documentation/ioctl/ioctl-number.txt +++ b/Documentation/ioctl/ioctl-number.txt @@ -270,6 +270,7 @@ Code Seq#(hex) Include File Comments 'v' 00-0F linux/sonypi.h conflict! 'v' C0-FF linux/meye.h conflict! 'w' all CERN SCI driver +'x' all media/rc-core.h Remote Control drivers 'y' 00-1F packet based user level communications <mailto:zapman@xxxxxxxxxxxx> 'z' 00-3F CAN bus card conflict! diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index d7b24a1..477ad49 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1635,6 +1635,67 @@ static int rc_fasync(int fd, struct file *file, int on) return fasync_helper(fd, file, on, &client->fasync); } +/** + * rc_do_ioctl() - internal implementation of ioctl handling + * @dev: the &struct rc_dev to perform the command on + * @cmd: the ioctl command to perform + * @arg: the argument to the ioctl cmd + * @return: zero on success, or a negative error code + * + * This function (which is called with the @dev mutex held) performs + * the actual processing of ioctl commands. + */ +static long rc_do_ioctl(struct rc_dev *dev, unsigned int cmd, unsigned long arg) +{ + void __user *p = (void __user *)arg; + unsigned int __user *ip = (unsigned int __user *)p; + + switch (cmd) { + + case RCIOCGVERSION: + return put_user(RC_VERSION, ip); + + case RCIOCGTYPE: + return put_user(dev->driver_type, ip); + } + + return -EINVAL; +} + +/** + * rc_ioctl() - allows userspace to do ioctl operations on the rc device file + * @fd: the file descriptor corresponding to the opened rc device + * @file: the &struct file corresponding to the previous open() + * @cmd: the ioctl command to perform + * @arg: the argument to the ioctl cmd + * @return: zero on success, or a negative error code + * + * This function (which implements the ioctl functionality in + * &struct file_operations) allows userspace to perform various ioctl + * operations on a rc device file. + */ +static long rc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct rc_client *client = file->private_data; + struct rc_dev *dev = client->dev; + int ret; + + ret = mutex_lock_interruptible(&dev->lock); + if (ret) + return ret; + + if (dev->dead) { + ret = -ENODEV; + goto out; + } + + ret = rc_do_ioctl(dev, cmd, arg); + +out: + mutex_unlock(&dev->lock); + return ret; +} + static const struct file_operations rc_fops = { .owner = THIS_MODULE, .open = rc_dev_open, @@ -1644,6 +1705,10 @@ static const struct file_operations rc_fops = { .poll = rc_poll, .fasync = rc_fasync, .llseek = no_llseek, + .unlocked_ioctl = rc_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = rc_ioctl, +#endif }; /** diff --git a/include/media/rc-core.h b/include/media/rc-core.h index 39f3794..660a331 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -30,6 +30,25 @@ do { \ pr_debug("%s: " fmt, __func__, ##__VA_ARGS__); \ } while (0) +#define RC_VERSION 0x010000 + +/* + * ioctl definitions + * + * Note: userspace programs which wish to interact with /dev/rc/rc? devices + * should make sure that the RC version and driver type is known + * (by using RCIOCGVERSION and RCIOCGTYPE) before continuing with any + * read/write/ioctl ops. + */ +#define RC_IOC_MAGIC 'x' + +/* get rc version */ +#define RCIOCGVERSION _IOR(RC_IOC_MAGIC, 0x01, unsigned int) + +/* get driver/hardware type */ +#define RCIOCGTYPE _IOR(RC_IOC_MAGIC, 0x02, unsigned int) + + enum rc_driver_type { RC_DRIVER_SCANCODE = 0, /* Driver or hardware generates a scancode */ RC_DRIVER_IR_RAW, /* Needs a Infra-Red pulse/space decoder */ -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html