All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: dri-devel@lists.freedesktop.org
Cc: intel-gfx@lists.freedesktop.org,
	Hans Verkuil <hans.verkuil@cisco.com>,
	linux-media@vger.kernel.org
Subject: Re: [PATCH v3 04/18] video/hdmi: Constify infoframe passed to the pack functions
Date: Mon, 1 Oct 2018 22:10:37 +0300	[thread overview]
Message-ID: <20181001191037.GN9144@intel.com> (raw)
In-Reply-To: <20180921143332.28970-1-ville.syrjala@linux.intel.com>

On Fri, Sep 21, 2018 at 05:33:32PM +0300, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Let's make the infoframe pack functions usable with a const infoframe
> structure. This allows us to precompute the infoframe earlier, and still
> pack it later when we're no longer allowed to modify the structure.
> So now we end up with a _check()+_pack_only() or _pack() functions
> depending on whether you want to precompute the infoframes or not.
> The names aren't great but I was lazy and didn't want to change all the
> drivers.
> 
> v2: Deal with exynos churn
>     Actually export the new funcs
> v3: Fix various documentation fails (Hans)

Hans, any more concerns about this patch?

> 
> Cc: Thierry Reding <thierry.reding@gmail.com>
> Cc: Hans Verkuil <hans.verkuil@cisco.com>
> Cc: linux-media@vger.kernel.org
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/video/hdmi.c | 425 +++++++++++++++++++++++++++++++++++++++++++++++----
>  include/linux/hdmi.h |  19 ++-
>  2 files changed, 416 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
> index 53e7ee2c83fc..08d94ab00467 100644
> --- a/drivers/video/hdmi.c
> +++ b/drivers/video/hdmi.c
> @@ -68,8 +68,36 @@ int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame)
>  }
>  EXPORT_SYMBOL(hdmi_avi_infoframe_init);
>  
> +static int hdmi_avi_infoframe_check_only(const struct hdmi_avi_infoframe *frame)
> +{
> +	if (frame->type != HDMI_INFOFRAME_TYPE_AVI ||
> +	    frame->version != 2 ||
> +	    frame->length != HDMI_AVI_INFOFRAME_SIZE)
> +		return -EINVAL;
> +
> +	if (frame->picture_aspect > HDMI_PICTURE_ASPECT_16_9)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
>  /**
> - * hdmi_avi_infoframe_pack() - write HDMI AVI infoframe to binary buffer
> + * hdmi_avi_infoframe_check() - check a HDMI AVI infoframe
> + * @frame: HDMI AVI infoframe
> + *
> + * Validates that the infoframe is consistent and updates derived fields
> + * (eg. length) based on other fields.
> + *
> + * Returns 0 on success or a negative error code on failure.
> + */
> +int hdmi_avi_infoframe_check(struct hdmi_avi_infoframe *frame)
> +{
> +	return hdmi_avi_infoframe_check_only(frame);
> +}
> +EXPORT_SYMBOL(hdmi_avi_infoframe_check);
> +
> +/**
> + * hdmi_avi_infoframe_pack_only() - write HDMI AVI infoframe to binary buffer
>   * @frame: HDMI AVI infoframe
>   * @buffer: destination buffer
>   * @size: size of buffer
> @@ -82,20 +110,22 @@ EXPORT_SYMBOL(hdmi_avi_infoframe_init);
>   * Returns the number of bytes packed into the binary buffer or a negative
>   * error code on failure.
>   */
> -ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer,
> -				size_t size)
> +ssize_t hdmi_avi_infoframe_pack_only(const struct hdmi_avi_infoframe *frame,
> +				     void *buffer, size_t size)
>  {
>  	u8 *ptr = buffer;
>  	size_t length;
> +	int ret;
> +
> +	ret = hdmi_avi_infoframe_check_only(frame);
> +	if (ret)
> +		return ret;
>  
>  	length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
>  
>  	if (size < length)
>  		return -ENOSPC;
>  
> -	if (frame->picture_aspect > HDMI_PICTURE_ASPECT_16_9)
> -		return -EINVAL;
> -
>  	memset(buffer, 0, size);
>  
>  	ptr[0] = frame->type;
> @@ -152,6 +182,36 @@ ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer,
>  
>  	return length;
>  }
> +EXPORT_SYMBOL(hdmi_avi_infoframe_pack_only);
> +
> +/**
> + * hdmi_avi_infoframe_pack() - check a HDMI AVI infoframe,
> + *                             and write it to binary buffer
> + * @frame: HDMI AVI infoframe
> + * @buffer: destination buffer
> + * @size: size of buffer
> + *
> + * Validates that the infoframe is consistent and updates derived fields
> + * (eg. length) based on other fields, after which it packs the information
> + * contained in the @frame structure into a binary representation that
> + * can be written into the corresponding controller registers. This function
> + * also computes the checksum as required by section 5.3.5 of the HDMI 1.4
> + * specification.
> + *
> + * Returns the number of bytes packed into the binary buffer or a negative
> + * error code on failure.
> + */
> +ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame,
> +				void *buffer, size_t size)
> +{
> +	int ret;
> +
> +	ret = hdmi_avi_infoframe_check(frame);
> +	if (ret)
> +		return ret;
> +
> +	return hdmi_avi_infoframe_pack_only(frame, buffer, size);
> +}
>  EXPORT_SYMBOL(hdmi_avi_infoframe_pack);
>  
>  /**
> @@ -178,8 +238,33 @@ int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame,
>  }
>  EXPORT_SYMBOL(hdmi_spd_infoframe_init);
>  
> +static int hdmi_spd_infoframe_check_only(const struct hdmi_spd_infoframe *frame)
> +{
> +	if (frame->type != HDMI_INFOFRAME_TYPE_SPD ||
> +	    frame->version != 1 ||
> +	    frame->length != HDMI_SPD_INFOFRAME_SIZE)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
>  /**
> - * hdmi_spd_infoframe_pack() - write HDMI SPD infoframe to binary buffer
> + * hdmi_spd_infoframe_check() - check a HDMI SPD infoframe
> + * @frame: HDMI SPD infoframe
> + *
> + * Validates that the infoframe is consistent and updates derived fields
> + * (eg. length) based on other fields.
> + *
> + * Returns 0 on success or a negative error code on failure.
> + */
> +int hdmi_spd_infoframe_check(struct hdmi_spd_infoframe *frame)
> +{
> +	return hdmi_spd_infoframe_check_only(frame);
> +}
> +EXPORT_SYMBOL(hdmi_spd_infoframe_check);
> +
> +/**
> + * hdmi_spd_infoframe_pack_only() - write HDMI SPD infoframe to binary buffer
>   * @frame: HDMI SPD infoframe
>   * @buffer: destination buffer
>   * @size: size of buffer
> @@ -192,11 +277,16 @@ EXPORT_SYMBOL(hdmi_spd_infoframe_init);
>   * Returns the number of bytes packed into the binary buffer or a negative
>   * error code on failure.
>   */
> -ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer,
> -				size_t size)
> +ssize_t hdmi_spd_infoframe_pack_only(const struct hdmi_spd_infoframe *frame,
> +				     void *buffer, size_t size)
>  {
>  	u8 *ptr = buffer;
>  	size_t length;
> +	int ret;
> +
> +	ret = hdmi_spd_infoframe_check_only(frame);
> +	if (ret)
> +		return ret;
>  
>  	length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
>  
> @@ -222,6 +312,36 @@ ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer,
>  
>  	return length;
>  }
> +EXPORT_SYMBOL(hdmi_spd_infoframe_pack_only);
> +
> +/**
> + * hdmi_spd_infoframe_pack() - check a HDMI SPD infoframe,
> + *                             and write it to binary buffer
> + * @frame: HDMI SPD infoframe
> + * @buffer: destination buffer
> + * @size: size of buffer
> + *
> + * Validates that the infoframe is consistent and updates derived fields
> + * (eg. length) based on other fields, after which it packs the information
> + * contained in the @frame structure into a binary representation that
> + * can be written into the corresponding controller registers. This function
> + * also computes the checksum as required by section 5.3.5 of the HDMI 1.4
> + * specification.
> + *
> + * Returns the number of bytes packed into the binary buffer or a negative
> + * error code on failure.
> + */
> +ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame,
> +				void *buffer, size_t size)
> +{
> +	int ret;
> +
> +	ret = hdmi_spd_infoframe_check(frame);
> +	if (ret)
> +		return ret;
> +
> +	return hdmi_spd_infoframe_pack_only(frame, buffer, size);
> +}
>  EXPORT_SYMBOL(hdmi_spd_infoframe_pack);
>  
>  /**
> @@ -242,8 +362,33 @@ int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame)
>  }
>  EXPORT_SYMBOL(hdmi_audio_infoframe_init);
>  
> +static int hdmi_audio_infoframe_check_only(const struct hdmi_audio_infoframe *frame)
> +{
> +	if (frame->type != HDMI_INFOFRAME_TYPE_AUDIO ||
> +	    frame->version != 1 ||
> +	    frame->length != HDMI_AUDIO_INFOFRAME_SIZE)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +/**
> + * hdmi_audio_infoframe_check() - check a HDMI audio infoframe
> + * @frame: HDMI audio infoframe
> + *
> + * Validates that the infoframe is consistent and updates derived fields
> + * (eg. length) based on other fields.
> + *
> + * Returns 0 on success or a negative error code on failure.
> + */
> +int hdmi_audio_infoframe_check(struct hdmi_audio_infoframe *frame)
> +{
> +	return hdmi_audio_infoframe_check_only(frame);
> +}
> +EXPORT_SYMBOL(hdmi_audio_infoframe_check);
> +
>  /**
> - * hdmi_audio_infoframe_pack() - write HDMI audio infoframe to binary buffer
> + * hdmi_audio_infoframe_pack_only() - write HDMI audio infoframe to binary buffer
>   * @frame: HDMI audio infoframe
>   * @buffer: destination buffer
>   * @size: size of buffer
> @@ -256,12 +401,17 @@ EXPORT_SYMBOL(hdmi_audio_infoframe_init);
>   * Returns the number of bytes packed into the binary buffer or a negative
>   * error code on failure.
>   */
> -ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
> -				  void *buffer, size_t size)
> +ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe *frame,
> +				       void *buffer, size_t size)
>  {
>  	unsigned char channels;
>  	u8 *ptr = buffer;
>  	size_t length;
> +	int ret;
> +
> +	ret = hdmi_audio_infoframe_check_only(frame);
> +	if (ret)
> +		return ret;
>  
>  	length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
>  
> @@ -297,6 +447,36 @@ ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
>  
>  	return length;
>  }
> +EXPORT_SYMBOL(hdmi_audio_infoframe_pack_only);
> +
> +/**
> + * hdmi_audio_infoframe_pack() - check a HDMI Audio infoframe,
> + *                               and write it to binary buffer
> + * @frame: HDMI Audio infoframe
> + * @buffer: destination buffer
> + * @size: size of buffer
> + *
> + * Validates that the infoframe is consistent and updates derived fields
> + * (eg. length) based on other fields, after which it packs the information
> + * contained in the @frame structure into a binary representation that
> + * can be written into the corresponding controller registers. This function
> + * also computes the checksum as required by section 5.3.5 of the HDMI 1.4
> + * specification.
> + *
> + * Returns the number of bytes packed into the binary buffer or a negative
> + * error code on failure.
> + */
> +ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
> +				  void *buffer, size_t size)
> +{
> +	int ret;
> +
> +	ret = hdmi_audio_infoframe_check(frame);
> +	if (ret)
> +		return ret;
> +
> +	return hdmi_audio_infoframe_pack_only(frame, buffer, size);
> +}
>  EXPORT_SYMBOL(hdmi_audio_infoframe_pack);
>  
>  /**
> @@ -319,6 +499,7 @@ int hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame)
>  	 * value
>  	 */
>  	frame->s3d_struct = HDMI_3D_STRUCTURE_INVALID;
> +	frame->length = 4;
>  
>  	return 0;
>  }
> @@ -335,8 +516,42 @@ static int hdmi_vendor_infoframe_length(const struct hdmi_vendor_infoframe *fram
>  		return 4;
>  }
>  
> +static int hdmi_vendor_infoframe_check_only(const struct hdmi_vendor_infoframe *frame)
> +{
> +	if (frame->type != HDMI_INFOFRAME_TYPE_VENDOR ||
> +	    frame->version != 1 ||
> +	    frame->oui != HDMI_IEEE_OUI)
> +		return -EINVAL;
> +
> +	/* only one of those can be supplied */
> +	if (frame->vic != 0 && frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID)
> +		return -EINVAL;
> +
> +	if (frame->length != hdmi_vendor_infoframe_length(frame))
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
>  /**
> - * hdmi_vendor_infoframe_pack() - write a HDMI vendor infoframe to binary buffer
> + * hdmi_vendor_infoframe_check() - check a HDMI vendor infoframe
> + * @frame: HDMI infoframe
> + *
> + * Validates that the infoframe is consistent and updates derived fields
> + * (eg. length) based on other fields.
> + *
> + * Returns 0 on success or a negative error code on failure.
> + */
> +int hdmi_vendor_infoframe_check(struct hdmi_vendor_infoframe *frame)
> +{
> +	frame->length = hdmi_vendor_infoframe_length(frame);
> +
> +	return hdmi_vendor_infoframe_check_only(frame);
> +}
> +EXPORT_SYMBOL(hdmi_vendor_infoframe_check);
> +
> +/**
> + * hdmi_vendor_infoframe_pack_only() - write a HDMI vendor infoframe to binary buffer
>   * @frame: HDMI infoframe
>   * @buffer: destination buffer
>   * @size: size of buffer
> @@ -349,17 +564,16 @@ static int hdmi_vendor_infoframe_length(const struct hdmi_vendor_infoframe *fram
>   * Returns the number of bytes packed into the binary buffer or a negative
>   * error code on failure.
>   */
> -ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
> -				 void *buffer, size_t size)
> +ssize_t hdmi_vendor_infoframe_pack_only(const struct hdmi_vendor_infoframe *frame,
> +					void *buffer, size_t size)
>  {
>  	u8 *ptr = buffer;
>  	size_t length;
> +	int ret;
>  
> -	/* only one of those can be supplied */
> -	if (frame->vic != 0 && frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID)
> -		return -EINVAL;
> -
> -	frame->length = hdmi_vendor_infoframe_length(frame);
> +	ret = hdmi_vendor_infoframe_check_only(frame);
> +	if (ret)
> +		return ret;
>  
>  	length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
>  
> @@ -394,24 +608,134 @@ ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
>  
>  	return length;
>  }
> +EXPORT_SYMBOL(hdmi_vendor_infoframe_pack_only);
> +
> +/**
> + * hdmi_vendor_infoframe_pack() - check a HDMI Vendor infoframe,
> + *                                and write it to binary buffer
> + * @frame: HDMI Vendor infoframe
> + * @buffer: destination buffer
> + * @size: size of buffer
> + *
> + * Validates that the infoframe is consistent and updates derived fields
> + * (eg. length) based on other fields, after which it packs the information
> + * contained in the @frame structure into a binary representation that
> + * can be written into the corresponding controller registers. This function
> + * also computes the checksum as required by section 5.3.5 of the HDMI 1.4
> + * specification.
> + *
> + * Returns the number of bytes packed into the binary buffer or a negative
> + * error code on failure.
> + */
> +ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
> +				   void *buffer, size_t size)
> +{
> +	int ret;
> +
> +	ret = hdmi_vendor_infoframe_check(frame);
> +	if (ret)
> +		return ret;
> +
> +	return hdmi_vendor_infoframe_pack_only(frame, buffer, size);
> +}
>  EXPORT_SYMBOL(hdmi_vendor_infoframe_pack);
>  
> +static int
> +hdmi_vendor_any_infoframe_check_only(const union hdmi_vendor_any_infoframe *frame)
> +{
> +	if (frame->any.type != HDMI_INFOFRAME_TYPE_VENDOR ||
> +	    frame->any.version != 1)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
>  /*
> - * hdmi_vendor_any_infoframe_pack() - write a vendor infoframe to binary buffer
> + * hdmi_vendor_any_infoframe_check() - check a vendor infoframe
> + */
> +static int
> +hdmi_vendor_any_infoframe_check(union hdmi_vendor_any_infoframe *frame)
> +{
> +	int ret;
> +
> +	ret = hdmi_vendor_any_infoframe_check_only(frame);
> +	if (ret)
> +		return ret;
> +
> +	/* we only know about HDMI vendor infoframes */
> +	if (frame->any.oui != HDMI_IEEE_OUI)
> +		return -EINVAL;
> +
> +	return hdmi_vendor_infoframe_check(&frame->hdmi);
> +}
> +
> +/*
> + * hdmi_vendor_any_infoframe_pack_only() - write a vendor infoframe to binary buffer
>   */
>  static ssize_t
> -hdmi_vendor_any_infoframe_pack(union hdmi_vendor_any_infoframe *frame,
> -			   void *buffer, size_t size)
> +hdmi_vendor_any_infoframe_pack_only(const union hdmi_vendor_any_infoframe *frame,
> +				    void *buffer, size_t size)
>  {
> +	int ret;
> +
> +	ret = hdmi_vendor_any_infoframe_check_only(frame);
> +	if (ret)
> +		return ret;
> +
>  	/* we only know about HDMI vendor infoframes */
>  	if (frame->any.oui != HDMI_IEEE_OUI)
>  		return -EINVAL;
>  
> -	return hdmi_vendor_infoframe_pack(&frame->hdmi, buffer, size);
> +	return hdmi_vendor_infoframe_pack_only(&frame->hdmi, buffer, size);
> +}
> +
> +/*
> + * hdmi_vendor_any_infoframe_pack() - check a vendor infoframe,
> + *                                    and write it to binary buffer
> + */
> +static ssize_t
> +hdmi_vendor_any_infoframe_pack(union hdmi_vendor_any_infoframe *frame,
> +			       void *buffer, size_t size)
> +{
> +	int ret;
> +
> +	ret = hdmi_vendor_any_infoframe_check(frame);
> +	if (ret)
> +		return ret;
> +
> +	return hdmi_vendor_any_infoframe_pack_only(frame, buffer, size);
> +}
> +
> +/**
> + * hdmi_infoframe_check() - check a HDMI infoframe
> + * @frame: HDMI infoframe
> + *
> + * Validates that the infoframe is consistent and updates derived fields
> + * (eg. length) based on other fields.
> + *
> + * Returns 0 on success or a negative error code on failure.
> + */
> +int
> +hdmi_infoframe_check(union hdmi_infoframe *frame)
> +{
> +	switch (frame->any.type) {
> +	case HDMI_INFOFRAME_TYPE_AVI:
> +		return hdmi_avi_infoframe_check(&frame->avi);
> +	case HDMI_INFOFRAME_TYPE_SPD:
> +		return hdmi_spd_infoframe_check(&frame->spd);
> +	case HDMI_INFOFRAME_TYPE_AUDIO:
> +		return hdmi_audio_infoframe_check(&frame->audio);
> +	case HDMI_INFOFRAME_TYPE_VENDOR:
> +		return hdmi_vendor_any_infoframe_check(&frame->vendor);
> +	default:
> +		WARN(1, "Bad infoframe type %d\n", frame->any.type);
> +		return -EINVAL;
> +	}
>  }
> +EXPORT_SYMBOL(hdmi_infoframe_check);
>  
>  /**
> - * hdmi_infoframe_pack() - write a HDMI infoframe to binary buffer
> + * hdmi_infoframe_pack_only() - write a HDMI infoframe to binary buffer
>   * @frame: HDMI infoframe
>   * @buffer: destination buffer
>   * @size: size of buffer
> @@ -425,7 +749,56 @@ hdmi_vendor_any_infoframe_pack(union hdmi_vendor_any_infoframe *frame,
>   * error code on failure.
>   */
>  ssize_t
> -hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, size_t size)
> +hdmi_infoframe_pack_only(const union hdmi_infoframe *frame, void *buffer, size_t size)
> +{
> +	ssize_t length;
> +
> +	switch (frame->any.type) {
> +	case HDMI_INFOFRAME_TYPE_AVI:
> +		length = hdmi_avi_infoframe_pack_only(&frame->avi,
> +						      buffer, size);
> +		break;
> +	case HDMI_INFOFRAME_TYPE_SPD:
> +		length = hdmi_spd_infoframe_pack_only(&frame->spd,
> +						      buffer, size);
> +		break;
> +	case HDMI_INFOFRAME_TYPE_AUDIO:
> +		length = hdmi_audio_infoframe_pack_only(&frame->audio,
> +							buffer, size);
> +		break;
> +	case HDMI_INFOFRAME_TYPE_VENDOR:
> +		length = hdmi_vendor_any_infoframe_pack_only(&frame->vendor,
> +							     buffer, size);
> +		break;
> +	default:
> +		WARN(1, "Bad infoframe type %d\n", frame->any.type);
> +		length = -EINVAL;
> +	}
> +
> +	return length;
> +}
> +EXPORT_SYMBOL(hdmi_infoframe_pack_only);
> +
> +/**
> + * hdmi_infoframe_pack() - check a HDMI infoframe,
> + *                         and write it to binary buffer
> + * @frame: HDMI infoframe
> + * @buffer: destination buffer
> + * @size: size of buffer
> + *
> + * Validates that the infoframe is consistent and updates derived fields
> + * (eg. length) based on other fields, after which it packs the information
> + * contained in the @frame structure into a binary representation that
> + * can be written into the corresponding controller registers. This function
> + * also computes the checksum as required by section 5.3.5 of the HDMI 1.4
> + * specification.
> + *
> + * Returns the number of bytes packed into the binary buffer or a negative
> + * error code on failure.
> + */
> +ssize_t
> +hdmi_infoframe_pack(union hdmi_infoframe *frame,
> +		    void *buffer, size_t size)
>  {
>  	ssize_t length;
>  
> diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
> index bce1abb1fe57..c76b50a48e48 100644
> --- a/include/linux/hdmi.h
> +++ b/include/linux/hdmi.h
> @@ -163,6 +163,9 @@ struct hdmi_avi_infoframe {
>  int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame);
>  ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer,
>  				size_t size);
> +ssize_t hdmi_avi_infoframe_pack_only(const struct hdmi_avi_infoframe *frame,
> +				     void *buffer, size_t size);
> +int hdmi_avi_infoframe_check(struct hdmi_avi_infoframe *frame);
>  
>  enum hdmi_spd_sdi {
>  	HDMI_SPD_SDI_UNKNOWN,
> @@ -194,6 +197,9 @@ int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame,
>  			    const char *vendor, const char *product);
>  ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer,
>  				size_t size);
> +ssize_t hdmi_spd_infoframe_pack_only(const struct hdmi_spd_infoframe *frame,
> +				     void *buffer, size_t size);
> +int hdmi_spd_infoframe_check(struct hdmi_spd_infoframe *frame);
>  
>  enum hdmi_audio_coding_type {
>  	HDMI_AUDIO_CODING_TYPE_STREAM,
> @@ -272,6 +278,9 @@ struct hdmi_audio_infoframe {
>  int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame);
>  ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
>  				  void *buffer, size_t size);
> +ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe *frame,
> +				       void *buffer, size_t size);
> +int hdmi_audio_infoframe_check(struct hdmi_audio_infoframe *frame);
>  
>  enum hdmi_3d_structure {
>  	HDMI_3D_STRUCTURE_INVALID = -1,
> @@ -299,6 +308,9 @@ struct hdmi_vendor_infoframe {
>  int hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame);
>  ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
>  				   void *buffer, size_t size);
> +ssize_t hdmi_vendor_infoframe_pack_only(const struct hdmi_vendor_infoframe *frame,
> +					void *buffer, size_t size);
> +int hdmi_vendor_infoframe_check(struct hdmi_vendor_infoframe *frame);
>  
>  union hdmi_vendor_any_infoframe {
>  	struct {
> @@ -330,8 +342,11 @@ union hdmi_infoframe {
>  	struct hdmi_audio_infoframe audio;
>  };
>  
> -ssize_t
> -hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, size_t size);
> +ssize_t hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer,
> +			    size_t size);
> +ssize_t hdmi_infoframe_pack_only(const union hdmi_infoframe *frame,
> +				 void *buffer, size_t size);
> +int hdmi_infoframe_check(union hdmi_infoframe *frame);
>  int hdmi_infoframe_unpack(union hdmi_infoframe *frame,
>  			  const void *buffer, size_t size);
>  void hdmi_infoframe_log(const char *level, struct device *dev,
> -- 
> 2.16.4

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

WARNING: multiple messages have this Message-ID (diff)
From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: dri-devel@lists.freedesktop.org
Cc: intel-gfx@lists.freedesktop.org,
	Thierry Reding <thierry.reding@gmail.com>,
	Hans Verkuil <hans.verkuil@cisco.com>,
	linux-media@vger.kernel.org
Subject: Re: [PATCH v3 04/18] video/hdmi: Constify infoframe passed to the pack functions
Date: Mon, 1 Oct 2018 22:10:37 +0300	[thread overview]
Message-ID: <20181001191037.GN9144@intel.com> (raw)
In-Reply-To: <20180921143332.28970-1-ville.syrjala@linux.intel.com>

On Fri, Sep 21, 2018 at 05:33:32PM +0300, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Let's make the infoframe pack functions usable with a const infoframe
> structure. This allows us to precompute the infoframe earlier, and still
> pack it later when we're no longer allowed to modify the structure.
> So now we end up with a _check()+_pack_only() or _pack() functions
> depending on whether you want to precompute the infoframes or not.
> The names aren't great but I was lazy and didn't want to change all the
> drivers.
> 
> v2: Deal with exynos churn
>     Actually export the new funcs
> v3: Fix various documentation fails (Hans)

Hans, any more concerns about this patch?

> 
> Cc: Thierry Reding <thierry.reding@gmail.com>
> Cc: Hans Verkuil <hans.verkuil@cisco.com>
> Cc: linux-media@vger.kernel.org
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/video/hdmi.c | 425 +++++++++++++++++++++++++++++++++++++++++++++++----
>  include/linux/hdmi.h |  19 ++-
>  2 files changed, 416 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
> index 53e7ee2c83fc..08d94ab00467 100644
> --- a/drivers/video/hdmi.c
> +++ b/drivers/video/hdmi.c
> @@ -68,8 +68,36 @@ int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame)
>  }
>  EXPORT_SYMBOL(hdmi_avi_infoframe_init);
>  
> +static int hdmi_avi_infoframe_check_only(const struct hdmi_avi_infoframe *frame)
> +{
> +	if (frame->type != HDMI_INFOFRAME_TYPE_AVI ||
> +	    frame->version != 2 ||
> +	    frame->length != HDMI_AVI_INFOFRAME_SIZE)
> +		return -EINVAL;
> +
> +	if (frame->picture_aspect > HDMI_PICTURE_ASPECT_16_9)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
>  /**
> - * hdmi_avi_infoframe_pack() - write HDMI AVI infoframe to binary buffer
> + * hdmi_avi_infoframe_check() - check a HDMI AVI infoframe
> + * @frame: HDMI AVI infoframe
> + *
> + * Validates that the infoframe is consistent and updates derived fields
> + * (eg. length) based on other fields.
> + *
> + * Returns 0 on success or a negative error code on failure.
> + */
> +int hdmi_avi_infoframe_check(struct hdmi_avi_infoframe *frame)
> +{
> +	return hdmi_avi_infoframe_check_only(frame);
> +}
> +EXPORT_SYMBOL(hdmi_avi_infoframe_check);
> +
> +/**
> + * hdmi_avi_infoframe_pack_only() - write HDMI AVI infoframe to binary buffer
>   * @frame: HDMI AVI infoframe
>   * @buffer: destination buffer
>   * @size: size of buffer
> @@ -82,20 +110,22 @@ EXPORT_SYMBOL(hdmi_avi_infoframe_init);
>   * Returns the number of bytes packed into the binary buffer or a negative
>   * error code on failure.
>   */
> -ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer,
> -				size_t size)
> +ssize_t hdmi_avi_infoframe_pack_only(const struct hdmi_avi_infoframe *frame,
> +				     void *buffer, size_t size)
>  {
>  	u8 *ptr = buffer;
>  	size_t length;
> +	int ret;
> +
> +	ret = hdmi_avi_infoframe_check_only(frame);
> +	if (ret)
> +		return ret;
>  
>  	length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
>  
>  	if (size < length)
>  		return -ENOSPC;
>  
> -	if (frame->picture_aspect > HDMI_PICTURE_ASPECT_16_9)
> -		return -EINVAL;
> -
>  	memset(buffer, 0, size);
>  
>  	ptr[0] = frame->type;
> @@ -152,6 +182,36 @@ ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer,
>  
>  	return length;
>  }
> +EXPORT_SYMBOL(hdmi_avi_infoframe_pack_only);
> +
> +/**
> + * hdmi_avi_infoframe_pack() - check a HDMI AVI infoframe,
> + *                             and write it to binary buffer
> + * @frame: HDMI AVI infoframe
> + * @buffer: destination buffer
> + * @size: size of buffer
> + *
> + * Validates that the infoframe is consistent and updates derived fields
> + * (eg. length) based on other fields, after which it packs the information
> + * contained in the @frame structure into a binary representation that
> + * can be written into the corresponding controller registers. This function
> + * also computes the checksum as required by section 5.3.5 of the HDMI 1.4
> + * specification.
> + *
> + * Returns the number of bytes packed into the binary buffer or a negative
> + * error code on failure.
> + */
> +ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame,
> +				void *buffer, size_t size)
> +{
> +	int ret;
> +
> +	ret = hdmi_avi_infoframe_check(frame);
> +	if (ret)
> +		return ret;
> +
> +	return hdmi_avi_infoframe_pack_only(frame, buffer, size);
> +}
>  EXPORT_SYMBOL(hdmi_avi_infoframe_pack);
>  
>  /**
> @@ -178,8 +238,33 @@ int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame,
>  }
>  EXPORT_SYMBOL(hdmi_spd_infoframe_init);
>  
> +static int hdmi_spd_infoframe_check_only(const struct hdmi_spd_infoframe *frame)
> +{
> +	if (frame->type != HDMI_INFOFRAME_TYPE_SPD ||
> +	    frame->version != 1 ||
> +	    frame->length != HDMI_SPD_INFOFRAME_SIZE)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
>  /**
> - * hdmi_spd_infoframe_pack() - write HDMI SPD infoframe to binary buffer
> + * hdmi_spd_infoframe_check() - check a HDMI SPD infoframe
> + * @frame: HDMI SPD infoframe
> + *
> + * Validates that the infoframe is consistent and updates derived fields
> + * (eg. length) based on other fields.
> + *
> + * Returns 0 on success or a negative error code on failure.
> + */
> +int hdmi_spd_infoframe_check(struct hdmi_spd_infoframe *frame)
> +{
> +	return hdmi_spd_infoframe_check_only(frame);
> +}
> +EXPORT_SYMBOL(hdmi_spd_infoframe_check);
> +
> +/**
> + * hdmi_spd_infoframe_pack_only() - write HDMI SPD infoframe to binary buffer
>   * @frame: HDMI SPD infoframe
>   * @buffer: destination buffer
>   * @size: size of buffer
> @@ -192,11 +277,16 @@ EXPORT_SYMBOL(hdmi_spd_infoframe_init);
>   * Returns the number of bytes packed into the binary buffer or a negative
>   * error code on failure.
>   */
> -ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer,
> -				size_t size)
> +ssize_t hdmi_spd_infoframe_pack_only(const struct hdmi_spd_infoframe *frame,
> +				     void *buffer, size_t size)
>  {
>  	u8 *ptr = buffer;
>  	size_t length;
> +	int ret;
> +
> +	ret = hdmi_spd_infoframe_check_only(frame);
> +	if (ret)
> +		return ret;
>  
>  	length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
>  
> @@ -222,6 +312,36 @@ ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer,
>  
>  	return length;
>  }
> +EXPORT_SYMBOL(hdmi_spd_infoframe_pack_only);
> +
> +/**
> + * hdmi_spd_infoframe_pack() - check a HDMI SPD infoframe,
> + *                             and write it to binary buffer
> + * @frame: HDMI SPD infoframe
> + * @buffer: destination buffer
> + * @size: size of buffer
> + *
> + * Validates that the infoframe is consistent and updates derived fields
> + * (eg. length) based on other fields, after which it packs the information
> + * contained in the @frame structure into a binary representation that
> + * can be written into the corresponding controller registers. This function
> + * also computes the checksum as required by section 5.3.5 of the HDMI 1.4
> + * specification.
> + *
> + * Returns the number of bytes packed into the binary buffer or a negative
> + * error code on failure.
> + */
> +ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame,
> +				void *buffer, size_t size)
> +{
> +	int ret;
> +
> +	ret = hdmi_spd_infoframe_check(frame);
> +	if (ret)
> +		return ret;
> +
> +	return hdmi_spd_infoframe_pack_only(frame, buffer, size);
> +}
>  EXPORT_SYMBOL(hdmi_spd_infoframe_pack);
>  
>  /**
> @@ -242,8 +362,33 @@ int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame)
>  }
>  EXPORT_SYMBOL(hdmi_audio_infoframe_init);
>  
> +static int hdmi_audio_infoframe_check_only(const struct hdmi_audio_infoframe *frame)
> +{
> +	if (frame->type != HDMI_INFOFRAME_TYPE_AUDIO ||
> +	    frame->version != 1 ||
> +	    frame->length != HDMI_AUDIO_INFOFRAME_SIZE)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +/**
> + * hdmi_audio_infoframe_check() - check a HDMI audio infoframe
> + * @frame: HDMI audio infoframe
> + *
> + * Validates that the infoframe is consistent and updates derived fields
> + * (eg. length) based on other fields.
> + *
> + * Returns 0 on success or a negative error code on failure.
> + */
> +int hdmi_audio_infoframe_check(struct hdmi_audio_infoframe *frame)
> +{
> +	return hdmi_audio_infoframe_check_only(frame);
> +}
> +EXPORT_SYMBOL(hdmi_audio_infoframe_check);
> +
>  /**
> - * hdmi_audio_infoframe_pack() - write HDMI audio infoframe to binary buffer
> + * hdmi_audio_infoframe_pack_only() - write HDMI audio infoframe to binary buffer
>   * @frame: HDMI audio infoframe
>   * @buffer: destination buffer
>   * @size: size of buffer
> @@ -256,12 +401,17 @@ EXPORT_SYMBOL(hdmi_audio_infoframe_init);
>   * Returns the number of bytes packed into the binary buffer or a negative
>   * error code on failure.
>   */
> -ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
> -				  void *buffer, size_t size)
> +ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe *frame,
> +				       void *buffer, size_t size)
>  {
>  	unsigned char channels;
>  	u8 *ptr = buffer;
>  	size_t length;
> +	int ret;
> +
> +	ret = hdmi_audio_infoframe_check_only(frame);
> +	if (ret)
> +		return ret;
>  
>  	length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
>  
> @@ -297,6 +447,36 @@ ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
>  
>  	return length;
>  }
> +EXPORT_SYMBOL(hdmi_audio_infoframe_pack_only);
> +
> +/**
> + * hdmi_audio_infoframe_pack() - check a HDMI Audio infoframe,
> + *                               and write it to binary buffer
> + * @frame: HDMI Audio infoframe
> + * @buffer: destination buffer
> + * @size: size of buffer
> + *
> + * Validates that the infoframe is consistent and updates derived fields
> + * (eg. length) based on other fields, after which it packs the information
> + * contained in the @frame structure into a binary representation that
> + * can be written into the corresponding controller registers. This function
> + * also computes the checksum as required by section 5.3.5 of the HDMI 1.4
> + * specification.
> + *
> + * Returns the number of bytes packed into the binary buffer or a negative
> + * error code on failure.
> + */
> +ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
> +				  void *buffer, size_t size)
> +{
> +	int ret;
> +
> +	ret = hdmi_audio_infoframe_check(frame);
> +	if (ret)
> +		return ret;
> +
> +	return hdmi_audio_infoframe_pack_only(frame, buffer, size);
> +}
>  EXPORT_SYMBOL(hdmi_audio_infoframe_pack);
>  
>  /**
> @@ -319,6 +499,7 @@ int hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame)
>  	 * value
>  	 */
>  	frame->s3d_struct = HDMI_3D_STRUCTURE_INVALID;
> +	frame->length = 4;
>  
>  	return 0;
>  }
> @@ -335,8 +516,42 @@ static int hdmi_vendor_infoframe_length(const struct hdmi_vendor_infoframe *fram
>  		return 4;
>  }
>  
> +static int hdmi_vendor_infoframe_check_only(const struct hdmi_vendor_infoframe *frame)
> +{
> +	if (frame->type != HDMI_INFOFRAME_TYPE_VENDOR ||
> +	    frame->version != 1 ||
> +	    frame->oui != HDMI_IEEE_OUI)
> +		return -EINVAL;
> +
> +	/* only one of those can be supplied */
> +	if (frame->vic != 0 && frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID)
> +		return -EINVAL;
> +
> +	if (frame->length != hdmi_vendor_infoframe_length(frame))
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
>  /**
> - * hdmi_vendor_infoframe_pack() - write a HDMI vendor infoframe to binary buffer
> + * hdmi_vendor_infoframe_check() - check a HDMI vendor infoframe
> + * @frame: HDMI infoframe
> + *
> + * Validates that the infoframe is consistent and updates derived fields
> + * (eg. length) based on other fields.
> + *
> + * Returns 0 on success or a negative error code on failure.
> + */
> +int hdmi_vendor_infoframe_check(struct hdmi_vendor_infoframe *frame)
> +{
> +	frame->length = hdmi_vendor_infoframe_length(frame);
> +
> +	return hdmi_vendor_infoframe_check_only(frame);
> +}
> +EXPORT_SYMBOL(hdmi_vendor_infoframe_check);
> +
> +/**
> + * hdmi_vendor_infoframe_pack_only() - write a HDMI vendor infoframe to binary buffer
>   * @frame: HDMI infoframe
>   * @buffer: destination buffer
>   * @size: size of buffer
> @@ -349,17 +564,16 @@ static int hdmi_vendor_infoframe_length(const struct hdmi_vendor_infoframe *fram
>   * Returns the number of bytes packed into the binary buffer or a negative
>   * error code on failure.
>   */
> -ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
> -				 void *buffer, size_t size)
> +ssize_t hdmi_vendor_infoframe_pack_only(const struct hdmi_vendor_infoframe *frame,
> +					void *buffer, size_t size)
>  {
>  	u8 *ptr = buffer;
>  	size_t length;
> +	int ret;
>  
> -	/* only one of those can be supplied */
> -	if (frame->vic != 0 && frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID)
> -		return -EINVAL;
> -
> -	frame->length = hdmi_vendor_infoframe_length(frame);
> +	ret = hdmi_vendor_infoframe_check_only(frame);
> +	if (ret)
> +		return ret;
>  
>  	length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
>  
> @@ -394,24 +608,134 @@ ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
>  
>  	return length;
>  }
> +EXPORT_SYMBOL(hdmi_vendor_infoframe_pack_only);
> +
> +/**
> + * hdmi_vendor_infoframe_pack() - check a HDMI Vendor infoframe,
> + *                                and write it to binary buffer
> + * @frame: HDMI Vendor infoframe
> + * @buffer: destination buffer
> + * @size: size of buffer
> + *
> + * Validates that the infoframe is consistent and updates derived fields
> + * (eg. length) based on other fields, after which it packs the information
> + * contained in the @frame structure into a binary representation that
> + * can be written into the corresponding controller registers. This function
> + * also computes the checksum as required by section 5.3.5 of the HDMI 1.4
> + * specification.
> + *
> + * Returns the number of bytes packed into the binary buffer or a negative
> + * error code on failure.
> + */
> +ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
> +				   void *buffer, size_t size)
> +{
> +	int ret;
> +
> +	ret = hdmi_vendor_infoframe_check(frame);
> +	if (ret)
> +		return ret;
> +
> +	return hdmi_vendor_infoframe_pack_only(frame, buffer, size);
> +}
>  EXPORT_SYMBOL(hdmi_vendor_infoframe_pack);
>  
> +static int
> +hdmi_vendor_any_infoframe_check_only(const union hdmi_vendor_any_infoframe *frame)
> +{
> +	if (frame->any.type != HDMI_INFOFRAME_TYPE_VENDOR ||
> +	    frame->any.version != 1)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
>  /*
> - * hdmi_vendor_any_infoframe_pack() - write a vendor infoframe to binary buffer
> + * hdmi_vendor_any_infoframe_check() - check a vendor infoframe
> + */
> +static int
> +hdmi_vendor_any_infoframe_check(union hdmi_vendor_any_infoframe *frame)
> +{
> +	int ret;
> +
> +	ret = hdmi_vendor_any_infoframe_check_only(frame);
> +	if (ret)
> +		return ret;
> +
> +	/* we only know about HDMI vendor infoframes */
> +	if (frame->any.oui != HDMI_IEEE_OUI)
> +		return -EINVAL;
> +
> +	return hdmi_vendor_infoframe_check(&frame->hdmi);
> +}
> +
> +/*
> + * hdmi_vendor_any_infoframe_pack_only() - write a vendor infoframe to binary buffer
>   */
>  static ssize_t
> -hdmi_vendor_any_infoframe_pack(union hdmi_vendor_any_infoframe *frame,
> -			   void *buffer, size_t size)
> +hdmi_vendor_any_infoframe_pack_only(const union hdmi_vendor_any_infoframe *frame,
> +				    void *buffer, size_t size)
>  {
> +	int ret;
> +
> +	ret = hdmi_vendor_any_infoframe_check_only(frame);
> +	if (ret)
> +		return ret;
> +
>  	/* we only know about HDMI vendor infoframes */
>  	if (frame->any.oui != HDMI_IEEE_OUI)
>  		return -EINVAL;
>  
> -	return hdmi_vendor_infoframe_pack(&frame->hdmi, buffer, size);
> +	return hdmi_vendor_infoframe_pack_only(&frame->hdmi, buffer, size);
> +}
> +
> +/*
> + * hdmi_vendor_any_infoframe_pack() - check a vendor infoframe,
> + *                                    and write it to binary buffer
> + */
> +static ssize_t
> +hdmi_vendor_any_infoframe_pack(union hdmi_vendor_any_infoframe *frame,
> +			       void *buffer, size_t size)
> +{
> +	int ret;
> +
> +	ret = hdmi_vendor_any_infoframe_check(frame);
> +	if (ret)
> +		return ret;
> +
> +	return hdmi_vendor_any_infoframe_pack_only(frame, buffer, size);
> +}
> +
> +/**
> + * hdmi_infoframe_check() - check a HDMI infoframe
> + * @frame: HDMI infoframe
> + *
> + * Validates that the infoframe is consistent and updates derived fields
> + * (eg. length) based on other fields.
> + *
> + * Returns 0 on success or a negative error code on failure.
> + */
> +int
> +hdmi_infoframe_check(union hdmi_infoframe *frame)
> +{
> +	switch (frame->any.type) {
> +	case HDMI_INFOFRAME_TYPE_AVI:
> +		return hdmi_avi_infoframe_check(&frame->avi);
> +	case HDMI_INFOFRAME_TYPE_SPD:
> +		return hdmi_spd_infoframe_check(&frame->spd);
> +	case HDMI_INFOFRAME_TYPE_AUDIO:
> +		return hdmi_audio_infoframe_check(&frame->audio);
> +	case HDMI_INFOFRAME_TYPE_VENDOR:
> +		return hdmi_vendor_any_infoframe_check(&frame->vendor);
> +	default:
> +		WARN(1, "Bad infoframe type %d\n", frame->any.type);
> +		return -EINVAL;
> +	}
>  }
> +EXPORT_SYMBOL(hdmi_infoframe_check);
>  
>  /**
> - * hdmi_infoframe_pack() - write a HDMI infoframe to binary buffer
> + * hdmi_infoframe_pack_only() - write a HDMI infoframe to binary buffer
>   * @frame: HDMI infoframe
>   * @buffer: destination buffer
>   * @size: size of buffer
> @@ -425,7 +749,56 @@ hdmi_vendor_any_infoframe_pack(union hdmi_vendor_any_infoframe *frame,
>   * error code on failure.
>   */
>  ssize_t
> -hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, size_t size)
> +hdmi_infoframe_pack_only(const union hdmi_infoframe *frame, void *buffer, size_t size)
> +{
> +	ssize_t length;
> +
> +	switch (frame->any.type) {
> +	case HDMI_INFOFRAME_TYPE_AVI:
> +		length = hdmi_avi_infoframe_pack_only(&frame->avi,
> +						      buffer, size);
> +		break;
> +	case HDMI_INFOFRAME_TYPE_SPD:
> +		length = hdmi_spd_infoframe_pack_only(&frame->spd,
> +						      buffer, size);
> +		break;
> +	case HDMI_INFOFRAME_TYPE_AUDIO:
> +		length = hdmi_audio_infoframe_pack_only(&frame->audio,
> +							buffer, size);
> +		break;
> +	case HDMI_INFOFRAME_TYPE_VENDOR:
> +		length = hdmi_vendor_any_infoframe_pack_only(&frame->vendor,
> +							     buffer, size);
> +		break;
> +	default:
> +		WARN(1, "Bad infoframe type %d\n", frame->any.type);
> +		length = -EINVAL;
> +	}
> +
> +	return length;
> +}
> +EXPORT_SYMBOL(hdmi_infoframe_pack_only);
> +
> +/**
> + * hdmi_infoframe_pack() - check a HDMI infoframe,
> + *                         and write it to binary buffer
> + * @frame: HDMI infoframe
> + * @buffer: destination buffer
> + * @size: size of buffer
> + *
> + * Validates that the infoframe is consistent and updates derived fields
> + * (eg. length) based on other fields, after which it packs the information
> + * contained in the @frame structure into a binary representation that
> + * can be written into the corresponding controller registers. This function
> + * also computes the checksum as required by section 5.3.5 of the HDMI 1.4
> + * specification.
> + *
> + * Returns the number of bytes packed into the binary buffer or a negative
> + * error code on failure.
> + */
> +ssize_t
> +hdmi_infoframe_pack(union hdmi_infoframe *frame,
> +		    void *buffer, size_t size)
>  {
>  	ssize_t length;
>  
> diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
> index bce1abb1fe57..c76b50a48e48 100644
> --- a/include/linux/hdmi.h
> +++ b/include/linux/hdmi.h
> @@ -163,6 +163,9 @@ struct hdmi_avi_infoframe {
>  int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame);
>  ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer,
>  				size_t size);
> +ssize_t hdmi_avi_infoframe_pack_only(const struct hdmi_avi_infoframe *frame,
> +				     void *buffer, size_t size);
> +int hdmi_avi_infoframe_check(struct hdmi_avi_infoframe *frame);
>  
>  enum hdmi_spd_sdi {
>  	HDMI_SPD_SDI_UNKNOWN,
> @@ -194,6 +197,9 @@ int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame,
>  			    const char *vendor, const char *product);
>  ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer,
>  				size_t size);
> +ssize_t hdmi_spd_infoframe_pack_only(const struct hdmi_spd_infoframe *frame,
> +				     void *buffer, size_t size);
> +int hdmi_spd_infoframe_check(struct hdmi_spd_infoframe *frame);
>  
>  enum hdmi_audio_coding_type {
>  	HDMI_AUDIO_CODING_TYPE_STREAM,
> @@ -272,6 +278,9 @@ struct hdmi_audio_infoframe {
>  int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame);
>  ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
>  				  void *buffer, size_t size);
> +ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe *frame,
> +				       void *buffer, size_t size);
> +int hdmi_audio_infoframe_check(struct hdmi_audio_infoframe *frame);
>  
>  enum hdmi_3d_structure {
>  	HDMI_3D_STRUCTURE_INVALID = -1,
> @@ -299,6 +308,9 @@ struct hdmi_vendor_infoframe {
>  int hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame);
>  ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
>  				   void *buffer, size_t size);
> +ssize_t hdmi_vendor_infoframe_pack_only(const struct hdmi_vendor_infoframe *frame,
> +					void *buffer, size_t size);
> +int hdmi_vendor_infoframe_check(struct hdmi_vendor_infoframe *frame);
>  
>  union hdmi_vendor_any_infoframe {
>  	struct {
> @@ -330,8 +342,11 @@ union hdmi_infoframe {
>  	struct hdmi_audio_infoframe audio;
>  };
>  
> -ssize_t
> -hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, size_t size);
> +ssize_t hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer,
> +			    size_t size);
> +ssize_t hdmi_infoframe_pack_only(const union hdmi_infoframe *frame,
> +				 void *buffer, size_t size);
> +int hdmi_infoframe_check(union hdmi_infoframe *frame);
>  int hdmi_infoframe_unpack(union hdmi_infoframe *frame,
>  			  const void *buffer, size_t size);
>  void hdmi_infoframe_log(const char *level, struct device *dev,
> -- 
> 2.16.4

-- 
Ville Syrjälä
Intel

  reply	other threads:[~2018-10-01 19:10 UTC|newest]

Thread overview: 95+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-20 18:51 [PATCH 00/18] drm/i915: Infoframe precompute/check Ville Syrjala
2018-09-20 18:51 ` Ville Syrjala
2018-09-20 18:51 ` [PATCH 01/18] video/hdmi: Constify 'buffer' to the unpack functions Ville Syrjala
2018-09-20 18:51   ` Ville Syrjala
2018-09-21  8:03   ` Hans Verkuil
2018-09-21  8:03     ` Hans Verkuil
2018-09-20 18:51 ` [PATCH 02/18] video/hdmi: Pass buffer size to infoframe " Ville Syrjala
2018-09-20 18:51   ` Ville Syrjala
2018-09-21  8:06   ` Hans Verkuil
2018-09-21  8:06     ` Hans Verkuil
2018-09-20 18:51 ` [PATCH 03/18] video/hdmi: Constify infoframe passed to the log functions Ville Syrjala
2018-09-20 18:51   ` Ville Syrjala
2018-09-21  8:06   ` Hans Verkuil
2018-09-21  8:06     ` Hans Verkuil
2018-09-20 18:51 ` [PATCH 04/18] video/hdmi: Constify infoframe passed to the pack functions Ville Syrjala
2018-09-20 18:51   ` Ville Syrjala
2018-09-21  8:24   ` Hans Verkuil
2018-09-21  8:24     ` Hans Verkuil
2018-09-21 14:30     ` Ville Syrjälä
2018-09-21 14:30       ` Ville Syrjälä
2018-09-21 14:33   ` [PATCH v3 " Ville Syrjala
2018-09-21 14:33     ` Ville Syrjala
2018-10-01 19:10     ` Ville Syrjälä [this message]
2018-10-01 19:10       ` Ville Syrjälä
2018-10-02  6:37       ` Hans Verkuil
2018-10-02  6:37         ` Hans Verkuil
2018-09-20 18:51 ` [PATCH 05/18] video/hdmi: Add an enum for HDMI packet types Ville Syrjala
2018-09-20 18:51   ` Ville Syrjala
2018-09-21  8:41   ` Hans Verkuil
2018-09-21  8:41     ` Hans Verkuil
2018-09-21 14:01     ` Ville Syrjälä
2018-09-21 14:01       ` Ville Syrjälä
2018-09-21 14:12       ` Hans Verkuil
2018-09-21 14:12         ` Hans Verkuil
2018-09-21 15:07         ` Ville Syrjälä
2018-09-21 15:07           ` Ville Syrjälä
2018-12-20 11:27   ` Sharma, Shashank
2018-09-20 18:51 ` [PATCH 06/18] video/hdmi: Handle the MPEG Source infoframe Ville Syrjala
2018-09-20 18:51   ` Ville Syrjala
2018-09-21  8:28   ` Hans Verkuil
2018-09-21  8:28     ` Hans Verkuil
2018-09-21 13:53     ` Ville Syrjälä
2018-09-21 13:53       ` Ville Syrjälä
2018-09-21 15:09   ` [PATCH v2 " Ville Syrjala
2018-09-21 15:09     ` Ville Syrjala
2018-09-20 18:51 ` [PATCH 07/18] video/hdmi: Handle the NTSC VBI infoframe Ville Syrjala
2018-09-20 18:51   ` Ville Syrjala
2018-09-21  8:30   ` Hans Verkuil
2018-09-21  8:30     ` Hans Verkuil
2018-09-21 13:54     ` Ville Syrjälä
2018-09-21 13:54       ` Ville Syrjälä
2018-09-21 15:10   ` [PATCH v2 " Ville Syrjala
2018-09-21 15:10     ` Ville Syrjala
2018-09-20 18:51 ` [PATCH 08/18] drm/i915: Use memmove() for punching the hole into infoframes Ville Syrjala
2018-09-21 13:52   ` Daniel Vetter
2018-09-20 18:51 ` [PATCH 09/18] drm/i915: Pass intel_encoder to infoframe functions Ville Syrjala
2018-09-21 13:59   ` Daniel Vetter
2018-09-21 15:03     ` Ville Syrjälä
2018-09-20 18:51 ` [PATCH 10/18] drm/i915: Add the missing HDMI gamut metadata packet stuff Ville Syrjala
2018-09-21 14:15   ` [Intel-gfx] " Daniel Vetter
2018-09-20 18:51 ` [PATCH 11/18] drm/i915: Return the mask of enabled infoframes from ->inforame_enabled() Ville Syrjala
2018-09-24 15:51   ` Daniel Vetter
2018-09-24 16:36     ` [Intel-gfx] " Ville Syrjälä
2018-10-01  6:55       ` Daniel Vetter
2018-10-01 19:29         ` Ville Syrjälä
2018-09-20 18:51 ` [PATCH 12/18] drm/i915: Store mask of enabled infoframes in the crtc state Ville Syrjala
2018-09-24 15:51   ` [Intel-gfx] " Daniel Vetter
2018-09-20 18:51 ` [PATCH 13/18] drm/i915: Precompute HDMI infoframes Ville Syrjala
2018-09-24 15:58   ` Daniel Vetter
2018-09-24 16:42     ` Ville Syrjälä
2018-09-20 18:51 ` [PATCH 14/18] drm/i915: Read out " Ville Syrjala
2018-09-24 16:08   ` Daniel Vetter
2018-09-24 16:52     ` Ville Syrjälä
2018-09-20 18:51 ` [PATCH 15/18] drm/i915/sdvo: Precompute " Ville Syrjala
2018-09-20 18:51 ` [PATCH 16/18] drm/i915/sdvo: Read out " Ville Syrjala
2018-09-24 16:10   ` [Intel-gfx] " Daniel Vetter
2018-09-24 17:13     ` Ville Syrjälä
2018-10-01  6:59       ` Daniel Vetter
2018-10-01 13:35         ` Ville Syrjälä
2018-10-01 16:48           ` Daniel Vetter
2018-09-20 18:51 ` [PATCH 17/18] drm/i915: Check infoframe state in intel_pipe_config_compare() Ville Syrjala
2018-09-24 16:12   ` Daniel Vetter
2018-10-01 20:35     ` [Intel-gfx] " Ville Syrjälä
2018-10-02  8:16       ` Daniel Vetter
2018-09-20 18:51 ` [PATCH 18/18] drm/i915: Include infoframes in the crtc state dump Ville Syrjala
2018-09-24 16:14   ` [Intel-gfx] " Daniel Vetter
2018-09-20 19:02 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Infoframe precompute/check Patchwork
2018-09-20 19:12 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-09-20 19:26 ` ✓ Fi.CI.BAT: success " Patchwork
2018-09-20 22:30 ` ✓ Fi.CI.IGT: " Patchwork
2018-09-21 14:40 ` ✗ Fi.CI.BAT: failure for drm/i915: Infoframe precompute/check (rev2) Patchwork
2018-09-21 15:25 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Infoframe precompute/check (rev4) Patchwork
2018-09-21 15:35 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-09-21 15:46 ` ✓ Fi.CI.BAT: success " Patchwork
2018-09-21 17:04 ` ✓ Fi.CI.IGT: " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20181001191037.GN9144@intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=hans.verkuil@cisco.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=linux-media@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.