[PATCH v3 24/70] bootstd: Support running bootdev hunters

Simon Glass sjg at chromium.org
Tue Jan 17 18:47:34 CET 2023


Add a way to run a bootdev hunter to find bootdevs of a certain type. Add
this to the 'bootdev hunt' command. Test for this are added in a later
patch, since a useful test needs some hunters to work with.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

(no changes since v1)

 boot/bootdev-uclass.c | 61 +++++++++++++++++++++++++++++++++++++++++++
 cmd/bootdev.c         |  7 ++++-
 include/bootdev.h     | 14 ++++++++++
 test/boot/bootdev.c   |  3 +++
 4 files changed, 84 insertions(+), 1 deletion(-)

diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index 62eb0b617cd..081b94ce332 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -636,6 +636,67 @@ int bootdev_setup_iter_order(struct bootflow_iter *iter, struct udevice **devp)
 	return 0;
 }
 
+static int bootdev_hunt_drv(struct bootdev_hunter *info, uint seq, bool show)
+{
+	const char *name = uclass_get_name(info->uclass);
+	struct bootstd_priv *std;
+	int ret;
+
+	ret = bootstd_get_priv(&std);
+	if (ret)
+		return log_msg_ret("std", ret);
+
+	if (!(std->hunters_used & BIT(seq))) {
+		if (show)
+			printf("Hunting with: %s\n",
+			       uclass_get_name(info->uclass));
+		log_debug("Hunting with: %s\n", name);
+		if (info->hunt) {
+			ret = info->hunt(info, show);
+			if (ret)
+				return ret;
+		}
+		std->hunters_used |= BIT(seq);
+	}
+
+	return 0;
+}
+
+int bootdev_hunt(const char *spec, bool show)
+{
+	struct bootdev_hunter *start;
+	const char *end;
+	int n_ent, i;
+	int result;
+	size_t len;
+
+	start = ll_entry_start(struct bootdev_hunter, bootdev_hunter);
+	n_ent = ll_entry_count(struct bootdev_hunter, bootdev_hunter);
+	result = 0;
+
+	len = SIZE_MAX;
+	if (spec) {
+		trailing_strtoln_end(spec, NULL, &end);
+		len = end - spec;
+	}
+
+	for (i = 0; i < n_ent; i++) {
+		struct bootdev_hunter *info = start + i;
+		const char *name = uclass_get_name(info->uclass);
+		int ret;
+
+		log_debug("looking at %.*s for %s\n",
+			  (int)max(strlen(name), len), spec, name);
+		if (spec && strncmp(spec, name, max(strlen(name), len)))
+			continue;
+		ret = bootdev_hunt_drv(info, i, show);
+		if (ret)
+			result = ret;
+	}
+
+	return result;
+}
+
 void bootdev_list_hunters(struct bootstd_priv *std)
 {
 	struct bootdev_hunter *orig, *start;
diff --git a/cmd/bootdev.c b/cmd/bootdev.c
index 80bfe2812e4..28866faac76 100644
--- a/cmd/bootdev.c
+++ b/cmd/bootdev.c
@@ -128,7 +128,12 @@ static int do_bootdev_hunt(struct cmd_tbl *cmdtp, int flag, int argc,
 	if (list) {
 		bootdev_list_hunters(priv);
 	} else {
-		/* TODO: implement hunting */
+		ret = bootdev_hunt(spec, true);
+		if (ret) {
+			printf("Failed (err=%dE)\n", ret);
+
+			return CMD_RET_FAILURE;
+		}
 	}
 
 	return 0;
diff --git a/include/bootdev.h b/include/bootdev.h
index cafb5285a28..deef7890489 100644
--- a/include/bootdev.h
+++ b/include/bootdev.h
@@ -263,6 +263,20 @@ int bootdev_setup_iter_order(struct bootflow_iter *iter, struct udevice **devp);
  */
 void bootdev_list_hunters(struct bootstd_priv *std);
 
+/**
+ * bootdev_hunt() - Hunt for bootdevs matching a particular spec
+ *
+ * This runs the selected hunter (or all if @spec is NULL) to try to find new
+ * bootdevs.
+ *
+ * @spec: Spec to match, e.g. "mmc0", or NULL for any. If provided, this must
+ * match a uclass name so that the hunter can be determined. Any trailing number
+ * is ignored
+ * @show: true to show each hunter before using it
+ * Returns: 0 if OK, -ve on error
+ */
+int bootdev_hunt(const char *spec, bool show);
+
 #if CONFIG_IS_ENABLED(BOOTSTD)
 /**
  * bootdev_setup_for_dev() - Bind a new bootdev device (deprecated)
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index a8ca12a3c8f..45a00c34c0c 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -237,6 +237,9 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
 	ut_assert_nextline("(total hunters: 0)");
 	ut_assert_console_end();
 
+	ut_assertok(bootdev_hunt("mmc1", false));
+	ut_assert_console_end();
+
 	return 0;
 }
 BOOTSTD_TEST(bootdev_test_hunter, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
-- 
2.39.0.246.g2a6d74b583-goog



More information about the U-Boot mailing list