From 0219399a4e3a8edb428e1924e1a03d58cccf8d8e Mon Sep 17 00:00:00 2001 From: David Gibson Date: Wed, 6 Aug 2008 14:50:49 +1000 Subject: [PATCH] libfdt: Implement fdt_get_property_namelen() and fdt_getprop_namelen() As well as fdt_subnode_offset(), libfdt includes an fdt_subnode_offset_namelen() function that takes the subnode name to look up not as a NUL-terminated string, but as a string with an explicit length. This can be useful when the caller has the name as part of a longer string, such as a full path. However, we don't have corresponding 'namelen' versions for fdt_get_property() and fdt_getprop(). There are less obvious use cases for these variants on property names, but there are circumstances where they can be useful e.g. looking up property names which need to be parsed from a longer string buffer such as user input or a configuration file, or looking up an alias in a path with IEEE1275 style aliases. So, since it's very easy to implement such variants, this patch does so. The original NUL-terminated variants are, of course, implemented in terms of the namelen versions. Signed-off-by: David Gibson --- include/libfdt.h | 30 ++++++++++++++++++++++++++++++ libfdt/fdt_ro.c | 37 ++++++++++++++++++++++++++++++------- 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/include/libfdt.h b/include/libfdt.h index 0747981af9..94c35e330c 100644 --- a/include/libfdt.h +++ b/include/libfdt.h @@ -342,6 +342,22 @@ int fdt_path_offset(const void *fdt, const char *path); */ const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp); +/** + * fdt_get_property_namelen - find a property based on substring + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to find + * @name: name of the property to find + * @namelen: number of characters of name to consider + * @lenp: pointer to an integer variable (will be overwritten) or NULL + * + * Identical to fdt_get_property_namelen(), but only examine the first + * namelen characters of name for matching the property name. + */ +const struct fdt_property *fdt_get_property_namelen(const void *fdt, + int nodeoffset, + const char *name, + int namelen, int *lenp); + /** * fdt_get_property - find a given property in a given node * @fdt: pointer to the device tree blob @@ -379,6 +395,20 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset, fdt_get_property(fdt, nodeoffset, name, lenp); } +/** + * fdt_getprop_namelen - get property value based on substring + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to find + * @name: name of the property to find + * @namelen: number of characters of name to consider + * @lenp: pointer to an integer variable (will be overwritten) or NULL + * + * Identical to fdt_getprop(), but only examine the first namelen + * characters of name for matching the property name. + */ +const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, + const char *name, int namelen, int *lenp); + /** * fdt_getprop - retrieve the value of a given property * @fdt: pointer to the device tree blob diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c index 6292a00be5..d566eba274 100644 --- a/libfdt/fdt_ro.c +++ b/libfdt/fdt_ro.c @@ -84,6 +84,14 @@ const char *fdt_string(const void *fdt, int stroffset) return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset; } +static int _fdt_string_eq(const void *fdt, int stroffset, + const char *s, int len) +{ + const char *p = fdt_string(fdt, stroffset); + + return (strlen(p) == len) && (memcmp(p, s, len) == 0); +} + int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size) { FDT_CHECK_HEADER(fdt); @@ -179,9 +187,10 @@ const char *fdt_get_name(const void *fdt, int nodeoffset, int *len) return NULL; } -const struct fdt_property *fdt_get_property(const void *fdt, - int nodeoffset, - const char *name, int *lenp) +const struct fdt_property *fdt_get_property_namelen(const void *fdt, + int nodeoffset, + const char *name, + int namelen, int *lenp) { uint32_t tag; const struct fdt_property *prop; @@ -214,7 +223,7 @@ const struct fdt_property *fdt_get_property(const void *fdt, if (! prop) goto fail; namestroff = fdt32_to_cpu(prop->nameoff); - if (strcmp(fdt_string(fdt, namestroff), name) == 0) { + if (_fdt_string_eq(fdt, namestroff, name, namelen)) { /* Found it! */ int len = fdt32_to_cpu(prop->len); prop = fdt_offset_ptr(fdt, offset, @@ -242,18 +251,32 @@ const struct fdt_property *fdt_get_property(const void *fdt, return NULL; } -const void *fdt_getprop(const void *fdt, int nodeoffset, - const char *name, int *lenp) +const struct fdt_property *fdt_get_property(const void *fdt, + int nodeoffset, + const char *name, int *lenp) +{ + return fdt_get_property_namelen(fdt, nodeoffset, name, + strlen(name), lenp); +} + +const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, + const char *name, int namelen, int *lenp) { const struct fdt_property *prop; - prop = fdt_get_property(fdt, nodeoffset, name, lenp); + prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp); if (! prop) return NULL; return prop->data; } +const void *fdt_getprop(const void *fdt, int nodeoffset, + const char *name, int *lenp) +{ + return fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), lenp); +} + uint32_t fdt_get_phandle(const void *fdt, int nodeoffset) { const uint32_t *php; -- 2.39.5