diff --git a/common/main.c b/common/main.c index 3324d9d6e4..b97d89e589 100644 --- a/common/main.c +++ b/common/main.c @@ -88,7 +88,10 @@ extern void mdm_init(void); /* defined in board.c */ */ #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) # if defined(CONFIG_AUTOBOOT_KEYED) -static inline int abortboot(int bootdelay) +#ifndef CONFIG_MENU +static inline +#endif +int abortboot(int bootdelay) { int abort = 0; uint64_t etime = endtick(bootdelay); @@ -202,7 +205,10 @@ static inline int abortboot(int bootdelay) static int menukey = 0; #endif -static inline int abortboot(int bootdelay) +#ifndef CONFIG_MENU +static inline +#endif +int abortboot(int bootdelay) { int abort = 0; diff --git a/common/menu.c b/common/menu.c index 56439374f7..f004823363 100644 --- a/common/menu.c +++ b/common/menu.c @@ -43,6 +43,7 @@ struct menu_item { */ struct menu { struct menu_item *default_item; + int timeout; char *title; int prompt; void (*item_data_print)(void *); @@ -157,14 +158,30 @@ static inline struct menu_item *menu_item_by_key(struct menu *m, return menu_items_iter(m, menu_item_key_match, item_key); } +/* + * Wait for the user to hit a key according to the timeout set for the menu. + * Returns 1 if the user hit a key, or 0 if the timeout expired. + */ +static inline int menu_interrupted(struct menu *m) +{ + if (!m->timeout) + return 0; + + if (abortboot(m->timeout/10)) + return 1; + + return 0; +} + /* * Checks whether or not the default menu item should be used without - * prompting for a user choice. If the menu is set to always prompt, return - * 0. Otherwise, return 1 to indicate we should use the default menu item. + * prompting for a user choice. If the menu is set to always prompt, or the + * user hits a key during the timeout period, return 0. Otherwise, return 1 to + * indicate we should use the default menu item. */ static inline int menu_use_default(struct menu *m) { - return !m->prompt; + return !m->prompt && !menu_interrupted(m); } /* @@ -250,7 +267,8 @@ int menu_default_set(struct menu *m, char *item_key) /* * menu_get_choice() - Returns the user's selected menu entry, or the default - * if the menu is set to not prompt. This is safe to call more than once. + * if the menu is set to not prompt or the timeout expires. This is safe to + * call more than once. * * m - Points to a menu created by menu_create(). * @@ -259,8 +277,8 @@ int menu_default_set(struct menu *m, char *item_key) * written at the location it points to. * * Returns 1 if successful, -EINVAL if m or choice is NULL, -ENOENT if no - * default has been set and the menu is set to not prompt, or -EINTR if the - * user exits the menu via ^c. + * default has been set and the menu is set to not prompt or the timeout + * expires, or -EINTR if the user exits the menu via ^c. */ int menu_get_choice(struct menu *m, void **choice) { @@ -330,7 +348,12 @@ int menu_item_add(struct menu *m, char *item_key, void *item_data) * list of menu items. It will be copied to internal storage, and is safe to * discard after passing to menu_create(). * - * prompt - If 0, don't ask for user input. + * timeout - A delay in seconds to wait for user input. If 0, timeout is + * disabled, and the default choice will be returned unless prompt is 1. + * + * prompt - If 0, don't ask for user input unless there is an interrupted + * timeout. If 1, the user will be prompted for input regardless of the value + * of timeout. * * item_data_print - If not NULL, will be called for each item when the menu * is displayed, with the pointer to the item's data passed as the argument. @@ -341,7 +364,7 @@ int menu_item_add(struct menu *m, char *item_key, void *item_data) * Returns a pointer to the menu if successful, or NULL if there is * insufficient memory available to create the menu. */ -struct menu *menu_create(char *title, int prompt, +struct menu *menu_create(char *title, int timeout, int prompt, void (*item_data_print)(void *)) { struct menu *m; @@ -353,6 +376,7 @@ struct menu *menu_create(char *title, int prompt, m->default_item = NULL; m->prompt = prompt; + m->timeout = timeout; m->item_data_print = item_data_print; if (title) { diff --git a/doc/README.menu b/doc/README.menu index f55eb801b9..1259c6ad57 100644 --- a/doc/README.menu +++ b/doc/README.menu @@ -45,7 +45,7 @@ struct menu; /* * menu_create() - Creates a menu handle with default settings */ -struct menu *menu_create(char *title, int prompt, +struct menu *menu_create(char *title, int timeout, int prompt, void (*item_data_print)(void *)); /* @@ -60,7 +60,7 @@ int menu_default_set(struct menu *m, char *item_key); /* * menu_get_choice() - Returns the user's selected menu entry, or the - * default if the menu is set to not prompt. + * default if the menu is set to not prompt or the timeout expires. */ int menu_get_choice(struct menu *m, void **choice); @@ -90,7 +90,7 @@ char *pick_a_tool(void) int i; char *tool = NULL; - m = menu_create("Tools", 1, NULL); + m = menu_create("Tools", 0, 1, NULL); for(i = 0; tools[i]; i++) { if (menu_item_add(m, tools[i], tools[i]) != 1) { diff --git a/include/common.h b/include/common.h index a55600b182..f9fea08115 100644 --- a/include/common.h +++ b/include/common.h @@ -260,6 +260,9 @@ int readline_into_buffer (const char *const prompt, char * buffer); int parse_line (char *, char *[]); void init_cmd_timeout(void); void reset_cmd_timeout(void); +#ifdef CONFIG_MENU +int abortboot(int bootdelay); +#endif /* arch/$(ARCH)/lib/board.c */ void board_init_f (ulong) __attribute__ ((noreturn)); diff --git a/include/menu.h b/include/menu.h index d47e1a029c..cf14a9cca3 100644 --- a/include/menu.h +++ b/include/menu.h @@ -20,7 +20,7 @@ struct menu; -struct menu *menu_create(char *title, int prompt, +struct menu *menu_create(char *title, int timeout, int prompt, void (*item_data_print)(void *)); int menu_default_set(struct menu *m, char *item_key); int menu_get_choice(struct menu *m, void **choice);