From 7bbe7813290df9fda0c175b7a703325720594912 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 1 Mar 2016 11:57:23 -0300 Subject: [media] v4l2: add device_caps to struct video_device Instead of letting drivers fill in device_caps at querycap time, let them fill it in when the video device is registered. This has the advantage that in the future the v4l2 core can access the video device's capabilities and take decisions based on that. Signed-off-by: Hans Verkuil Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ioctl.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/media/v4l2-core') diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 170dd68d27f4..6bf5a3ecd126 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1020,9 +1020,12 @@ static int v4l_querycap(const struct v4l2_ioctl_ops *ops, struct file *file, void *fh, void *arg) { struct v4l2_capability *cap = (struct v4l2_capability *)arg; + struct video_device *vfd = video_devdata(file); int ret; cap->version = LINUX_VERSION_CODE; + cap->device_caps = vfd->device_caps; + cap->capabilities = vfd->device_caps | V4L2_CAP_DEVICE_CAPS; ret = ops->vidioc_querycap(file, fh, cap); -- cgit From 54ace1cfd4358fd11112f17cc711eea234d5ab9e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 29 Feb 2016 07:16:39 -0300 Subject: [media] v4l2-ioctl: simplify code Instead of a big if at the beginning, just check if g_selection == NULL and call the cropcap op immediately and return the result. No functional changes in this patch. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ioctl.c | 51 ++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 22 deletions(-) (limited to 'drivers/media/v4l2-core') diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 6bf5a3ecd126..3cf8d3adab03 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -2160,33 +2160,40 @@ static int v4l_cropcap(const struct v4l2_ioctl_ops *ops, struct file *file, void *fh, void *arg) { struct v4l2_cropcap *p = arg; + struct v4l2_selection s = { .type = p->type }; + int ret; - if (ops->vidioc_g_selection) { - struct v4l2_selection s = { .type = p->type }; - int ret; + if (ops->vidioc_g_selection == NULL) { + /* + * The determine_valid_ioctls() call already should ensure + * that ops->vidioc_cropcap != NULL, but just in case... + */ + if (ops->vidioc_cropcap) + return ops->vidioc_cropcap(file, fh, p); + return -ENOTTY; + } - /* obtaining bounds */ - if (V4L2_TYPE_IS_OUTPUT(p->type)) - s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS; - else - s.target = V4L2_SEL_TGT_CROP_BOUNDS; + /* obtaining bounds */ + if (V4L2_TYPE_IS_OUTPUT(p->type)) + s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS; + else + s.target = V4L2_SEL_TGT_CROP_BOUNDS; - ret = ops->vidioc_g_selection(file, fh, &s); - if (ret) - return ret; - p->bounds = s.r; + ret = ops->vidioc_g_selection(file, fh, &s); + if (ret) + return ret; + p->bounds = s.r; - /* obtaining defrect */ - if (V4L2_TYPE_IS_OUTPUT(p->type)) - s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT; - else - s.target = V4L2_SEL_TGT_CROP_DEFAULT; + /* obtaining defrect */ + if (V4L2_TYPE_IS_OUTPUT(p->type)) + s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT; + else + s.target = V4L2_SEL_TGT_CROP_DEFAULT; - ret = ops->vidioc_g_selection(file, fh, &s); - if (ret) - return ret; - p->defrect = s.r; - } + ret = ops->vidioc_g_selection(file, fh, &s); + if (ret) + return ret; + p->defrect = s.r; /* setting trivial pixelaspect */ p->pixelaspect.numerator = 1; -- cgit From baf43c6eace43868e490f18560287fa3481b2159 Mon Sep 17 00:00:00 2001 From: Tiffany Lin Date: Mon, 14 Mar 2016 08:16:14 -0300 Subject: [media] media: v4l2-compat-ioctl32: fix missing reserved field copy in put_v4l2_create32 In v4l2-compliance utility, test VIDIOC_CREATE_BUFS will check whether reserved filed of v4l2_create_buffers filled with zero Reserved field is filled with zero in v4l_create_bufs. This patch copy reserved field of v4l2_create_buffer from kernel space to user space Signed-off-by: Tiffany Lin Signed-off-by: Hans Verkuil Cc: # for v3.19 and up Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/media/v4l2-core') diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c index 019644ff627d..bacecbd68a6d 100644 --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c @@ -280,7 +280,8 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up) { if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_create_buffers32)) || - copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format))) + copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format)) || + copy_to_user(up->reserved, kp->reserved, sizeof(kp->reserved))) return -EFAULT; return __put_v4l2_format32(&kp->format, &up->format); } -- cgit From b76a2a8cb6f6d9da711305d805156b40c698e94f Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 29 Feb 2016 08:45:44 -0300 Subject: [media] media: Add obj_type field to struct media_entity Code that processes media entities can require knowledge of the structure type that embeds a particular media entity instance in order to cast the entity to the proper object type. This needs is shown by the presence of the is_media_entity_v4l2_io and is_media_entity_v4l2_subdev functions. The implementation of those two functions relies on the entity function field, which is both a wrong and an inefficient design, without even mentioning the maintenance issue involved in updating the functions every time a new entity function is added. Fix this by adding add an obj_type field to the media entity structure to carry the information. Signed-off-by: Laurent Pinchart Acked-by: Hans Verkuil Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-dev.c | 1 + drivers/media/v4l2-core/v4l2-subdev.c | 1 + include/media/media-entity.h | 76 ++++++++++++++++++----------------- 3 files changed, 41 insertions(+), 37 deletions(-) (limited to 'drivers/media/v4l2-core') diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index d8e5994cccf1..70b559d7ca80 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -735,6 +735,7 @@ static int video_register_media_controller(struct video_device *vdev, int type) if (!vdev->v4l2_dev->mdev) return 0; + vdev->entity.obj_type = MEDIA_ENTITY_TYPE_VIDEO_DEVICE; vdev->entity.function = MEDIA_ENT_F_UNKNOWN; switch (type) { diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index d63083803144..0fa60801a428 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -584,6 +584,7 @@ void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops) sd->host_priv = NULL; #if defined(CONFIG_MEDIA_CONTROLLER) sd->entity.name = sd->name; + sd->entity.obj_type = MEDIA_ENTITY_TYPE_V4L2_SUBDEV; sd->entity.function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN; #endif } diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 6dc9e4e8cbd4..1986340a8cf2 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -187,11 +187,39 @@ struct media_entity_operations { int (*link_validate)(struct media_link *link); }; +/** + * enum media_entity_type - Media entity type + * + * @MEDIA_ENTITY_TYPE_BASE: + * The entity isn't embedded in another subsystem structure. + * @MEDIA_ENTITY_TYPE_VIDEO_DEVICE: + * The entity is embedded in a struct video_device instance. + * @MEDIA_ENTITY_TYPE_V4L2_SUBDEV: + * The entity is embedded in a struct v4l2_subdev instance. + * + * Media entity objects are often not instantiated directly, but the media + * entity structure is inherited by (through embedding) other subsystem-specific + * structures. The media entity type identifies the type of the subclass + * structure that implements a media entity instance. + * + * This allows runtime type identification of media entities and safe casting to + * the correct object type. For instance, a media entity structure instance + * embedded in a v4l2_subdev structure instance will have the type + * MEDIA_ENTITY_TYPE_V4L2_SUBDEV and can safely be cast to a v4l2_subdev + * structure using the container_of() macro. + */ +enum media_entity_type { + MEDIA_ENTITY_TYPE_BASE, + MEDIA_ENTITY_TYPE_VIDEO_DEVICE, + MEDIA_ENTITY_TYPE_V4L2_SUBDEV, +}; + /** * struct media_entity - A media entity graph object. * * @graph_obj: Embedded structure containing the media object common data. * @name: Entity name. + * @obj_type: Type of the object that implements the media_entity. * @function: Entity main function, as defined in uapi/media.h * (MEDIA_ENT_F_*) * @flags: Entity flags, as defined in uapi/media.h (MEDIA_ENT_FL_*) @@ -220,6 +248,7 @@ struct media_entity_operations { struct media_entity { struct media_gobj graph_obj; /* must be first field in struct */ const char *name; + enum media_entity_type obj_type; u32 function; unsigned long flags; @@ -329,56 +358,29 @@ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u64 local_id) } /** - * is_media_entity_v4l2_io() - identify if the entity main function - * is a V4L2 I/O - * + * is_media_entity_v4l2_io() - Check if the entity is a video_device * @entity: pointer to entity * - * Return: true if the entity main function is one of the V4L2 I/O types - * (video, VBI or SDR radio); false otherwise. + * Return: true if the entity is an instance of a video_device object and can + * safely be cast to a struct video_device using the container_of() macro, or + * false otherwise. */ static inline bool is_media_entity_v4l2_io(struct media_entity *entity) { - if (!entity) - return false; - - switch (entity->function) { - case MEDIA_ENT_F_IO_V4L: - case MEDIA_ENT_F_IO_VBI: - case MEDIA_ENT_F_IO_SWRADIO: - return true; - default: - return false; - } + return entity && entity->obj_type == MEDIA_ENTITY_TYPE_VIDEO_DEVICE; } /** - * is_media_entity_v4l2_subdev - return true if the entity main function is - * associated with the V4L2 API subdev usage - * + * is_media_entity_v4l2_subdev() - Check if the entity is a v4l2_subdev * @entity: pointer to entity * - * This is an ancillary function used by subdev-based V4L2 drivers. - * It checks if the entity function is one of functions used by a V4L2 subdev, - * e. g. camera-relatef functions, analog TV decoder, TV tuner, V4L2 DSPs. + * Return: true if the entity is an instance of a v4l2_subdev object and can + * safely be cast to a struct v4l2_subdev using the container_of() macro, or + * false otherwise. */ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) { - if (!entity) - return false; - - switch (entity->function) { - case MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN: - case MEDIA_ENT_F_CAM_SENSOR: - case MEDIA_ENT_F_FLASH: - case MEDIA_ENT_F_LENS: - case MEDIA_ENT_F_ATV_DECODER: - case MEDIA_ENT_F_TUNER: - return true; - - default: - return false; - } + return entity && entity->obj_type == MEDIA_ENTITY_TYPE_V4L2_SUBDEV; } /** -- cgit From 45b46879a785678e08953c8f97df945bf634e472 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 29 Feb 2016 08:45:45 -0300 Subject: [media] media: Rename is_media_entity_v4l2_io to is_media_entity_v4l2_video_device All users of is_media_entity_v4l2_io() (the exynos4-is, omap3isp, davince_vpfe and omap4iss drivers and the v4l2-mc power management code) use the function to check whether entities are video_device instances, either to ensure they can cast the entity to a struct video_device, or to count the number of video nodes users. The purpose of the function is thus to identify whether the media entity instance is an instance of the video_device object, not to check whether it can perform I/O. Rename it accordingly, we will introduce a more specific is_media_entity_v4l2_io() check when needed. Signed-off-by: Laurent Pinchart Acked-by: Hans Verkuil Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos4-is/media-dev.c | 4 ++-- drivers/media/platform/omap3isp/ispvideo.c | 2 +- drivers/media/v4l2-core/v4l2-mc.c | 2 +- drivers/staging/media/davinci_vpfe/vpfe_video.c | 2 +- drivers/staging/media/omap4iss/iss_video.c | 2 +- include/media/media-entity.h | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/media/v4l2-core') diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index 48f62dc4453e..04348b502232 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -1132,7 +1132,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable, media_entity_graph_walk_start(graph, entity); while ((entity = media_entity_graph_walk_next(graph))) { - if (!is_media_entity_v4l2_io(entity)) + if (!is_media_entity_v4l2_video_device(entity)) continue; ret = __fimc_md_modify_pipeline(entity, enable); @@ -1147,7 +1147,7 @@ err: media_entity_graph_walk_start(graph, entity_err); while ((entity_err = media_entity_graph_walk_next(graph))) { - if (!is_media_entity_v4l2_io(entity_err)) + if (!is_media_entity_v4l2_video_device(entity_err)) continue; __fimc_md_modify_pipeline(entity_err, !enable); diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index ac76d2901501..1b1a95d546f6 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c @@ -251,7 +251,7 @@ static int isp_video_get_graph_data(struct isp_video *video, if (entity == &video->video.entity) continue; - if (!is_media_entity_v4l2_io(entity)) + if (!is_media_entity_v4l2_video_device(entity)) continue; __video = to_isp_video(media_entity_to_video_device(entity)); diff --git a/drivers/media/v4l2-core/v4l2-mc.c b/drivers/media/v4l2-core/v4l2-mc.c index 2228cd3a846e..ca94bded3386 100644 --- a/drivers/media/v4l2-core/v4l2-mc.c +++ b/drivers/media/v4l2-core/v4l2-mc.c @@ -263,7 +263,7 @@ static int pipeline_pm_use_count(struct media_entity *entity, media_entity_graph_walk_start(graph, entity); while ((entity = media_entity_graph_walk_next(graph))) { - if (is_media_entity_v4l2_io(entity)) + if (is_media_entity_v4l2_video_device(entity)) use += entity->use_count; } diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c index b793c04028a3..df4f298617c0 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c @@ -154,7 +154,7 @@ static int vpfe_prepare_pipeline(struct vpfe_video_device *video) while ((entity = media_entity_graph_walk_next(&graph))) { if (entity == &video->video_dev.entity) continue; - if (!is_media_entity_v4l2_io(entity)) + if (!is_media_entity_v4l2_video_device(entity)) continue; far_end = to_vpfe_video(media_entity_to_video_device(entity)); if (far_end->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c index f54349bce4de..cf8da23558bb 100644 --- a/drivers/staging/media/omap4iss/iss_video.c +++ b/drivers/staging/media/omap4iss/iss_video.c @@ -223,7 +223,7 @@ iss_video_far_end(struct iss_video *video) if (entity == &video->video.entity) continue; - if (!is_media_entity_v4l2_io(entity)) + if (!is_media_entity_v4l2_video_device(entity)) continue; far_end = to_iss_video(media_entity_to_video_device(entity)); diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 1986340a8cf2..e0295eefd702 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -358,14 +358,14 @@ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u64 local_id) } /** - * is_media_entity_v4l2_io() - Check if the entity is a video_device + * is_media_entity_v4l2_video_device() - Check if the entity is a video_device * @entity: pointer to entity * * Return: true if the entity is an instance of a video_device object and can * safely be cast to a struct video_device using the container_of() macro, or * false otherwise. */ -static inline bool is_media_entity_v4l2_io(struct media_entity *entity) +static inline bool is_media_entity_v4l2_video_device(struct media_entity *entity) { return entity && entity->obj_type == MEDIA_ENTITY_TYPE_VIDEO_DEVICE; } -- cgit From 9b02cbb3ede89b5cd84bbe4ef493bd130d76b070 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 24 Apr 2015 20:06:31 -0300 Subject: [media] v4l: subdev: Add pad config allocator and init Add a new subdev operation to initialize a subdev pad config array, and a helper function to allocate and initialize the array. This can be used by bridge drivers to implement try format based on subdev pad operations. Signed-off-by: Laurent Pinchart Acked-by: Vaibhav Hiremath Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-subdev.c | 39 +++++++++++++++++++++++++++++++---- include/media/v4l2-subdev.h | 8 +++++++ 2 files changed, 43 insertions(+), 4 deletions(-) (limited to 'drivers/media/v4l2-core') diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 0fa60801a428..224ea6028b55 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -35,9 +35,11 @@ static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd) { #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) - fh->pad = kzalloc(sizeof(*fh->pad) * sd->entity.num_pads, GFP_KERNEL); - if (fh->pad == NULL) - return -ENOMEM; + if (sd->entity.num_pads) { + fh->pad = v4l2_subdev_alloc_pad_config(sd); + if (fh->pad == NULL) + return -ENOMEM; + } #endif return 0; } @@ -45,7 +47,7 @@ static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd) static void subdev_fh_free(struct v4l2_subdev_fh *fh) { #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) - kfree(fh->pad); + v4l2_subdev_free_pad_config(fh->pad); fh->pad = NULL; #endif } @@ -569,6 +571,35 @@ int v4l2_subdev_link_validate(struct media_link *link) sink, link, &source_fmt, &sink_fmt); } EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate); + +struct v4l2_subdev_pad_config * +v4l2_subdev_alloc_pad_config(struct v4l2_subdev *sd) +{ + struct v4l2_subdev_pad_config *cfg; + int ret; + + if (!sd->entity.num_pads) + return NULL; + + cfg = kcalloc(sd->entity.num_pads, sizeof(*cfg), GFP_KERNEL); + if (!cfg) + return NULL; + + ret = v4l2_subdev_call(sd, pad, init_cfg, cfg); + if (ret < 0 && ret != -ENOIOCTLCMD) { + kfree(cfg); + return NULL; + } + + return cfg; +} +EXPORT_SYMBOL_GPL(v4l2_subdev_alloc_pad_config); + +void v4l2_subdev_free_pad_config(struct v4l2_subdev_pad_config *cfg) +{ + kfree(cfg); +} +EXPORT_SYMBOL_GPL(v4l2_subdev_free_pad_config); #endif /* CONFIG_MEDIA_CONTROLLER */ void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops) diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 11e2dfec0198..32fc7a4beb5e 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -572,6 +572,7 @@ struct v4l2_subdev_pad_config { /** * struct v4l2_subdev_pad_ops - v4l2-subdev pad level operations * + * @init_cfg: initialize the pad config to default values * @enum_mbus_code: callback for VIDIOC_SUBDEV_ENUM_MBUS_CODE ioctl handler * code. * @enum_frame_size: callback for VIDIOC_SUBDEV_ENUM_FRAME_SIZE ioctl handler @@ -607,6 +608,8 @@ struct v4l2_subdev_pad_config { * may be adjusted by the subdev driver to device capabilities. */ struct v4l2_subdev_pad_ops { + int (*init_cfg)(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg); int (*enum_mbus_code)(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_mbus_code_enum *code); @@ -801,7 +804,12 @@ int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd, struct v4l2_subdev_format *source_fmt, struct v4l2_subdev_format *sink_fmt); int v4l2_subdev_link_validate(struct media_link *link); + +struct v4l2_subdev_pad_config * +v4l2_subdev_alloc_pad_config(struct v4l2_subdev *sd); +void v4l2_subdev_free_pad_config(struct v4l2_subdev_pad_config *cfg); #endif /* CONFIG_MEDIA_CONTROLLER */ + void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops); -- cgit From c431cbbb446851ecb17095812e049119b2be17ed Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 13 Apr 2016 19:08:55 -0300 Subject: Revert "[media] v4l2-ioctl: simplify code" There are some issues rised on this patch during patch review. I ended by merging this one by mistake. So, let's revert it. This reverts commit 54ace1cfd4358fd11112f17cc711eea234d5ab9e. Cc: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ioctl.c | 51 ++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 29 deletions(-) (limited to 'drivers/media/v4l2-core') diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 3cf8d3adab03..6bf5a3ecd126 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -2160,40 +2160,33 @@ static int v4l_cropcap(const struct v4l2_ioctl_ops *ops, struct file *file, void *fh, void *arg) { struct v4l2_cropcap *p = arg; - struct v4l2_selection s = { .type = p->type }; - int ret; - if (ops->vidioc_g_selection == NULL) { - /* - * The determine_valid_ioctls() call already should ensure - * that ops->vidioc_cropcap != NULL, but just in case... - */ - if (ops->vidioc_cropcap) - return ops->vidioc_cropcap(file, fh, p); - return -ENOTTY; - } + if (ops->vidioc_g_selection) { + struct v4l2_selection s = { .type = p->type }; + int ret; - /* obtaining bounds */ - if (V4L2_TYPE_IS_OUTPUT(p->type)) - s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS; - else - s.target = V4L2_SEL_TGT_CROP_BOUNDS; + /* obtaining bounds */ + if (V4L2_TYPE_IS_OUTPUT(p->type)) + s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS; + else + s.target = V4L2_SEL_TGT_CROP_BOUNDS; - ret = ops->vidioc_g_selection(file, fh, &s); - if (ret) - return ret; - p->bounds = s.r; + ret = ops->vidioc_g_selection(file, fh, &s); + if (ret) + return ret; + p->bounds = s.r; - /* obtaining defrect */ - if (V4L2_TYPE_IS_OUTPUT(p->type)) - s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT; - else - s.target = V4L2_SEL_TGT_CROP_DEFAULT; + /* obtaining defrect */ + if (V4L2_TYPE_IS_OUTPUT(p->type)) + s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT; + else + s.target = V4L2_SEL_TGT_CROP_DEFAULT; - ret = ops->vidioc_g_selection(file, fh, &s); - if (ret) - return ret; - p->defrect = s.r; + ret = ops->vidioc_g_selection(file, fh, &s); + if (ret) + return ret; + p->defrect = s.r; + } /* setting trivial pixelaspect */ p->pixelaspect.numerator = 1; -- cgit From 47dfdb3a888733ab76702fc2801b6715c9d77937 Mon Sep 17 00:00:00 2001 From: Helen Mae Koike Fornazier Date: Sun, 28 Jun 2015 16:14:10 -0300 Subject: [media] media: change pipeline validation return error According to the V4L2 API, the VIDIOC_STREAMON ioctl should return EPIPE if there is a format mismatch in the pipeline configuration. As the .vidioc_streamon in the v4l2_ioctl_ops usually forwards the error caused by the v4l2_subdev_link_validate_default (if it is in use), it should return -EPIPE when it detect the mismatch. When an entity is connected to a non enabled link, media_entity_pipeline_start should return -ENOLINK, as the link does not exist. Signed-off-by: Helen Mae Koike Fornazier Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 2 +- drivers/media/v4l2-core/v4l2-subdev.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media/v4l2-core') diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index c53c1d5589a0..d8a2299f0c2a 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -445,7 +445,7 @@ __must_check int __media_entity_pipeline_start(struct media_entity *entity, bitmap_or(active, active, has_no_links, entity->num_pads); if (!bitmap_full(active, entity->num_pads)) { - ret = -EPIPE; + ret = -ENOLINK; dev_dbg(entity->graph_obj.mdev->dev, "\"%s\":%u must be connected by an enabled link\n", entity->name, diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 224ea6028b55..953eab08e420 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -510,7 +510,7 @@ int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd, if (source_fmt->format.width != sink_fmt->format.width || source_fmt->format.height != sink_fmt->format.height || source_fmt->format.code != sink_fmt->format.code) - return -EINVAL; + return -EPIPE; /* The field order must match, or the sink field order must be NONE * to support interlaced hardware connected to bridges that support @@ -518,7 +518,7 @@ int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd, */ if (source_fmt->format.field != sink_fmt->format.field && sink_fmt->format.field != V4L2_FIELD_NONE) - return -EINVAL; + return -EPIPE; return 0; } -- cgit From 95dd7b7e30f385c1c2d5e41457c082c5f6c535b3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 15 Apr 2016 06:27:28 -0300 Subject: [media] v4l2-ioctl.c: improve cropcap compatibility code - Add a check for the case that both the cropcap and g_selection ops are NULL. This shouldn't happen, but I feel happier if the code guards against this. - If g_selection exists, then ignore ENOTTY and ENOIOCTLCMD error codes from cropcap. Just assume square pixelaspect ratio in that case. This situation can happen if the bridge driver's cropcap op calls the corresponding subdev's op. So the cropcap ioctl is set, but it might return ENOIOCTLCMD anyway. In the past this would just return an error which is wrong. - Call cropcap first and let g_selection overwrite the bounds and defrect. This safeguards against subdev cropcap implementations that set those rectangles as well. What g_selection returns has priority over what such cropcap implementations return. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ioctl.c | 70 ++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 27 deletions(-) (limited to 'drivers/media/v4l2-core') diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 6bf5a3ecd126..28e5be2c2eef 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -2160,40 +2160,56 @@ static int v4l_cropcap(const struct v4l2_ioctl_ops *ops, struct file *file, void *fh, void *arg) { struct v4l2_cropcap *p = arg; + struct v4l2_selection s = { .type = p->type }; + int ret = 0; - if (ops->vidioc_g_selection) { - struct v4l2_selection s = { .type = p->type }; - int ret; + /* setting trivial pixelaspect */ + p->pixelaspect.numerator = 1; + p->pixelaspect.denominator = 1; - /* obtaining bounds */ - if (V4L2_TYPE_IS_OUTPUT(p->type)) - s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS; - else - s.target = V4L2_SEL_TGT_CROP_BOUNDS; + /* + * The determine_valid_ioctls() call already should ensure + * that this can never happen, but just in case... + */ + if (WARN_ON(!ops->vidioc_cropcap && !ops->vidioc_cropcap)) + return -ENOTTY; - ret = ops->vidioc_g_selection(file, fh, &s); - if (ret) - return ret; - p->bounds = s.r; + if (ops->vidioc_cropcap) + ret = ops->vidioc_cropcap(file, fh, p); - /* obtaining defrect */ - if (V4L2_TYPE_IS_OUTPUT(p->type)) - s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT; - else - s.target = V4L2_SEL_TGT_CROP_DEFAULT; + if (!ops->vidioc_g_selection) + return ret; - ret = ops->vidioc_g_selection(file, fh, &s); - if (ret) - return ret; - p->defrect = s.r; - } + /* + * Ignore ENOTTY or ENOIOCTLCMD error returns, just use the + * square pixel aspect ratio in that case. + */ + if (ret && ret != -ENOTTY && ret != -ENOIOCTLCMD) + return ret; - /* setting trivial pixelaspect */ - p->pixelaspect.numerator = 1; - p->pixelaspect.denominator = 1; + /* Use g_selection() to fill in the bounds and defrect rectangles */ - if (ops->vidioc_cropcap) - return ops->vidioc_cropcap(file, fh, p); + /* obtaining bounds */ + if (V4L2_TYPE_IS_OUTPUT(p->type)) + s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS; + else + s.target = V4L2_SEL_TGT_CROP_BOUNDS; + + ret = ops->vidioc_g_selection(file, fh, &s); + if (ret) + return ret; + p->bounds = s.r; + + /* obtaining defrect */ + if (V4L2_TYPE_IS_OUTPUT(p->type)) + s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT; + else + s.target = V4L2_SEL_TGT_CROP_DEFAULT; + + ret = ops->vidioc_g_selection(file, fh, &s); + if (ret) + return ret; + p->defrect = s.r; return 0; } -- cgit