summaryrefslogtreecommitdiff
path: root/boot
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2023-01-17 10:47:34 -0700
committerTom Rini <trini@konsulko.com>2023-01-23 18:11:40 -0500
commitc7b63d500df707bd9c9041e0dae3a25f56098978 (patch)
tree1e9e545f889364b42b4772393bfd93f0e365baa4 /boot
parentbd90b092882099afa3786829036c82d6a4241fc8 (diff)
bootstd: Support running bootdev hunters
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@chromium.org>
Diffstat (limited to 'boot')
-rw-r--r--boot/bootdev-uclass.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index 62eb0b617c..081b94ce33 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;