Commit 12bc4e94251c369c529ffa505cf58b148c372f7f

Authored by Jean-Christophe PLAGNIOL-VILLARD
Committed by Wolfgang Denk
1 parent 1b9ed2574a

cmd_nand: fix warning: str2long ncompatible pointer type

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>

Showing 1 changed file with 1 additions and 1 deletions Inline Diff

1 /* 1 /*
2 * Driver for NAND support, Rick Bronson 2 * Driver for NAND support, Rick Bronson
3 * borrowed heavily from: 3 * borrowed heavily from:
4 * (c) 1999 Machine Vision Holdings, Inc. 4 * (c) 1999 Machine Vision Holdings, Inc.
5 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> 5 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
6 * 6 *
7 * Added 16-bit nand support 7 * Added 16-bit nand support
8 * (C) 2004 Texas Instruments 8 * (C) 2004 Texas Instruments
9 */ 9 */
10 10
11 #include <common.h> 11 #include <common.h>
12 12
13 13
14 #ifndef CFG_NAND_LEGACY 14 #ifndef CFG_NAND_LEGACY
15 /* 15 /*
16 * 16 *
17 * New NAND support 17 * New NAND support
18 * 18 *
19 */ 19 */
20 #include <common.h> 20 #include <common.h>
21 21
22 #if defined(CONFIG_CMD_NAND) 22 #if defined(CONFIG_CMD_NAND)
23 23
24 #include <command.h> 24 #include <command.h>
25 #include <watchdog.h> 25 #include <watchdog.h>
26 #include <malloc.h> 26 #include <malloc.h>
27 #include <asm/byteorder.h> 27 #include <asm/byteorder.h>
28 #include <jffs2/jffs2.h> 28 #include <jffs2/jffs2.h>
29 #include <nand.h> 29 #include <nand.h>
30 30
31 #if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE) 31 #if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
32 32
33 /* parition handling routines */ 33 /* parition handling routines */
34 int mtdparts_init(void); 34 int mtdparts_init(void);
35 int id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *dev_num); 35 int id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *dev_num);
36 int find_dev_and_part(const char *id, struct mtd_device **dev, 36 int find_dev_and_part(const char *id, struct mtd_device **dev,
37 u8 *part_num, struct part_info **part); 37 u8 *part_num, struct part_info **part);
38 #endif 38 #endif
39 39
40 extern nand_info_t nand_info[]; /* info for NAND chips */ 40 extern nand_info_t nand_info[]; /* info for NAND chips */
41 41
42 static int nand_dump_oob(nand_info_t *nand, ulong off) 42 static int nand_dump_oob(nand_info_t *nand, ulong off)
43 { 43 {
44 return 0; 44 return 0;
45 } 45 }
46 46
47 static int nand_dump(nand_info_t *nand, ulong off) 47 static int nand_dump(nand_info_t *nand, ulong off)
48 { 48 {
49 int i; 49 int i;
50 u_char *buf, *p; 50 u_char *buf, *p;
51 51
52 buf = malloc(nand->oobblock + nand->oobsize); 52 buf = malloc(nand->oobblock + nand->oobsize);
53 if (!buf) { 53 if (!buf) {
54 puts("No memory for page buffer\n"); 54 puts("No memory for page buffer\n");
55 return 1; 55 return 1;
56 } 56 }
57 off &= ~(nand->oobblock - 1); 57 off &= ~(nand->oobblock - 1);
58 i = nand_read_raw(nand, buf, off, nand->oobblock, nand->oobsize); 58 i = nand_read_raw(nand, buf, off, nand->oobblock, nand->oobsize);
59 if (i < 0) { 59 if (i < 0) {
60 printf("Error (%d) reading page %08x\n", i, off); 60 printf("Error (%d) reading page %08x\n", i, off);
61 free(buf); 61 free(buf);
62 return 1; 62 return 1;
63 } 63 }
64 printf("Page %08x dump:\n", off); 64 printf("Page %08x dump:\n", off);
65 i = nand->oobblock >> 4; p = buf; 65 i = nand->oobblock >> 4; p = buf;
66 while (i--) { 66 while (i--) {
67 printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x" 67 printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x"
68 " %02x %02x %02x %02x %02x %02x %02x %02x\n", 68 " %02x %02x %02x %02x %02x %02x %02x %02x\n",
69 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], 69 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
70 p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); 70 p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
71 p += 16; 71 p += 16;
72 } 72 }
73 puts("OOB:\n"); 73 puts("OOB:\n");
74 i = nand->oobsize >> 3; 74 i = nand->oobsize >> 3;
75 while (i--) { 75 while (i--) {
76 printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x\n", 76 printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x\n",
77 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); 77 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
78 p += 8; 78 p += 8;
79 } 79 }
80 free(buf); 80 free(buf);
81 81
82 return 0; 82 return 0;
83 } 83 }
84 84
85 /* ------------------------------------------------------------------------- */ 85 /* ------------------------------------------------------------------------- */
86 86
87 static inline int str2long(char *p, ulong *num) 87 static inline int str2long(char *p, ulong *num)
88 { 88 {
89 char *endptr; 89 char *endptr;
90 90
91 *num = simple_strtoul(p, &endptr, 16); 91 *num = simple_strtoul(p, &endptr, 16);
92 return (*p != '\0' && *endptr == '\0') ? 1 : 0; 92 return (*p != '\0' && *endptr == '\0') ? 1 : 0;
93 } 93 }
94 94
95 static int 95 static int
96 arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off, size_t *size) 96 arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off, size_t *size)
97 { 97 {
98 int idx = nand_curr_device; 98 int idx = nand_curr_device;
99 #if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE) 99 #if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
100 struct mtd_device *dev; 100 struct mtd_device *dev;
101 struct part_info *part; 101 struct part_info *part;
102 u8 pnum; 102 u8 pnum;
103 103
104 if (argc >= 1 && !(str2long(argv[0], off))) { 104 if (argc >= 1 && !(str2long(argv[0], off))) {
105 if ((mtdparts_init() == 0) && 105 if ((mtdparts_init() == 0) &&
106 (find_dev_and_part(argv[0], &dev, &pnum, &part) == 0)) { 106 (find_dev_and_part(argv[0], &dev, &pnum, &part) == 0)) {
107 if (dev->id->type != MTD_DEV_TYPE_NAND) { 107 if (dev->id->type != MTD_DEV_TYPE_NAND) {
108 puts("not a NAND device\n"); 108 puts("not a NAND device\n");
109 return -1; 109 return -1;
110 } 110 }
111 *off = part->offset; 111 *off = part->offset;
112 if (argc >= 2) { 112 if (argc >= 2) {
113 if (!(str2long(argv[1], size))) { 113 if (!(str2long(argv[1], (ulong *)size))) {
114 printf("'%s' is not a number\n", argv[1]); 114 printf("'%s' is not a number\n", argv[1]);
115 return -1; 115 return -1;
116 } 116 }
117 if (*size > part->size) 117 if (*size > part->size)
118 *size = part->size; 118 *size = part->size;
119 } else { 119 } else {
120 *size = part->size; 120 *size = part->size;
121 } 121 }
122 idx = dev->id->num; 122 idx = dev->id->num;
123 *nand = nand_info[idx]; 123 *nand = nand_info[idx];
124 goto out; 124 goto out;
125 } 125 }
126 } 126 }
127 #endif 127 #endif
128 128
129 if (argc >= 1) { 129 if (argc >= 1) {
130 if (!(str2long(argv[0], off))) { 130 if (!(str2long(argv[0], off))) {
131 printf("'%s' is not a number\n", argv[0]); 131 printf("'%s' is not a number\n", argv[0]);
132 return -1; 132 return -1;
133 } 133 }
134 } else { 134 } else {
135 *off = 0; 135 *off = 0;
136 } 136 }
137 137
138 if (argc >= 2) { 138 if (argc >= 2) {
139 if (!(str2long(argv[1], (ulong *)size))) { 139 if (!(str2long(argv[1], (ulong *)size))) {
140 printf("'%s' is not a number\n", argv[1]); 140 printf("'%s' is not a number\n", argv[1]);
141 return -1; 141 return -1;
142 } 142 }
143 } else { 143 } else {
144 *size = nand->size - *off; 144 *size = nand->size - *off;
145 } 145 }
146 146
147 #if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE) 147 #if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
148 out: 148 out:
149 #endif 149 #endif
150 printf("device %d ", idx); 150 printf("device %d ", idx);
151 if (*size == nand->size) 151 if (*size == nand->size)
152 puts("whole chip\n"); 152 puts("whole chip\n");
153 else 153 else
154 printf("offset 0x%x, size 0x%x\n", *off, *size); 154 printf("offset 0x%x, size 0x%x\n", *off, *size);
155 return 0; 155 return 0;
156 } 156 }
157 157
158 int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) 158 int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
159 { 159 {
160 int i, dev, ret; 160 int i, dev, ret;
161 ulong addr, off; 161 ulong addr, off;
162 size_t size; 162 size_t size;
163 char *cmd, *s; 163 char *cmd, *s;
164 nand_info_t *nand; 164 nand_info_t *nand;
165 #ifdef CFG_NAND_QUIET 165 #ifdef CFG_NAND_QUIET
166 int quiet = CFG_NAND_QUIET; 166 int quiet = CFG_NAND_QUIET;
167 #else 167 #else
168 int quiet = 0; 168 int quiet = 0;
169 #endif 169 #endif
170 const char *quiet_str = getenv("quiet"); 170 const char *quiet_str = getenv("quiet");
171 171
172 /* at least two arguments please */ 172 /* at least two arguments please */
173 if (argc < 2) 173 if (argc < 2)
174 goto usage; 174 goto usage;
175 175
176 if (quiet_str) 176 if (quiet_str)
177 quiet = simple_strtoul(quiet_str, NULL, 0) != 0; 177 quiet = simple_strtoul(quiet_str, NULL, 0) != 0;
178 178
179 cmd = argv[1]; 179 cmd = argv[1];
180 180
181 if (strcmp(cmd, "info") == 0) { 181 if (strcmp(cmd, "info") == 0) {
182 182
183 putc('\n'); 183 putc('\n');
184 for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) { 184 for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) {
185 if (nand_info[i].name) 185 if (nand_info[i].name)
186 printf("Device %d: %s, sector size %lu KiB\n", 186 printf("Device %d: %s, sector size %lu KiB\n",
187 i, nand_info[i].name, 187 i, nand_info[i].name,
188 nand_info[i].erasesize >> 10); 188 nand_info[i].erasesize >> 10);
189 } 189 }
190 return 0; 190 return 0;
191 } 191 }
192 192
193 if (strcmp(cmd, "device") == 0) { 193 if (strcmp(cmd, "device") == 0) {
194 194
195 if (argc < 3) { 195 if (argc < 3) {
196 if ((nand_curr_device < 0) || 196 if ((nand_curr_device < 0) ||
197 (nand_curr_device >= CFG_MAX_NAND_DEVICE)) 197 (nand_curr_device >= CFG_MAX_NAND_DEVICE))
198 puts("\nno devices available\n"); 198 puts("\nno devices available\n");
199 else 199 else
200 printf("\nDevice %d: %s\n", nand_curr_device, 200 printf("\nDevice %d: %s\n", nand_curr_device,
201 nand_info[nand_curr_device].name); 201 nand_info[nand_curr_device].name);
202 return 0; 202 return 0;
203 } 203 }
204 dev = (int)simple_strtoul(argv[2], NULL, 10); 204 dev = (int)simple_strtoul(argv[2], NULL, 10);
205 if (dev < 0 || dev >= CFG_MAX_NAND_DEVICE || !nand_info[dev].name) { 205 if (dev < 0 || dev >= CFG_MAX_NAND_DEVICE || !nand_info[dev].name) {
206 puts("No such device\n"); 206 puts("No such device\n");
207 return 1; 207 return 1;
208 } 208 }
209 printf("Device %d: %s", dev, nand_info[dev].name); 209 printf("Device %d: %s", dev, nand_info[dev].name);
210 puts("... is now current device\n"); 210 puts("... is now current device\n");
211 nand_curr_device = dev; 211 nand_curr_device = dev;
212 212
213 #ifdef CFG_NAND_SELECT_DEVICE 213 #ifdef CFG_NAND_SELECT_DEVICE
214 /* 214 /*
215 * Select the chip in the board/cpu specific driver 215 * Select the chip in the board/cpu specific driver
216 */ 216 */
217 board_nand_select_device(nand_info[dev].priv, dev); 217 board_nand_select_device(nand_info[dev].priv, dev);
218 #endif 218 #endif
219 219
220 return 0; 220 return 0;
221 } 221 }
222 222
223 if (strcmp(cmd, "bad") != 0 && strcmp(cmd, "erase") != 0 && 223 if (strcmp(cmd, "bad") != 0 && strcmp(cmd, "erase") != 0 &&
224 strncmp(cmd, "dump", 4) != 0 && 224 strncmp(cmd, "dump", 4) != 0 &&
225 strncmp(cmd, "read", 4) != 0 && strncmp(cmd, "write", 5) != 0 && 225 strncmp(cmd, "read", 4) != 0 && strncmp(cmd, "write", 5) != 0 &&
226 strcmp(cmd, "scrub") != 0 && strcmp(cmd, "markbad") != 0 && 226 strcmp(cmd, "scrub") != 0 && strcmp(cmd, "markbad") != 0 &&
227 strcmp(cmd, "biterr") != 0 && 227 strcmp(cmd, "biterr") != 0 &&
228 strcmp(cmd, "lock") != 0 && strcmp(cmd, "unlock") != 0 ) 228 strcmp(cmd, "lock") != 0 && strcmp(cmd, "unlock") != 0 )
229 goto usage; 229 goto usage;
230 230
231 /* the following commands operate on the current device */ 231 /* the following commands operate on the current device */
232 if (nand_curr_device < 0 || nand_curr_device >= CFG_MAX_NAND_DEVICE || 232 if (nand_curr_device < 0 || nand_curr_device >= CFG_MAX_NAND_DEVICE ||
233 !nand_info[nand_curr_device].name) { 233 !nand_info[nand_curr_device].name) {
234 puts("\nno devices available\n"); 234 puts("\nno devices available\n");
235 return 1; 235 return 1;
236 } 236 }
237 nand = &nand_info[nand_curr_device]; 237 nand = &nand_info[nand_curr_device];
238 238
239 if (strcmp(cmd, "bad") == 0) { 239 if (strcmp(cmd, "bad") == 0) {
240 printf("\nDevice %d bad blocks:\n", nand_curr_device); 240 printf("\nDevice %d bad blocks:\n", nand_curr_device);
241 for (off = 0; off < nand->size; off += nand->erasesize) 241 for (off = 0; off < nand->size; off += nand->erasesize)
242 if (nand_block_isbad(nand, off)) 242 if (nand_block_isbad(nand, off))
243 printf(" %08x\n", off); 243 printf(" %08x\n", off);
244 return 0; 244 return 0;
245 } 245 }
246 246
247 /* 247 /*
248 * Syntax is: 248 * Syntax is:
249 * 0 1 2 3 4 249 * 0 1 2 3 4
250 * nand erase [clean] [off size] 250 * nand erase [clean] [off size]
251 */ 251 */
252 if (strcmp(cmd, "erase") == 0 || strcmp(cmd, "scrub") == 0) { 252 if (strcmp(cmd, "erase") == 0 || strcmp(cmd, "scrub") == 0) {
253 nand_erase_options_t opts; 253 nand_erase_options_t opts;
254 /* "clean" at index 2 means request to write cleanmarker */ 254 /* "clean" at index 2 means request to write cleanmarker */
255 int clean = argc > 2 && !strcmp("clean", argv[2]); 255 int clean = argc > 2 && !strcmp("clean", argv[2]);
256 int o = clean ? 3 : 2; 256 int o = clean ? 3 : 2;
257 int scrub = !strcmp(cmd, "scrub"); 257 int scrub = !strcmp(cmd, "scrub");
258 258
259 printf("\nNAND %s: ", scrub ? "scrub" : "erase"); 259 printf("\nNAND %s: ", scrub ? "scrub" : "erase");
260 /* skip first two or three arguments, look for offset and size */ 260 /* skip first two or three arguments, look for offset and size */
261 if (arg_off_size(argc - o, argv + o, nand, &off, &size) != 0) 261 if (arg_off_size(argc - o, argv + o, nand, &off, &size) != 0)
262 return 1; 262 return 1;
263 263
264 memset(&opts, 0, sizeof(opts)); 264 memset(&opts, 0, sizeof(opts));
265 opts.offset = off; 265 opts.offset = off;
266 opts.length = size; 266 opts.length = size;
267 opts.jffs2 = clean; 267 opts.jffs2 = clean;
268 opts.quiet = quiet; 268 opts.quiet = quiet;
269 269
270 if (scrub) { 270 if (scrub) {
271 puts("Warning: " 271 puts("Warning: "
272 "scrub option will erase all factory set " 272 "scrub option will erase all factory set "
273 "bad blocks!\n" 273 "bad blocks!\n"
274 " " 274 " "
275 "There is no reliable way to recover them.\n" 275 "There is no reliable way to recover them.\n"
276 " " 276 " "
277 "Use this command only for testing purposes " 277 "Use this command only for testing purposes "
278 "if you\n" 278 "if you\n"
279 " " 279 " "
280 "are sure of what you are doing!\n" 280 "are sure of what you are doing!\n"
281 "\nReally scrub this NAND flash? <y/N>\n"); 281 "\nReally scrub this NAND flash? <y/N>\n");
282 282
283 if (getc() == 'y' && getc() == '\r') { 283 if (getc() == 'y' && getc() == '\r') {
284 opts.scrub = 1; 284 opts.scrub = 1;
285 } else { 285 } else {
286 puts("scrub aborted\n"); 286 puts("scrub aborted\n");
287 return -1; 287 return -1;
288 } 288 }
289 } 289 }
290 ret = nand_erase_opts(nand, &opts); 290 ret = nand_erase_opts(nand, &opts);
291 printf("%s\n", ret ? "ERROR" : "OK"); 291 printf("%s\n", ret ? "ERROR" : "OK");
292 292
293 return ret == 0 ? 0 : 1; 293 return ret == 0 ? 0 : 1;
294 } 294 }
295 295
296 if (strncmp(cmd, "dump", 4) == 0) { 296 if (strncmp(cmd, "dump", 4) == 0) {
297 if (argc < 3) 297 if (argc < 3)
298 goto usage; 298 goto usage;
299 299
300 s = strchr(cmd, '.'); 300 s = strchr(cmd, '.');
301 off = (int)simple_strtoul(argv[2], NULL, 16); 301 off = (int)simple_strtoul(argv[2], NULL, 16);
302 302
303 if (s != NULL && strcmp(s, ".oob") == 0) 303 if (s != NULL && strcmp(s, ".oob") == 0)
304 ret = nand_dump_oob(nand, off); 304 ret = nand_dump_oob(nand, off);
305 else 305 else
306 ret = nand_dump(nand, off); 306 ret = nand_dump(nand, off);
307 307
308 return ret == 0 ? 1 : 0; 308 return ret == 0 ? 1 : 0;
309 309
310 } 310 }
311 311
312 /* read write */ 312 /* read write */
313 if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) { 313 if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) {
314 int read; 314 int read;
315 315
316 if (argc < 4) 316 if (argc < 4)
317 goto usage; 317 goto usage;
318 318
319 addr = (ulong)simple_strtoul(argv[2], NULL, 16); 319 addr = (ulong)simple_strtoul(argv[2], NULL, 16);
320 320
321 read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */ 321 read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */
322 printf("\nNAND %s: ", read ? "read" : "write"); 322 printf("\nNAND %s: ", read ? "read" : "write");
323 if (arg_off_size(argc - 3, argv + 3, nand, &off, &size) != 0) 323 if (arg_off_size(argc - 3, argv + 3, nand, &off, &size) != 0)
324 return 1; 324 return 1;
325 325
326 s = strchr(cmd, '.'); 326 s = strchr(cmd, '.');
327 if (s != NULL && 327 if (s != NULL &&
328 (!strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i"))) { 328 (!strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i"))) {
329 if (read) { 329 if (read) {
330 /* read */ 330 /* read */
331 nand_read_options_t opts; 331 nand_read_options_t opts;
332 memset(&opts, 0, sizeof(opts)); 332 memset(&opts, 0, sizeof(opts));
333 opts.buffer = (u_char*) addr; 333 opts.buffer = (u_char*) addr;
334 opts.length = size; 334 opts.length = size;
335 opts.offset = off; 335 opts.offset = off;
336 opts.quiet = quiet; 336 opts.quiet = quiet;
337 ret = nand_read_opts(nand, &opts); 337 ret = nand_read_opts(nand, &opts);
338 } else { 338 } else {
339 /* write */ 339 /* write */
340 nand_write_options_t opts; 340 nand_write_options_t opts;
341 memset(&opts, 0, sizeof(opts)); 341 memset(&opts, 0, sizeof(opts));
342 opts.buffer = (u_char*) addr; 342 opts.buffer = (u_char*) addr;
343 opts.length = size; 343 opts.length = size;
344 opts.offset = off; 344 opts.offset = off;
345 /* opts.forcejffs2 = 1; */ 345 /* opts.forcejffs2 = 1; */
346 opts.pad = 1; 346 opts.pad = 1;
347 opts.blockalign = 1; 347 opts.blockalign = 1;
348 opts.quiet = quiet; 348 opts.quiet = quiet;
349 ret = nand_write_opts(nand, &opts); 349 ret = nand_write_opts(nand, &opts);
350 } 350 }
351 } else if (s != NULL && !strcmp(s, ".oob")) { 351 } else if (s != NULL && !strcmp(s, ".oob")) {
352 /* read out-of-band data */ 352 /* read out-of-band data */
353 if (read) 353 if (read)
354 ret = nand->read_oob(nand, off, size, &size, 354 ret = nand->read_oob(nand, off, size, &size,
355 (u_char *) addr); 355 (u_char *) addr);
356 else 356 else
357 ret = nand->write_oob(nand, off, size, &size, 357 ret = nand->write_oob(nand, off, size, &size,
358 (u_char *) addr); 358 (u_char *) addr);
359 } else { 359 } else {
360 if (read) 360 if (read)
361 ret = nand_read(nand, off, &size, (u_char *)addr); 361 ret = nand_read(nand, off, &size, (u_char *)addr);
362 else 362 else
363 ret = nand_write(nand, off, &size, (u_char *)addr); 363 ret = nand_write(nand, off, &size, (u_char *)addr);
364 } 364 }
365 365
366 printf(" %d bytes %s: %s\n", size, 366 printf(" %d bytes %s: %s\n", size,
367 read ? "read" : "written", ret ? "ERROR" : "OK"); 367 read ? "read" : "written", ret ? "ERROR" : "OK");
368 368
369 return ret == 0 ? 0 : 1; 369 return ret == 0 ? 0 : 1;
370 } 370 }
371 371
372 if (strcmp(cmd, "markbad") == 0) { 372 if (strcmp(cmd, "markbad") == 0) {
373 addr = (ulong)simple_strtoul(argv[2], NULL, 16); 373 addr = (ulong)simple_strtoul(argv[2], NULL, 16);
374 374
375 int ret = nand->block_markbad(nand, addr); 375 int ret = nand->block_markbad(nand, addr);
376 if (ret == 0) { 376 if (ret == 0) {
377 printf("block 0x%08lx successfully marked as bad\n", 377 printf("block 0x%08lx successfully marked as bad\n",
378 (ulong) addr); 378 (ulong) addr);
379 return 0; 379 return 0;
380 } else { 380 } else {
381 printf("block 0x%08lx NOT marked as bad! ERROR %d\n", 381 printf("block 0x%08lx NOT marked as bad! ERROR %d\n",
382 (ulong) addr, ret); 382 (ulong) addr, ret);
383 } 383 }
384 return 1; 384 return 1;
385 } 385 }
386 if (strcmp(cmd, "biterr") == 0) { 386 if (strcmp(cmd, "biterr") == 0) {
387 /* todo */ 387 /* todo */
388 return 1; 388 return 1;
389 } 389 }
390 390
391 if (strcmp(cmd, "lock") == 0) { 391 if (strcmp(cmd, "lock") == 0) {
392 int tight = 0; 392 int tight = 0;
393 int status = 0; 393 int status = 0;
394 if (argc == 3) { 394 if (argc == 3) {
395 if (!strcmp("tight", argv[2])) 395 if (!strcmp("tight", argv[2]))
396 tight = 1; 396 tight = 1;
397 if (!strcmp("status", argv[2])) 397 if (!strcmp("status", argv[2]))
398 status = 1; 398 status = 1;
399 } 399 }
400 400
401 if (status) { 401 if (status) {
402 ulong block_start = 0; 402 ulong block_start = 0;
403 ulong off; 403 ulong off;
404 int last_status = -1; 404 int last_status = -1;
405 405
406 struct nand_chip *nand_chip = nand->priv; 406 struct nand_chip *nand_chip = nand->priv;
407 /* check the WP bit */ 407 /* check the WP bit */
408 nand_chip->cmdfunc (nand, NAND_CMD_STATUS, -1, -1); 408 nand_chip->cmdfunc (nand, NAND_CMD_STATUS, -1, -1);
409 printf("device is %swrite protected\n", 409 printf("device is %swrite protected\n",
410 (nand_chip->read_byte(nand) & 0x80 ? 410 (nand_chip->read_byte(nand) & 0x80 ?
411 "NOT " : "" ) ); 411 "NOT " : "" ) );
412 412
413 for (off = 0; off < nand->size; off += nand->oobblock) { 413 for (off = 0; off < nand->size; off += nand->oobblock) {
414 int s = nand_get_lock_status(nand, off); 414 int s = nand_get_lock_status(nand, off);
415 415
416 /* print message only if status has changed 416 /* print message only if status has changed
417 * or at end of chip 417 * or at end of chip
418 */ 418 */
419 if (off == nand->size - nand->oobblock 419 if (off == nand->size - nand->oobblock
420 || (s != last_status && off != 0)) { 420 || (s != last_status && off != 0)) {
421 421
422 printf("%08x - %08x: %8d pages %s%s%s\n", 422 printf("%08x - %08x: %8d pages %s%s%s\n",
423 block_start, 423 block_start,
424 off-1, 424 off-1,
425 (off-block_start)/nand->oobblock, 425 (off-block_start)/nand->oobblock,
426 ((last_status & NAND_LOCK_STATUS_TIGHT) ? "TIGHT " : ""), 426 ((last_status & NAND_LOCK_STATUS_TIGHT) ? "TIGHT " : ""),
427 ((last_status & NAND_LOCK_STATUS_LOCK) ? "LOCK " : ""), 427 ((last_status & NAND_LOCK_STATUS_LOCK) ? "LOCK " : ""),
428 ((last_status & NAND_LOCK_STATUS_UNLOCK) ? "UNLOCK " : "")); 428 ((last_status & NAND_LOCK_STATUS_UNLOCK) ? "UNLOCK " : ""));
429 } 429 }
430 430
431 last_status = s; 431 last_status = s;
432 } 432 }
433 } else { 433 } else {
434 if (!nand_lock(nand, tight)) { 434 if (!nand_lock(nand, tight)) {
435 puts("NAND flash successfully locked\n"); 435 puts("NAND flash successfully locked\n");
436 } else { 436 } else {
437 puts("Error locking NAND flash\n"); 437 puts("Error locking NAND flash\n");
438 return 1; 438 return 1;
439 } 439 }
440 } 440 }
441 return 0; 441 return 0;
442 } 442 }
443 443
444 if (strcmp(cmd, "unlock") == 0) { 444 if (strcmp(cmd, "unlock") == 0) {
445 if (arg_off_size(argc - 2, argv + 2, nand, &off, &size) < 0) 445 if (arg_off_size(argc - 2, argv + 2, nand, &off, &size) < 0)
446 return 1; 446 return 1;
447 447
448 if (!nand_unlock(nand, off, size)) { 448 if (!nand_unlock(nand, off, size)) {
449 puts("NAND flash successfully unlocked\n"); 449 puts("NAND flash successfully unlocked\n");
450 } else { 450 } else {
451 puts("Error unlocking NAND flash, " 451 puts("Error unlocking NAND flash, "
452 "write and erase will probably fail\n"); 452 "write and erase will probably fail\n");
453 return 1; 453 return 1;
454 } 454 }
455 return 0; 455 return 0;
456 } 456 }
457 457
458 usage: 458 usage:
459 printf("Usage:\n%s\n", cmdtp->usage); 459 printf("Usage:\n%s\n", cmdtp->usage);
460 return 1; 460 return 1;
461 } 461 }
462 462
463 U_BOOT_CMD(nand, 5, 1, do_nand, 463 U_BOOT_CMD(nand, 5, 1, do_nand,
464 "nand - NAND sub-system\n", 464 "nand - NAND sub-system\n",
465 "info - show available NAND devices\n" 465 "info - show available NAND devices\n"
466 "nand device [dev] - show or set current device\n" 466 "nand device [dev] - show or set current device\n"
467 "nand read[.jffs2] - addr off|partition size\n" 467 "nand read[.jffs2] - addr off|partition size\n"
468 "nand write[.jffs2] - addr off|partition size - read/write `size' bytes starting\n" 468 "nand write[.jffs2] - addr off|partition size - read/write `size' bytes starting\n"
469 " at offset `off' to/from memory address `addr'\n" 469 " at offset `off' to/from memory address `addr'\n"
470 "nand erase [clean] [off size] - erase `size' bytes from\n" 470 "nand erase [clean] [off size] - erase `size' bytes from\n"
471 " offset `off' (entire device if not specified)\n" 471 " offset `off' (entire device if not specified)\n"
472 "nand bad - show bad blocks\n" 472 "nand bad - show bad blocks\n"
473 "nand dump[.oob] off - dump page\n" 473 "nand dump[.oob] off - dump page\n"
474 "nand scrub - really clean NAND erasing bad blocks (UNSAFE)\n" 474 "nand scrub - really clean NAND erasing bad blocks (UNSAFE)\n"
475 "nand markbad off - mark bad block at offset (UNSAFE)\n" 475 "nand markbad off - mark bad block at offset (UNSAFE)\n"
476 "nand biterr off - make a bit error at offset (UNSAFE)\n" 476 "nand biterr off - make a bit error at offset (UNSAFE)\n"
477 "nand lock [tight] [status] - bring nand to lock state or display locked pages\n" 477 "nand lock [tight] [status] - bring nand to lock state or display locked pages\n"
478 "nand unlock [offset] [size] - unlock section\n"); 478 "nand unlock [offset] [size] - unlock section\n");
479 479
480 static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, 480 static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
481 ulong offset, ulong addr, char *cmd) 481 ulong offset, ulong addr, char *cmd)
482 { 482 {
483 int r; 483 int r;
484 char *ep, *s; 484 char *ep, *s;
485 size_t cnt; 485 size_t cnt;
486 image_header_t *hdr; 486 image_header_t *hdr;
487 int jffs2 = 0; 487 int jffs2 = 0;
488 #if defined(CONFIG_FIT) 488 #if defined(CONFIG_FIT)
489 const void *fit_hdr; 489 const void *fit_hdr;
490 #endif 490 #endif
491 491
492 s = strchr(cmd, '.'); 492 s = strchr(cmd, '.');
493 if (s != NULL && 493 if (s != NULL &&
494 (!strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i"))) 494 (!strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i")))
495 jffs2 = 1; 495 jffs2 = 1;
496 496
497 printf("\nLoading from %s, offset 0x%lx\n", nand->name, offset); 497 printf("\nLoading from %s, offset 0x%lx\n", nand->name, offset);
498 498
499 cnt = nand->oobblock; 499 cnt = nand->oobblock;
500 if (jffs2) { 500 if (jffs2) {
501 nand_read_options_t opts; 501 nand_read_options_t opts;
502 memset(&opts, 0, sizeof(opts)); 502 memset(&opts, 0, sizeof(opts));
503 opts.buffer = (u_char*) addr; 503 opts.buffer = (u_char*) addr;
504 opts.length = cnt; 504 opts.length = cnt;
505 opts.offset = offset; 505 opts.offset = offset;
506 opts.quiet = 1; 506 opts.quiet = 1;
507 r = nand_read_opts(nand, &opts); 507 r = nand_read_opts(nand, &opts);
508 } else { 508 } else {
509 r = nand_read(nand, offset, &cnt, (u_char *) addr); 509 r = nand_read(nand, offset, &cnt, (u_char *) addr);
510 } 510 }
511 511
512 if (r) { 512 if (r) {
513 puts("** Read error\n"); 513 puts("** Read error\n");
514 show_boot_progress (-56); 514 show_boot_progress (-56);
515 return 1; 515 return 1;
516 } 516 }
517 show_boot_progress (56); 517 show_boot_progress (56);
518 518
519 switch (genimg_get_format ((void *)addr)) { 519 switch (genimg_get_format ((void *)addr)) {
520 case IMAGE_FORMAT_LEGACY: 520 case IMAGE_FORMAT_LEGACY:
521 hdr = (image_header_t *)addr; 521 hdr = (image_header_t *)addr;
522 522
523 show_boot_progress (57); 523 show_boot_progress (57);
524 image_print_contents (hdr); 524 image_print_contents (hdr);
525 525
526 cnt = image_get_image_size (hdr); 526 cnt = image_get_image_size (hdr);
527 break; 527 break;
528 #if defined(CONFIG_FIT) 528 #if defined(CONFIG_FIT)
529 case IMAGE_FORMAT_FIT: 529 case IMAGE_FORMAT_FIT:
530 fit_hdr = (const void *)addr; 530 fit_hdr = (const void *)addr;
531 if (!fit_check_format (fit_hdr)) { 531 if (!fit_check_format (fit_hdr)) {
532 show_boot_progress (-150); 532 show_boot_progress (-150);
533 puts ("** Bad FIT image format\n"); 533 puts ("** Bad FIT image format\n");
534 return 1; 534 return 1;
535 } 535 }
536 show_boot_progress (151); 536 show_boot_progress (151);
537 puts ("Fit image detected...\n"); 537 puts ("Fit image detected...\n");
538 538
539 cnt = fit_get_size (fit_hdr); 539 cnt = fit_get_size (fit_hdr);
540 break; 540 break;
541 #endif 541 #endif
542 default: 542 default:
543 show_boot_progress (-57); 543 show_boot_progress (-57);
544 puts ("** Unknown image type\n"); 544 puts ("** Unknown image type\n");
545 return 1; 545 return 1;
546 } 546 }
547 547
548 if (jffs2) { 548 if (jffs2) {
549 nand_read_options_t opts; 549 nand_read_options_t opts;
550 memset(&opts, 0, sizeof(opts)); 550 memset(&opts, 0, sizeof(opts));
551 opts.buffer = (u_char*) addr; 551 opts.buffer = (u_char*) addr;
552 opts.length = cnt; 552 opts.length = cnt;
553 opts.offset = offset; 553 opts.offset = offset;
554 opts.quiet = 1; 554 opts.quiet = 1;
555 r = nand_read_opts(nand, &opts); 555 r = nand_read_opts(nand, &opts);
556 } else { 556 } else {
557 r = nand_read(nand, offset, &cnt, (u_char *) addr); 557 r = nand_read(nand, offset, &cnt, (u_char *) addr);
558 } 558 }
559 559
560 if (r) { 560 if (r) {
561 puts("** Read error\n"); 561 puts("** Read error\n");
562 show_boot_progress (-58); 562 show_boot_progress (-58);
563 return 1; 563 return 1;
564 } 564 }
565 show_boot_progress (58); 565 show_boot_progress (58);
566 566
567 #if defined(CONFIG_FIT) 567 #if defined(CONFIG_FIT)
568 /* This cannot be done earlier, we need complete FIT image in RAM first */ 568 /* This cannot be done earlier, we need complete FIT image in RAM first */
569 if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) 569 if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT)
570 fit_print_contents ((const void *)addr); 570 fit_print_contents ((const void *)addr);
571 #endif 571 #endif
572 572
573 /* Loading ok, update default load address */ 573 /* Loading ok, update default load address */
574 574
575 load_addr = addr; 575 load_addr = addr;
576 576
577 /* Check if we should attempt an auto-start */ 577 /* Check if we should attempt an auto-start */
578 if (((ep = getenv("autostart")) != NULL) && (strcmp(ep, "yes") == 0)) { 578 if (((ep = getenv("autostart")) != NULL) && (strcmp(ep, "yes") == 0)) {
579 char *local_args[2]; 579 char *local_args[2];
580 extern int do_bootm(cmd_tbl_t *, int, int, char *[]); 580 extern int do_bootm(cmd_tbl_t *, int, int, char *[]);
581 581
582 local_args[0] = cmd; 582 local_args[0] = cmd;
583 local_args[1] = NULL; 583 local_args[1] = NULL;
584 584
585 printf("Automatic boot of image at addr 0x%08lx ...\n", addr); 585 printf("Automatic boot of image at addr 0x%08lx ...\n", addr);
586 586
587 do_bootm(cmdtp, 0, 1, local_args); 587 do_bootm(cmdtp, 0, 1, local_args);
588 return 1; 588 return 1;
589 } 589 }
590 return 0; 590 return 0;
591 } 591 }
592 592
593 int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) 593 int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
594 { 594 {
595 char *boot_device = NULL; 595 char *boot_device = NULL;
596 int idx; 596 int idx;
597 ulong addr, offset = 0; 597 ulong addr, offset = 0;
598 #if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE) 598 #if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
599 struct mtd_device *dev; 599 struct mtd_device *dev;
600 struct part_info *part; 600 struct part_info *part;
601 u8 pnum; 601 u8 pnum;
602 602
603 if (argc >= 2) { 603 if (argc >= 2) {
604 char *p = (argc == 2) ? argv[1] : argv[2]; 604 char *p = (argc == 2) ? argv[1] : argv[2];
605 if (!(str2long(p, &addr)) && (mtdparts_init() == 0) && 605 if (!(str2long(p, &addr)) && (mtdparts_init() == 0) &&
606 (find_dev_and_part(p, &dev, &pnum, &part) == 0)) { 606 (find_dev_and_part(p, &dev, &pnum, &part) == 0)) {
607 if (dev->id->type != MTD_DEV_TYPE_NAND) { 607 if (dev->id->type != MTD_DEV_TYPE_NAND) {
608 puts("Not a NAND device\n"); 608 puts("Not a NAND device\n");
609 return 1; 609 return 1;
610 } 610 }
611 if (argc > 3) 611 if (argc > 3)
612 goto usage; 612 goto usage;
613 if (argc == 3) 613 if (argc == 3)
614 addr = simple_strtoul(argv[1], NULL, 16); 614 addr = simple_strtoul(argv[1], NULL, 16);
615 else 615 else
616 addr = CFG_LOAD_ADDR; 616 addr = CFG_LOAD_ADDR;
617 return nand_load_image(cmdtp, &nand_info[dev->id->num], 617 return nand_load_image(cmdtp, &nand_info[dev->id->num],
618 part->offset, addr, argv[0]); 618 part->offset, addr, argv[0]);
619 } 619 }
620 } 620 }
621 #endif 621 #endif
622 622
623 show_boot_progress(52); 623 show_boot_progress(52);
624 switch (argc) { 624 switch (argc) {
625 case 1: 625 case 1:
626 addr = CFG_LOAD_ADDR; 626 addr = CFG_LOAD_ADDR;
627 boot_device = getenv("bootdevice"); 627 boot_device = getenv("bootdevice");
628 break; 628 break;
629 case 2: 629 case 2:
630 addr = simple_strtoul(argv[1], NULL, 16); 630 addr = simple_strtoul(argv[1], NULL, 16);
631 boot_device = getenv("bootdevice"); 631 boot_device = getenv("bootdevice");
632 break; 632 break;
633 case 3: 633 case 3:
634 addr = simple_strtoul(argv[1], NULL, 16); 634 addr = simple_strtoul(argv[1], NULL, 16);
635 boot_device = argv[2]; 635 boot_device = argv[2];
636 break; 636 break;
637 case 4: 637 case 4:
638 addr = simple_strtoul(argv[1], NULL, 16); 638 addr = simple_strtoul(argv[1], NULL, 16);
639 boot_device = argv[2]; 639 boot_device = argv[2];
640 offset = simple_strtoul(argv[3], NULL, 16); 640 offset = simple_strtoul(argv[3], NULL, 16);
641 break; 641 break;
642 default: 642 default:
643 #if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE) 643 #if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
644 usage: 644 usage:
645 #endif 645 #endif
646 printf("Usage:\n%s\n", cmdtp->usage); 646 printf("Usage:\n%s\n", cmdtp->usage);
647 show_boot_progress(-53); 647 show_boot_progress(-53);
648 return 1; 648 return 1;
649 } 649 }
650 650
651 show_boot_progress(53); 651 show_boot_progress(53);
652 if (!boot_device) { 652 if (!boot_device) {
653 puts("\n** No boot device **\n"); 653 puts("\n** No boot device **\n");
654 show_boot_progress(-54); 654 show_boot_progress(-54);
655 return 1; 655 return 1;
656 } 656 }
657 show_boot_progress(54); 657 show_boot_progress(54);
658 658
659 idx = simple_strtoul(boot_device, NULL, 16); 659 idx = simple_strtoul(boot_device, NULL, 16);
660 660
661 if (idx < 0 || idx >= CFG_MAX_NAND_DEVICE || !nand_info[idx].name) { 661 if (idx < 0 || idx >= CFG_MAX_NAND_DEVICE || !nand_info[idx].name) {
662 printf("\n** Device %d not available\n", idx); 662 printf("\n** Device %d not available\n", idx);
663 show_boot_progress(-55); 663 show_boot_progress(-55);
664 return 1; 664 return 1;
665 } 665 }
666 show_boot_progress(55); 666 show_boot_progress(55);
667 667
668 return nand_load_image(cmdtp, &nand_info[idx], offset, addr, argv[0]); 668 return nand_load_image(cmdtp, &nand_info[idx], offset, addr, argv[0]);
669 } 669 }
670 670
671 U_BOOT_CMD(nboot, 4, 1, do_nandboot, 671 U_BOOT_CMD(nboot, 4, 1, do_nandboot,
672 "nboot - boot from NAND device\n", 672 "nboot - boot from NAND device\n",
673 "[.jffs2] [partition] | [[[loadAddr] dev] offset]\n"); 673 "[.jffs2] [partition] | [[[loadAddr] dev] offset]\n");
674 674
675 #endif 675 #endif
676 676
677 #else /* CFG_NAND_LEGACY */ 677 #else /* CFG_NAND_LEGACY */
678 /* 678 /*
679 * 679 *
680 * Legacy NAND support - to be phased out 680 * Legacy NAND support - to be phased out
681 * 681 *
682 */ 682 */
683 #include <command.h> 683 #include <command.h>
684 #include <malloc.h> 684 #include <malloc.h>
685 #include <asm/io.h> 685 #include <asm/io.h>
686 #include <watchdog.h> 686 #include <watchdog.h>
687 687
688 #ifdef CONFIG_show_boot_progress 688 #ifdef CONFIG_show_boot_progress
689 # include <status_led.h> 689 # include <status_led.h>
690 # define show_boot_progress(arg) show_boot_progress(arg) 690 # define show_boot_progress(arg) show_boot_progress(arg)
691 #else 691 #else
692 # define show_boot_progress(arg) 692 # define show_boot_progress(arg)
693 #endif 693 #endif
694 694
695 #if defined(CONFIG_CMD_NAND) 695 #if defined(CONFIG_CMD_NAND)
696 #include <linux/mtd/nand_legacy.h> 696 #include <linux/mtd/nand_legacy.h>
697 #if 0 697 #if 0
698 #include <linux/mtd/nand_ids.h> 698 #include <linux/mtd/nand_ids.h>
699 #include <jffs2/jffs2.h> 699 #include <jffs2/jffs2.h>
700 #endif 700 #endif
701 701
702 #ifdef CONFIG_OMAP1510 702 #ifdef CONFIG_OMAP1510
703 void archflashwp(void *archdata, int wp); 703 void archflashwp(void *archdata, int wp);
704 #endif 704 #endif
705 705
706 #define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1))) 706 #define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1)))
707 707
708 #undef NAND_DEBUG 708 #undef NAND_DEBUG
709 #undef PSYCHO_DEBUG 709 #undef PSYCHO_DEBUG
710 710
711 /* ****************** WARNING ********************* 711 /* ****************** WARNING *********************
712 * When ALLOW_ERASE_BAD_DEBUG is non-zero the erase command will 712 * When ALLOW_ERASE_BAD_DEBUG is non-zero the erase command will
713 * erase (or at least attempt to erase) blocks that are marked 713 * erase (or at least attempt to erase) blocks that are marked
714 * bad. This can be very handy if you are _sure_ that the block 714 * bad. This can be very handy if you are _sure_ that the block
715 * is OK, say because you marked a good block bad to test bad 715 * is OK, say because you marked a good block bad to test bad
716 * block handling and you are done testing, or if you have 716 * block handling and you are done testing, or if you have
717 * accidentally marked blocks bad. 717 * accidentally marked blocks bad.
718 * 718 *
719 * Erasing factory marked bad blocks is a _bad_ idea. If the 719 * Erasing factory marked bad blocks is a _bad_ idea. If the
720 * erase succeeds there is no reliable way to find them again, 720 * erase succeeds there is no reliable way to find them again,
721 * and attempting to program or erase bad blocks can affect 721 * and attempting to program or erase bad blocks can affect
722 * the data in _other_ (good) blocks. 722 * the data in _other_ (good) blocks.
723 */ 723 */
724 #define ALLOW_ERASE_BAD_DEBUG 0 724 #define ALLOW_ERASE_BAD_DEBUG 0
725 725
726 #define CONFIG_MTD_NAND_ECC /* enable ECC */ 726 #define CONFIG_MTD_NAND_ECC /* enable ECC */
727 #define CONFIG_MTD_NAND_ECC_JFFS2 727 #define CONFIG_MTD_NAND_ECC_JFFS2
728 728
729 /* bits for nand_legacy_rw() `cmd'; or together as needed */ 729 /* bits for nand_legacy_rw() `cmd'; or together as needed */
730 #define NANDRW_READ 0x01 730 #define NANDRW_READ 0x01
731 #define NANDRW_WRITE 0x00 731 #define NANDRW_WRITE 0x00
732 #define NANDRW_JFFS2 0x02 732 #define NANDRW_JFFS2 0x02
733 #define NANDRW_JFFS2_SKIP 0x04 733 #define NANDRW_JFFS2_SKIP 0x04
734 734
735 /* 735 /*
736 * Imports from nand_legacy.c 736 * Imports from nand_legacy.c
737 */ 737 */
738 extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; 738 extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];
739 extern int curr_device; 739 extern int curr_device;
740 extern int nand_legacy_erase(struct nand_chip *nand, size_t ofs, 740 extern int nand_legacy_erase(struct nand_chip *nand, size_t ofs,
741 size_t len, int clean); 741 size_t len, int clean);
742 extern int nand_legacy_rw(struct nand_chip *nand, int cmd, size_t start, 742 extern int nand_legacy_rw(struct nand_chip *nand, int cmd, size_t start,
743 size_t len, size_t *retlen, u_char *buf); 743 size_t len, size_t *retlen, u_char *buf);
744 extern void nand_print(struct nand_chip *nand); 744 extern void nand_print(struct nand_chip *nand);
745 extern void nand_print_bad(struct nand_chip *nand); 745 extern void nand_print_bad(struct nand_chip *nand);
746 extern int nand_read_oob(struct nand_chip *nand, size_t ofs, 746 extern int nand_read_oob(struct nand_chip *nand, size_t ofs,
747 size_t len, size_t *retlen, u_char *buf); 747 size_t len, size_t *retlen, u_char *buf);
748 extern int nand_write_oob(struct nand_chip *nand, size_t ofs, 748 extern int nand_write_oob(struct nand_chip *nand, size_t ofs,
749 size_t len, size_t *retlen, const u_char *buf); 749 size_t len, size_t *retlen, const u_char *buf);
750 750
751 751
752 int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) 752 int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
753 { 753 {
754 int rcode = 0; 754 int rcode = 0;
755 755
756 switch (argc) { 756 switch (argc) {
757 case 0: 757 case 0:
758 case 1: 758 case 1:
759 printf ("Usage:\n%s\n", cmdtp->usage); 759 printf ("Usage:\n%s\n", cmdtp->usage);
760 return 1; 760 return 1;
761 case 2: 761 case 2:
762 if (strcmp (argv[1], "info") == 0) { 762 if (strcmp (argv[1], "info") == 0) {
763 int i; 763 int i;
764 764
765 putc ('\n'); 765 putc ('\n');
766 766
767 for (i = 0; i < CFG_MAX_NAND_DEVICE; ++i) { 767 for (i = 0; i < CFG_MAX_NAND_DEVICE; ++i) {
768 if (nand_dev_desc[i].ChipID == 768 if (nand_dev_desc[i].ChipID ==
769 NAND_ChipID_UNKNOWN) 769 NAND_ChipID_UNKNOWN)
770 continue; /* list only known devices */ 770 continue; /* list only known devices */
771 printf ("Device %d: ", i); 771 printf ("Device %d: ", i);
772 nand_print (&nand_dev_desc[i]); 772 nand_print (&nand_dev_desc[i]);
773 } 773 }
774 return 0; 774 return 0;
775 775
776 } else if (strcmp (argv[1], "device") == 0) { 776 } else if (strcmp (argv[1], "device") == 0) {
777 if ((curr_device < 0) 777 if ((curr_device < 0)
778 || (curr_device >= CFG_MAX_NAND_DEVICE)) { 778 || (curr_device >= CFG_MAX_NAND_DEVICE)) {
779 puts ("\nno devices available\n"); 779 puts ("\nno devices available\n");
780 return 1; 780 return 1;
781 } 781 }
782 printf ("\nDevice %d: ", curr_device); 782 printf ("\nDevice %d: ", curr_device);
783 nand_print (&nand_dev_desc[curr_device]); 783 nand_print (&nand_dev_desc[curr_device]);
784 return 0; 784 return 0;
785 785
786 } else if (strcmp (argv[1], "bad") == 0) { 786 } else if (strcmp (argv[1], "bad") == 0) {
787 if ((curr_device < 0) 787 if ((curr_device < 0)
788 || (curr_device >= CFG_MAX_NAND_DEVICE)) { 788 || (curr_device >= CFG_MAX_NAND_DEVICE)) {
789 puts ("\nno devices available\n"); 789 puts ("\nno devices available\n");
790 return 1; 790 return 1;
791 } 791 }
792 printf ("\nDevice %d bad blocks:\n", curr_device); 792 printf ("\nDevice %d bad blocks:\n", curr_device);
793 nand_print_bad (&nand_dev_desc[curr_device]); 793 nand_print_bad (&nand_dev_desc[curr_device]);
794 return 0; 794 return 0;
795 795
796 } 796 }
797 printf ("Usage:\n%s\n", cmdtp->usage); 797 printf ("Usage:\n%s\n", cmdtp->usage);
798 return 1; 798 return 1;
799 case 3: 799 case 3:
800 if (strcmp (argv[1], "device") == 0) { 800 if (strcmp (argv[1], "device") == 0) {
801 int dev = (int) simple_strtoul (argv[2], NULL, 10); 801 int dev = (int) simple_strtoul (argv[2], NULL, 10);
802 802
803 printf ("\nDevice %d: ", dev); 803 printf ("\nDevice %d: ", dev);
804 if (dev >= CFG_MAX_NAND_DEVICE) { 804 if (dev >= CFG_MAX_NAND_DEVICE) {
805 puts ("unknown device\n"); 805 puts ("unknown device\n");
806 return 1; 806 return 1;
807 } 807 }
808 nand_print (&nand_dev_desc[dev]); 808 nand_print (&nand_dev_desc[dev]);
809 /*nand_print (dev); */ 809 /*nand_print (dev); */
810 810
811 if (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN) { 811 if (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN) {
812 return 1; 812 return 1;
813 } 813 }
814 814
815 curr_device = dev; 815 curr_device = dev;
816 816
817 puts ("... is now current device\n"); 817 puts ("... is now current device\n");
818 818
819 return 0; 819 return 0;
820 } else if (strcmp (argv[1], "erase") == 0 820 } else if (strcmp (argv[1], "erase") == 0
821 && strcmp (argv[2], "clean") == 0) { 821 && strcmp (argv[2], "clean") == 0) {
822 struct nand_chip *nand = &nand_dev_desc[curr_device]; 822 struct nand_chip *nand = &nand_dev_desc[curr_device];
823 ulong off = 0; 823 ulong off = 0;
824 ulong size = nand->totlen; 824 ulong size = nand->totlen;
825 int ret; 825 int ret;
826 826
827 printf ("\nNAND erase: device %d offset %ld, size %ld ... ", curr_device, off, size); 827 printf ("\nNAND erase: device %d offset %ld, size %ld ... ", curr_device, off, size);
828 828
829 ret = nand_legacy_erase (nand, off, size, 1); 829 ret = nand_legacy_erase (nand, off, size, 1);
830 830
831 printf ("%s\n", ret ? "ERROR" : "OK"); 831 printf ("%s\n", ret ? "ERROR" : "OK");
832 832
833 return ret; 833 return ret;
834 } 834 }
835 835
836 printf ("Usage:\n%s\n", cmdtp->usage); 836 printf ("Usage:\n%s\n", cmdtp->usage);
837 return 1; 837 return 1;
838 default: 838 default:
839 /* at least 4 args */ 839 /* at least 4 args */
840 840
841 if (strncmp (argv[1], "read", 4) == 0 || 841 if (strncmp (argv[1], "read", 4) == 0 ||
842 strncmp (argv[1], "write", 5) == 0) { 842 strncmp (argv[1], "write", 5) == 0) {
843 ulong addr = simple_strtoul (argv[2], NULL, 16); 843 ulong addr = simple_strtoul (argv[2], NULL, 16);
844 off_t off = simple_strtoul (argv[3], NULL, 16); 844 off_t off = simple_strtoul (argv[3], NULL, 16);
845 size_t size = simple_strtoul (argv[4], NULL, 16); 845 size_t size = simple_strtoul (argv[4], NULL, 16);
846 int cmd = (strncmp (argv[1], "read", 4) == 0) ? 846 int cmd = (strncmp (argv[1], "read", 4) == 0) ?
847 NANDRW_READ : NANDRW_WRITE; 847 NANDRW_READ : NANDRW_WRITE;
848 size_t total; 848 size_t total;
849 int ret; 849 int ret;
850 char *cmdtail = strchr (argv[1], '.'); 850 char *cmdtail = strchr (argv[1], '.');
851 851
852 if (cmdtail && !strncmp (cmdtail, ".oob", 2)) { 852 if (cmdtail && !strncmp (cmdtail, ".oob", 2)) {
853 /* read out-of-band data */ 853 /* read out-of-band data */
854 if (cmd & NANDRW_READ) { 854 if (cmd & NANDRW_READ) {
855 ret = nand_read_oob (nand_dev_desc + curr_device, 855 ret = nand_read_oob (nand_dev_desc + curr_device,
856 off, size, &total, 856 off, size, &total,
857 (u_char *) addr); 857 (u_char *) addr);
858 } else { 858 } else {
859 ret = nand_write_oob (nand_dev_desc + curr_device, 859 ret = nand_write_oob (nand_dev_desc + curr_device,
860 off, size, &total, 860 off, size, &total,
861 (u_char *) addr); 861 (u_char *) addr);
862 } 862 }
863 return ret; 863 return ret;
864 } else if (cmdtail && !strncmp (cmdtail, ".jffs2", 2)) 864 } else if (cmdtail && !strncmp (cmdtail, ".jffs2", 2))
865 cmd |= NANDRW_JFFS2; /* skip bad blocks */ 865 cmd |= NANDRW_JFFS2; /* skip bad blocks */
866 else if (cmdtail && !strncmp (cmdtail, ".jffs2s", 2)) { 866 else if (cmdtail && !strncmp (cmdtail, ".jffs2s", 2)) {
867 cmd |= NANDRW_JFFS2; /* skip bad blocks (on read too) */ 867 cmd |= NANDRW_JFFS2; /* skip bad blocks (on read too) */
868 if (cmd & NANDRW_READ) 868 if (cmd & NANDRW_READ)
869 cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */ 869 cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */
870 } 870 }
871 #ifdef SXNI855T 871 #ifdef SXNI855T
872 /* need ".e" same as ".j" for compatibility with older units */ 872 /* need ".e" same as ".j" for compatibility with older units */
873 else if (cmdtail && !strcmp (cmdtail, ".e")) 873 else if (cmdtail && !strcmp (cmdtail, ".e"))
874 cmd |= NANDRW_JFFS2; /* skip bad blocks */ 874 cmd |= NANDRW_JFFS2; /* skip bad blocks */
875 #endif 875 #endif
876 #ifdef CFG_NAND_SKIP_BAD_DOT_I 876 #ifdef CFG_NAND_SKIP_BAD_DOT_I
877 /* need ".i" same as ".jffs2s" for compatibility with older units (esd) */ 877 /* need ".i" same as ".jffs2s" for compatibility with older units (esd) */
878 /* ".i" for image -> read skips bad block (no 0xff) */ 878 /* ".i" for image -> read skips bad block (no 0xff) */
879 else if (cmdtail && !strcmp (cmdtail, ".i")) { 879 else if (cmdtail && !strcmp (cmdtail, ".i")) {
880 cmd |= NANDRW_JFFS2; /* skip bad blocks (on read too) */ 880 cmd |= NANDRW_JFFS2; /* skip bad blocks (on read too) */
881 if (cmd & NANDRW_READ) 881 if (cmd & NANDRW_READ)
882 cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */ 882 cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */
883 } 883 }
884 #endif /* CFG_NAND_SKIP_BAD_DOT_I */ 884 #endif /* CFG_NAND_SKIP_BAD_DOT_I */
885 else if (cmdtail) { 885 else if (cmdtail) {
886 printf ("Usage:\n%s\n", cmdtp->usage); 886 printf ("Usage:\n%s\n", cmdtp->usage);
887 return 1; 887 return 1;
888 } 888 }
889 889
890 printf ("\nNAND %s: device %d offset %ld, size %ld ...\n", 890 printf ("\nNAND %s: device %d offset %ld, size %ld ...\n",
891 (cmd & NANDRW_READ) ? "read" : "write", 891 (cmd & NANDRW_READ) ? "read" : "write",
892 curr_device, off, size); 892 curr_device, off, size);
893 893
894 ret = nand_legacy_rw (nand_dev_desc + curr_device, 894 ret = nand_legacy_rw (nand_dev_desc + curr_device,
895 cmd, off, size, 895 cmd, off, size,
896 &total, 896 &total,
897 (u_char *) addr); 897 (u_char *) addr);
898 898
899 printf (" %d bytes %s: %s\n", total, 899 printf (" %d bytes %s: %s\n", total,
900 (cmd & NANDRW_READ) ? "read" : "written", 900 (cmd & NANDRW_READ) ? "read" : "written",
901 ret ? "ERROR" : "OK"); 901 ret ? "ERROR" : "OK");
902 902
903 return ret; 903 return ret;
904 } else if (strcmp (argv[1], "erase") == 0 && 904 } else if (strcmp (argv[1], "erase") == 0 &&
905 (argc == 4 || strcmp ("clean", argv[2]) == 0)) { 905 (argc == 4 || strcmp ("clean", argv[2]) == 0)) {
906 int clean = argc == 5; 906 int clean = argc == 5;
907 ulong off = 907 ulong off =
908 simple_strtoul (argv[2 + clean], NULL, 16); 908 simple_strtoul (argv[2 + clean], NULL, 16);
909 ulong size = 909 ulong size =
910 simple_strtoul (argv[3 + clean], NULL, 16); 910 simple_strtoul (argv[3 + clean], NULL, 16);
911 int ret; 911 int ret;
912 912
913 printf ("\nNAND erase: device %d offset %ld, size %ld ...\n", 913 printf ("\nNAND erase: device %d offset %ld, size %ld ...\n",
914 curr_device, off, size); 914 curr_device, off, size);
915 915
916 ret = nand_legacy_erase (nand_dev_desc + curr_device, 916 ret = nand_legacy_erase (nand_dev_desc + curr_device,
917 off, size, clean); 917 off, size, clean);
918 918
919 printf ("%s\n", ret ? "ERROR" : "OK"); 919 printf ("%s\n", ret ? "ERROR" : "OK");
920 920
921 return ret; 921 return ret;
922 } else { 922 } else {
923 printf ("Usage:\n%s\n", cmdtp->usage); 923 printf ("Usage:\n%s\n", cmdtp->usage);
924 rcode = 1; 924 rcode = 1;
925 } 925 }
926 926
927 return rcode; 927 return rcode;
928 } 928 }
929 } 929 }
930 930
931 U_BOOT_CMD( 931 U_BOOT_CMD(
932 nand, 5, 1, do_nand, 932 nand, 5, 1, do_nand,
933 "nand - legacy NAND sub-system\n", 933 "nand - legacy NAND sub-system\n",
934 "info - show available NAND devices\n" 934 "info - show available NAND devices\n"
935 "nand device [dev] - show or set current device\n" 935 "nand device [dev] - show or set current device\n"
936 "nand read[.jffs2[s]] addr off size\n" 936 "nand read[.jffs2[s]] addr off size\n"
937 "nand write[.jffs2] addr off size - read/write `size' bytes starting\n" 937 "nand write[.jffs2] addr off size - read/write `size' bytes starting\n"
938 " at offset `off' to/from memory address `addr'\n" 938 " at offset `off' to/from memory address `addr'\n"
939 "nand erase [clean] [off size] - erase `size' bytes from\n" 939 "nand erase [clean] [off size] - erase `size' bytes from\n"
940 " offset `off' (entire device if not specified)\n" 940 " offset `off' (entire device if not specified)\n"
941 "nand bad - show bad blocks\n" 941 "nand bad - show bad blocks\n"
942 "nand read.oob addr off size - read out-of-band data\n" 942 "nand read.oob addr off size - read out-of-band data\n"
943 "nand write.oob addr off size - read out-of-band data\n" 943 "nand write.oob addr off size - read out-of-band data\n"
944 ); 944 );
945 945
946 int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) 946 int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
947 { 947 {
948 char *boot_device = NULL; 948 char *boot_device = NULL;
949 char *ep; 949 char *ep;
950 int dev; 950 int dev;
951 ulong cnt; 951 ulong cnt;
952 ulong addr; 952 ulong addr;
953 ulong offset = 0; 953 ulong offset = 0;
954 image_header_t *hdr; 954 image_header_t *hdr;
955 int rcode = 0; 955 int rcode = 0;
956 #if defined(CONFIG_FIT) 956 #if defined(CONFIG_FIT)
957 const void *fit_hdr; 957 const void *fit_hdr;
958 #endif 958 #endif
959 959
960 show_boot_progress (52); 960 show_boot_progress (52);
961 switch (argc) { 961 switch (argc) {
962 case 1: 962 case 1:
963 addr = CFG_LOAD_ADDR; 963 addr = CFG_LOAD_ADDR;
964 boot_device = getenv ("bootdevice"); 964 boot_device = getenv ("bootdevice");
965 break; 965 break;
966 case 2: 966 case 2:
967 addr = simple_strtoul(argv[1], NULL, 16); 967 addr = simple_strtoul(argv[1], NULL, 16);
968 boot_device = getenv ("bootdevice"); 968 boot_device = getenv ("bootdevice");
969 break; 969 break;
970 case 3: 970 case 3:
971 addr = simple_strtoul(argv[1], NULL, 16); 971 addr = simple_strtoul(argv[1], NULL, 16);
972 boot_device = argv[2]; 972 boot_device = argv[2];
973 break; 973 break;
974 case 4: 974 case 4:
975 addr = simple_strtoul(argv[1], NULL, 16); 975 addr = simple_strtoul(argv[1], NULL, 16);
976 boot_device = argv[2]; 976 boot_device = argv[2];
977 offset = simple_strtoul(argv[3], NULL, 16); 977 offset = simple_strtoul(argv[3], NULL, 16);
978 break; 978 break;
979 default: 979 default:
980 printf ("Usage:\n%s\n", cmdtp->usage); 980 printf ("Usage:\n%s\n", cmdtp->usage);
981 show_boot_progress (-53); 981 show_boot_progress (-53);
982 return 1; 982 return 1;
983 } 983 }
984 984
985 show_boot_progress (53); 985 show_boot_progress (53);
986 if (!boot_device) { 986 if (!boot_device) {
987 puts ("\n** No boot device **\n"); 987 puts ("\n** No boot device **\n");
988 show_boot_progress (-54); 988 show_boot_progress (-54);
989 return 1; 989 return 1;
990 } 990 }
991 show_boot_progress (54); 991 show_boot_progress (54);
992 992
993 dev = simple_strtoul(boot_device, &ep, 16); 993 dev = simple_strtoul(boot_device, &ep, 16);
994 994
995 if ((dev >= CFG_MAX_NAND_DEVICE) || 995 if ((dev >= CFG_MAX_NAND_DEVICE) ||
996 (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN)) { 996 (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN)) {
997 printf ("\n** Device %d not available\n", dev); 997 printf ("\n** Device %d not available\n", dev);
998 show_boot_progress (-55); 998 show_boot_progress (-55);
999 return 1; 999 return 1;
1000 } 1000 }
1001 show_boot_progress (55); 1001 show_boot_progress (55);
1002 1002
1003 printf ("\nLoading from device %d: %s at 0x%lx (offset 0x%lx)\n", 1003 printf ("\nLoading from device %d: %s at 0x%lx (offset 0x%lx)\n",
1004 dev, nand_dev_desc[dev].name, nand_dev_desc[dev].IO_ADDR, 1004 dev, nand_dev_desc[dev].name, nand_dev_desc[dev].IO_ADDR,
1005 offset); 1005 offset);
1006 1006
1007 if (nand_legacy_rw (nand_dev_desc + dev, NANDRW_READ, offset, 1007 if (nand_legacy_rw (nand_dev_desc + dev, NANDRW_READ, offset,
1008 SECTORSIZE, NULL, (u_char *)addr)) { 1008 SECTORSIZE, NULL, (u_char *)addr)) {
1009 printf ("** Read error on %d\n", dev); 1009 printf ("** Read error on %d\n", dev);
1010 show_boot_progress (-56); 1010 show_boot_progress (-56);
1011 return 1; 1011 return 1;
1012 } 1012 }
1013 show_boot_progress (56); 1013 show_boot_progress (56);
1014 1014
1015 switch (genimg_get_format ((void *)addr)) { 1015 switch (genimg_get_format ((void *)addr)) {
1016 case IMAGE_FORMAT_LEGACY: 1016 case IMAGE_FORMAT_LEGACY:
1017 hdr = (image_header_t *)addr; 1017 hdr = (image_header_t *)addr;
1018 image_print_contents (hdr); 1018 image_print_contents (hdr);
1019 1019
1020 cnt = image_get_image_size (hdr); 1020 cnt = image_get_image_size (hdr);
1021 cnt -= SECTORSIZE; 1021 cnt -= SECTORSIZE;
1022 break; 1022 break;
1023 #if defined(CONFIG_FIT) 1023 #if defined(CONFIG_FIT)
1024 case IMAGE_FORMAT_FIT: 1024 case IMAGE_FORMAT_FIT:
1025 fit_hdr = (const void *)addr; 1025 fit_hdr = (const void *)addr;
1026 if (!fit_check_format (fit_hdr)) { 1026 if (!fit_check_format (fit_hdr)) {
1027 show_boot_progress (-150); 1027 show_boot_progress (-150);
1028 puts ("** Bad FIT image format\n"); 1028 puts ("** Bad FIT image format\n");
1029 return 1; 1029 return 1;
1030 } 1030 }
1031 show_boot_progress (151); 1031 show_boot_progress (151);
1032 puts ("Fit image detected...\n"); 1032 puts ("Fit image detected...\n");
1033 1033
1034 cnt = fit_get_size (fit_hdr); 1034 cnt = fit_get_size (fit_hdr);
1035 break; 1035 break;
1036 #endif 1036 #endif
1037 default: 1037 default:
1038 show_boot_progress (-57); 1038 show_boot_progress (-57);
1039 puts ("** Unknown image type\n"); 1039 puts ("** Unknown image type\n");
1040 return 1; 1040 return 1;
1041 } 1041 }
1042 show_boot_progress (57); 1042 show_boot_progress (57);
1043 1043
1044 if (nand_legacy_rw (nand_dev_desc + dev, NANDRW_READ, 1044 if (nand_legacy_rw (nand_dev_desc + dev, NANDRW_READ,
1045 offset + SECTORSIZE, cnt, NULL, 1045 offset + SECTORSIZE, cnt, NULL,
1046 (u_char *)(addr+SECTORSIZE))) { 1046 (u_char *)(addr+SECTORSIZE))) {
1047 printf ("** Read error on %d\n", dev); 1047 printf ("** Read error on %d\n", dev);
1048 show_boot_progress (-58); 1048 show_boot_progress (-58);
1049 return 1; 1049 return 1;
1050 } 1050 }
1051 show_boot_progress (58); 1051 show_boot_progress (58);
1052 1052
1053 #if defined(CONFIG_FIT) 1053 #if defined(CONFIG_FIT)
1054 /* This cannot be done earlier, we need complete FIT image in RAM first */ 1054 /* This cannot be done earlier, we need complete FIT image in RAM first */
1055 if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) 1055 if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT)
1056 fit_print_contents ((const void *)addr); 1056 fit_print_contents ((const void *)addr);
1057 #endif 1057 #endif
1058 1058
1059 /* Loading ok, update default load address */ 1059 /* Loading ok, update default load address */
1060 1060
1061 load_addr = addr; 1061 load_addr = addr;
1062 1062
1063 /* Check if we should attempt an auto-start */ 1063 /* Check if we should attempt an auto-start */
1064 if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) { 1064 if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
1065 char *local_args[2]; 1065 char *local_args[2];
1066 extern int do_bootm (cmd_tbl_t *, int, int, char *[]); 1066 extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
1067 1067
1068 local_args[0] = argv[0]; 1068 local_args[0] = argv[0];
1069 local_args[1] = NULL; 1069 local_args[1] = NULL;
1070 1070
1071 printf ("Automatic boot of image at addr 0x%08lx ...\n", addr); 1071 printf ("Automatic boot of image at addr 0x%08lx ...\n", addr);
1072 1072
1073 do_bootm (cmdtp, 0, 1, local_args); 1073 do_bootm (cmdtp, 0, 1, local_args);
1074 rcode = 1; 1074 rcode = 1;
1075 } 1075 }
1076 return rcode; 1076 return rcode;
1077 } 1077 }
1078 1078
1079 U_BOOT_CMD( 1079 U_BOOT_CMD(
1080 nboot, 4, 1, do_nandboot, 1080 nboot, 4, 1, do_nandboot,
1081 "nboot - boot from NAND device\n", 1081 "nboot - boot from NAND device\n",
1082 "loadAddr dev\n" 1082 "loadAddr dev\n"
1083 ); 1083 );
1084 1084
1085 #endif 1085 #endif
1086 1086
1087 #endif /* CFG_NAND_LEGACY */ 1087 #endif /* CFG_NAND_LEGACY */
1088 1088