Merge tag 'u-boot-stm32-20200310' of https://gitlab.denx.de/u-boot/custodians/u-boot-stm
[oweals/u-boot.git] / env / nand.c
index 760f6859e354daeaa5299cf159f53938ae64f975..8b0027d30472fe2cef56f13c95d2fcba739436c9 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * (C) Copyright 2000-2010
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
  * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  * Andreas Heppel <aheppel@sysgo.de>
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
 #include <command.h>
-#include <environment.h>
+#include <env.h>
+#include <env_internal.h>
 #include <linux/stddef.h>
 #include <malloc.h>
 #include <memalign.h>
 #include <nand.h>
 #include <search.h>
 #include <errno.h>
+#include <u-boot/crc.h>
 
-#if defined(CONFIG_CMD_SAVEENV) && defined(CONFIG_CMD_NAND)
+#if defined(CONFIG_CMD_SAVEENV) && defined(CONFIG_CMD_NAND) && \
+               !defined(CONFIG_SPL_BUILD)
 #define CMD_SAVEENV
-#elif defined(CONFIG_ENV_OFFSET_REDUND)
+#elif defined(CONFIG_ENV_OFFSET_REDUND) && !defined(CONFIG_SPL_BUILD)
 #error CONFIG_ENV_OFFSET_REDUND must have CONFIG_CMD_SAVEENV & CONFIG_CMD_NAND
 #endif
 
-#if defined(CONFIG_ENV_SIZE_REDUND) && \
-       (CONFIG_ENV_SIZE_REDUND != CONFIG_ENV_SIZE)
-#error CONFIG_ENV_SIZE_REDUND should be the same as CONFIG_ENV_SIZE
-#endif
-
 #ifndef CONFIG_ENV_RANGE
 #define CONFIG_ENV_RANGE       CONFIG_ENV_SIZE
 #endif
 
-char *env_name_spec = "NAND";
-
 #if defined(ENV_IS_EMBEDDED)
-env_t *env_ptr = &environment;
+static env_t *env_ptr = &environment;
 #elif defined(CONFIG_NAND_ENV_DST)
-env_t *env_ptr = (env_t *)CONFIG_NAND_ENV_DST;
-#else /* ! ENV_IS_EMBEDDED */
-env_t *env_ptr;
+static env_t *env_ptr = (env_t *)CONFIG_NAND_ENV_DST;
 #endif /* ENV_IS_EMBEDDED */
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -63,7 +56,7 @@ DECLARE_GLOBAL_DATA_PTR;
  * This way the SPL loads not only the U-Boot image from NAND but
  * also the environment.
  */
-int env_init(void)
+static int env_nand_init(void)
 {
 #if defined(ENV_IS_EMBEDDED) || defined(CONFIG_NAND_ENV_DST)
        int crc1_ok = 0, crc2_ok = 0;
@@ -80,41 +73,41 @@ int env_init(void)
 
        if (!crc1_ok && !crc2_ok) {
                gd->env_addr    = 0;
-               gd->env_valid   = 0;
+               gd->env_valid   = ENV_INVALID;
 
                return 0;
        } else if (crc1_ok && !crc2_ok) {
-               gd->env_valid = 1;
+               gd->env_valid = ENV_VALID;
        }
 #ifdef CONFIG_ENV_OFFSET_REDUND
        else if (!crc1_ok && crc2_ok) {
-               gd->env_valid = 2;
+               gd->env_valid = ENV_REDUND;
        } else {
                /* both ok - check serial */
                if (tmp_env1->flags == 255 && tmp_env2->flags == 0)
-                       gd->env_valid = 2;
+                       gd->env_valid = ENV_REDUND;
                else if (tmp_env2->flags == 255 && tmp_env1->flags == 0)
-                       gd->env_valid = 1;
+                       gd->env_valid = ENV_VALID;
                else if (tmp_env1->flags > tmp_env2->flags)
-                       gd->env_valid = 1;
+                       gd->env_valid = ENV_VALID;
                else if (tmp_env2->flags > tmp_env1->flags)
-                       gd->env_valid = 2;
+                       gd->env_valid = ENV_REDUND;
                else /* flags are equal - almost impossible */
-                       gd->env_valid = 1;
+                       gd->env_valid = ENV_VALID;
        }
 
-       if (gd->env_valid == 2)
+       if (gd->env_valid == ENV_REDUND)
                env_ptr = tmp_env2;
        else
 #endif
-       if (gd->env_valid == 1)
+       if (gd->env_valid == ENV_VALID)
                env_ptr = tmp_env1;
 
        gd->env_addr = (ulong)env_ptr->data;
 
 #else /* ENV_IS_EMBEDDED || CONFIG_NAND_ENV_DST */
        gd->env_addr    = (ulong)&default_environment[0];
-       gd->env_valid   = 1;
+       gd->env_valid   = ENV_VALID;
 #endif /* ENV_IS_EMBEDDED || CONFIG_NAND_ENV_DST */
 
        return 0;
@@ -158,12 +151,12 @@ static int writeenv(size_t offset, u_char *buf)
        return 0;
 }
 
