X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=env%2Fenv.c;h=69848fb060807e928990cc600082cb04ff291a18;hb=10f6e4dc3a16c21f235416f975ecf2070ceb351f;hp=9237bb9c742a5242940cd6248751bc5d4eef86fa;hpb=60f38d82c45fef55ac04ee52b234e6dd07e31935;p=platform%2Fkernel%2Fu-boot.git diff --git a/env/env.c b/env/env.c index 9237bb9..69848fb 100644 --- a/env/env.c +++ b/env/env.c @@ -7,6 +7,10 @@ #include #include #include +#include +#include +#include +#include DECLARE_GLOBAL_DATA_PTR; @@ -100,19 +104,20 @@ static void env_set_inited(enum env_location location) * using the above enum value as the bit index. We need to * make sure that we're not overflowing it. */ - BUILD_BUG_ON(ARRAY_SIZE(env_locations) > BITS_PER_LONG); + BUILD_BUG_ON(ENVL_COUNT > BITS_PER_LONG); gd->env_has_init |= BIT(location); } /** - * env_get_location() - Returns the best env location for a board + * arch_env_get_location() - Returns the best env location for an arch * @op: operations performed on the environment * @prio: priority between the multiple environments, 0 being the * highest priority * * This will return the preferred environment for the given priority. - * This is overridable by boards if they need to. + * This is overridable by architectures if they need to and has lower + * priority than board side env_get_location() override. * * All implementations are free to use the operation, the priority and * any other data relevant to their choice, but must take into account @@ -123,16 +128,36 @@ static void env_set_inited(enum env_location location) * Returns: * an enum env_location value on success, a negative error code otherwise */ -__weak enum env_location env_get_location(enum env_operation op, int prio) +__weak enum env_location arch_env_get_location(enum env_operation op, int prio) { if (prio >= ARRAY_SIZE(env_locations)) return ENVL_UNKNOWN; - gd->env_load_prio = prio; - return env_locations[prio]; } +/** + * env_get_location() - Returns the best env location for a board + * @op: operations performed on the environment + * @prio: priority between the multiple environments, 0 being the + * highest priority + * + * This will return the preferred environment for the given priority. + * This is overridable by boards if they need to. + * + * All implementations are free to use the operation, the priority and + * any other data relevant to their choice, but must take into account + * the fact that the lowest prority (0) is the most important location + * in the system. The following locations should be returned by order + * of descending priorities, from the highest to the lowest priority. + * + * Returns: + * an enum env_location value on success, a negative error code otherwise + */ +__weak enum env_location env_get_location(enum env_operation op, int prio) +{ + return arch_env_get_location(op, prio); +} /** * env_driver_lookup() - Finds the most suited environment location @@ -164,19 +189,6 @@ static struct env_driver *env_driver_lookup(enum env_operation op, int prio) return drv; } -__weak int env_get_char_spec(int index) -{ - return *(uchar *)(gd->env_addr + index); -} - -int env_get_char(int index) -{ - if (gd->env_valid == ENV_INVALID) - return default_environment[index]; - else - return env_get_char_spec(index); -} - int env_load(void) { struct env_driver *drv; @@ -186,9 +198,6 @@ int env_load(void) for (prio = 0; (drv = env_driver_lookup(ENVOP_LOAD, prio)); prio++) { int ret; - if (!drv->load) - continue; - if (!env_has_inited(drv->location)) continue; @@ -201,7 +210,11 @@ int env_load(void) ret = drv->load(); if (!ret) { printf("OK\n"); + gd->env_load_prio = prio; + +#if !CONFIG_IS_ENABLED(ENV_APPEND) return 0; +#endif } else if (ret == -ENOMSG) { /* Handle "bad CRC" case */ if (best_prio == -1) @@ -224,7 +237,36 @@ int env_load(void) debug("Selecting environment with bad CRC\n"); else best_prio = 0; - env_get_location(ENVOP_LOAD, best_prio); + + gd->env_load_prio = best_prio; + + return -ENODEV; +} + +int env_reload(void) +{ + struct env_driver *drv; + + drv = env_driver_lookup(ENVOP_LOAD, gd->env_load_prio); + if (drv) { + int ret; + + printf("Loading Environment from %s... ", drv->name); + + if (!env_has_inited(drv->location)) { + printf("not initialized\n"); + return -ENODEV; + } + + ret = drv->load(); + if (ret) + printf("Failed (%d)\n", ret); + else + printf("OK\n"); + + if (!ret) + return 0; + } return -ENODEV; } @@ -237,13 +279,17 @@ int env_save(void) if (drv) { int ret; - if (!drv->save) + printf("Saving Environment to %s... ", drv->name); + if (!drv->save) { + printf("not possible\n"); return -ENODEV; + } - if (!env_has_inited(drv->location)) + if (!env_has_inited(drv->location)) { + printf("not initialized\n"); return -ENODEV; + } - printf("Saving Environment to %s... ", drv->name); ret = drv->save(); if (ret) printf("Failed (%d)\n", ret); @@ -294,9 +340,14 @@ int env_init(void) for (prio = 0; (drv = env_driver_lookup(ENVOP_INIT, prio)); prio++) { if (!drv->init || !(ret = drv->init())) env_set_inited(drv->location); + if (ret == -ENOENT) + env_set_inited(drv->location); debug("%s: Environment %s init done (ret=%d)\n", __func__, drv->name, ret); + + if (gd->env_valid == ENV_INVALID) + ret = -ENOENT; } if (!prio) @@ -311,3 +362,45 @@ int env_init(void) return ret; } + +int env_select(const char *name) +{ + struct env_driver *drv; + const int n_ents = ll_entry_count(struct env_driver, env_driver); + struct env_driver *entry; + int prio; + bool found = false; + + printf("Select Environment on %s: ", name); + + /* search ENV driver by name */ + drv = ll_entry_start(struct env_driver, env_driver); + for (entry = drv; entry != drv + n_ents; entry++) { + if (!strcmp(entry->name, name)) { + found = true; + break; + } + } + + if (!found) { + printf("driver not found\n"); + return -ENODEV; + } + + /* search priority by driver */ + for (prio = 0; (drv = env_driver_lookup(ENVOP_INIT, prio)); prio++) { + if (entry->location == env_get_location(ENVOP_LOAD, prio)) { + /* when priority change, reset the ENV flags */ + if (gd->env_load_prio != prio) { + gd->env_load_prio = prio; + gd->env_valid = ENV_INVALID; + gd->flags &= ~GD_FLG_ENV_DEFAULT; + } + printf("OK\n"); + return 0; + } + } + printf("priority not found\n"); + + return -ENODEV; +}