[PATCH] of_path: Make partition names work again

Trent Piepho tpiepho at kymetacorp.com
Thu Jan 7 10:31:45 PST 2016


There's already a patch in barebox-next that fixes this bug, 985e773.
It doesn't delete the patname: parsing code, but does add a number of
comments that this patch doesn't.

On Thu, 2016-01-07 at 12:27 +0100, Sascha Hauer wrote:
> The device-path "partname:<name>" mechanism is broken by:
> 
> 75b6827 of_path: of_find_path() factor out device detection logic into separate function
> 
> This is because since said commit the device-path property is no longer
> searched in the original device node anymore, but in the device node
> of the device itself.
> 
> Fix this by passing the partition name directly to __of_find_path.
> 
> Originally it was intended to further extend the multi string property
> device-path further with more elements, like for example a filename. It
> turned out though that this is too complex and instead of further
> extending the property we should instead create additional properties,
> so this mechanism is removed with this patch.
> 
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> Cc: Marc Kleine-Budde <mkl at pengutronix.de>
> ---
>  drivers/of/of_path.c | 125 ++++++++++++---------------------------------------
>  1 file changed, 29 insertions(+), 96 deletions(-)
> 
> diff --git a/drivers/of/of_path.c b/drivers/of/of_path.c
> index 6903905..35d3576 100644
> --- a/drivers/of/of_path.c
> +++ b/drivers/of/of_path.c
> @@ -23,16 +23,6 @@
>  
>  #include <linux/mtd/mtd.h>
>  
> -struct of_path {
> -	struct cdev *cdev;
> -	struct device_d *dev;
> -};
> -
> -struct of_path_type {
> -	const char *name;
> -	int (*parse)(struct of_path *op, const char *str);
> -};
> -
>  struct device_d *of_find_device_by_node_path(const char *path)
>  {
>  	struct device_d *dev;
> @@ -47,103 +37,34 @@ struct device_d *of_find_device_by_node_path(const char *path)
>  	return NULL;
>  }
>  
> -/**
> - * of_path_type_partname - find a partition based on physical device and
> - *                         partition name
> - * @op: of_path context
> - * @name: the partition name to find
> - */
> -static int of_path_type_partname(struct of_path *op, const char *name)
> -{
> -	if (!op->dev)
> -		return -EINVAL;
> -
> -	op->cdev = device_find_partition(op->dev, name);
> -	if (op->cdev) {
> -		pr_debug("%s: found part '%s'\n", __func__, name);
> -		return 0;
> -	} else {
> -		pr_debug("%s: cannot find part '%s'\n", __func__, name);
> -		return -ENODEV;
> -	}
> -}
> -
> -static struct of_path_type of_path_types[] = {
> -	{
> -		.name = "partname",
> -		.parse = of_path_type_partname,
> -	},
> -};
> -
> -static int of_path_parse_one(struct of_path *op, const char *str)
> -{
> -	int i, ret;
> -	char *name, *desc;
> -
> -	pr_debug("parsing: %s\n", str);
> -
> -	name = xstrdup(str);
> -	desc = strchr(name, ':');
> -	if (!desc) {
> -		free(name);
> -		return -EINVAL;
> -	}
> -
> -	*desc = 0;
> -	desc++;
> -
> -	for (i = 0; i < ARRAY_SIZE(of_path_types); i++) {
> -		if (!strcmp(of_path_types[i].name, name)) {
> -			ret = of_path_types[i].parse(op, desc);
> -			goto out;
> -		}
> -	}
> -
> -	ret = -EINVAL;
> -out:
> -	free(name);
> -
> -	return ret;
> -}
> -
> -static int __of_find_path(struct device_node *node, const char *propname, char **outpath, unsigned flags)
> +static int __of_find_path(struct device_node *node, const char *partname, char **outpath, unsigned flags)
>  {
> -	struct of_path op = {};
> -	const char *str;
> +	struct device_d *dev;
> +	struct cdev *cdev;
>  	bool add_bb = false;
> -	int i, ret;
>  
> -	op.dev = of_find_device_by_node_path(node->full_name);
> -	if (!op.dev) {
> -		op.dev = of_find_device_by_node_path(node->parent->full_name);
> -		if (!op.dev)
> +	dev = of_find_device_by_node_path(node->full_name);
> +	if (!dev) {
> +		dev = of_find_device_by_node_path(node->parent->full_name);
> +		if (!dev)
>  			return -ENODEV;
>  	}
>  
> -	device_detect(op.dev);
> -
> -	op.cdev = cdev_by_device_node(node);
> +	device_detect(dev);
>  
> -	i = 1;
> +	if (partname)
> +		cdev = device_find_partition(dev, partname);
> +	else
> +		cdev = cdev_by_device_node(node);
>  
> -	while (propname) {
> -		ret = of_property_read_string_index(node, propname, i++, &str);
> -		if (ret)
> -			break;
> -
> -		ret = of_path_parse_one(&op, str);
> -		if (ret)
> -			return ret;
> -	}
> -
> -	if (!op.cdev)
> +	if (!cdev)
>  		return -ENOENT;
>  
> -	if ((flags & OF_FIND_PATH_FLAGS_BB) && op.cdev->mtd &&
> -	    mtd_can_have_bb(op.cdev->mtd))
> +	if ((flags & OF_FIND_PATH_FLAGS_BB) && cdev->mtd &&
> +	    mtd_can_have_bb(cdev->mtd))
>  		add_bb = true;
>  
> -	*outpath = asprintf("/dev/%s%s", op.cdev->name, add_bb ? ".bb" : "");
> +	*outpath = asprintf("/dev/%s%s", cdev->name, add_bb ? ".bb" : "");
>  
>  	return 0;
>  }
> @@ -193,6 +114,8 @@ int of_find_path(struct device_node *node, const char *propname, char **outpath,
>  {
>  	struct device_node *rnode;
>  	const char *path;
> +	const char *partname = NULL;
> +	char partnamestr[] = "partname:";
>  
>  	path = of_get_property(node, propname, NULL);
>  	if (!path)
> @@ -202,5 +125,15 @@ int of_find_path(struct device_node *node, const char *propname, char **outpath,
>  	if (!rnode)
>  		return -ENODEV;
>  
> -	return __of_find_path(rnode, propname, outpath, flags);
> +	of_property_read_string_index(node, propname, 1, &partname);
> +	if (partname) {
> +		if (!strncmp(partname, partnamestr, sizeof(partnamestr) - 1)) {
> +			partname += sizeof(partnamestr) - 1;
> +		} else {
> +			pr_err("Invalid device-path: %s\n", partname);
> +			return -EINVAL;
> +		}
> +	}
> +
> +	return __of_find_path(rnode, partname, outpath, flags);
>  }



More information about the barebox mailing list