On Thu, 16 Nov 2017 10:22:25 +0100
Maxime Ripard <maxime.rip...@free-electrons.com> wrote:

> In preparation for the multiple environment support, let's introduce
> two new parameters to the environment driver lookup function: the
> priority and operation.
> 
> The operation parameter is meant to identify, obviously, the
> operation you might want to perform on the environment.
> 
> The priority is a number passed to identify the environment priority
> you want to retrieve. The lowest priority parameter (0) will be the
> primary source.
> 
> Combining the two parameters allow you to support multiple
> environments through different priorities, and to change those
> priorities between read and writes operations.
> 
> This is especially useful to implement migration mechanisms where you
> want to always use the same environment first, be it to read or
> write, while the common case is more likely to use the same
> environment it has read from to write it to.
> 
> Signed-off-by: Maxime Ripard <maxime.rip...@free-electrons.com>
> ---
>  env/env.c             | 122
> ++++++++++++++++++++++++++++++--------------------
> include/environment.h |   7 +++ 2 files changed, 80 insertions(+), 49
> deletions(-)
> 
> diff --git a/env/env.c b/env/env.c
> index 97ada5b5a6fd..673bfa6ba41b 100644
> --- a/env/env.c
> +++ b/env/env.c
> @@ -26,8 +26,11 @@ static struct env_driver *_env_driver_lookup(enum
> env_location loc) return NULL;
>  }
>  
> -static enum env_location env_get_location(void)
> +static enum env_location env_get_location(enum env_operation op, int
> prio) {
> +     if (prio >= 1)
> +             return ENVL_UNKNOWN;

Is this correct? 

Above you mentioned that prio = 0 is the default.

With this condition you may only allow prio <= 0...

> +
>       if IS_ENABLED(CONFIG_ENV_IS_IN_EEPROM)
>               return ENVL_EEPROM;
>       else if IS_ENABLED(CONFIG_ENV_IS_IN_FAT)
> @@ -52,11 +55,14 @@ static enum env_location env_get_location(void)
>               return ENVL_UNKNOWN;
>  }
>  
> -static struct env_driver *env_driver_lookup(void)
> +static struct env_driver *env_driver_lookup(enum env_operation op,
> int prio) {
> -     enum env_location loc = env_get_location();
> +     enum env_location loc = env_get_location(op, prio);
>       struct env_driver *drv;
>  
> +     if (loc == ENVL_UNKNOWN)
> +             return NULL;
> +
>       drv = _env_driver_lookup(loc);
>       if (!drv) {
>               debug("%s: No environment driver for location %d\n",
> __func__, @@ -69,83 +75,101 @@ static struct env_driver
> *env_driver_lookup(void) 
>  int env_get_char(int index)
>  {
> -     struct env_driver *drv = env_driver_lookup();
> -     int ret;
> +     struct env_driver *drv;
> +     int prio;
>  
>       if (gd->env_valid == ENV_INVALID)
>               return default_environment[index];
> -     if (!drv)
> -             return -ENODEV;
> -     if (!drv->get_char)
> -             return *(uchar *)(gd->env_addr + index);
> -     ret = drv->get_char(index);
> -     if (ret < 0) {
> -             debug("%s: Environment failed to load (err=%d)\n",
> -                   __func__, ret);
> +
> +     for (prio = 0; (drv = env_driver_lookup(ENVO_GET_CHAR,
> prio)); prio++) {
> +             int ret;
> +
> +             if (!drv->get_char)
> +                     continue;
> +
> +             ret = drv->get_char(index);
> +             if (!ret)
> +                     return 0;
> +
> +             debug("%s: Environment %s failed to load
> (err=%d)\n", __func__,
> +                   drv->name, ret);
>       }
>  
> -     return ret;
> +     return -ENODEV;
>  }
>  
>  int env_load(void)
>  {
> -     struct env_driver *drv = env_driver_lookup();
> -     int ret = 0;
> +     struct env_driver *drv;
> +     int prio;
>  
> -     if (!drv)
> -             return -ENODEV;
> -     if (!drv->load)
> -             return 0;
> -     ret = drv->load();
> -     if (ret) {
> -             debug("%s: Environment failed to load (err=%d)\n",
> __func__,
> -                   ret);
> -             return ret;
> +     for (prio = 0; (drv = env_driver_lookup(ENVO_LOAD, prio));
> prio++) {
> +             int ret;
> +
> +             if (!drv->load)
> +                     continue;
> +
> +             ret = drv->load();
> +             if (!ret)
> +                     return 0;
> +
> +             debug("%s: Environment %s failed to load
> (err=%d)\n", __func__,
> +                   drv->name, ret);
>       }
>  
> -     return 0;
> +     return -ENODEV;
>  }
>  
>  int env_save(void)
>  {
> -     struct env_driver *drv = env_driver_lookup();
> -     int ret;
> +     struct env_driver *drv;
> +     int prio;
>  
> -     if (!drv)
> -             return -ENODEV;
> -     if (!drv->save)
> -             return -ENOSYS;
> -
> -     printf("Saving Environment to %s...\n", drv->name);
> -     ret = drv->save();
> -     if (ret) {
> -             debug("%s: Environment failed to save (err=%d)\n",
> __func__,
> -                   ret);
> -             return ret;
> +     for (prio = 0; (drv = env_driver_lookup(ENVO_SAVE, prio));
> prio++) {
> +             int ret;
> +
> +             if (!drv->save)
> +                     continue;
> +
> +             printf("Saving Environment to %s...\n", drv->name);
> +             ret = drv->save();
> +             if (!ret)
> +                     return 0;
> +
> +             debug("%s: Environment %s failed to save
> (err=%d)\n", __func__,
> +                   drv->name, ret);
>       }
>  
> -     return 0;
> +     return -ENODEV;
>  }
>  
>  int env_init(void)
>  {
> -     struct env_driver *drv = env_driver_lookup();
> +     struct env_driver *drv;
>       int ret = -ENOENT;
> +     int prio;
> +
> +     for (prio = 0; (drv = env_driver_lookup(ENVO_INIT, prio));
> prio++) {
> +             if (!drv->init)
> +                     continue;
>  
> -     if (!drv)
> -             return -ENODEV;
> -     if (drv->init)
>               ret = drv->init();
> +             if (!ret)
> +                     return 0;
> +
> +             debug("%s: Environment %s failed to init
> (err=%d)\n", __func__,
> +                   drv->name, ret);
> +     }
> +
> +     if (!prio)
> +             return -ENODEV;
> +
>       if (ret == -ENOENT) {
>               gd->env_addr = (ulong)&default_environment[0];
>               gd->env_valid = ENV_VALID;
>  
>               return 0;
> -     } else if (ret) {
> -             debug("%s: Environment failed to init (err=%d)\n",
> __func__,
> -                   ret);
> -             return ret;
>       }
>  
> -     return 0;
> +     return ret;
>  }
> diff --git a/include/environment.h b/include/environment.h
> index 226e3ef2d23a..7fa8b98cc0db 100644
> --- a/include/environment.h
> +++ b/include/environment.h
> @@ -215,6 +215,13 @@ enum env_location {
>       ENVL_UNKNOWN,
>  };
>  
> +enum env_operation {
> +     ENVO_GET_CHAR,
> +     ENVO_INIT,
> +     ENVO_LOAD,
> +     ENVO_SAVE,
> +};
> +
>  struct env_driver {
>       const char *name;
>       enum env_location location;



Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: w...@denx.de

Attachment: pgpB3iXTkXyvK.pgp
Description: OpenPGP digital signature

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to