aboutsummaryrefslogtreecommitdiff
path: root/common/env_nand.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/env_nand.c')
-rw-r--r--common/env_nand.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/common/env_nand.c b/common/env_nand.c
index 50bc111a3..47d9848ac 100644
--- a/common/env_nand.c
+++ b/common/env_nand.c
@@ -38,6 +38,7 @@
#include <linux/stddef.h>
#include <malloc.h>
#include <nand.h>
+#include <asm/errno.h>
#if defined(CONFIG_CMD_SAVEENV) && defined(CONFIG_CMD_NAND)
#define CMD_SAVEENV
@@ -284,6 +285,40 @@ int readenv (size_t offset, u_char * buf)
return 0;
}
+#ifdef CONFIG_ENV_OFFSET_OOB
+int get_nand_env_oob(nand_info_t *nand, unsigned long *result)
+{
+ struct mtd_oob_ops ops;
+ uint32_t oob_buf[ENV_OFFSET_SIZE/sizeof(uint32_t)];
+ int ret;
+
+ ops.datbuf = NULL;
+ ops.mode = MTD_OOB_AUTO;
+ ops.ooboffs = 0;
+ ops.ooblen = ENV_OFFSET_SIZE;
+ ops.oobbuf = (void *) oob_buf;
+
+ ret = nand->read_oob(nand, ENV_OFFSET_SIZE, &ops);
+
+ if (!ret) {
+ if (oob_buf[0] == ENV_OOB_MARKER) {
+ *result = oob_buf[1] * nand->erasesize;
+ } else if (oob_buf[0] == ENV_OOB_MARKER_OLD) {
+ *result = oob_buf[1];
+ } else {
+ printf("No dynamic environment marker in OOB block 0"
+ "\n");
+ ret = -ENOENT;
+ goto fail;
+ }
+ } else {
+ printf("error reading OOB block 0\n");
+ }
+fail:
+ return ret;
+}
+#endif
+
#ifdef CONFIG_ENV_OFFSET_REDUND
void env_relocate_spec (void)
{
@@ -353,6 +388,17 @@ void env_relocate_spec (void)
#if !defined(ENV_IS_EMBEDDED)
int ret;
+#if defined(CONFIG_ENV_OFFSET_OOB)
+ ret = get_nand_env_oob(&nand_info[0], &nand_env_oob_offset);
+ /* If unable to read environment offset from NAND OOB then fall through
+ * to the normal environment reading code below
+ */
+ if (!ret)
+ printf("Found Environment offset in OOB..\n");
+ else
+ return use_default();
+#endif
+
ret = readenv(CONFIG_ENV_OFFSET, (u_char *) env_ptr);
if (ret)
return use_default();