if (!can_assume(LATEST) && fdt_version(fdt) < 0x10) { /* * For old FDT versions, match the naming conventions of V16: * give only the leaf name (after all /). The actual tree * contents are loosely checked.
*/ constchar *leaf;
leaf = strrchr(nameptr, '/'); if (leaf == NULL) {
err = -FDT_ERR_BADSTRUCTURE; goto fail;
}
nameptr = leaf+1;
}
if (len)
*len = strlen(nameptr);
return nameptr;
fail: if (len)
*len = err; return NULL;
}
int fdt_first_property_offset(constvoid *fdt, int nodeoffset)
{ int offset;
if ((offset = fdt_check_node_offset_(fdt, nodeoffset)) < 0) return offset;
return nextprop_(fdt, offset);
}
int fdt_next_property_offset(constvoid *fdt, int offset)
{ if ((offset = fdt_check_prop_offset_(fdt, offset)) < 0) return offset;
return nextprop_(fdt, offset);
}
staticconststruct fdt_property *fdt_get_property_by_offset_(constvoid *fdt, int offset, int *lenp)
{ int err; conststruct fdt_property *prop;
if (!can_assume(VALID_INPUT) &&
(err = fdt_check_prop_offset_(fdt, offset)) < 0) { if (lenp)
*lenp = err; return NULL;
}
prop = fdt_offset_ptr_(fdt, offset);
if (lenp)
*lenp = fdt32_ld_(&prop->len);
return prop;
}
conststruct fdt_property *fdt_get_property_by_offset(constvoid *fdt, int offset, int *lenp)
{ /* Prior to version 16, properties may need realignment
* and this API does not work. fdt_getprop_*() will, however. */
if (!can_assume(LATEST) && fdt_version(fdt) < 0x10) { if (lenp)
*lenp = -FDT_ERR_BADVERSION; return NULL;
}
staticconststruct fdt_property *fdt_get_property_namelen_(constvoid *fdt, int offset, constchar *name, int namelen, int *lenp, int *poffset)
{ for (offset = fdt_first_property_offset(fdt, offset);
(offset >= 0);
(offset = fdt_next_property_offset(fdt, offset))) { conststruct fdt_property *prop;
prop = fdt_get_property_by_offset_(fdt, offset, lenp); if (!can_assume(LIBFDT_FLAWLESS) && !prop) {
offset = -FDT_ERR_INTERNAL; break;
} if (fdt_string_eq_(fdt, fdt32_ld_(&prop->nameoff),
name, namelen)) { if (poffset)
*poffset = offset; return prop;
}
}
if (lenp)
*lenp = offset; return NULL;
}
conststruct fdt_property *fdt_get_property_namelen(constvoid *fdt, int offset, constchar *name, int namelen, int *lenp)
{ /* Prior to version 16, properties may need realignment
* and this API does not work. fdt_getprop_*() will, however. */ if (!can_assume(LATEST) && fdt_version(fdt) < 0x10) { if (lenp)
*lenp = -FDT_ERR_BADVERSION; return NULL;
}
constvoid *fdt_getprop(constvoid *fdt, int nodeoffset, constchar *name, int *lenp)
{ return fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), lenp);
}
uint32_t fdt_get_phandle(constvoid *fdt, int nodeoffset)
{ const fdt32_t *php; int len;
/* FIXME: This is a bit sub-optimal, since we potentially scan
* over all the properties twice. */
php = fdt_getprop(fdt, nodeoffset, "phandle", &len); if (!php || (len != sizeof(*php))) {
php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len); if (!php || (len != sizeof(*php))) return 0;
}
return fdt32_ld_(php);
}
staticconstvoid *fdt_path_getprop_namelen(constvoid *fdt, constchar *path, constchar *propname, int propnamelen, int *lenp)
{ int offset = fdt_path_offset(fdt, path);
int fdt_supernode_atdepth_offset(constvoid *fdt, int nodeoffset, int supernodedepth, int *nodedepth)
{ int offset, depth; int supernodeoffset = -FDT_ERR_INTERNAL;
int fdt_node_offset_by_prop_value(constvoid *fdt, int startoffset, constchar *propname, constvoid *propval, int proplen)
{ int offset; constvoid *val; int len;
FDT_RO_PROBE(fdt);
/* FIXME: The algorithm here is pretty horrible: we scan each * property of a node in fdt_getprop(), then if that didn't * find what we want, we scan over them again making our way * to the next node. Still it's the easiest to implement
* approach; performance can come later. */ for (offset = fdt_next_node(fdt, startoffset, NULL);
offset >= 0;
offset = fdt_next_node(fdt, offset, NULL)) {
val = fdt_getprop(fdt, offset, propname, &len); if (val && (len == proplen)
&& (memcmp(val, propval, len) == 0)) return offset;
}
return offset; /* error from fdt_next_node() */
}
int fdt_node_offset_by_phandle(constvoid *fdt, uint32_t phandle)
{ int offset;
if ((phandle == 0) || (phandle == ~0U)) return -FDT_ERR_BADPHANDLE;
FDT_RO_PROBE(fdt);
/* FIXME: The algorithm here is pretty horrible: we * potentially scan each property of a node in * fdt_get_phandle(), then if that didn't find what * we want, we scan over them again making our way to the next * node. Still it's the easiest to implement approach;
* performance can come later. */ for (offset = fdt_next_node(fdt, -1, NULL);
offset >= 0;
offset = fdt_next_node(fdt, offset, NULL)) { if (fdt_get_phandle(fdt, offset) == phandle) return offset;
}
return offset; /* error from fdt_next_node() */
}
int fdt_stringlist_contains(constchar *strlist, int listlen, constchar *str)
{ int len = strlen(str); constchar *p;
while (listlen >= len) { if (memcmp(str, strlist, len+1) == 0) return 1;
p = memchr(strlist, '\0', listlen); if (!p) return 0; /* malformed strlist.. */
listlen -= (p-strlist) + 1;
strlist = p + 1;
} return 0;
}
int fdt_stringlist_count(constvoid *fdt, int nodeoffset, constchar *property)
{ constchar *list, *end; int length, count = 0;
list = fdt_getprop(fdt, nodeoffset, property, &length); if (!list) return length;
end = list + length;
while (list < end) {
length = strnlen(list, end - list) + 1;
/* Abort if the last string isn't properly NUL-terminated. */ if (list + length > end) return -FDT_ERR_BADVALUE;
list += length;
count++;
}
return count;
}
int fdt_stringlist_search(constvoid *fdt, int nodeoffset, constchar *property, constchar *string)
{ int length, len, idx = 0; constchar *list, *end;
list = fdt_getprop(fdt, nodeoffset, property, &length); if (!list) return length;
len = strlen(string) + 1;
end = list + length;
while (list < end) {
length = strnlen(list, end - list) + 1;
/* Abort if the last string isn't properly NUL-terminated. */ if (list + length > end) return -FDT_ERR_BADVALUE;
if (length == len && memcmp(list, string, length) == 0) return idx;
list += length;
idx++;
}
return -FDT_ERR_NOTFOUND;
}
constchar *fdt_stringlist_get(constvoid *fdt, int nodeoffset, constchar *property, int idx, int *lenp)
{ constchar *list, *end; int length;
list = fdt_getprop(fdt, nodeoffset, property, &length); if (!list) { if (lenp)
*lenp = length;
return NULL;
}
end = list + length;
while (list < end) {
length = strnlen(list, end - list) + 1;
/* Abort if the last string isn't properly NUL-terminated. */ if (list + length > end) { if (lenp)
*lenp = -FDT_ERR_BADVALUE;
return NULL;
}
if (idx == 0) { if (lenp)
*lenp = length - 1;
return list;
}
list += length;
idx--;
}
if (lenp)
*lenp = -FDT_ERR_NOTFOUND;
return NULL;
}
int fdt_node_check_compatible(constvoid *fdt, int nodeoffset, constchar *compatible)
{ constvoid *prop; int len;
prop = fdt_getprop(fdt, nodeoffset, "compatible", &len); if (!prop) return len;
int fdt_node_offset_by_compatible(constvoid *fdt, int startoffset, constchar *compatible)
{ int offset, err;
FDT_RO_PROBE(fdt);
/* FIXME: The algorithm here is pretty horrible: we scan each * property of a node in fdt_node_check_compatible(), then if * that didn't find what we want, we scan over them again * making our way to the next node. Still it's the easiest to
* implement approach; performance can come later. */ for (offset = fdt_next_node(fdt, startoffset, NULL);
offset >= 0;
offset = fdt_next_node(fdt, offset, NULL)) {
err = fdt_node_check_compatible(fdt, offset, compatible); if ((err < 0) && (err != -FDT_ERR_NOTFOUND)) return err; elseif (err == 0) return offset;
}
return offset; /* error from fdt_next_node() */
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.