-struct env_location {
+struct nand_env_location {
        const char *name;
        const nand_erase_options_t erase_opts;
 };
 
-static int erase_and_write_env(const struct env_location *location,
+static int erase_and_write_env(const struct nand_env_location *location,
                u_char *env_new)
 {
        struct mtd_info *mtd;
@@ -184,12 +177,12 @@ static int erase_and_write_env(const struct env_location *location,
        return ret;
 }
 
-int saveenv(void)
+static int env_nand_save(void)
 {
        int     ret = 0;
        ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
        int     env_idx = 0;
-       static const struct env_location location[] = {
+       static const struct nand_env_location location[] = {
                {
                        .name = "NAND",
                        .erase_opts = {
@@ -217,14 +210,15 @@ int saveenv(void)
                return ret;
 
 #ifdef CONFIG_ENV_OFFSET_REDUND
-       env_idx = (gd->env_valid == 1);
+       env_idx = (gd->env_valid == ENV_VALID);
 #endif
 
        ret = erase_and_write_env(&location[env_idx], (u_char *)env_new);
 #ifdef CONFIG_ENV_OFFSET_REDUND
        if (!ret) {
                /* preset other copy for next write */
-               gd->env_valid = gd->env_valid == 2 ? 1 : 2;
+               gd->env_valid = gd->env_valid == ENV_REDUND ? ENV_VALID :
+                               ENV_REDUND;
                return ret;
        }
 
@@ -302,7 +296,7 @@ int get_nand_env_oob(struct mtd_info *mtd, unsigned long *result)
        }
 
        if (oob_buf[0] == ENV_OOB_MARKER) {
-               *result = oob_buf[1] * mtd->erasesize;
+               *result = ovoid ob_buf[1] * mtd->erasesize;
        } else if (oob_buf[0] == ENV_OOB_MARKER_OLD) {
                *result = oob_buf[1];
        } else {
@@ -315,46 +309,35 @@ int get_nand_env_oob(struct mtd_info *mtd, unsigned long *result)
 #endif
 
 #ifdef CONFIG_ENV_OFFSET_REDUND
-void env_relocate_spec(void)
+static int env_nand_load(void)
 {
-#if !defined(ENV_IS_EMBEDDED)
-       int read1_fail = 0, read2_fail = 0;
+#if defined(ENV_IS_EMBEDDED)
+       return 0;
+#else
+       int read1_fail, read2_fail;
        env_t *tmp_env1, *tmp_env2;
+       int ret = 0;
 
        tmp_env1 = (env_t *)malloc(CONFIG_ENV_SIZE);
        tmp_env2 = (env_t *)malloc(CONFIG_ENV_SIZE);
        if (tmp_env1 == NULL || tmp_env2 == NULL) {
                puts("Can't allocate buffers for environment\n");
-               set_default_env("!malloc() failed");
+               env_set_default("malloc() failed", 0);
+               ret = -EIO;
                goto done;
        }
 
        read1_fail = readenv(CONFIG_ENV_OFFSET, (u_char *) tmp_env1);
        read2_fail = readenv(CONFIG_ENV_OFFSET_REDUND, (u_char *) tmp_env2);
 
-       if (read1_fail && read2_fail)
-               puts("*** Error - No Valid Environment Area found\n");
-       else if (read1_fail || read2_fail)
-               puts("*** Warning - some problems detected "
-                    "reading environment; recovered successfully\n");
-
-       if (read1_fail && read2_fail) {
-               set_default_env("!bad env area");
-               goto done;
-       } else if (!read1_fail && read2_fail) {
-               gd->env_valid = 1;
-               env_import((char *)tmp_env1, 1);
-       } else if (read1_fail && !read2_fail) {
-               gd->env_valid = 2;
-               env_import((char *)tmp_env2, 1);
-       } else {
-               env_import_redund((char *)tmp_env1, (char *)tmp_env2);
-       }
+       ret = env_import_redund((char *)tmp_env1, read1_fail, (char *)tmp_env2,
+                               read2_fail);
 
 done:
        free(tmp_env1);
        free(tmp_env2);
 
+       return ret;
 #endif /* ! ENV_IS_EMBEDDED */
 }
 #else /* ! CONFIG_ENV_OFFSET_REDUND */
@@ -363,7 +346,7 @@ done:
  * device i.e., nand_dev_desc + 0. This is also the behaviour using
  * the new NAND code.
  */
-void env_relocate_spec(void)
+static int env_nand_load(void)
 {
 #if !defined(ENV_IS_EMBEDDED)
        int ret;
@@ -378,18 +361,30 @@ void env_relocate_spec(void)
        if (mtd && !get_nand_env_oob(mtd, &nand_env_oob_offset)) {
                printf("Found Environment offset in OOB..\n");
        } else {
-               set_default_env("!no env offset in OOB");
+               env_set_default("no env offset in OOB", 0);
                return;
        }
 #endif
 
        ret = readenv(CONFIG_ENV_OFFSET, (u_char *)buf);
        if (ret) {
-               set_default_env("!readenv() failed");
-               return;
+               env_set_default("readenv() failed", 0);
+               return -EIO;
        }
 
-       env_import(buf, 1);
+       return env_import(buf, 1);
 #endif /* ! ENV_IS_EMBEDDED */
+
+       return 0;
 }
 #endif /* CONFIG_ENV_OFFSET_REDUND */
+
+U_BOOT_ENV_LOCATION(nand) = {
+       .location       = ENVL_NAND,
+       ENV_NAME("NAND")
+       .load           = env_nand_load,
+#if defined(CMD_SAVEENV)
+       .save           = env_save_ptr(env_nand_save),
+#endif
+       .init           = env_nand_init,
+};