summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2019-03-26 16:33:00 +0100
committerDavid Gibson <david@gibson.dropbear.id.au>2019-03-29 13:29:51 +1100
commit2bc5b66d7f6c441bf6183a6f769a95de6f90297b (patch)
tree4216cca36c2101ce095e52d192c3ef596661ae7b
parent7fcf8208b8a98f65ce938a64fab674add3656f27 (diff)
downloaddevice-tree-compiler-2bc5b66d7f6c441bf6183a6f769a95de6f90297b.tar.gz
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>
-rw-r--r--libfdt/fdt_ro.c44
-rw-r--r--libfdt/libfdt.h16
-rw-r--r--libfdt/libfdt_env.h1
-rw-r--r--libfdt/version.lds1
-rw-r--r--tests/get_phandle.c9
5 files changed, 56 insertions, 15 deletions
diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c
index eafc142..1d0335e 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 e70f5bf..e1498c3 100644
--- a/libfdt/libfdt.h
+++ b/libfdt/libfdt.h
@@ -386,6 +386,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
diff --git a/libfdt/libfdt_env.h b/libfdt/libfdt_env.h
index eb20538..4d1cdfa 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 a5fe62d..87bbb2f 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 22bd7b8..6973ee4 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",