diff options
Diffstat (limited to 'common/bootchooser.c')
-rw-r--r-- | common/bootchooser.c | 70 |
1 files changed, 32 insertions, 38 deletions
diff --git a/common/bootchooser.c b/common/bootchooser.c index c08db03eba..022e225165 100644 --- a/common/bootchooser.c +++ b/common/bootchooser.c @@ -1,16 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (C) 2012 Jan Luebbe <j.luebbe@pengutronix.de> * Copyright (C) 2015 Marc Kleine-Budde <mkl@pengutronix.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #define pr_fmt(fmt) "bootchooser: " fmt @@ -22,7 +13,7 @@ #include <libfile.h> #include <common.h> #include <malloc.h> -#include <printk.h> +#include <linux/printk.h> #include <xfuncs.h> #include <envfs.h> #include <errno.h> @@ -86,6 +77,7 @@ struct bootchooser_target { enum reset_attempts { RESET_ATTEMPTS_POWER_ON, RESET_ATTEMPTS_ALL_ZERO, + RESET_ATTEMPTS_SRC_RST, }; static unsigned long reset_attempts; @@ -137,7 +129,7 @@ static void pr_target(struct bootchooser_target *target) printf(" disabled due to %s\n", reason); } -static int pr_setenv(struct bootchooser *bc, const char *fmt, ...) +static int bc_setenv(struct bootchooser *bc, const char *fmt, ...) { va_list ap; int ret = 0; @@ -151,14 +143,12 @@ static int pr_setenv(struct bootchooser *bc, const char *fmt, ...) if (!str) return -ENOMEM; - val = strchr(str, '='); + val = parse_assignment(str); if (!val) { ret = -EINVAL; goto err; } - *val++ = '\0'; - oldval = getenv(str); if (!oldval || strcmp(oldval, val)) { if (bc->state) @@ -173,7 +163,7 @@ err: return ret; } -static const char *pr_getenv(const char *fmt, ...) +static const char *bc_getenv(const char *fmt, ...) { va_list ap; char *str; @@ -269,7 +259,7 @@ static struct bootchooser_target *bootchooser_target_new(struct bootchooser *bc, target->remaining_attempts = 0; } - val = pr_getenv("%s.boot", target->prefix); + val = bc_getenv("%s.boot", target->prefix); if (!val) val = target->name; target->boot = xstrdup(val); @@ -450,6 +440,13 @@ struct bootchooser *bootchooser_get(void) attempts_resetted = 1; } + if (test_bit(RESET_ATTEMPTS_SRC_RST, &reset_attempts) && + reset_source_get() == RESET_RST && !attempts_resetted) { + pr_info("RST Reset, resetting remaining attempts\n"); + bootchooser_reset_attempts(bc); + attempts_resetted = 1; + } + if (test_bit(RESET_ATTEMPTS_ALL_ZERO, &reset_attempts)) { int attempts = 0; @@ -508,17 +505,17 @@ int bootchooser_save(struct bootchooser *bc) int ret; if (bc->last_chosen) - pr_setenv(bc, "%s.last_chosen=%d", bc->state_prefix, + bc_setenv(bc, "%s.last_chosen=%d", bc->state_prefix, bc->last_chosen->id); list_for_each_entry(target, &bc->targets, list) { - ret = pr_setenv(bc, "%s.remaining_attempts=%d", + ret = bc_setenv(bc, "%s.remaining_attempts=%d", target->state_prefix, target->remaining_attempts); if (ret) return ret; - ret = pr_setenv(bc, "%s.priority=%d", + ret = bc_setenv(bc, "%s.priority=%d", target->state_prefix, target->priority); if (ret) return ret; @@ -926,6 +923,7 @@ static int bootchooser_add_entry(struct bootentries *entries, const char *name) static const char * const reset_attempts_names[] = { [RESET_ATTEMPTS_POWER_ON] = "power-on", [RESET_ATTEMPTS_ALL_ZERO] = "all-zero", + [RESET_ATTEMPTS_SRC_RST] = "reset", }; static const char * const reset_priorities_names[] = { @@ -954,21 +952,17 @@ static int bootchooser_init(void) } device_initcall(bootchooser_init); -BAREBOX_MAGICVAR_NAMED(global_bootchooser_disable_on_zero_attempts, - global.bootchooser.disable_on_zero_attempts, - "bootchooser: Disable target when remaining attempts counter reaches 0"); -BAREBOX_MAGICVAR_NAMED(global_bootchooser_retry, - global.bootchooser.retry, - "bootchooser: Try again when booting a target fails"); -BAREBOX_MAGICVAR_NAMED(global_bootchooser_targets, - global.bootchooser.targets, - "bootchooser: Space separated list of target names"); -BAREBOX_MAGICVAR_NAMED(global_bootchooser_default_attempts, - global.bootchooser.default_attempts, - "bootchooser: Default number of attempts for a target"); -BAREBOX_MAGICVAR_NAMED(global_bootchooser_default_priority, - global.bootchooser.default_priority, - "bootchooser: Default priority for a target"); -BAREBOX_MAGICVAR_NAMED(global_bootchooser_state_prefix, - global.bootchooser.state_prefix, - "bootchooser: state name prefix, empty for nv backend"); +BAREBOX_MAGICVAR(global.bootchooser.disable_on_zero_attempts, + "bootchooser: Disable target when remaining attempts counter reaches 0"); +BAREBOX_MAGICVAR(global.bootchooser.retry, + "bootchooser: Try again when booting a target fails"); +BAREBOX_MAGICVAR(global.bootchooser.targets, + "bootchooser: Space separated list of target names"); +BAREBOX_MAGICVAR(global.bootchooser.default_attempts, + "bootchooser: Default number of attempts for a target"); +BAREBOX_MAGICVAR(global.bootchooser.reset_attempts, + "bootchooser: Choose condition to reset number of attempts for all enabled targets ('power-on', 'all-zero', 'reset')"); +BAREBOX_MAGICVAR(global.bootchooser.default_priority, + "bootchooser: Default priority for a target"); +BAREBOX_MAGICVAR(global.bootchooser.state_prefix, + "bootchooser: state name prefix, empty for nv backend"); |