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))) return0;
}
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 *propertyofanodeinfdt_getprop(),thenifthatdidn't *findwhatwewant,wescanoverthemagainmakingourway *tothenextnode.Stillit'stheeasiesttoimplement
* 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 *potentiallyscaneachpropertyofanodein *fdt_get_phandle(),thenifthatdidn'tfindwhat *wewant,wescanoverthemagainmakingourwaytothenext *node.Stillit'stheeasiesttoimplementapproach;
* 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) return1;
p = memchr(strlist, '\0', listlen); if (!p) return0; /* malformed strlist.. */
listlen -= (p-strlist) + 1;
strlist = p + 1;
} return0;
}
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;
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.