diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c index 6365c26..d12c7ee 100644 --- a/libfdt/fdt_ro.c +++ b/libfdt/fdt_ro.c @@ -108,12 +108,12 @@ int fdt_num_mem_rsv(const void *fdt) int fdt_subnode_offset_namelen(const void *fdt, int offset, const char *name, int namelen) { - int depth; + int depth = 0; FDT_CHECK_HEADER(fdt); - for (depth = 0; - offset >= 0; + for (depth = 0, offset = fdt_next_node(fdt, offset, &depth); + (offset >= 0) && (depth > 0); offset = fdt_next_node(fdt, offset, &depth)) { if (depth < 0) return -FDT_ERR_NOTFOUND; @@ -122,7 +122,10 @@ int fdt_subnode_offset_namelen(const void *fdt, int offset, return offset; } - return offset; /* error */ + if (offset < 0) + return offset; /* error */ + else + return -FDT_ERR_NOTFOUND; } int fdt_subnode_offset(const void *fdt, int parentoffset, diff --git a/tests/include1.dts b/tests/include1.dts index 0c7f42e..8d7e747 100644 --- a/tests/include1.dts +++ b/tests/include1.dts @@ -19,5 +19,8 @@ compatible = "subsubnode2", "subsubnode"; prop-int = <0726746425>; }; + + ss2 { + }; }; }; diff --git a/tests/include7.dts b/tests/include7.dts index fa726f9..dba5e47 100644 --- a/tests/include7.dts +++ b/tests/include7.dts @@ -6,4 +6,7 @@ compatible = "subsubnode1", "subsubnode"; prop-int = <0xdeadbeef>; }; + + ss1 { + }; }; diff --git a/tests/rw_tree1.c b/tests/rw_tree1.c index 8f335c9..f0bce88 100644 --- a/tests/rw_tree1.c +++ b/tests/rw_tree1.c @@ -50,7 +50,7 @@ int main(int argc, char *argv[]) { void *fdt; int err; - int offset; + int offset, s1, s2; test_init(argc, argv); @@ -77,21 +77,25 @@ int main(int argc, char *argv[]) CHECK(fdt_setprop_string(fdt, 0, "prop-str", TEST_STRING_1)); OFF_CHECK(offset, fdt_add_subnode(fdt, 0, "subnode@1")); - CHECK(fdt_setprop_string(fdt, offset, "compatible", "subnode1")); - CHECK(fdt_setprop_cell(fdt, offset, "prop-int", TEST_VALUE_1)); - OFF_CHECK(offset, fdt_add_subnode(fdt, offset, "subsubnode")); + s1 = offset; + CHECK(fdt_setprop_string(fdt, s1, "compatible", "subnode1")); + CHECK(fdt_setprop_cell(fdt, s1, "prop-int", TEST_VALUE_1)); + OFF_CHECK(offset, fdt_add_subnode(fdt, s1, "subsubnode")); CHECK(fdt_setprop(fdt, offset, "compatible", "subsubnode1\0subsubnode", 23)); CHECK(fdt_setprop_cell(fdt, offset, "prop-int", TEST_VALUE_1)); + OFF_CHECK(offset, fdt_add_subnode(fdt, s1, "ss1")); OFF_CHECK(offset, fdt_add_subnode(fdt, 0, "subnode@2")); - CHECK(fdt_setprop_cell(fdt, offset, "linux,phandle", PHANDLE_1)); - CHECK(fdt_setprop_cell(fdt, offset, "prop-int", TEST_VALUE_2)); - OFF_CHECK(offset, fdt_add_subnode(fdt, offset, "subsubnode@0")); + s2 = offset; + CHECK(fdt_setprop_cell(fdt, s2, "linux,phandle", PHANDLE_1)); + CHECK(fdt_setprop_cell(fdt, s2, "prop-int", TEST_VALUE_2)); + OFF_CHECK(offset, fdt_add_subnode(fdt, s2, "subsubnode@0")); CHECK(fdt_setprop_cell(fdt, offset, "linux,phandle", PHANDLE_2)); CHECK(fdt_setprop(fdt, offset, "compatible", "subsubnode2\0subsubnode", 23)); CHECK(fdt_setprop_cell(fdt, offset, "prop-int", TEST_VALUE_2)); + OFF_CHECK(offset, fdt_add_subnode(fdt, s2, "ss2")); CHECK(fdt_pack(fdt)); diff --git a/tests/subnode_offset.c b/tests/subnode_offset.c index 17be8d8..b961070 100644 --- a/tests/subnode_offset.c +++ b/tests/subnode_offset.c @@ -60,6 +60,7 @@ int main(int argc, char *argv[]) void *fdt; int subnode1_offset, subnode2_offset; int subsubnode1_offset, subsubnode2_offset, subsubnode2_offset2; + int ss11_off, ss12_off, ss21_off, ss22_off; test_init(argc, argv); fdt = load_blob_arg(argc, argv); @@ -84,5 +85,15 @@ int main(int argc, char *argv[]) if (subsubnode2_offset != subsubnode2_offset2) FAIL("Different offsets with and without unit address"); + ss11_off = check_subnode(fdt, subnode1_offset, "ss1"); + ss21_off = fdt_subnode_offset(fdt, subnode2_offset, "ss1"); + if (ss21_off != -FDT_ERR_NOTFOUND) + FAIL("Incorrectly found ss1 in subnode2"); + + ss12_off = fdt_subnode_offset(fdt, subnode1_offset, "ss2"); + if (ss12_off != -FDT_ERR_NOTFOUND) + FAIL("Incorrectly found ss2 in subnode1"); + ss22_off = check_subnode(fdt, subnode2_offset, "ss2"); + PASS(); } diff --git a/tests/sw_tree1.c b/tests/sw_tree1.c index 2a94b63..687fb82 100644 --- a/tests/sw_tree1.c +++ b/tests/sw_tree1.c @@ -66,6 +66,8 @@ int main(int argc, char *argv[]) 23)); CHECK(fdt_property_cell(fdt, "prop-int", TEST_VALUE_1)); CHECK(fdt_end_node(fdt)); + CHECK(fdt_begin_node(fdt, "ss1")); + CHECK(fdt_end_node(fdt)); CHECK(fdt_end_node(fdt)); CHECK(fdt_begin_node(fdt, "subnode@2")); @@ -77,6 +79,9 @@ int main(int argc, char *argv[]) 23)); CHECK(fdt_property_cell(fdt, "prop-int", TEST_VALUE_2)); CHECK(fdt_end_node(fdt)); + CHECK(fdt_begin_node(fdt, "ss2")); + CHECK(fdt_end_node(fdt)); + CHECK(fdt_end_node(fdt)); CHECK(fdt_end_node(fdt)); diff --git a/tests/test_tree1.dts b/tests/test_tree1.dts index 27602af..1593554 100644 --- a/tests/test_tree1.dts +++ b/tests/test_tree1.dts @@ -16,6 +16,9 @@ compatible = "subsubnode1", "subsubnode"; prop-int = <0xdeadbeef>; }; + + ss1 { + }; }; subnode@2 { @@ -27,5 +30,8 @@ compatible = "subsubnode2", "subsubnode"; prop-int = <0726746425>; }; + + ss2 { + }; }; }; diff --git a/tests/test_tree1_dts0.dts b/tests/test_tree1_dts0.dts index 6b40cf5..032d540 100644 --- a/tests/test_tree1_dts0.dts +++ b/tests/test_tree1_dts0.dts @@ -16,6 +16,9 @@ compatible = "subsubnode1", "subsubnode"; prop-int = < 0xdeadbeef>; }; + + ss1 { + }; }; subnode@2 { @@ -27,5 +30,8 @@ compatible = "subsubnode2", "subsubnode"; prop-int = < 0726746425>; }; + + ss2 { + }; }; }; diff --git a/tests/trees.S b/tests/trees.S index cedf5f9..609cdd6 100644 --- a/tests/trees.S +++ b/tests/trees.S @@ -96,6 +96,10 @@ test_tree1_struct: PROP_STR(test_tree1, compatible, "subsubnode1\0subsubnode") PROP_INT(test_tree1, prop_int, TEST_VALUE_1) END_NODE + + BEGIN_NODE("ss1") + END_NODE + END_NODE BEGIN_NODE("subnode@2") @@ -107,6 +111,10 @@ test_tree1_struct: PROP_STR(test_tree1, compatible, "subsubnode2\0subsubnode") PROP_INT(test_tree1, prop_int, TEST_VALUE_2) END_NODE + + BEGIN_NODE("ss2") + END_NODE + END_NODE END_NODE