mailarchive of the pengutronix oss-tools mailing list
 help / color / mirror / Atom feed
From: Marco Felsch <m.felsch@pengutronix.de>
To: oss-tools@pengutronix.de
Cc: mfe@pengutronix.de
Subject: [OSS-Tools] [PATCH dt-utils 14/14] state: sync with barebox to support new backend type
Date: Fri, 14 Oct 2022 18:42:04 +0200	[thread overview]
Message-ID: <20221014164204.3812506-15-m.felsch@pengutronix.de> (raw)
In-Reply-To: <20221014164204.3812506-1-m.felsch@pengutronix.de>

The state backend format was changed from a phandle based description to
a string based description. This was done because of the missing support
to store the state within a on-disk partition like MBR/GPT. By this sync
we import the code required to manipulate the state which is stored on a
on-disk partition.

Furthermore the sync did a few minor style fixes.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
 src/barebox-state/state.c | 168 ++++++++++++++++++++++++++++----------
 src/barebox-state/state.h |   6 +-
 src/dt/common.h           |  17 ++++
 3 files changed, 145 insertions(+), 46 deletions(-)

diff --git a/src/barebox-state/state.c b/src/barebox-state/state.c
index 4779574..e8c08d6 100644
--- a/src/barebox-state/state.c
+++ b/src/barebox-state/state.c
@@ -40,11 +40,11 @@ static LIST_HEAD(state_list);
  */
 int state_save(struct state *state)
 {
-	void *buf;
-	ssize_t len;
-	int ret;
 	struct state_backend_storage_bucket *bucket;
 	struct state_backend_storage *storage;
+	ssize_t len;
+	void *buf;
+	int ret;
 
 	if (!state->dirty)
 		return 0;
@@ -211,13 +211,13 @@ static int state_convert_node_variable(struct state *state,
 				       const char *parent_name,
 				       enum state_convert conv)
 {
+	struct device_node *new_node = NULL;
 	const struct variable_type *vtype;
+	char *short_name, *name, *indexs;
+	unsigned int start_size[2];
 	struct device_node *child;
-	struct device_node *new_node = NULL;
 	struct state_variable *sv;
 	const char *type_name;
-	char *short_name, *name, *indexs;
-	unsigned int start_size[2];
 	int ret;
 
 	/* strip trailing @<ADDRESS> */
@@ -341,8 +341,8 @@ struct device_node *state_to_node(struct state *state,
 				  struct device_node *parent,
 				  enum state_convert conv)
 {
-	struct device_node *child;
 	struct device_node *root, *state_root;
+	struct device_node *child;
 	int ret;
 
 	state_root = of_find_node_by_path(state->of_path);
@@ -369,8 +369,8 @@ int state_from_node(struct state *state, struct device_node *node, bool create)
 {
 	struct device_node *child;
 	enum state_convert conv;
-	int ret;
 	uint32_t magic;
+	int ret;
 
 	ret = of_property_read_u32(node, "magic", &magic);
 	if (ret)
@@ -428,12 +428,11 @@ int state_from_node(struct state *state, struct device_node *node, bool create)
 
 static int of_state_fixup(struct device_node *root, void *ctx)
 {
-	struct state *state = ctx;
-	const char *compatible = "barebox,state";
 	struct device_node *new_node, *node, *parent, *backend_node, *aliases;
+	const char *compatible = "barebox,state";
+	struct state *state = ctx;
 	struct property *p;
 	int ret;
-	phandle phandle;
 
 	node = of_find_node_by_path_from(root, state->of_path);
 	if (node) {
@@ -493,16 +492,26 @@ static int of_state_fixup(struct device_node *root, void *ctx)
 
 	/* backend phandle */
 	backend_node = of_find_node_by_reproducible_name(root,
-						state->backend_reproducible_name);
+						state->backend_dts_dev_or_part);
 	if (!backend_node) {
 		ret = -ENODEV;
 		goto out;
 	}
 
-	phandle = of_node_create_phandle(backend_node);
-	ret = of_property_write_u32(new_node, "backend", phandle);
-	if (ret)
-		goto out;
+	if (state->backend_is_new_format) {
+		ret = of_property_write_strings(new_node, "backend",
+						backend_node->full_name,
+						state->backend_dts_partition, NULL);
+		if (ret)
+			goto out;
+	} else {
+		phandle phandle;
+
+		phandle = of_node_create_phandle(backend_node);
+		ret = of_property_write_u32(new_node, "backend", phandle);
+		if (ret)
+			goto out;
+	}
 
 	if (!strcmp("raw", state->format->name)) {
 		struct digest *digest =
@@ -572,12 +581,86 @@ void state_release(struct state *state)
 	unregister_device(&state->dev);
 	state_storage_free(&state->storage);
 	state_format_free(state->format);
-	free(state->backend_path);
-	free(state->backend_reproducible_name);
+	free(state->backend_dev_path);
+	free(state->backend_dts_dev_or_part);
+	free(state->backend_dts_partition);
 	free(state->of_path);
 	free(state);
 }
 
+#ifdef __BAREBOX__
+
+#define state_of_find_path_by_node(node, path, flags, offset, size) \
+	of_find_path_by_node(node, path, flags)
+#define state_of_find_path(node, propname, outpath, flags, offset, size) \
+	of_find_path(node, propname, outpath, flags)
+
+#else
+
+#define state_of_find_path_by_node(node, path, flags, offset, size) \
+	of_get_devicepath(node, path, offset, size)
+#define state_of_find_path(node, propname, outpath, flags, offset, size) \
+	of_find_path(node, propname, outpath, offset, size)
+
+#endif /* __BAREBOX__ */
+
+static int
+state_parse_old_backend_format(struct device_node *backend_node,
+			       struct state *state, off_t *offset, size_t *size)
+{
+	int ret;
+
+	ret = of_partition_ensure_probed(backend_node);
+	if (ret)
+		return ret;
+
+	ret = state_of_find_path_by_node(backend_node, &state->backend_dev_path,
+					 0, offset, size);
+	if (ret) {
+		if (ret != -EPROBE_DEFER)
+			dev_err(&state->dev, "state failed to parse path to backend: %s\n",
+			       strerror(-ret));
+		return ret;
+	}
+
+	state->backend_dts_dev_or_part = of_get_reproducible_name(backend_node);
+
+	return 0;
+}
+
+static int
+state_parse_new_backend_format(struct device_node *state_node,
+			       struct state *state, off_t *offset, size_t *size)
+{
+	struct device_node *backend_node;
+	const char *backend_dev_or_part;
+	const char *part = NULL;
+	int ret;
+
+	backend_dev_or_part = of_get_property(state_node, "backend", NULL);
+	if (!backend_dev_or_part)
+		return -EINVAL;
+
+	backend_node = of_find_node_by_path(backend_dev_or_part);
+	if (!backend_node)
+		return -ENODEV;
+
+	if (is_of_partition(backend_node))
+		ret = of_partition_ensure_probed(backend_node);
+	else
+		ret = of_device_ensure_probed(backend_node);
+	if (ret)
+		return ret;
+
+	of_property_read_string_index(state_node, "backend", 1, &part);
+	state->backend_dts_dev_or_part = of_get_reproducible_name(backend_node);
+	state->backend_dts_partition = xstrdup(part);
+	state->backend_is_new_format = true;
+
+	return state_of_find_path(state_node, "backend",
+				  &state->backend_dev_path, 0, offset, size);
+}
+
 /*
  * state_new_from_node - create a new state instance from a device_node
  *
@@ -587,15 +670,15 @@ void state_release(struct state *state)
  */
 struct state *state_new_from_node(struct device_node *node, bool readonly)
 {
-	struct state *state;
-	int ret = 0;
-	const char *backend_type;
+	struct device_node *backend_node;
 	const char *storage_type = NULL;
-	const char *alias;
+	const char *backend_type;
+	struct state *state;
 	uint32_t stridesize;
-	struct device_node *partition_node;
+	const char *alias;
 	off_t offset = 0;
 	size_t size = 0;
+	int ret;
 
 	alias = of_alias_get(node);
 	if (!alias) {
@@ -607,26 +690,23 @@ struct state *state_new_from_node(struct device_node *node, bool readonly)
 	if (IS_ERR(state))
 		return state;
 
-	partition_node = of_parse_phandle(node, "backend", 0);
-	if (!partition_node) {
-		dev_err(&state->dev, "Cannot resolve \"backend\" phandle\n");
-		ret = -EINVAL;
-		goto out_release_state;
-	}
-
-#ifdef __BAREBOX__
-	ret = of_find_path_by_node(partition_node, &state->backend_path, 0);
-#else
-	ret = of_get_devicepath(partition_node, &state->backend_path, &offset, &size);
-#endif
-	if (ret) {
-		if (ret != -EPROBE_DEFER)
-			dev_err(&state->dev, "state failed to parse path to backend: %s\n",
-			       strerror(-ret));
+	/*
+	 * backend can be in three formats:
+	 *  old) backend = <&state_part>;
+	 *  new) backend = &state_part;
+	 *       backend = &state_part_dev, "partname:0";
+	 *
+	 * Start with the old format for compatibility reasons.
+	 */
+	backend_node = of_parse_phandle(node, "backend", 0);
+	if (backend_node)
+		ret = state_parse_old_backend_format(backend_node, state,
+						     &offset, &size);
+	else
+		ret = state_parse_new_backend_format(node, state,
+						     &offset, &size);
+	if (ret)
 		goto out_release_state;
-	}
-
-	state->backend_reproducible_name = of_get_reproducible_name(partition_node);
 
 	ret = of_property_read_string(node, "backend-type", &backend_type);
 	if (ret) {
@@ -649,7 +729,7 @@ struct state *state_new_from_node(struct device_node *node, bool readonly)
 	if (ret)
 		goto out_release_state;
 
-	ret = state_storage_init(state, state->backend_path, offset,
+	ret = state_storage_init(state, state->backend_dev_path, offset,
 				 size, stridesize, storage_type);
 	if (ret)
 		goto out_release_state;
@@ -744,7 +824,7 @@ void state_info(void)
 		if (state->format)
 			printf("(backend: %s, path: %s)\n",
 			       state->format->name,
-			       state->backend_path);
+			       state->backend_dev_path);
 		else
 			printf("(no backend)\n");
 	}
diff --git a/src/barebox-state/state.h b/src/barebox-state/state.h
index 719f7e4..2d3ec41 100644
--- a/src/barebox-state/state.h
+++ b/src/barebox-state/state.h
@@ -118,8 +118,10 @@ struct state {
 
 	struct state_backend_format *format;
 	struct state_backend_storage storage;
-	char *backend_path;
-	char *backend_reproducible_name;
+	char *backend_dev_path;
+	char *backend_dts_dev_or_part;
+	char *backend_dts_partition;
+	bool backend_is_new_format;
 };
 
 enum state_convert {
diff --git a/src/dt/common.h b/src/dt/common.h
index 9b1c169..4cb0dc2 100644
--- a/src/dt/common.h
+++ b/src/dt/common.h
@@ -360,6 +360,23 @@ static inline int is_zero_ether_addr(const u8 *addr)
 	return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]);
 }
 
+struct device_node;
+
+static inline int of_partition_ensure_probed(struct device_node *np)
+{
+	return 0;
+}
+
+static inline int of_device_ensure_probed(struct device_node *np)
+{
+	return 0;
+}
+
+static inline int is_of_partition(struct device_node *np)
+{
+	return 0;
+}
+
 #define MAX_DRIVER_NAME		32
 #define DEVICE_ID_SINGLE	-1
 
-- 
2.30.2




  parent reply	other threads:[~2022-10-14 16:42 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-14 16:41 [OSS-Tools] [PATCH dt-utils 00/14] Sync Barebox-State code base Marco Felsch
2022-10-14 16:41 ` [OSS-Tools] [PATCH dt-utils 01/14] state: Remove duplicate incudes Marco Felsch
2022-10-14 16:41 ` [OSS-Tools] [PATCH dt-utils 02/14] state: backend_raw: fix ignoring unpack failures Marco Felsch
2022-10-14 16:41 ` [OSS-Tools] [PATCH dt-utils 03/14] state: backend_storage: deal gracefully with runtime bucket corruption Marco Felsch
2022-10-14 16:41 ` [OSS-Tools] [PATCH dt-utils 04/14] state: treat state with all-invalid buckets as dirty Marco Felsch
2022-10-14 16:41 ` [OSS-Tools] [PATCH dt-utils 05/14] state: remove param member from struct state_string Marco Felsch
2022-10-14 16:41 ` [OSS-Tools] [PATCH dt-utils 06/14] state: remove param member from state_uint32, state_enum32, state_mac Marco Felsch
2022-10-14 16:41 ` [OSS-Tools] [PATCH dt-utils 07/14] state: remove unused function Marco Felsch
2022-10-14 16:41 ` [OSS-Tools] [PATCH dt-utils 08/14] state: propagate failure to fixup enum32 into DT Marco Felsch
2022-10-14 16:41 ` [OSS-Tools] [PATCH dt-utils 09/14] state: add SPDX-License-Identifier for files without explicit license Marco Felsch
2022-10-14 16:42 ` [OSS-Tools] [PATCH dt-utils 10/14] state: fix typos found with codespell Marco Felsch
2022-10-14 16:42 ` [OSS-Tools] [PATCH dt-utils 11/14] common: xstrdup: don't panic on xstrdup(NULL) Marco Felsch
2022-10-14 16:42 ` [OSS-Tools] [PATCH dt-utils 12/14] libdt: add of_property_write_strings support Marco Felsch
2022-10-14 16:42 ` [OSS-Tools] [PATCH dt-utils 13/14] libdt: add partition search function Marco Felsch
2022-10-14 16:42 ` Marco Felsch [this message]
2022-10-21  7:37 ` [OSS-Tools] [PATCH dt-utils 00/14] Sync Barebox-State code base Marco Felsch
2023-06-05 13:12 ` Ahmad Fatoum

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221014164204.3812506-15-m.felsch@pengutronix.de \
    --to=m.felsch@pengutronix.de \
    --cc=mfe@pengutronix.de \
    --cc=oss-tools@pengutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox