diff options
author | Sakari Ailus <sakari.ailus@linux.intel.com> | 2017-03-28 14:22:18 +0200 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2017-03-29 00:00:30 +0200 |
commit | 0f194992c85f972ee99f176eb78a5860cef78573 (patch) | |
tree | 41fa770d02cab8a1cc09c2826da75ea8c12285bf /drivers/base/property.c | |
parent | device property: fwnode_property_read_string_array() may return -EILSEQ (diff) | |
download | linux-0f194992c85f972ee99f176eb78a5860cef78573.tar.xz linux-0f194992c85f972ee99f176eb78a5860cef78573.zip |
device property: Fix reading pset strings using array access functions
The length field value of non-array string properties is the length of the
string itself. Non-array string properties thus require specific handling.
Fix this.
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/base/property.c')
-rw-r--r-- | drivers/base/property.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/drivers/base/property.c b/drivers/base/property.c index c69bde8086cc..166cfdb5e851 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -147,14 +147,36 @@ static int pset_prop_read_string_array(struct property_set *pset, const char *propname, const char **strings, size_t nval) { + const struct property_entry *prop; const void *pointer; - size_t length = nval * sizeof(*strings); + size_t array_len, length; + + /* Find out the array length. */ + prop = pset_prop_get(pset, propname); + if (!prop) + return -EINVAL; + + if (!prop->is_array) + /* The array length for a non-array string property is 1. */ + array_len = 1; + else + /* Find the length of an array. */ + array_len = pset_prop_count_elems_of_size(pset, propname, + sizeof(const char *)); + + /* Return how many there are if strings is NULL. */ + if (!strings) + return array_len; + + array_len = min(nval, array_len); + length = array_len * sizeof(*strings); pointer = pset_prop_find(pset, propname, length); if (IS_ERR(pointer)) return PTR_ERR(pointer); memcpy(strings, pointer, length); + return 0; } @@ -555,12 +577,8 @@ static int __fwnode_property_read_string_array(struct fwnode_handle *fwnode, return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING, val, nval); else if (is_pset_node(fwnode)) - return val ? - pset_prop_read_string_array(to_pset_node(fwnode), - propname, val, nval) : - pset_prop_count_elems_of_size(to_pset_node(fwnode), - propname, - sizeof(const char *)); + return pset_prop_read_string_array(to_pset_node(fwnode), + propname, val, nval); return -ENXIO; } |