diff options
author | Simon Glass <sjg@chromium.org> | 2023-01-17 20:47:34 +0300 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2023-01-24 02:11:40 +0300 |
commit | c7b63d500df707bd9c9041e0dae3a25f56098978 (patch) | |
tree | 1e9e545f889364b42b4772393bfd93f0e365baa4 /boot/bootdev-uclass.c | |
parent | bd90b092882099afa3786829036c82d6a4241fc8 (diff) | |
download | u-boot-c7b63d500df707bd9c9041e0dae3a25f56098978.tar.xz |
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/bootdev-uclass.c')
-rw-r--r-- | boot/bootdev-uclass.c | 61 |
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; |