summaryrefslogtreecommitdiff
path: root/drivers/base
diff options
context:
space:
mode:
authorSakari Ailus <sakari.ailus@linux.intel.com>2017-03-28 15:22:18 +0300
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2017-03-29 01:00:30 +0300
commit0f194992c85f972ee99f176eb78a5860cef78573 (patch)
tree41fa770d02cab8a1cc09c2826da75ea8c12285bf /drivers/base
parent026b821745a7dd4552d43539e70c83d7143b59c8 (diff)
downloadlinux-0f194992c85f972ee99f176eb78a5860cef78573.tar.xz
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')
-rw-r--r--drivers/base/property.c32
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;
}