Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 1 | Upstream-Status: Pending |
| 2 | From patchwork Mon Aug 8 08:16:43 2011 |
| 3 | Content-Type: text/plain; charset="utf-8" |
| 4 | MIME-Version: 1.0 |
| 5 | Content-Transfer-Encoding: 7bit |
| 6 | Subject: mtd-utils: fix corrupt cleanmarker with flash_erase -j command |
| 7 | Date: Sun, 07 Aug 2011 22:16:43 -0000 |
| 8 | From: b35362@freescale.com |
| 9 | X-Patchwork-Id: 108873 |
| 10 | Message-Id: <1312791403-13473-1-git-send-email-b35362@freescale.com> |
| 11 | To: <dwmw2@infradead.org> |
| 12 | Cc: Liu Shuo <b35362@freescale.com>, Artem.Bityutskiy@nokia.com, |
| 13 | Li Yang <leoli@freescale.com>, linux-mtd@lists.infradead.org |
| 14 | |
| 15 | From: Liu Shuo <b35362@freescale.com> |
| 16 | |
| 17 | Flash_erase -j should fill discrete freeoob areas with required bytes |
| 18 | of JFFS2 cleanmarker in jffs2_check_nand_cleanmarker(). Not just fill |
| 19 | the first freeoob area. |
| 20 | |
| 21 | The below is the result without this workaround: |
| 22 | |
| 23 | JFFS2: Erase block at 0x00000000 is not formatted. It will be erased |
| 24 | JFFS2: Erase block at 0x00004000 is not formatted. It will be erased |
| 25 | JFFS2: Erase block at 0x00008000 is not formatted. It will be erased |
| 26 | JFFS2: Erase block at 0x0000c000 is not formatted. It will be erased |
| 27 | JFFS2: Erase block at 0x00010000 is not formatted. It will be erased |
| 28 | JFFS2: Erase block at 0x00014000 is not formatted. It will be erased |
| 29 | JFFS2: Erase block at 0x00018000 is not formatted. It will be erased |
| 30 | JFFS2: Erase block at 0x0001c000 is not formatted. It will be erased |
| 31 | JFFS2: Erase block at 0x00020000 is not formatted. It will be erased |
| 32 | JFFS2: Erase block at 0x00024000 is not formatted. It will be erased |
| 33 | JFFS2: Erase block at 0x00028000 is not formatted. It will be erased |
| 34 | ... |
| 35 | |
| 36 | Signed-off-by: Liu Shuo <b35362@freescale.com> |
| 37 | Signed-off-by: Li Yang <leoli@freescale.com> |
| 38 | |
| 39 | Updated for the new version |
| 40 | |
| 41 | Signed-off-by: Robert Yang <liezhi.yang@windriver.com> |
| 42 | |
| 43 | --- |
| 44 | v2 : get length of availble freeoob bytes from oobinfo information, |
| 45 | not use the ioctl ECCGETLAYOUT which is being deprecated. |
| 46 | |
| 47 | flash_erase.c | 46 +++++++++++++++++++++++++++++++++++++++------- |
| 48 | 1 files changed, 39 insertions(+), 7 deletions(-) |
| 49 | |
| 50 | diff --git a/flash_erase.c b/flash_erase.c |
| 51 | index 933373a..4b9d84b 100644 |
| 52 | --- a/flash_erase.c |
| 53 | +++ b/flash_erase.c |
| 54 | @@ -99,6 +99,7 @@ int main(int argc, char *argv[]) |
| 55 | bool isNAND; |
| 56 | int error = 0; |
| 57 | off_t offset = 0; |
| 58 | + void *oob_data = NULL; |
| 59 | |
| 60 | /* |
| 61 | * Process user arguments |
| 62 | @@ -201,15 +202,43 @@ int main(int argc, char *argv[]) |
| 63 | if (ioctl(fd, MEMGETOOBSEL, &oobinfo) != 0) |
| 64 | return sys_errmsg("%s: unable to get NAND oobinfo", mtd_device); |
| 65 | |
| 66 | + cleanmarker.totlen = cpu_to_je32(8); |
| 67 | /* Check for autoplacement */ |
| 68 | if (oobinfo.useecc == MTD_NANDECC_AUTOPLACE) { |
| 69 | - /* Get the position of the free bytes */ |
| 70 | - if (!oobinfo.oobfree[0][1]) |
| 71 | + struct nand_ecclayout_user ecclayout; |
| 72 | + int i, oobavail; |
| 73 | + |
| 74 | + for (i = 0, oobavail = 0; oobinfo.oobfree[i][1]; i++) |
| 75 | + oobavail += oobinfo.oobfree[i][1]; |
| 76 | + |
| 77 | + if (!oobavail) |
| 78 | return errmsg(" Eeep. Autoplacement selected and no empty space in oob"); |
| 79 | + |
| 80 | + /* Get the position of the free bytes */ |
| 81 | clmpos = oobinfo.oobfree[0][0]; |
| 82 | - clmlen = oobinfo.oobfree[0][1]; |
| 83 | - if (clmlen > 8) |
| 84 | - clmlen = 8; |
| 85 | + clmlen = MIN(oobavail, 8); |
| 86 | + |
| 87 | + if (oobinfo.oobfree[0][1] < 8 && oobavail >= 8) { |
| 88 | + int left, n, last = 0; |
| 89 | + void *cm; |
| 90 | + |
| 91 | + oob_data = malloc(mtd.oob_size); |
| 92 | + if (!oob_data) |
| 93 | + return -ENOMEM; |
| 94 | + |
| 95 | + memset(oob_data, 0xff, mtd.oob_size); |
| 96 | + cm = &cleanmarker; |
| 97 | + for (i = 0, left = clmlen; left ; i++) { |
| 98 | + n = MIN(left, oobinfo.oobfree[i][1]); |
| 99 | + memcpy(oob_data + oobinfo.oobfree[i][0], |
| 100 | + cm, n); |
| 101 | + left -= n; |
| 102 | + cm += n; |
| 103 | + last = oobinfo.oobfree[i][0] + n; |
| 104 | + } |
| 105 | + |
| 106 | + clmlen = last - clmpos; |
| 107 | + } |
| 108 | } else { |
| 109 | /* Legacy mode */ |
| 110 | switch (mtd.oob_size) { |
| 111 | @@ -227,7 +256,6 @@ int main(int argc, char *argv[]) |
| 112 | break; |
| 113 | } |
| 114 | } |
| 115 | - cleanmarker.totlen = cpu_to_je32(8); |
| 116 | } |
| 117 | cleanmarker.hdr_crc = cpu_to_je32(mtd_crc32(0, &cleanmarker, sizeof(cleanmarker) - 4)); |
| 118 | } |
| 119 | @@ -276,7 +304,8 @@ int main(int argc, char *argv[]) |
| 120 | |
| 121 | /* write cleanmarker */ |
| 122 | if (isNAND) { |
| 123 | - if (mtd_write_oob(mtd_desc, &mtd, fd, (uint64_t)offset + clmpos, clmlen, &cleanmarker) != 0) { |
| 124 | + void *data = oob_data ? oob_data + clmpos : &cleanmarker; |
| 125 | + if (mtd_write_oob(mtd_desc, &mtd, fd, (uint64_t)offset + clmpos, clmlen, data) != 0) { |
| 126 | sys_errmsg("%s: MTD writeoob failure", mtd_device); |
| 127 | continue; |
| 128 | } |
| 129 | @@ -291,5 +320,8 @@ int main(int argc, char *argv[]) |
| 130 | show_progress(&mtd, offset, eb, eb_start, eb_cnt); |
| 131 | bareverbose(!quiet, "\n"); |
| 132 | |
| 133 | + if (oob_data) |
| 134 | + free(oob_data); |
| 135 | + |
| 136 | return 0; |
| 137 | } |