Re: [PATCH 3/7] media: renesas: vsp1: Fix code checks in frame size enumeration

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, May 28, 2025 at 04:45:58PM +0200, Jacopo Mondi wrote:
> On Wed, Apr 30, 2025 at 02:53:18AM +0300, Laurent Pinchart wrote:
> > The media bus code passed to the .enum_frame_size() operation for the
> > sink pad is required to be supported by the device, but not to match the
> > current format. All entities that use the vsp1_subdev_enum_frame_size()
> > helper, as well as the SRU and UDS entities that implement the operation
> > manually, perform the check incorrectly.
> >
> > Fix the issue by implementing the correct code check in the
> > vsp1_subdev_enum_frame_size(). For the SRU and UDS, to avoid duplicating
> > code, use the vsp1_subdev_enum_frame_size() as a base and override the
> > enumerated size on the source pad with entity-specific constraints.
> >
> > Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@xxxxxxxxxxxxxxxx>
> > ---
> >  .../media/platform/renesas/vsp1/vsp1_entity.c | 47 +++++++++++--------
> >  .../media/platform/renesas/vsp1/vsp1_sru.c    | 36 ++++++--------
> >  .../media/platform/renesas/vsp1/vsp1_uds.c    | 36 ++++++--------
> >  3 files changed, 58 insertions(+), 61 deletions(-)
> >
> > diff --git a/drivers/media/platform/renesas/vsp1/vsp1_entity.c b/drivers/media/platform/renesas/vsp1/vsp1_entity.c
> > index 0d4fe0028b13..a3d4bf2887ec 100644
> > --- a/drivers/media/platform/renesas/vsp1/vsp1_entity.c
> > +++ b/drivers/media/platform/renesas/vsp1/vsp1_entity.c
> > @@ -233,42 +233,51 @@ int vsp1_subdev_enum_frame_size(struct v4l2_subdev *subdev,
> >  				struct v4l2_subdev_frame_size_enum *fse)
> >  {
> >  	struct vsp1_entity *entity = to_vsp1_entity(subdev);
> > -	struct v4l2_subdev_state *state;
> > -	struct v4l2_mbus_framefmt *format;
> > -	int ret = 0;
> >
> > -	state = vsp1_entity_get_state(entity, sd_state, fse->which);
> > -	if (!state)
> > +	if (fse->index)
> >  		return -EINVAL;
> >
> > -	format = v4l2_subdev_state_get_format(state, fse->pad);
> > -
> > -	mutex_lock(&entity->lock);
> > -
> > -	if (fse->index || fse->code != format->code) {
> > -		ret = -EINVAL;
> > -		goto done;
> > -	}
> > -
> >  	if (fse->pad == 0) {
> > +		unsigned int i;
> > +
> > +		for (i = 0; i < entity->num_codes; ++i) {
> > +			if (fse->code == entity->codes[i])
> > +				break;
> > +		}
> > +
> > +		if (i == entity->num_codes)
> > +			return -EINVAL;
> > +
> >  		fse->min_width = entity->min_width;
> >  		fse->max_width = entity->max_width;
> >  		fse->min_height = entity->min_height;
> >  		fse->max_height = entity->max_height;
> >  	} else {
> > +		struct v4l2_subdev_state *state;
> > +		struct v4l2_mbus_framefmt *format;
> > +
> > +		state = vsp1_entity_get_state(entity, sd_state, fse->which);
> > +		if (!state)
> > +			return -EINVAL;
> > +
> >  		/*
> > -		 * The size on the source pad are fixed and always identical to
> > -		 * the size on the sink pad.
> > +		 * The media bus code and size on the source pad are fixed and
> > +		 * always identical to the sink pad.
> >  		 */
> > +		format = v4l2_subdev_state_get_format(state, 0);
> > +
> > +		guard(mutex)(&entity->lock);
> 
> Should you now include cleanup.h ?

I'm in two minds about that. Yes, the guard() macro is provided by
cleanup.h, but the API here is really guard(mutex), which is provided by
mutex.h by using DEFINE_GUARD(), provided by cleanup.h. There's
therefore a guarantee cleanup.h is included.

I think I'll still include cleanup.h in v2, and while at it I'll also
include mutex.h that was missing.

> > +
> > +		if (fse->code != format->code)
> > +			return -EINVAL;
> > +
> >  		fse->min_width = format->width;
> >  		fse->max_width = format->width;
> >  		fse->min_height = format->height;
> >  		fse->max_height = format->height;
> >  	}
> >
> > -done:
> > -	mutex_unlock(&entity->lock);
> > -	return ret;
> > +	return 0;
> >  }
> >
> >  /*
> > diff --git a/drivers/media/platform/renesas/vsp1/vsp1_sru.c b/drivers/media/platform/renesas/vsp1/vsp1_sru.c
> > index 1dc34e6a510d..e821eac1cbc2 100644
> > --- a/drivers/media/platform/renesas/vsp1/vsp1_sru.c
> > +++ b/drivers/media/platform/renesas/vsp1/vsp1_sru.c
> > @@ -116,29 +116,25 @@ static int sru_enum_frame_size(struct v4l2_subdev *subdev,
> >  			       struct v4l2_subdev_frame_size_enum *fse)
> >  {
> >  	struct vsp1_sru *sru = to_sru(subdev);
> > -	struct v4l2_subdev_state *state;
> > -	struct v4l2_mbus_framefmt *format;
> > -	int ret = 0;
> > +	int ret;
> >
> > -	state = vsp1_entity_get_state(&sru->entity, sd_state, fse->which);
> > -	if (!state)
> > -		return -EINVAL;
> > +	ret = vsp1_subdev_enum_frame_size(subdev, sd_state, fse);
> > +	if (ret)
> > +		return ret;
> >
> > -	format = v4l2_subdev_state_get_format(state, SRU_PAD_SINK);
> > +	if (fse->pad == SRU_PAD_SOURCE) {
> > +		struct v4l2_subdev_state *state;
> > +		struct v4l2_mbus_framefmt *format;
> >
> > -	mutex_lock(&sru->entity.lock);
> > +		state = vsp1_entity_get_state(&sru->entity, sd_state,
> > +					      fse->which);
> > +		if (!state)
> > +			return -EINVAL;
> >
> > -	if (fse->index || fse->code != format->code) {
> > -		ret = -EINVAL;
> > -		goto done;
> > -	}
> > +		format = v4l2_subdev_state_get_format(state, SRU_PAD_SINK);
> > +
> > +		guard(mutex)(&sru->entity.lock);
> >
> > -	if (fse->pad == SRU_PAD_SINK) {
> > -		fse->min_width = SRU_MIN_SIZE;
> > -		fse->max_width = SRU_MAX_SIZE;
> > -		fse->min_height = SRU_MIN_SIZE;
> > -		fse->max_height = SRU_MAX_SIZE;
> > -	} else {
> >  		fse->min_width = format->width;
> >  		fse->min_height = format->height;
> >  		if (format->width <= SRU_MAX_SIZE / 2 &&
> > @@ -151,9 +147,7 @@ static int sru_enum_frame_size(struct v4l2_subdev *subdev,
> >  		}
> >  	}
> >
> > -done:
> > -	mutex_unlock(&sru->entity.lock);
> > -	return ret;
> > +	return 0;
> >  }
> >
> >  static void sru_try_format(struct vsp1_sru *sru,
> > diff --git a/drivers/media/platform/renesas/vsp1/vsp1_uds.c b/drivers/media/platform/renesas/vsp1/vsp1_uds.c
> > index 8006d49ffbea..95c9939ae077 100644
> > --- a/drivers/media/platform/renesas/vsp1/vsp1_uds.c
> > +++ b/drivers/media/platform/renesas/vsp1/vsp1_uds.c
> > @@ -121,38 +121,32 @@ static int uds_enum_frame_size(struct v4l2_subdev *subdev,
> >  			       struct v4l2_subdev_frame_size_enum *fse)
> >  {
> >  	struct vsp1_uds *uds = to_uds(subdev);
> > -	struct v4l2_subdev_state *state;
> > -	struct v4l2_mbus_framefmt *format;
> > -	int ret = 0;
> > +	int ret;
> >
> > -	state = vsp1_entity_get_state(&uds->entity, sd_state, fse->which);
> > -	if (!state)
> > -		return -EINVAL;
> > +	ret = vsp1_subdev_enum_frame_size(subdev, sd_state, fse);
> > +	if (ret)
> > +		return ret;
> >
> > -	format = v4l2_subdev_state_get_format(state, UDS_PAD_SINK);
> > +	if (fse->pad == UDS_PAD_SOURCE) {
> > +		struct v4l2_subdev_state *state;
> > +		struct v4l2_mbus_framefmt *format;
> >
> > -	mutex_lock(&uds->entity.lock);
> > +		state = vsp1_entity_get_state(&uds->entity, sd_state,
> > +					      fse->which);
> > +		if (!state)
> > +			return -EINVAL;
> >
> > -	if (fse->index || fse->code != format->code) {
> > -		ret = -EINVAL;
> > -		goto done;
> > -	}
> > +		format = v4l2_subdev_state_get_format(state, UDS_PAD_SINK);
> > +
> > +		guard(mutex)(&uds->entity.lock);
> >
> > -	if (fse->pad == UDS_PAD_SINK) {
> > -		fse->min_width = UDS_MIN_SIZE;
> > -		fse->max_width = UDS_MAX_SIZE;
> > -		fse->min_height = UDS_MIN_SIZE;
> > -		fse->max_height = UDS_MAX_SIZE;
> > -	} else {
> >  		uds_output_limits(format->width, &fse->min_width,
> >  				  &fse->max_width);
> >  		uds_output_limits(format->height, &fse->min_height,
> >  				  &fse->max_height);
> >  	}
> >
> > -done:
> > -	mutex_unlock(&uds->entity.lock);
> > -	return ret;
> > +	return 0;
> >  }
> >
> >  static void uds_try_format(struct vsp1_uds *uds,

-- 
Regards,

Laurent Pinchart




[Index of Archives]     [Linux Samsung SOC]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux