diff --git a/flash_eraseall.c b/flash_eraseall.c index 3694e3d..1609859 100644 --- a/flash_eraseall.c +++ b/flash_eraseall.c @@ -56,12 +56,16 @@ static void display_version (void); static struct jffs2_unknown_node cleanmarker; int target_endian = __BYTE_ORDER; +#define MTD_MAX_OOBFREE_ENTRIES 8 + int main (int argc, char *argv[]) { mtd_info_t meminfo; int fd, clmpos = 0, clmlen = 8; erase_info_t erase; int isNAND, bbtest = 1; + struct nand_oobinfo oobinfo; + unsigned char oobdata[64]; process_options(argc, argv); @@ -81,29 +85,46 @@ int main (int argc, char *argv[]) isNAND = meminfo.type == MTD_NANDFLASH ? 1 : 0; if (jffs2) { + + /* prepare cleanmarker */ cleanmarker.magic = cpu_to_je16 (JFFS2_MAGIC_BITMASK); cleanmarker.nodetype = cpu_to_je16 (JFFS2_NODETYPE_CLEANMARKER); if (!isNAND) cleanmarker.totlen = cpu_to_je32 (sizeof (struct jffs2_unknown_node)); - else { - struct nand_oobinfo oobinfo; + else + cleanmarker.totlen = cpu_to_je32(8); + cleanmarker.hdr_crc = cpu_to_je32(crc32(0, &cleanmarker, + sizeof(struct jffs2_unknown_node) - 4)); + if (isNAND) { if (ioctl(fd, MEMGETOOBSEL, &oobinfo) != 0) { fprintf(stderr, "%s: %s: unable to get NAND oobinfo\n", exe_name, mtd_device); exit(1); } - /* Check for autoplacement */ if (oobinfo.useecc == MTD_NANDECC_AUTOPLACE) { - /* Get the position of the free bytes */ - if (!oobinfo.oobfree[0][1]) { - fprintf (stderr, " Eeep. Autoplacement selected and no empty space in oob\n"); + int i, one_len, copied = 0; + memset(oobdata, 0xff, sizeof(oobdata)); + for (i = 0; copied < 8 && + i < MTD_MAX_OOBFREE_ENTRIES && + oobinfo.oobfree[i][1]; i++) { + if (8 - copied <= oobinfo.oobfree[i][1]) + one_len = 8 - copied; + else + one_len = oobinfo.oobfree[i][1]; + memcpy(oobdata + oobinfo.oobfree[i][0], + (char *)&cleanmarker + copied, + one_len); + copied += one_len; + } + clmpos = 0; + clmlen = oobinfo.oobfree[i][0] + one_len; + if (clmlen < 2) { + fprintf (stderr, " Eeep. Autoplacement" + " selected and no empty space" + " in oob\n"); exit(1); } - clmpos = oobinfo.oobfree[0][0]; - clmlen = oobinfo.oobfree[0][1]; - if (clmlen > 8) - clmlen = 8; } else { /* Legacy mode */ switch (meminfo.oobsize) { @@ -121,9 +142,8 @@ int main (int argc, char *argv[]) break; } } - cleanmarker.totlen = cpu_to_je32(8); } - cleanmarker.hdr_crc = cpu_to_je32 (crc32 (0, &cleanmarker, sizeof (struct jffs2_unknown_node) - 4)); + } for (erase.start = 0; erase.start < meminfo.size; erase.start += meminfo.erasesize) { @@ -169,7 +189,10 @@ int main (int argc, char *argv[]) /* write cleanmarker */ if (isNAND) { struct mtd_oob_buf oob; - oob.ptr = (unsigned char *) &cleanmarker; + if (oobinfo.useecc == MTD_NANDECC_AUTOPLACE) + oob.ptr = oobdata; + else + oob.ptr = (unsigned char *) &cleanmarker; oob.start = erase.start + clmpos; oob.length = clmlen; if (ioctl (fd, MEMWRITEOOB, &oob) != 0) {