Re: [PATCH v4 1/3] libfdt: Add new maximum phandle lookup function

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



On Tue, Mar 26, 2019 at 04:33:00PM +0100, Thierry Reding wrote:
> From: Thierry Reding <treding@xxxxxxxxxx>
> 
> The fdt_get_max_phandle() function has some shortcomings. On one hand it
> returns a uint32_t phandle value via a signed return value.

Uh.. no it doesn't..

> This means a
> caller has to explicitly cast the return value to a uint32_t and perform
> explicit checks against the error code (uint32_t)-1. In addition, the -1
> is the only error code that can be returned, so a caller cannot tell the
> difference between the various failures.
> 
> Fix this by adding a new fdt_find_max_phandle() function that returns an
> error code on failure and 0 on success, just like other APIs, and stores
> the maximum phandle value in an output argument on success.
> 
> This also refactors fdt_get_max_phandle() to use the new function. Add a
> note pointing out that the new fdt_find_max_phandle() function should be
> preferred over fdt_get_max_phandle().
> 
> Signed-off-by: Thierry Reding <treding@xxxxxxxxxx>

I've applied the series, but adjusted the commit message above for
accuracy.  I'm also planning on some followup cleanups which may
change things up a bit more.

> ---
> Changes in v4:
> - new patch
> 
>  libfdt/fdt_ro.c     | 44 +++++++++++++++++++++++++++++---------------
>  libfdt/libfdt.h     | 16 ++++++++++++++++
>  libfdt/libfdt_env.h |  1 +
>  libfdt/version.lds  |  1 +
>  tests/get_phandle.c |  9 +++++++++
>  5 files changed, 56 insertions(+), 15 deletions(-)
> 
> diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c
> index eafc14282892..1d0335ee7188 100644
> --- a/libfdt/fdt_ro.c
> +++ b/libfdt/fdt_ro.c
> @@ -144,32 +144,46 @@ static int fdt_string_eq_(const void *fdt, int stroffset,
>  	return p && (slen == len) && (memcmp(p, s, len) == 0);
>  }
>  
> -uint32_t fdt_get_max_phandle(const void *fdt)
> +int fdt_find_max_phandle(const void *fdt, uint32_t *phandle)
>  {
> -	uint32_t max_phandle = 0;
> -	int offset;
> +	uint32_t max = 0;
> +	int offset = -1;
>  
> -	for (offset = fdt_next_node(fdt, -1, NULL);;
> -	     offset = fdt_next_node(fdt, offset, NULL)) {
> -		uint32_t phandle;
> +	while (true) {
> +		uint32_t value;
>  
> -		if (offset == -FDT_ERR_NOTFOUND)
> -			return max_phandle;
> +		offset = fdt_next_node(fdt, offset, NULL);
> +		if (offset < 0) {
> +			if (offset == -FDT_ERR_NOTFOUND)
> +				break;
>  
> -		if (offset < 0)
> -			return (uint32_t)-1;
> +			return offset;
> +		}
>  
> -		phandle = fdt_get_phandle(fdt, offset);
> -		if (phandle == (uint32_t)-1)
> -			continue;
> +		value = fdt_get_phandle(fdt, offset);
>  
> -		if (phandle > max_phandle)
> -			max_phandle = phandle;
> +		if (value > max)
> +			max = value;
>  	}
>  
> +	if (phandle)
> +		*phandle = max;
> +
>  	return 0;
>  }
>  
> +uint32_t fdt_get_max_phandle(const void *fdt)
> +{
> +	uint32_t phandle;
> +	int err;
> +
> +	err = fdt_find_max_phandle(fdt, &phandle);
> +	if (err < 0)
> +		return (uint32_t)-1;
> +
> +	return phandle;
> +}
> +
>  static const struct fdt_reserve_entry *fdt_mem_rsv(const void *fdt, int n)
>  {
>  	int offset = n * sizeof(struct fdt_reserve_entry);
> diff --git a/libfdt/libfdt.h b/libfdt/libfdt.h
> index a470d1df6d2a..6fce659fd279 100644
> --- a/libfdt/libfdt.h
> +++ b/libfdt/libfdt.h
> @@ -361,6 +361,20 @@ const char *fdt_get_string(const void *fdt, int stroffset, int *lenp);
>   */
>  const char *fdt_string(const void *fdt, int stroffset);
>  
> +/**
> + * fdt_find_max_phandle - find and return the highest phandle in a tree
> + * @fdt: pointer to the device tree blob
> + * @phandle: return location for the highest phandle value found in the tree
> + *
> + * fdt_find_max_phandle() finds the highest phandle value in the given device
> + * tree. The value returned in @phandle is only valid if the function returns
> + * success.
> + *
> + * returns:
> + *     0 on success or a negative error code on failure
> + */
> +int fdt_find_max_phandle(const void *fdt, uint32_t *phandle);
> +
>  /**
>   * fdt_get_max_phandle - retrieves the highest phandle in a tree
>   * @fdt: pointer to the device tree blob
> @@ -369,6 +383,8 @@ const char *fdt_string(const void *fdt, int stroffset);
>   * device tree. This will ignore badly formatted phandles, or phandles
>   * with a value of 0 or -1.
>   *
> + * This function is deprecated in favour of fdt_find_max_phandle().
> + *
>   * returns:
>   *      the highest phandle on success
>   *      0, if no phandle was found in the device tree
> diff --git a/libfdt/libfdt_env.h b/libfdt/libfdt_env.h
> index eb2053845c9c..4d1cdfa58547 100644
> --- a/libfdt/libfdt_env.h
> +++ b/libfdt/libfdt_env.h
> @@ -52,6 +52,7 @@
>   *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>   */
>  
> +#include <stdbool.h>
>  #include <stddef.h>
>  #include <stdint.h>
>  #include <stdlib.h>
> diff --git a/libfdt/version.lds b/libfdt/version.lds
> index a5fe62d5c5ff..87bbb2fe54d3 100644
> --- a/libfdt/version.lds
> +++ b/libfdt/version.lds
> @@ -66,6 +66,7 @@ LIBFDT_1.2 {
>  		fdt_resize;
>  		fdt_overlay_apply;
>  		fdt_get_string;
> +		fdt_find_max_phandle;
>  		fdt_get_max_phandle;
>  		fdt_check_full;
>  		fdt_setprop_placeholder;
> diff --git a/tests/get_phandle.c b/tests/get_phandle.c
> index 22bd7b81b3f0..6973ee4caa17 100644
> --- a/tests/get_phandle.c
> +++ b/tests/get_phandle.c
> @@ -46,6 +46,7 @@ int main(int argc, char *argv[])
>  {
>  	uint32_t max;
>  	void *fdt;
> +	int err;
>  
>  	test_init(argc, argv);
>  	fdt = load_blob_arg(argc, argv);
> @@ -54,6 +55,14 @@ int main(int argc, char *argv[])
>  	check_phandle(fdt, "/subnode@2", PHANDLE_1);
>  	check_phandle(fdt, "/subnode@2/subsubnode@0", PHANDLE_2);
>  
> +	err = fdt_find_max_phandle(fdt, &max);
> +	if (err < 0)
> +		FAIL("fdt_find_max_phandle returned %d instead of 0\n", err);
> +
> +	if (max != PHANDLE_2)
> +		FAIL("fdt_find_max_phandle found 0x%x instead of 0x%x", max,
> +		     PHANDLE_2);
> +
>  	max = fdt_get_max_phandle(fdt);
>  	if (max != PHANDLE_2)
>  		FAIL("fdt_get_max_phandle returned 0x%x instead of 0x%x\n",

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Device Tree]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux