static int check_subnode(struct fdt_header *fdt, int parent, const char *name) { int offset; const struct fdt_node_header *nh; uint32_t tag; verbose_printf("Checking subnode \"%s\" of %d...", name, parent); offset = fdt_subnode_offset(fdt, parent, name); verbose_printf("offset %d...", offset); if (offset < 0) FAIL("fdt_subnode_offset(\"%s\"): %s", name, fdt_strerror(offset)); nh = fdt_offset_ptr(fdt, offset, sizeof(*nh)); verbose_printf("pointer %p\n", nh); if (! nh) FAIL("NULL retrieving subnode \"%s\"", name); tag = fdt32_to_cpu(nh->tag); if (tag != FDT_BEGIN_NODE) FAIL("Incorrect tag 0x%08x on property \"%s\"", tag, name); if (!nodename_eq(nh->name, name)) FAIL("Subnode name mismatch \"%s\" instead of \"%s\"", nh->name, name); return offset; }
int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, const char *name, int namelen) { int level = 0; uint32_t tag; int offset, nextoffset; CHECK_HEADER(fdt); tag = fdt_next_tag(fdt, parentoffset, &nextoffset); if (tag != FDT_BEGIN_NODE) return -FDT_ERR_BADOFFSET; do { offset = nextoffset; tag = fdt_next_tag(fdt, offset, &nextoffset); switch (tag) { case FDT_END: return -FDT_ERR_TRUNCATED; case FDT_BEGIN_NODE: level++; if (level != 1) continue; if (nodename_eq(fdt, offset+FDT_TAGSIZE, name, namelen)) /* Found it! */ return offset; break; case FDT_END_NODE: level--; break; case FDT_PROP: case FDT_NOP: break; default: return -FDT_ERR_BADSTRUCTURE; } } while (level >= 0); return -FDT_ERR_NOTFOUND; }
int fdt_subnode_offset_namelen(const void *fdt, int offset, const char *name, int namelen) { int depth; CHECK_HEADER(fdt); for (depth = 0; offset >= 0; offset = fdt_next_node(fdt, offset, &depth)) { if (depth < 0) return -FDT_ERR_NOTFOUND; else if ((depth == 1) && nodename_eq(fdt, offset, name, namelen)) return offset; } return offset; /* error */ }