/* * clear flash by writing all 1's value */ int nvram_clear(int index) { unsigned long to; int len; RANV_PRINT("--> nvram_clear %d\n", index); RANV_CHECK_INDEX(-1); ra_nvram_close(index); down(&nvram_sem); //construct all 1s env block len = fb[index].flash_max_len - sizeof(fb[index].env.crc); if (!fb[index].env.data) { fb[index].env.data = (char *)kmalloc(len, GFP_KERNEL); if (!fb[index].env.data) return -ENOMEM; } memset(fb[index].env.data, 0xFF, len); //calculate crc fb[index].env.crc = (unsigned long)nv_crc32(0, (unsigned char *)fb[index].env.data, len); //write crc to flash to = fb[index].flash_offset; len = sizeof(fb[index].env.crc); ra_mtd_write_nm(RALINK_NVRAM_MTDNAME, to, len, (unsigned char *)&fb[index].env.crc); //write all 1s data to flash to = to + len; len = fb[index].flash_max_len - len; ra_mtd_write_nm(RALINK_NVRAM_MTDNAME, to, len, (unsigned char *)fb[index].env.data); RANV_PRINT("clear flash from 0x%x for 0x%x bytes\n", (unsigned int)to, len); fb[index].dirty = 0; fb[index].valid = 1; up(&nvram_sem); return 0; }
int nvram_commit(int index) { unsigned long to; int i, len; char *p; RANV_PRINT("--> nvram_commit %d\n", index); RANV_CHECK_INDEX(-1); down(&nvram_sem); RANV_CHECK_VALID(); counter++; if (!fb[index].dirty) { RANV_PRINT("nothing to be committed\n"); up(&nvram_sem); return 0; } //construct env block len = fb[index].flash_max_len - sizeof(fb[index].env.crc); if (!fb[index].env.data) { fb[index].env.data = (char *)kmalloc(len, GFP_KERNEL); if (!fb[index].env.data) return -ENOMEM; } memset(fb[index].env.data, 0, len); p = fb[index].env.data; for (i = 0; i < MAX_CACHE_ENTRY; i++) { int l; if (!fb[index].cache[i].name || !fb[index].cache[i].value) break; l = strlen(fb[index].cache[i].name) + strlen(fb[index].cache[i].value) + 2; if (p - fb[index].env.data + 2 >= fb[index].flash_max_len) { RANV_ERROR("ENV_BLK_SIZE 0x%x is not enough!", ENV_BLK_SIZE); up(&nvram_sem); return -1; } snprintf(p, l, "%s=%s", fb[index].cache[i].name, fb[index].cache[i].value); p += l; } *p = '\0'; //ending null //calculate crc fb[index].env.crc = (unsigned long)nv_crc32(0, (unsigned char *)fb[index].env.data, len); //write crc to flash to = fb[index].flash_offset; len = sizeof(fb[index].env.crc); ra_mtd_write_nm(RALINK_NVRAM_MTDNAME, to, len, (unsigned char *)&fb[index].env.crc); //write data to flash to = to + len; len = fb[index].flash_max_len - len; ra_mtd_write_nm(RALINK_NVRAM_MTDNAME, to, len, (unsigned char *)fb[index].env.data); fb[index].dirty = 0; up(&nvram_sem); return 0; }
static int init_nvram_block(int index) { unsigned long from; int i, j, len; char *p, *q; i = index; RANV_PRINT("--> nvram_init %d\n", index); RANV_CHECK_INDEX(-1); if (fb[index].valid) return -EINVAL; //read crc from flash from = fb[i].flash_offset; len = sizeof(fb[i].env.crc); ra_mtd_read_nm(RALINK_NVRAM_MTDNAME, from, len, (unsigned char *)&fb[i].env.crc); //read data from flash from = from + len; len = fb[i].flash_max_len - len; fb[i].env.data = (char *)kmalloc(len, GFP_KERNEL); if (!fb[i].env.data) return -ENOMEM; ra_mtd_read_nm(RALINK_NVRAM_MTDNAME, from, len, (unsigned char *)fb[i].env.data); //check crc if (nv_crc32(0, fb[i].env.data, len) != fb[i].env.crc) { RANV_PRINT("Bad CRC %x, ignore values in flash.\n", (unsigned int)fb[i].env.crc); memset(fb[index].env.data, 0, len); //kfree(fb[i].env.data); fb[i].valid = 1; fb[i].dirty = 0; return -1; } //parse env to cache p = fb[i].env.data; for (j = 0; j < MAX_CACHE_ENTRY; j++) { if (NULL == (q = strchr(p, '='))) { RANV_PRINT("parsed failed - cannot find '='\n"); break; } *q = '\0'; //strip '=' fb[i].cache[j].name = kstrdup(p, GFP_KERNEL); //printk(" %d '%s'->", i, p); p = q + 1; //value if (NULL == (q = strchr(p, '\0'))) { RANV_PRINT("parsed failed - cannot find '\\0'\n"); break; } fb[i].cache[j].value = kstrdup(p, GFP_KERNEL); //printk("'%s'\n", p); p = q + 1; //next entry if (p - fb[i].env.data + 1 >= len) { //end of block break; } if (*p == '\0') { //end of env break; } } if (j == MAX_CACHE_ENTRY) RANV_PRINT("run out of env cache, please increase MAX_CACHE_ENTRY\n"); fb[i].valid = 1; fb[i].dirty = 0; return 0; }