X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=common%2Fenv_nand.c;h=b745822be781fe3e4f14c1682032a2448e4be4f7;hb=32d2ffe7316b39fbeb38525e9445601cb39276fd;hp=da4d3b1df1dbd80ba698a14baf3b86f6e7894976;hpb=0e62e0a72cba76205c93b6913b9ae267f8fe08dc;p=u-boot diff --git a/common/env_nand.c b/common/env_nand.c index da4d3b1df1..b745822be7 100644 --- a/common/env_nand.c +++ b/common/env_nand.c @@ -30,8 +30,6 @@ * MA 02111-1307 USA */ -#define DEBUG - #include #include #include @@ -44,10 +42,11 @@ #if defined(CONFIG_CMD_SAVEENV) && defined(CONFIG_CMD_NAND) #define CMD_SAVEENV #elif defined(CONFIG_ENV_OFFSET_REDUND) -#error Cannot use CONFIG_ENV_OFFSET_REDUND without CONFIG_CMD_SAVEENV & CONFIG_CMD_NAND +#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) +#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 @@ -55,28 +54,18 @@ #define CONFIG_ENV_RANGE CONFIG_ENV_SIZE #endif -/* references to names in env_common.c */ -extern uchar default_environment[]; - char *env_name_spec = "NAND"; - #if defined(ENV_IS_EMBEDDED) -extern uchar environment[]; -env_t *env_ptr = (env_t *)(&environment[0]); +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 = 0; +env_t *env_ptr; #endif /* ENV_IS_EMBEDDED */ DECLARE_GLOBAL_DATA_PTR; -uchar env_get_char_spec (int index) -{ - return ( *((uchar *)(gd->env_addr + index)) ); -} - /* * This is called before nand_init() so we can't read NAND to * validate env data. @@ -99,16 +88,14 @@ int env_init(void) env_t *tmp_env2; tmp_env2 = (env_t *)((ulong)env_ptr + CONFIG_ENV_SIZE); - crc2_ok = (crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc); + crc2_ok = crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc; #endif - tmp_env1 = env_ptr; - - crc1_ok = (crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc); + crc1_ok = crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc; if (!crc1_ok && !crc2_ok) { - gd->env_addr = 0; - gd->env_valid = 0; + gd->env_addr = 0; + gd->env_valid = 0; return 0; } else if (crc1_ok && !crc2_ok) { @@ -119,13 +106,13 @@ int env_init(void) gd->env_valid = 2; } else { /* both ok - check serial */ - if(tmp_env1->flags == 255 && tmp_env2->flags == 0) + if (tmp_env1->flags == 255 && tmp_env2->flags == 0) gd->env_valid = 2; - else if(tmp_env2->flags == 255 && tmp_env1->flags == 0) + else if (tmp_env2->flags == 255 && tmp_env1->flags == 0) gd->env_valid = 1; - else if(tmp_env1->flags > tmp_env2->flags) + else if (tmp_env1->flags > tmp_env2->flags) gd->env_valid = 1; - else if(tmp_env2->flags > tmp_env1->flags) + else if (tmp_env2->flags > tmp_env1->flags) gd->env_valid = 2; else /* flags are equal - almost impossible */ gd->env_valid = 1; @@ -141,11 +128,11 @@ int env_init(void) 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_addr = (ulong)&default_environment[0]; + gd->env_valid = 1; #endif /* ENV_IS_EMBEDDED || CONFIG_NAND_ENV_DST */ - return (0); + return 0; } #ifdef CMD_SAVEENV @@ -158,7 +145,6 @@ int writeenv(size_t offset, u_char *buf) size_t end = offset + CONFIG_ENV_RANGE; size_t amount_saved = 0; size_t blocksize, len; - u_char *char_ptr; blocksize = nand_info[0].erasesize; @@ -169,9 +155,9 @@ int writeenv(size_t offset, u_char *buf) offset += blocksize; } else { char_ptr = &buf[amount_saved]; - if (nand_write(&nand_info[0], offset, &len, - char_ptr)) + if (nand_write(&nand_info[0], offset, &len, char_ptr)) return 1; + offset += blocksize; amount_saved += len; } @@ -200,23 +186,22 @@ int saveenv(void) return 1; res = (char *)&env_new.data; - len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL); + len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); return 1; } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); - env_new.flags = ++env_flags; /* increase the serial */ + env_new.crc = crc32(0, env_new.data, ENV_SIZE); + env_new.flags = ++env_flags; /* increase the serial */ - if(gd->env_valid == 1) { + if (gd->env_valid == 1) { puts("Erasing redundant NAND...\n"); nand_erase_options.offset = CONFIG_ENV_OFFSET_REDUND; if (nand_erase_opts(&nand_info[0], &nand_erase_options)) return 1; puts("Writing to redundant NAND... "); - ret = writeenv(CONFIG_ENV_OFFSET_REDUND, - (u_char *)&env_new); + ret = writeenv(CONFIG_ENV_OFFSET_REDUND, (u_char *)&env_new); } else { puts("Erasing NAND...\n"); nand_erase_options.offset = CONFIG_ENV_OFFSET; @@ -224,8 +209,7 @@ int saveenv(void) return 1; puts("Writing to NAND... "); - ret = writeenv(CONFIG_ENV_OFFSET, - (u_char *)&env_new); + ret = writeenv(CONFIG_ENV_OFFSET, (u_char *)&env_new); } if (ret) { puts("FAILED!\n"); @@ -234,15 +218,15 @@ int saveenv(void) puts("done\n"); - gd->env_valid = (gd->env_valid == 2 ? 1 : 2); + gd->env_valid = gd->env_valid == 2 ? 1 : 2; return ret; } #else /* ! CONFIG_ENV_OFFSET_REDUND */ int saveenv(void) { - int ret = 0; - env_t env_new; + int ret = 0; + ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); ssize_t len; char *res; nand_erase_options_t nand_erase_options; @@ -254,20 +238,20 @@ int saveenv(void) if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE) return 1; - res = (char *)&env_new.data; - len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL); + res = (char *)&env_new->data; + len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); return 1; } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); + env_new->crc = crc32(0, env_new->data, ENV_SIZE); puts("Erasing Nand...\n"); if (nand_erase_opts(&nand_info[0], &nand_erase_options)) return 1; puts("Writing to Nand... "); - if (writeenv(CONFIG_ENV_OFFSET, (u_char *)&env_new)) { + if (writeenv(CONFIG_ENV_OFFSET, (u_char *)env_new)) { puts("FAILED!\n"); return 1; } @@ -278,17 +262,17 @@ int saveenv(void) #endif /* CONFIG_ENV_OFFSET_REDUND */ #endif /* CMD_SAVEENV */ -int readenv(size_t offset, u_char * buf) +int readenv(size_t offset, u_char *buf) { size_t end = offset + CONFIG_ENV_RANGE; size_t amount_loaded = 0; size_t blocksize, len; - u_char *char_ptr; blocksize = nand_info[0].erasesize; if (!blocksize) return 1; + len = min(blocksize, CONFIG_ENV_SIZE); while (amount_loaded < CONFIG_ENV_SIZE && offset < end) { @@ -296,12 +280,16 @@ int readenv(size_t offset, u_char * buf) offset += blocksize; } else { char_ptr = &buf[amount_loaded]; - if (nand_read_skip_bad(&nand_info[0], offset, &len, char_ptr)) + if (nand_read_skip_bad(&nand_info[0], offset, + &len, NULL, + nand_info[0].size, char_ptr)) return 1; + offset += blocksize; amount_loaded += len; } } + if (amount_loaded != CONFIG_ENV_SIZE) return 1; @@ -312,14 +300,14 @@ int readenv(size_t offset, u_char * buf) 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)]; + 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; + 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) { @@ -344,34 +332,35 @@ int get_nand_env_oob(nand_info_t *nand, unsigned long *result) void env_relocate_spec(void) { #if !defined(ENV_IS_EMBEDDED) + int read1_fail = 0, read2_fail = 0; int crc1_ok = 0, crc2_ok = 0; env_t *ep, *tmp_env1, *tmp_env2; tmp_env1 = (env_t *)malloc(CONFIG_ENV_SIZE); tmp_env2 = (env_t *)malloc(CONFIG_ENV_SIZE); - - if ((tmp_env1 == NULL) || (tmp_env2 == NULL)) { + if (tmp_env1 == NULL || tmp_env2 == NULL) { puts("Can't allocate buffers for environment\n"); - free(tmp_env1); - free(tmp_env2); set_default_env("!malloc() failed"); - return; + goto done; } - if (readenv(CONFIG_ENV_OFFSET, (u_char *) tmp_env1)) - puts("No Valid Environment Area found\n"); + read1_fail = readenv(CONFIG_ENV_OFFSET, (u_char *) tmp_env1); + read2_fail = readenv(CONFIG_ENV_OFFSET_REDUND, (u_char *) tmp_env2); - if (readenv(CONFIG_ENV_OFFSET_REDUND, (u_char *) tmp_env2)) - puts("No Valid Redundant Environment Area found\n"); + 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"); - crc1_ok = (crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc); - crc2_ok = (crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc); + crc1_ok = !read1_fail && + (crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc); + crc2_ok = !read2_fail && + (crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc); if (!crc1_ok && !crc2_ok) { - free(tmp_env1); - free(tmp_env2); set_default_env("!bad CRC"); - return; + goto done; } else if (crc1_ok && !crc2_ok) { gd->env_valid = 1; } else if (!crc1_ok && crc2_ok) { @@ -388,7 +377,6 @@ void env_relocate_spec(void) gd->env_valid = 2; else /* flags are equal - almost impossible */ gd->env_valid = 1; - } free(env_ptr); @@ -401,6 +389,7 @@ void env_relocate_spec(void) env_flags = ep->flags; env_import((char *)ep, 0); +done: free(tmp_env1); free(tmp_env2); @@ -412,11 +401,11 @@ void env_relocate_spec(void) * device i.e., nand_dev_desc + 0. This is also the behaviour using * the new NAND code. */ -void env_relocate_spec (void) +void env_relocate_spec(void) { #if !defined(ENV_IS_EMBEDDED) int ret; - char buf[CONFIG_ENV_SIZE]; + ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE); #if defined(CONFIG_ENV_OFFSET_OOB) ret = get_nand_env_oob(&nand_info[0], &nand_env_oob_offset);