On 9/13/19 8:57 AM, Vandana BN wrote: > Add VFL_TYPE_METADATA, to detect devices of type metadata and > to disable unneeded ioctls. > Without this change, format ioctls for both video and metadata devices > could be called on both device nodes.This is true for other ioctls as > well. > > Signed-off-by: Vandana BN <bnvandana@xxxxxxxxx> > --- > V3 Updated commit message > > drivers/media/v4l2-core/v4l2-dev.c | 57 ++++++++++++++++++---------- > drivers/media/v4l2-core/v4l2-ioctl.c | 5 ++- > include/media/v4l2-dev.h | 2 + > 3 files changed, 41 insertions(+), 23 deletions(-) > > diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c > index 4037689a945a..5f2ead772c5f 100644 > --- a/drivers/media/v4l2-core/v4l2-dev.c > +++ b/drivers/media/v4l2-core/v4l2-dev.c > @@ -112,6 +112,7 @@ static inline unsigned long *devnode_bits(enum vfl_devnode_type vfl_type) > one single bitmap for the purposes of finding a free node number > since all those unassigned types use the same minor range. */ > int idx = (vfl_type > VFL_TYPE_RADIO) ? VFL_TYPE_MAX - 1 : vfl_type; > + idx = (vfl_type == VFL_TYPE_METADATA) ? VFL_TYPE_GRABBER : vfl_type; > > return devnode_nums[idx]; > } > @@ -119,7 +120,9 @@ static inline unsigned long *devnode_bits(enum vfl_devnode_type vfl_type) > /* Return the bitmap corresponding to vfl_type. */ > static inline unsigned long *devnode_bits(enum vfl_devnode_type vfl_type) > { > - return devnode_nums[vfl_type]; > + int idx = (vfl_type == VFL_TYPE_METADATA) ? VFL_TYPE_GRABBER : vfl_type; > + > + return devnode_nums[idx]; > } > #endif > > @@ -540,6 +543,7 @@ static void determine_valid_ioctls(struct video_device *vdev) > bool is_radio = vdev->vfl_type == VFL_TYPE_RADIO; > bool is_sdr = vdev->vfl_type == VFL_TYPE_SDR; > bool is_tch = vdev->vfl_type == VFL_TYPE_TOUCH; > + bool is_meta = vdev->vfl_type == VFL_TYPE_METADATA; > bool is_rx = vdev->vfl_dir != VFL_DIR_TX; > bool is_tx = vdev->vfl_dir != VFL_DIR_RX; > > @@ -571,8 +575,10 @@ static void determine_valid_ioctls(struct video_device *vdev) > set_bit(_IOC_NR(VIDIOC_TRY_EXT_CTRLS), valid_ioctls); > if (vdev->ctrl_handler || ops->vidioc_querymenu) > set_bit(_IOC_NR(VIDIOC_QUERYMENU), valid_ioctls); > - SET_VALID_IOCTL(ops, VIDIOC_G_FREQUENCY, vidioc_g_frequency); > - SET_VALID_IOCTL(ops, VIDIOC_S_FREQUENCY, vidioc_s_frequency); > + if (!is_meta) { > + SET_VALID_IOCTL(ops, VIDIOC_G_FREQUENCY, vidioc_g_frequency); > + SET_VALID_IOCTL(ops, VIDIOC_S_FREQUENCY, vidioc_s_frequency); > + } > SET_VALID_IOCTL(ops, VIDIOC_LOG_STATUS, vidioc_log_status); > #ifdef CONFIG_VIDEO_ADV_DEBUG > set_bit(_IOC_NR(VIDIOC_DBG_G_CHIP_INFO), valid_ioctls); > @@ -589,37 +595,29 @@ static void determine_valid_ioctls(struct video_device *vdev) > if (is_vid || is_tch) { > /* video and metadata specific ioctls */ > if ((is_rx && (ops->vidioc_enum_fmt_vid_cap || > - ops->vidioc_enum_fmt_vid_overlay || > - ops->vidioc_enum_fmt_meta_cap)) || > - (is_tx && (ops->vidioc_enum_fmt_vid_out || > - ops->vidioc_enum_fmt_meta_out))) > + ops->vidioc_enum_fmt_vid_overlay)) || > + (is_tx && ops->vidioc_enum_fmt_vid_out)) > set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls); > if ((is_rx && (ops->vidioc_g_fmt_vid_cap || > ops->vidioc_g_fmt_vid_cap_mplane || > - ops->vidioc_g_fmt_vid_overlay || > - ops->vidioc_g_fmt_meta_cap)) || > + ops->vidioc_g_fmt_vid_overlay)) || > (is_tx && (ops->vidioc_g_fmt_vid_out || > ops->vidioc_g_fmt_vid_out_mplane || > - ops->vidioc_g_fmt_vid_out_overlay || > - ops->vidioc_g_fmt_meta_out))) > + ops->vidioc_g_fmt_vid_out_overlay))) > set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls); > if ((is_rx && (ops->vidioc_s_fmt_vid_cap || > ops->vidioc_s_fmt_vid_cap_mplane || > - ops->vidioc_s_fmt_vid_overlay || > - ops->vidioc_s_fmt_meta_cap)) || > + ops->vidioc_s_fmt_vid_overlay)) || > (is_tx && (ops->vidioc_s_fmt_vid_out || > ops->vidioc_s_fmt_vid_out_mplane || > - ops->vidioc_s_fmt_vid_out_overlay || > - ops->vidioc_s_fmt_meta_out))) > + ops->vidioc_s_fmt_vid_out_overlay))) > set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls); > if ((is_rx && (ops->vidioc_try_fmt_vid_cap || > ops->vidioc_try_fmt_vid_cap_mplane || > - ops->vidioc_try_fmt_vid_overlay || > - ops->vidioc_try_fmt_meta_cap)) || > + ops->vidioc_try_fmt_vid_overlay)) || > (is_tx && (ops->vidioc_try_fmt_vid_out || > ops->vidioc_try_fmt_vid_out_mplane || > - ops->vidioc_try_fmt_vid_out_overlay || > - ops->vidioc_try_fmt_meta_out))) > + ops->vidioc_try_fmt_vid_out_overlay))) > set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls); > SET_VALID_IOCTL(ops, VIDIOC_OVERLAY, vidioc_overlay); > SET_VALID_IOCTL(ops, VIDIOC_G_FBUF, vidioc_g_fbuf); > @@ -679,9 +677,23 @@ static void determine_valid_ioctls(struct video_device *vdev) > set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls); > if (ops->vidioc_try_fmt_sdr_out) > set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls); > + } else if (is_meta) { > + /* metadata specific ioctls */ > + if ((is_rx && ops->vidioc_enum_fmt_meta_cap) || > + (is_tx && ops->vidioc_enum_fmt_meta_out)) > + set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls); > + if ((is_rx && ops->vidioc_g_fmt_meta_cap) || > + (is_tx && ops->vidioc_g_fmt_meta_out)) > + set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls); > + if ((is_rx && ops->vidioc_s_fmt_meta_cap) || > + (is_tx && ops->vidioc_s_fmt_meta_out)) > + set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls); > + if ((is_rx && ops->vidioc_try_fmt_meta_cap) || > + (is_tx && ops->vidioc_try_fmt_meta_out)) > + set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls); After some more testing I realized that metadata devices should still support ENUM/G/S_INPUT for capture and ENUM/S/G_OUTPUT for output. Can you post a v4 with support for that? Thanks! Hans > } > > - if (is_vid || is_vbi || is_sdr || is_tch) { > + if (is_vid || is_vbi || is_sdr || is_tch || is_meta) { > /* ioctls valid for video, metadata, vbi or sdr */ > SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs); > SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf); > @@ -734,7 +746,7 @@ static void determine_valid_ioctls(struct video_device *vdev) > SET_VALID_IOCTL(ops, VIDIOC_G_MODULATOR, vidioc_g_modulator); > SET_VALID_IOCTL(ops, VIDIOC_S_MODULATOR, vidioc_s_modulator); > } > - if (is_rx) { > + if (is_rx && !is_meta) { > /* receiver only ioctls */ > SET_VALID_IOCTL(ops, VIDIOC_G_TUNER, vidioc_g_tuner); > SET_VALID_IOCTL(ops, VIDIOC_S_TUNER, vidioc_s_tuner); > @@ -762,6 +774,7 @@ static int video_register_media_controller(struct video_device *vdev) > > switch (vdev->vfl_type) { > case VFL_TYPE_GRABBER: > + case VFL_TYPE_METADATA: > intf_type = MEDIA_INTF_T_V4L_VIDEO; > vdev->entity.function = MEDIA_ENT_F_IO_V4L; > break; > @@ -870,6 +883,7 @@ int __video_register_device(struct video_device *vdev, > /* Part 1: check device type */ > switch (type) { > case VFL_TYPE_GRABBER: > + case VFL_TYPE_METADATA: > name_base = "video"; > break; > case VFL_TYPE_VBI: > @@ -914,6 +928,7 @@ int __video_register_device(struct video_device *vdev, > * (new style). */ > switch (type) { > case VFL_TYPE_GRABBER: > + case VFL_TYPE_METADATA: > minor_offset = 0; > minor_cnt = 64; > break; > diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c > index 51b912743f0f..0d71c06c82cf 100644 > --- a/drivers/media/v4l2-core/v4l2-ioctl.c > +++ b/drivers/media/v4l2-core/v4l2-ioctl.c > @@ -938,6 +938,7 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type) > bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI; > bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR; > bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH; > + bool is_meta = vfd->vfl_type == VFL_TYPE_METADATA; > bool is_rx = vfd->vfl_dir != VFL_DIR_TX; > bool is_tx = vfd->vfl_dir != VFL_DIR_RX; > > @@ -996,11 +997,11 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type) > return 0; > break; > case V4L2_BUF_TYPE_META_CAPTURE: > - if (is_vid && is_rx && ops->vidioc_g_fmt_meta_cap) > + if (is_meta && is_rx && ops->vidioc_g_fmt_meta_cap) > return 0; > break; > case V4L2_BUF_TYPE_META_OUTPUT: > - if (is_vid && is_tx && ops->vidioc_g_fmt_meta_out) > + if (is_meta && is_tx && ops->vidioc_g_fmt_meta_out) > return 0; > break; > default: > diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h > index 48531e57cc5a..2da91d454c10 100644 > --- a/include/media/v4l2-dev.h > +++ b/include/media/v4l2-dev.h > @@ -30,6 +30,7 @@ > * @VFL_TYPE_SUBDEV: for V4L2 subdevices > * @VFL_TYPE_SDR: for Software Defined Radio tuners > * @VFL_TYPE_TOUCH: for touch sensors > + * @VFL_TYPE_METADATA: for Metadata device > * @VFL_TYPE_MAX: number of VFL types, must always be last in the enum > */ > enum vfl_devnode_type { > @@ -39,6 +40,7 @@ enum vfl_devnode_type { > VFL_TYPE_SUBDEV, > VFL_TYPE_SDR, > VFL_TYPE_TOUCH, > + VFL_TYPE_METADATA, > VFL_TYPE_MAX /* Shall be the last one */ > }; > >