From 99cd47bc733436da282016e629eef6baa0f6047c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 11 Mar 2011 19:00:56 -0300 Subject: [PATCH] [media] v4l2-ioctl: add priority handling support Drivers that use v4l2_fh can now use the core framework support of g/s_priority. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-si4713.c | 3 +- drivers/media/video/cpia2/cpia2_v4l.c | 3 +- drivers/media/video/cx18/cx18-ioctl.c | 3 +- drivers/media/video/davinci/vpfe_capture.c | 2 +- drivers/media/video/ivtv/ivtv-ioctl.c | 3 +- drivers/media/video/meye.c | 3 +- drivers/media/video/mxb.c | 3 +- drivers/media/video/pwc/pwc-v4l.c | 3 +- drivers/media/video/v4l2-ioctl.c | 64 +++++++++++++++++++--- include/media/v4l2-ioctl.h | 2 +- 10 files changed, 73 insertions(+), 16 deletions(-) diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c index 726d367ad8d0..444b4cf7e65c 100644 --- a/drivers/media/radio/radio-si4713.c +++ b/drivers/media/radio/radio-si4713.c @@ -224,7 +224,8 @@ static int radio_si4713_s_frequency(struct file *file, void *p, s_frequency, vf); } -static long radio_si4713_default(struct file *file, void *p, int cmd, void *arg) +static long radio_si4713_default(struct file *file, void *p, + bool valid_prio, int cmd, void *arg) { return v4l2_device_call_until_err(get_v4l2_dev(file), 0, core, ioctl, cmd, arg); diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c index 363fe098b748..5111bbcefad5 100644 --- a/drivers/media/video/cpia2/cpia2_v4l.c +++ b/drivers/media/video/cpia2/cpia2_v4l.c @@ -395,7 +395,8 @@ static int sync(struct camera_data *cam, int frame_nr) * *****************************************************************************/ -static long cpia2_default(struct file *file, void *fh, int cmd, void *arg) +static long cpia2_default(struct file *file, void *fh, bool valid_prio, + int cmd, void *arg) { struct camera_data *cam = video_drvdata(file); __u32 gpio_val; diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index 36b018c943e5..08ed75de1912 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c @@ -1057,7 +1057,8 @@ static int cx18_log_status(struct file *file, void *fh) return 0; } -static long cx18_default(struct file *file, void *fh, int cmd, void *arg) +static long cx18_default(struct file *file, void *fh, bool valid_prio, + int cmd, void *arg) { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c index 353eadaa823e..71e961e53a56 100644 --- a/drivers/media/video/davinci/vpfe_capture.c +++ b/drivers/media/video/davinci/vpfe_capture.c @@ -1719,7 +1719,7 @@ static int vpfe_s_crop(struct file *file, void *priv, static long vpfe_param_handler(struct file *file, void *priv, - int cmd, void *param) + bool valid_prio, int cmd, void *param) { struct vpfe_device *vpfe_dev = video_drvdata(file); int ret = 0; diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index b686da5e4326..d34a326c0ef0 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -1795,7 +1795,8 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) return 0; } -static long ivtv_default(struct file *file, void *fh, int cmd, void *arg) +static long ivtv_default(struct file *file, void *fh, bool valid_prio, + int cmd, void *arg) { struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index 48d2c2419c13..b09a3c80a15e 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c @@ -1547,7 +1547,8 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) return 0; } -static long vidioc_default(struct file *file, void *fh, int cmd, void *arg) +static long vidioc_default(struct file *file, void *fh, bool valid_prio, + int cmd, void *arg) { switch (cmd) { case MEYEIOC_G_PARAMS: diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c index e8846a09b026..0b3850023505 100644 --- a/drivers/media/video/mxb.c +++ b/drivers/media/video/mxb.c @@ -643,7 +643,8 @@ static int vidioc_s_register(struct file *file, void *fh, struct v4l2_dbg_regist } #endif -static long vidioc_default(struct file *file, void *fh, int cmd, void *arg) +static long vidioc_default(struct file *file, void *fh, bool valid_prio, + int cmd, void *arg) { struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; struct mxb *mxb = (struct mxb *)dev->ext_priv; diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c index 68a5313a52d5..aa87e462a958 100644 --- a/drivers/media/video/pwc/pwc-v4l.c +++ b/drivers/media/video/pwc/pwc-v4l.c @@ -860,7 +860,8 @@ static int pwc_enum_frameintervals(struct file *file, void *fh, return 0; } -static long pwc_default(struct file *file, void *fh, int cmd, void *arg) +static long pwc_default(struct file *file, void *fh, bool valid_prio, + int cmd, void *arg) { struct pwc_device *pdev = video_drvdata(file); diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index db6ec3868347..3e6b6fa5771a 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #define dbgarg(cmd, fmt, arg...) \ @@ -538,6 +539,7 @@ static long __video_do_ioctl(struct file *file, struct video_device *vfd = video_devdata(file); const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; void *fh = file->private_data; + struct v4l2_fh *vfh = NULL; struct v4l2_format f_copy; long ret = -EINVAL; @@ -553,6 +555,43 @@ static long __video_do_ioctl(struct file *file, printk(KERN_CONT "\n"); } + if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) + vfh = file->private_data; + + if (vfh && !ops->vidioc_s_priority) { + switch (cmd) { + case VIDIOC_S_CTRL: + case VIDIOC_S_STD: + case VIDIOC_S_INPUT: + case VIDIOC_S_OUTPUT: + case VIDIOC_S_TUNER: + case VIDIOC_S_FREQUENCY: + case VIDIOC_S_FMT: + case VIDIOC_S_CROP: + case VIDIOC_S_AUDIO: + case VIDIOC_S_AUDOUT: + case VIDIOC_S_EXT_CTRLS: + case VIDIOC_S_FBUF: + case VIDIOC_S_PRIORITY: + case VIDIOC_S_DV_PRESET: + case VIDIOC_S_DV_TIMINGS: + case VIDIOC_S_JPEGCOMP: + case VIDIOC_S_MODULATOR: + case VIDIOC_S_PARM: + case VIDIOC_S_HW_FREQ_SEEK: + case VIDIOC_ENCODER_CMD: + case VIDIOC_OVERLAY: + case VIDIOC_REQBUFS: + case VIDIOC_STREAMON: + case VIDIOC_STREAMOFF: + ret = v4l2_prio_check(vfd->prio, vfh->prio); + if (ret) + goto exit_prio; + ret = -EINVAL; + break; + } + } + switch (cmd) { /* --- capabilities ------------------------------------------ */ @@ -579,9 +618,12 @@ static long __video_do_ioctl(struct file *file, { enum v4l2_priority *p = arg; - if (!ops->vidioc_g_priority) - break; - ret = ops->vidioc_g_priority(file, fh, p); + if (ops->vidioc_g_priority) { + ret = ops->vidioc_g_priority(file, fh, p); + } else if (vfh) { + *p = v4l2_prio_max(&vfd->v4l2_dev->prio); + ret = 0; + } if (!ret) dbgarg(cmd, "priority is %d\n", *p); break; @@ -590,10 +632,13 @@ static long __video_do_ioctl(struct file *file, { enum v4l2_priority *p = arg; - if (!ops->vidioc_s_priority) - break; + if (!ops->vidioc_s_priority && vfh == NULL) + break; dbgarg(cmd, "setting priority to %d\n", *p); - ret = ops->vidioc_s_priority(file, fh, *p); + if (ops->vidioc_s_priority) + ret = ops->vidioc_s_priority(file, fh, *p); + else + ret = v4l2_prio_change(&vfd->v4l2_dev->prio, &vfh->prio, *p); break; } @@ -2138,13 +2183,18 @@ static long __video_do_ioctl(struct file *file, } default: { + bool valid_prio = true; + if (!ops->vidioc_default) break; - ret = ops->vidioc_default(file, fh, cmd, arg); + if (vfh && !ops->vidioc_s_priority) + valid_prio = v4l2_prio_check(vfd->prio, vfh->prio) >= 0; + ret = ops->vidioc_default(file, fh, valid_prio, cmd, arg); break; } } /* switch */ +exit_prio: if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { if (ret < 0) { v4l_print_ioctl(vfd->name, cmd); diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h index 1572c7f25777..dd9f1e7b8ff7 100644 --- a/include/media/v4l2-ioctl.h +++ b/include/media/v4l2-ioctl.h @@ -270,7 +270,7 @@ struct v4l2_ioctl_ops { /* For other private ioctls */ long (*vidioc_default) (struct file *file, void *fh, - int cmd, void *arg); + bool valid_prio, int cmd, void *arg); };