[PATCH 21/52] expo: Split bootflow_menu_run() into two pieces
Simon Glass
sjg at chromium.org
Wed Mar 19 15:54:26 CET 2025
Split the starting piece of this function into bootflow_menu_start()
and the polling part into bootflow_menu_poll() so that it is possible
for the caller to be in control of the event loop.
Move the expo_destroy() call into the caller.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
boot/bootflow_menu.c | 86 ++++++++++++++++++++------------------------
cmd/bootflow.c | 35 +++++++++++-------
include/bootflow.h | 33 ++++++++++-------
3 files changed, 82 insertions(+), 72 deletions(-)
diff --git a/boot/bootflow_menu.c b/boot/bootflow_menu.c
index d20d0be4734..018910c65b8 100644
--- a/boot/bootflow_menu.c
+++ b/boot/bootflow_menu.c
@@ -175,20 +175,13 @@ int bootflow_menu_apply_theme(struct expo *exp, ofnode node)
return 0;
}
-int bootflow_menu_run(struct bootstd_priv *std, bool text_mode,
- struct bootflow **bflowp)
+int bootflow_menu_start(struct bootstd_priv *std, bool text_mode,
+ struct expo **expp)
{
- struct bootflow *sel_bflow;
struct udevice *dev;
- struct scene *scn;
struct expo *exp;
- uint sel_id;
- bool done;
int ret;
- sel_bflow = NULL;
- *bflowp = NULL;
-
ret = bootflow_menu_new(&exp);
if (ret)
return log_msg_ret("exp", ret);
@@ -210,56 +203,55 @@ int bootflow_menu_run(struct bootstd_priv *std, bool text_mode,
ret = expo_set_scene_id(exp, MAIN);
if (ret)
return log_msg_ret("scn", ret);
- scn = expo_lookup_scene_id(exp, MAIN);
- if (!scn)
- return log_msg_ret("scn", -ENOENT);
if (text_mode)
expo_set_text_mode(exp, text_mode);
- done = false;
- do {
- struct expo_action act;
-
- ret = expo_poll(exp, &act);
- if (!ret) {
- switch (act.type) {
- case EXPOACT_SELECT:
- sel_id = act.select.id;
- done = true;
- break;
- case EXPOACT_POINT_ITEM:
- LOGR("bmp", scene_menu_select_item(scn,
- OBJ_MENU, act.select.id));
- break;
- case EXPOACT_QUIT:
- return -EPIPE;
- default:
- break;
- }
- } else if (ret != -EPIPE && ret != -EAGAIN) {
- LOGR("bmr", ret);
- }
- } while (!done);
+ *expp = exp;
+
+ return 0;
+}
- if (sel_id) {
+int bootflow_menu_poll(struct expo *exp, struct bootflow **bflowp)
+{
+ struct bootflow *sel_bflow;
+ struct expo_action act;
+ int ret;
+
+ sel_bflow = NULL;
+ *bflowp = NULL;
+
+ LOGR("bmp", expo_poll(exp, &act));
+
+ switch (act.type) {
+ case EXPOACT_SELECT: {
struct bootflow *bflow;
int i;
for (ret = bootflow_first_glob(&bflow), i = 0; !ret && i < 36;
ret = bootflow_next_glob(&bflow), i++) {
- if (i == sel_id - ITEM) {
- sel_bflow = bflow;
- break;
+ if (i == act.select.id - ITEM) {
+ *bflowp = bflow;
+ // printf("found %p\n", bflow);
+ return 0;
}
}
+ break;
+ }
+ case EXPOACT_POINT_ITEM: {
+ struct scene *scn = expo_lookup_scene_id(exp, MAIN);
+
+ if (!scn)
+ return log_msg_ret("bms", -ENOENT);
+ LOGR("bmp", scene_menu_select_item(scn, OBJ_MENU,
+ act.select.id));
+ break;
+ }
+ case EXPOACT_QUIT:
+ return -EPIPE;
+ default:
+ break;
}
- expo_destroy(exp);
-
- if (!sel_bflow)
- return -EAGAIN;
- *bflowp = sel_bflow;
-
- return 0;
+ return -EAGAIN;
}
diff --git a/cmd/bootflow.c b/cmd/bootflow.c
index 0163129deba..2871d91dd29 100644
--- a/cmd/bootflow.c
+++ b/cmd/bootflow.c
@@ -13,6 +13,8 @@
#include <command.h>
#include <console.h>
#include <dm.h>
+#include <expo.h>
+#include <log.h>
#include <mapmem.h>
/**
@@ -105,24 +107,31 @@ __maybe_unused static int bootflow_handle_menu(struct bootstd_priv *std,
bool text_mode,
struct bootflow **bflowp)
{
+ struct expo *exp;
struct bootflow *bflow;
int ret;
- ret = bootflow_menu_run(std, text_mode, &bflow);
- if (ret) {
- if (ret == -EAGAIN) {
- printf("Nothing chosen\n");
- std->cur_bootflow = NULL;
- } else {
- printf("Menu failed (err=%d)\n", ret);
- }
+ LOGR("bhs", bootflow_menu_start(std, text_mode, &exp));
- return ret;
- }
+ do {
+ ret = bootflow_menu_poll(exp, &bflow);
+ } while (ret == -EAGAIN);
+ // printf("ret %d bflow %p\n", ret, bflow);
- printf("Selected: %s\n", bflow->os_name ? bflow->os_name : bflow->name);
- std->cur_bootflow = bflow;
- *bflowp = bflow;
+ if (ret == -EPIPE) {
+ printf("Nothing chosen\n");
+ std->cur_bootflow = NULL;
+ } else if (ret) {
+ printf("Menu failed (err=%d)\n", ret);
+ } else {
+ printf("Selected: %s\n", bflow->os_name ? bflow->os_name :
+ bflow->name);
+ std->cur_bootflow = bflow;
+ *bflowp = bflow;
+ }
+ expo_destroy(exp);
+ if (ret)
+ return ret;
return 0;
}
diff --git a/include/bootflow.h b/include/bootflow.h
index ef1d1a75ded..72f09304cff 100644
--- a/include/bootflow.h
+++ b/include/bootflow.h
@@ -503,18 +503,6 @@ int bootflow_menu_new(struct expo **expp);
*/
int bootflow_menu_apply_theme(struct expo *exp, ofnode node);
-/**
- * bootflow_menu_run() - Create and run a menu of available bootflows
- *
- * @std: Bootstd information
- * @text_mode: Uses a text-based menu suitable for a serial port
- * @bflowp: Returns chosen bootflow (set to NULL if nothing is chosen)
- * @return 0 if an option was chosen, -EPIPE if nothing was chosen, -ve on
- * error
- */
-int bootflow_menu_run(struct bootstd_priv *std, bool text_mode,
- struct bootflow **bflowp);
-
#define BOOTFLOWCL_EMPTY ((void *)1)
/**
@@ -639,4 +627,25 @@ struct bootflow_img *bootflow_img_add(struct bootflow *bflow, const char *fname,
*/
int bootflow_get_seq(const struct bootflow *bflow);
+/**
+ * bootflow_menu_start() - Start up a menu for bootflows
+ *
+ * @std: bootstd information
+ * @text_mode: true to show the menu in text mode, false to use video display
+ * @expp: Returns the expo created, on success
+ * Return: 0 if OK, -ve on error
+ */
+int bootflow_menu_start(struct bootstd_priv *std, bool text_mode,
+ struct expo **expp);
+
+/**
+ * bootflow_menu_poll() - Poll a menu for user action
+ *
+ * @exp: Expo to poll
+ * @bflowp: Returns chosen bootflow (set to NULL if nothing is chosen)
+ * Return 0 if a bootflow was chosen, -EAGAIN if nothing is chosen yet, -EPIPE
+ * if the user quit
+ */
+int bootflow_menu_poll(struct expo *exp, struct bootflow **bflowp);
+
#endif
--
2.43.0
More information about the U-Boot
mailing list