libfdt: Add new maximum phandle lookup function
The fdt_get_max_phandle() function has some shortcomings. On one hand it returns just a uint32_t which means to check for the "negative" error code a caller has to explicitly check 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@nvidia.com> Message-Id: <20190326153302.17109-1-thierry.reding@gmail.com> [dwg: Reword for some inaccuracies in the commit message] Signed-off-by: David Gibson <david@gibson.dropbear.id.au>main
parent
7fcf8208b8
commit
2bc5b66d7f
|
@ -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;
|
||||
|
||||
offset = fdt_next_node(fdt, offset, NULL);
|
||||
if (offset < 0) {
|
||||
if (offset == -FDT_ERR_NOTFOUND)
|
||||
return max_phandle;
|
||||
break;
|
||||
|
||||
if (offset < 0)
|
||||
return (uint32_t)-1;
|
||||
|
||||
phandle = fdt_get_phandle(fdt, offset);
|
||||
if (phandle == (uint32_t)-1)
|
||||
continue;
|
||||
|
||||
if (phandle > max_phandle)
|
||||
max_phandle = phandle;
|
||||
return offset;
|
||||
}
|
||||
|
||||
value = fdt_get_phandle(fdt, offset);
|
||||
|
||||
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);
|
||||
|
|
|
@ -385,6 +385,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
|
||||
|
@ -393,6 +407,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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue