diff options
Diffstat (limited to 'common/env_nand.c')
| -rw-r--r-- | common/env_nand.c | 46 | 
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(); |