aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--miscutils/flash_eraseall.c74
1 files changed, 39 insertions, 35 deletions
diff --git a/miscutils/flash_eraseall.c b/miscutils/flash_eraseall.c
index ece2500b2..0411c5a88 100644
--- a/miscutils/flash_eraseall.c
+++ b/miscutils/flash_eraseall.c
@@ -16,9 +16,8 @@
16 16
17#define OPTION_J (1 << 0) 17#define OPTION_J (1 << 0)
18#define OPTION_Q (1 << 1) 18#define OPTION_Q (1 << 1)
19#define _bitNAND (2) 19#define IS_NAND (1 << 2)
20#define isNAND (1 << _bitNAND) 20#define BBTEST (1 << 3)
21#define bbtest (1 << 3)
22 21
23struct globals { 22struct globals {
24 /* This is used in the cpu_to_je/je_to_cpu macros in jffs2_user.h */ 23 /* This is used in the cpu_to_je/je_to_cpu macros in jffs2_user.h */
@@ -42,7 +41,7 @@ static uint32_t crc32(uint32_t val, const void *ss, int len,
42static void show_progress(mtd_info_t *meminfo, erase_info_t *erase) 41static void show_progress(mtd_info_t *meminfo, erase_info_t *erase)
43{ 42{
44 printf("\rErasing %d Kibyte @ %x -- %2llu %% complete.", 43 printf("\rErasing %d Kibyte @ %x -- %2llu %% complete.",
45 meminfo->erasesize / 1024, erase->start, 44 (unsigned)meminfo->erasesize / 1024, erase->start,
46 (unsigned long long) erase->start * 100 / meminfo->size); 45 (unsigned long long) erase->start * 100 / meminfo->size);
47 fflush(stdout); 46 fflush(stdout);
48} 47}
@@ -52,7 +51,7 @@ int flash_eraseall_main(int argc UNUSED_PARAM, char **argv)
52{ 51{
53 struct jffs2_unknown_node cleanmarker; 52 struct jffs2_unknown_node cleanmarker;
54 mtd_info_t meminfo; 53 mtd_info_t meminfo;
55 int fd, clmpos = 0, clmlen = 8; 54 int fd, clmpos, clmlen;
56 erase_info_t erase; 55 erase_info_t erase;
57 struct stat st; 56 struct stat st;
58 unsigned int flags; 57 unsigned int flags;
@@ -60,9 +59,9 @@ int flash_eraseall_main(int argc UNUSED_PARAM, char **argv)
60 59
61 INIT_G(); 60 INIT_G();
62 opt_complementary = "=1"; 61 opt_complementary = "=1";
63 flags = getopt32(argv, "jq"); 62 flags = BBTEST | getopt32(argv, "jq");
64 63
65 mtd_name = *(argv + optind); 64 mtd_name = argv[optind];
66 xstat(mtd_name, &st); 65 xstat(mtd_name, &st);
67 if (!S_ISCHR(st.st_mode)) 66 if (!S_ISCHR(st.st_mode))
68 bb_error_msg_and_die("%s: not a char device", mtd_name); 67 bb_error_msg_and_die("%s: not a char device", mtd_name);
@@ -70,19 +69,21 @@ int flash_eraseall_main(int argc UNUSED_PARAM, char **argv)
70 fd = xopen(mtd_name, O_RDWR); 69 fd = xopen(mtd_name, O_RDWR);
71 70
72 xioctl(fd, MEMGETINFO, &meminfo); 71 xioctl(fd, MEMGETINFO, &meminfo);
73
74 erase.length = meminfo.erasesize; 72 erase.length = meminfo.erasesize;
75 flags |= bbtest | ((meminfo.type == MTD_NANDFLASH) << _bitNAND); 73 if (meminfo.type == MTD_NANDFLASH)
74 flags |= IS_NAND;
76 75
76 clmpos = 0;
77 clmlen = 8;
77 if (flags & OPTION_J) { 78 if (flags & OPTION_J) {
78 uint32_t *crc32_table; 79 uint32_t *crc32_table;
79 80
80 crc32_table = crc32_filltable(NULL, 0); 81 crc32_table = crc32_filltable(NULL, 0);
81 82
82 cleanmarker.magic = cpu_to_je16 (JFFS2_MAGIC_BITMASK); 83 cleanmarker.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
83 cleanmarker.nodetype = cpu_to_je16 (JFFS2_NODETYPE_CLEANMARKER); 84 cleanmarker.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER);
84 if (!(flags & isNAND)) 85 if (!(flags & IS_NAND))
85 cleanmarker.totlen = cpu_to_je32 (sizeof (struct jffs2_unknown_node)); 86 cleanmarker.totlen = cpu_to_je32(sizeof(struct jffs2_unknown_node));
86 else { 87 else {
87 struct nand_oobinfo oobinfo; 88 struct nand_oobinfo oobinfo;
88 89
@@ -91,13 +92,12 @@ int flash_eraseall_main(int argc UNUSED_PARAM, char **argv)
91 /* Check for autoplacement */ 92 /* Check for autoplacement */
92 if (oobinfo.useecc == MTD_NANDECC_AUTOPLACE) { 93 if (oobinfo.useecc == MTD_NANDECC_AUTOPLACE) {
93 /* Get the position of the free bytes */ 94 /* Get the position of the free bytes */
94 if (!oobinfo.oobfree[0][1])
95 bb_error_msg_and_die("Autoplacement selected and no empty space in oob");
96
97 clmpos = oobinfo.oobfree[0][0]; 95 clmpos = oobinfo.oobfree[0][0];
98 clmlen = oobinfo.oobfree[0][1]; 96 clmlen = oobinfo.oobfree[0][1];
99 if (clmlen > 8) 97 if (clmlen > 8)
100 clmlen = 8; 98 clmlen = 8;
99 if (clmlen == 0)
100 bb_error_msg_and_die("Autoplacement selected and no empty space in oob");
101 } else { 101 } else {
102 /* Legacy mode */ 102 /* Legacy mode */
103 switch (meminfo.oobsize) { 103 switch (meminfo.oobsize) {
@@ -107,24 +107,27 @@ int flash_eraseall_main(int argc UNUSED_PARAM, char **argv)
107 break; 107 break;
108 case 16: 108 case 16:
109 clmpos = 8; 109 clmpos = 8;
110 clmlen = 8; 110 /*clmlen = 8;*/
111 break; 111 break;
112 case 64: 112 case 64:
113 clmpos = 16; 113 clmpos = 16;
114 clmlen = 8; 114 /*clmlen = 8;*/
115 break; 115 break;
116 } 116 }
117 } 117 }
118 cleanmarker.totlen = cpu_to_je32(8); 118 cleanmarker.totlen = cpu_to_je32(8);
119 } 119 }
120 120
121 cleanmarker.hdr_crc = cpu_to_je32(crc32(0, &cleanmarker, sizeof(struct jffs2_unknown_node) - 4, 121 cleanmarker.hdr_crc = cpu_to_je32(crc32(0, &cleanmarker, sizeof(struct jffs2_unknown_node) - 4,
122 crc32_table)); 122 crc32_table));
123 } 123 }
124 124
125 /* Don't want to destroy progress indicator by bb_error_msg's */
126 applet_name = xasprintf("\n%s: %s", applet_name, mtd_name);
127
125 for (erase.start = 0; erase.start < meminfo.size; 128 for (erase.start = 0; erase.start < meminfo.size;
126 erase.start += meminfo.erasesize) { 129 erase.start += meminfo.erasesize) {
127 if (flags & bbtest) { 130 if (flags & BBTEST) {
128 int ret; 131 int ret;
129 loff_t offset = erase.start; 132 loff_t offset = erase.start;
130 133
@@ -133,18 +136,17 @@ int flash_eraseall_main(int argc UNUSED_PARAM, char **argv)
133 if (!(flags & OPTION_Q)) 136 if (!(flags & OPTION_Q))
134 bb_info_msg("\nSkipping bad block at 0x%08x", erase.start); 137 bb_info_msg("\nSkipping bad block at 0x%08x", erase.start);
135 continue; 138 continue;
136 } else if (ret < 0) { 139 }
140 if (ret < 0) {
137 /* Black block table is not available on certain flash 141 /* Black block table is not available on certain flash
138 * types e.g. NOR 142 * types e.g. NOR
139 */ 143 */
140 if (errno == EOPNOTSUPP) { 144 if (errno == EOPNOTSUPP) {
141 flags =~ bbtest; 145 flags = ~BBTEST;
142 if (flags & isNAND) 146 if (flags & IS_NAND)
143 bb_error_msg_and_die("%s: Bad block check not available", 147 bb_error_msg_and_die("bad block check not available");
144 mtd_name);
145 } else { 148 } else {
146 bb_perror_msg_and_die("\n%s: MTD %s failure", 149 bb_perror_msg_and_die("MEMGETBADBLOCK error");
147 mtd_name, "get bad block ");
148 } 150 }
149 } 151 }
150 } 152 }
@@ -159,22 +161,24 @@ int flash_eraseall_main(int argc UNUSED_PARAM, char **argv)
159 continue; 161 continue;
160 162
161 /* write cleanmarker */ 163 /* write cleanmarker */
162 if (flags & isNAND) { 164 if (flags & IS_NAND) {
163 struct mtd_oob_buf oob; 165 struct mtd_oob_buf oob;
164 166
165 oob.ptr = (unsigned char *) &cleanmarker; 167 oob.ptr = (unsigned char *) &cleanmarker;
166 oob.start = erase.start + clmpos; 168 oob.start = erase.start + clmpos;
167 oob.length = clmlen; 169 oob.length = clmlen;
168 xioctl (fd, MEMWRITEOOB, &oob); 170 xioctl(fd, MEMWRITEOOB, &oob);
169 } else { 171 } else {
170 if (lseek (fd, erase.start, SEEK_SET) < 0) { 172 xlseek(fd, erase.start, SEEK_SET);
171 bb_perror_msg("\n%s: MTD %s failure", mtd_name, "seek"); 173 /* if (lseek(fd, erase.start, SEEK_SET) < 0) {
174 bb_perror_msg("MTD %s failure", "seek");
172 continue; 175 continue;
173 } 176 } */
174 if (write (fd , &cleanmarker, sizeof (cleanmarker)) != sizeof (cleanmarker)) { 177 xwrite(fd, &cleanmarker, sizeof(cleanmarker));
175 bb_perror_msg("\n%s: MTD %s failure", mtd_name, "write"); 178 /* if (write(fd, &cleanmarker, sizeof(cleanmarker)) != sizeof(cleanmarker)) {
179 bb_perror_msg("MTD %s failure", "write");
176 continue; 180 continue;
177 } 181 } */
178 } 182 }
179 if (!(flags & OPTION_Q)) 183 if (!(flags & OPTION_Q))
180 printf(" Cleanmarker written at %x.", erase.start); 184 printf(" Cleanmarker written at %x.", erase.start);