Commit 856f054410cef52d868feb330168b2a4c4091328
1 parent
07a69a18c2
Exists in
master
and in
55 other branches
[PATCH] NAND: Partition name support added to NAND subsystem
chpart, nboot and NAND subsystem related commands now accept also partition name to specify offset. Signed-off-by: Ladislav Michl <ladis@linux-mips.org> Signed-off-by: Stefan Roese <sr@denx.de>
Showing 4 changed files with 226 additions and 174 deletions Side-by-side Diff
common/cmd_jffs2.c
... | ... | @@ -1300,7 +1300,7 @@ |
1300 | 1300 | * Given partition identifier in form of <dev_type><dev_num>,<part_num> find |
1301 | 1301 | * corresponding device and verify partition number. |
1302 | 1302 | * |
1303 | - * @param id string describing device and partition | |
1303 | + * @param id string describing device and partition or partition name | |
1304 | 1304 | * @param dev pointer to the requested device (output) |
1305 | 1305 | * @param part_num verified partition number (output) |
1306 | 1306 | * @param part pointer to requested partition (output) |
1307 | 1307 | |
... | ... | @@ -1309,10 +1309,22 @@ |
1309 | 1309 | int find_dev_and_part(const char *id, struct mtd_device **dev, |
1310 | 1310 | u8 *part_num, struct part_info **part) |
1311 | 1311 | { |
1312 | + struct list_head *dentry, *pentry; | |
1312 | 1313 | u8 type, dnum, pnum; |
1313 | 1314 | const char *p; |
1314 | 1315 | |
1315 | 1316 | DEBUGF("--- find_dev_and_part ---\nid = %s\n", id); |
1317 | + | |
1318 | + list_for_each(dentry, &devices) { | |
1319 | + *part_num = 0; | |
1320 | + *dev = list_entry(dentry, struct mtd_device, link); | |
1321 | + list_for_each(pentry, &(*dev)->parts) { | |
1322 | + *part = list_entry(pentry, struct part_info, link); | |
1323 | + if (strcmp((*part)->name, id) == 0) | |
1324 | + return 0; | |
1325 | + (*part_num)++; | |
1326 | + } | |
1327 | + } | |
1316 | 1328 | |
1317 | 1329 | p = id; |
1318 | 1330 | *dev = NULL; |
common/cmd_nand.c
... | ... | @@ -36,6 +36,15 @@ |
36 | 36 | #include <jffs2/jffs2.h> |
37 | 37 | #include <nand.h> |
38 | 38 | |
39 | +#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE) | |
40 | + | |
41 | +/* parition handling routines */ | |
42 | +int mtdparts_init(void); | |
43 | +int id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *dev_num); | |
44 | +int find_dev_and_part(const char *id, struct mtd_device **dev, | |
45 | + u8 *part_num, struct part_info **part); | |
46 | +#endif | |
47 | + | |
39 | 48 | extern nand_info_t nand_info[]; /* info for NAND chips */ |
40 | 49 | |
41 | 50 | static int nand_dump_oob(nand_info_t *nand, ulong off) |
42 | 51 | |
43 | 52 | |
44 | 53 | |
45 | 54 | |
46 | 55 | |
47 | 56 | |
48 | 57 | |
49 | 58 | |
50 | 59 | |
... | ... | @@ -83,50 +92,75 @@ |
83 | 92 | |
84 | 93 | /* ------------------------------------------------------------------------- */ |
85 | 94 | |
86 | -static void | |
87 | -arg_off_size(int argc, char *argv[], ulong *off, ulong *size, ulong totsize) | |
95 | +static inline int str2long(char *p, ulong *num) | |
88 | 96 | { |
89 | - *off = 0; | |
90 | - *size = 0; | |
97 | + char *endptr; | |
91 | 98 | |
92 | -#if defined(CONFIG_JFFS2_NAND) && defined(CFG_JFFS_CUSTOM_PART) | |
93 | - if (argc >= 1 && strcmp(argv[0], "partition") == 0) { | |
94 | - int part_num; | |
95 | - struct part_info *part; | |
96 | - const char *partstr; | |
99 | + *num = simple_strtoul(p, &endptr, 16); | |
100 | + return (*p != '\0' && *endptr == '\0') ? 1 : 0; | |
101 | +} | |
97 | 102 | |
98 | - if (argc >= 2) | |
99 | - partstr = argv[1]; | |
100 | - else | |
101 | - partstr = getenv("partition"); | |
103 | +static int | |
104 | +arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off, ulong *size) | |
105 | +{ | |
106 | + int idx = nand_curr_device; | |
107 | +#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE) | |
108 | + struct mtd_device *dev; | |
109 | + struct part_info *part; | |
110 | + u8 pnum; | |
102 | 111 | |
103 | - if (partstr) | |
104 | - part_num = (int)simple_strtoul(partstr, NULL, 10); | |
105 | - else | |
106 | - part_num = 0; | |
107 | - | |
108 | - part = jffs2_part_info(part_num); | |
109 | - if (part == NULL) { | |
110 | - printf("\nInvalid partition %d\n", part_num); | |
111 | - return; | |
112 | + if (argc >= 1 && !(str2long(argv[0], off))) { | |
113 | + if ((mtdparts_init() == 0) && | |
114 | + (find_dev_and_part(argv[0], &dev, &pnum, &part) == 0)) { | |
115 | + if (dev->id->type != MTD_DEV_TYPE_NAND) { | |
116 | + puts("not a NAND device\n"); | |
117 | + return -1; | |
118 | + } | |
119 | + *off = part->offset; | |
120 | + if (argc >= 2) { | |
121 | + if (!(str2long(argv[1], size))) { | |
122 | + printf("'%s' is not a number\n", argv[1]); | |
123 | + return -1; | |
124 | + } | |
125 | + if (*size > part->size) | |
126 | + *size = part->size; | |
127 | + } else { | |
128 | + *size = part->size; | |
129 | + } | |
130 | + idx = dev->id->num; | |
131 | + *nand = nand_info[idx]; | |
132 | + goto out; | |
112 | 133 | } |
113 | - *size = part->size; | |
114 | - *off = (ulong)part->offset; | |
115 | - } else | |
134 | + } | |
116 | 135 | #endif |
117 | - { | |
118 | - if (argc >= 1) | |
119 | - *off = (ulong)simple_strtoul(argv[0], NULL, 16); | |
120 | - else | |
121 | - *off = 0; | |
122 | 136 | |
123 | - if (argc >= 2) | |
124 | - *size = (ulong)simple_strtoul(argv[1], NULL, 16); | |
125 | - else | |
126 | - *size = totsize - *off; | |
137 | + if (argc >= 1) { | |
138 | + if (!(str2long(argv[0], off))) { | |
139 | + printf("'%s' is not a number\n", argv[0]); | |
140 | + return -1; | |
141 | + } | |
142 | + } else { | |
143 | + *off = 0; | |
144 | + } | |
127 | 145 | |
146 | + if (argc >= 2) { | |
147 | + if (!(str2long(argv[1], size))) { | |
148 | + printf("'%s' is not a number\n", argv[1]); | |
149 | + return -1; | |
150 | + } | |
151 | + } else { | |
152 | + *size = nand->size - *off; | |
128 | 153 | } |
129 | 154 | |
155 | +#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE) | |
156 | +out: | |
157 | +#endif | |
158 | + printf("device %d ", idx); | |
159 | + if (*size == nand->size) | |
160 | + puts("whole chip\n"); | |
161 | + else | |
162 | + printf("offset 0x%x, size 0x%x\n", *off, *size); | |
163 | + return 0; | |
130 | 164 | } |
131 | 165 | |
132 | 166 | int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) |
133 | 167 | |
134 | 168 | |
135 | 169 | |
... | ... | @@ -213,36 +247,23 @@ |
213 | 247 | return 0; |
214 | 248 | } |
215 | 249 | |
250 | + /* | |
251 | + * Syntax is: | |
252 | + * 0 1 2 3 4 | |
253 | + * nand erase [clean] [off size] | |
254 | + */ | |
216 | 255 | if (strcmp(cmd, "erase") == 0 || strcmp(cmd, "scrub") == 0) { |
217 | 256 | nand_erase_options_t opts; |
218 | - int clean = argc >= 3 && !strcmp("clean", argv[2]); | |
219 | - int rest_argc = argc - 2; | |
220 | - char **rest_argv = argv + 2; | |
257 | + /* "clean" at index 2 means request to write cleanmarker */ | |
258 | + int clean = argc > 2 && !strcmp("clean", argv[2]); | |
259 | + int o = clean ? 3 : 2; | |
221 | 260 | int scrub = !strcmp(cmd, "scrub"); |
222 | 261 | |
223 | - if (clean) { | |
224 | - rest_argc--; | |
225 | - rest_argv++; | |
226 | - } | |
262 | + printf("\nNAND %s: ", scrub ? "scrub" : "erase"); | |
263 | + /* skip first two or three arguments, look for offset and size */ | |
264 | + if (arg_off_size(argc - o, argv + o, nand, &off, &size) != 0) | |
265 | + return 1; | |
227 | 266 | |
228 | - if (rest_argc == 0) { | |
229 | - | |
230 | - printf("\nNAND %s: device %d whole chip\n", | |
231 | - cmd, | |
232 | - nand_curr_device); | |
233 | - | |
234 | - off = size = 0; | |
235 | - } else { | |
236 | - arg_off_size(rest_argc, rest_argv, &off, &size, | |
237 | - nand->size); | |
238 | - | |
239 | - if (off == 0 && size == 0) | |
240 | - return 1; | |
241 | - | |
242 | - printf("\nNAND %s: device %d offset 0x%x, size 0x%x\n", | |
243 | - cmd, nand_curr_device, off, size); | |
244 | - } | |
245 | - | |
246 | 267 | memset(&opts, 0, sizeof(opts)); |
247 | 268 | opts.offset = off; |
248 | 269 | opts.length = size; |
249 | 270 | |
... | ... | @@ -250,23 +271,22 @@ |
250 | 271 | opts.quiet = quiet; |
251 | 272 | |
252 | 273 | if (scrub) { |
253 | - printf("Warning: " | |
254 | - "scrub option will erase all factory set " | |
255 | - "bad blocks!\n" | |
256 | - " " | |
257 | - "There is no reliable way to recover them.\n" | |
258 | - " " | |
259 | - "Use this command only for testing purposes " | |
260 | - "if you\n" | |
261 | - " " | |
262 | - "are sure of what you are doing!\n" | |
263 | - "\nReally scrub this NAND flash? <y/N>\n" | |
264 | - ); | |
274 | + puts("Warning: " | |
275 | + "scrub option will erase all factory set " | |
276 | + "bad blocks!\n" | |
277 | + " " | |
278 | + "There is no reliable way to recover them.\n" | |
279 | + " " | |
280 | + "Use this command only for testing purposes " | |
281 | + "if you\n" | |
282 | + " " | |
283 | + "are sure of what you are doing!\n" | |
284 | + "\nReally scrub this NAND flash? <y/N>\n"); | |
265 | 285 | |
266 | 286 | if (getc() == 'y' && getc() == '\r') { |
267 | 287 | opts.scrub = 1; |
268 | 288 | } else { |
269 | - printf("scrub aborted\n"); | |
289 | + puts("scrub aborted\n"); | |
270 | 290 | return -1; |
271 | 291 | } |
272 | 292 | } |
273 | 293 | |
... | ... | @@ -301,14 +321,11 @@ |
301 | 321 | |
302 | 322 | addr = (ulong)simple_strtoul(argv[2], NULL, 16); |
303 | 323 | |
304 | - arg_off_size(argc - 3, argv + 3, &off, &size, nand->size); | |
305 | - if (off == 0 && size == 0) | |
324 | + read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */ | |
325 | + printf("\nNAND %s: ", read ? "read" : "write"); | |
326 | + if (arg_off_size(argc - 3, argv + 3, nand, &off, &size) != 0) | |
306 | 327 | return 1; |
307 | 328 | |
308 | - read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */ | |
309 | - printf("\nNAND %s: device %d offset %u, size %u ... ", | |
310 | - read ? "read" : "write", nand_curr_device, off, size); | |
311 | - | |
312 | 329 | s = strchr(cmd, '.'); |
313 | 330 | if (s != NULL && |
314 | 331 | (!strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i"))) { |
315 | 332 | |
... | ... | @@ -334,15 +351,13 @@ |
334 | 351 | opts.quiet = quiet; |
335 | 352 | ret = nand_write_opts(nand, &opts); |
336 | 353 | } |
337 | - printf("%s\n", ret ? "ERROR" : "OK"); | |
338 | - return ret == 0 ? 0 : 1; | |
354 | + } else { | |
355 | + if (read) | |
356 | + ret = nand_read(nand, off, &size, (u_char *)addr); | |
357 | + else | |
358 | + ret = nand_write(nand, off, &size, (u_char *)addr); | |
339 | 359 | } |
340 | 360 | |
341 | - if (read) | |
342 | - ret = nand_read(nand, off, &size, (u_char *)addr); | |
343 | - else | |
344 | - ret = nand_write(nand, off, &size, (u_char *)addr); | |
345 | - | |
346 | 361 | printf(" %d bytes %s: %s\n", size, |
347 | 362 | read ? "read" : "written", ret ? "ERROR" : "OK"); |
348 | 363 | |
349 | 364 | |
... | ... | @@ -412,9 +427,9 @@ |
412 | 427 | } |
413 | 428 | } else { |
414 | 429 | if (!nand_lock(nand, tight)) { |
415 | - printf ("NAND flash successfully locked\n"); | |
430 | + puts("NAND flash successfully locked\n"); | |
416 | 431 | } else { |
417 | - printf ("Error locking NAND flash. \n"); | |
432 | + puts("Error locking NAND flash\n"); | |
418 | 433 | return 1; |
419 | 434 | } |
420 | 435 | } |
421 | 436 | |
422 | 437 | |
... | ... | @@ -422,19 +437,14 @@ |
422 | 437 | } |
423 | 438 | |
424 | 439 | if (strcmp(cmd, "unlock") == 0) { |
425 | - if (argc == 2) { | |
426 | - off = 0; | |
427 | - size = nand->size; | |
428 | - } else { | |
429 | - arg_off_size(argc - 2, argv + 2, &off, &size, | |
430 | - nand->size); | |
431 | - } | |
440 | + if (arg_off_size(argc - 2, argv + 2, nand, &off, &size) < 0) | |
441 | + return 1; | |
432 | 442 | |
433 | 443 | if (!nand_unlock(nand, off, size)) { |
434 | - printf("NAND flash successfully unlocked\n"); | |
444 | + puts("NAND flash successfully unlocked\n"); | |
435 | 445 | } else { |
436 | - printf("Error unlocking NAND flash. " | |
437 | - "Write and erase will probably fail\n"); | |
446 | + puts("Error unlocking NAND flash, " | |
447 | + "write and erase will probably fail\n"); | |
438 | 448 | return 1; |
439 | 449 | } |
440 | 450 | return 0; |
... | ... | @@ -449,8 +459,8 @@ |
449 | 459 | "nand - NAND sub-system\n", |
450 | 460 | "info - show available NAND devices\n" |
451 | 461 | "nand device [dev] - show or set current device\n" |
452 | - "nand read[.jffs2] - addr off size\n" | |
453 | - "nand write[.jffs2] - addr off size - read/write `size' bytes starting\n" | |
462 | + "nand read[.jffs2] - addr off|partition size\n" | |
463 | + "nand write[.jffs2] - addr off|partiton size - read/write `size' bytes starting\n" | |
454 | 464 | " at offset `off' to/from memory address `addr'\n" |
455 | 465 | "nand erase [clean] [off size] - erase `size' bytes from\n" |
456 | 466 | " offset `off' (entire device if not specified)\n" |
457 | 467 | |
458 | 468 | |
459 | 469 | |
460 | 470 | |
461 | 471 | |
462 | 472 | |
... | ... | @@ -462,62 +472,20 @@ |
462 | 472 | "nand lock [tight] [status] - bring nand to lock state or display locked pages\n" |
463 | 473 | "nand unlock [offset] [size] - unlock section\n"); |
464 | 474 | |
465 | -int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | |
475 | +static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, | |
476 | + ulong offset, ulong addr, char *cmd) | |
466 | 477 | { |
467 | - char *boot_device = NULL; | |
468 | - char *ep; | |
469 | - int dev; | |
470 | 478 | int r; |
471 | - ulong addr, cnt, offset = 0; | |
479 | + char *ep; | |
480 | + ulong cnt; | |
472 | 481 | image_header_t *hdr; |
473 | - nand_info_t *nand; | |
474 | 482 | |
475 | - switch (argc) { | |
476 | - case 1: | |
477 | - addr = CFG_LOAD_ADDR; | |
478 | - boot_device = getenv("bootdevice"); | |
479 | - break; | |
480 | - case 2: | |
481 | - addr = simple_strtoul(argv[1], NULL, 16); | |
482 | - boot_device = getenv("bootdevice"); | |
483 | - break; | |
484 | - case 3: | |
485 | - addr = simple_strtoul(argv[1], NULL, 16); | |
486 | - boot_device = argv[2]; | |
487 | - break; | |
488 | - case 4: | |
489 | - addr = simple_strtoul(argv[1], NULL, 16); | |
490 | - boot_device = argv[2]; | |
491 | - offset = simple_strtoul(argv[3], NULL, 16); | |
492 | - break; | |
493 | - default: | |
494 | - printf("Usage:\n%s\n", cmdtp->usage); | |
495 | - SHOW_BOOT_PROGRESS(-1); | |
496 | - return 1; | |
497 | - } | |
483 | + printf("\nLoading from %s, offset 0x%lx\n", nand->name, offset); | |
498 | 484 | |
499 | - if (!boot_device) { | |
500 | - puts("\n** No boot device **\n"); | |
501 | - SHOW_BOOT_PROGRESS(-1); | |
502 | - return 1; | |
503 | - } | |
504 | - | |
505 | - dev = simple_strtoul(boot_device, &ep, 16); | |
506 | - | |
507 | - if (dev < 0 || dev >= CFG_MAX_NAND_DEVICE || !nand_info[dev].name) { | |
508 | - printf("\n** Device %d not available\n", dev); | |
509 | - SHOW_BOOT_PROGRESS(-1); | |
510 | - return 1; | |
511 | - } | |
512 | - | |
513 | - nand = &nand_info[dev]; | |
514 | - printf("\nLoading from device %d: %s (offset 0x%lx)\n", | |
515 | - dev, nand->name, offset); | |
516 | - | |
517 | 485 | cnt = nand->oobblock; |
518 | 486 | r = nand_read(nand, offset, &cnt, (u_char *) addr); |
519 | 487 | if (r) { |
520 | - printf("** Read error on %d\n", dev); | |
488 | + puts("** Read error\n"); | |
521 | 489 | SHOW_BOOT_PROGRESS(-1); |
522 | 490 | return 1; |
523 | 491 | } |
... | ... | @@ -536,7 +504,7 @@ |
536 | 504 | |
537 | 505 | r = nand_read(nand, offset, &cnt, (u_char *) addr); |
538 | 506 | if (r) { |
539 | - printf("** Read error on %d\n", dev); | |
507 | + puts("** Read error\n"); | |
540 | 508 | SHOW_BOOT_PROGRESS(-1); |
541 | 509 | return 1; |
542 | 510 | } |
... | ... | @@ -550,7 +518,7 @@ |
550 | 518 | char *local_args[2]; |
551 | 519 | extern int do_bootm(cmd_tbl_t *, int, int, char *[]); |
552 | 520 | |
553 | - local_args[0] = argv[0]; | |
521 | + local_args[0] = cmd; | |
554 | 522 | local_args[1] = NULL; |
555 | 523 | |
556 | 524 | printf("Automatic boot of image at addr 0x%08lx ...\n", addr); |
557 | 525 | |
... | ... | @@ -561,9 +529,83 @@ |
561 | 529 | return 0; |
562 | 530 | } |
563 | 531 | |
564 | -U_BOOT_CMD(nboot, 4, 1, do_nandboot, | |
565 | - "nboot - boot from NAND device\n", "loadAddr dev\n"); | |
532 | +int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | |
533 | +{ | |
534 | + char *boot_device = NULL; | |
535 | + int idx; | |
536 | + ulong addr, offset = 0; | |
537 | +#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE) | |
538 | + struct mtd_device *dev; | |
539 | + struct part_info *part; | |
540 | + u8 pnum; | |
566 | 541 | |
542 | + if (argc >= 2) { | |
543 | + char *p = (argc == 2) ? argv[1] : argv[2]; | |
544 | + if (!(str2long(p, &addr)) && (mtdparts_init() == 0) && | |
545 | + (find_dev_and_part(p, &dev, &pnum, &part) == 0)) { | |
546 | + if (dev->id->type != MTD_DEV_TYPE_NAND) { | |
547 | + puts("Not a NAND device\n"); | |
548 | + return 1; | |
549 | + } | |
550 | + if (argc > 3) | |
551 | + goto usage; | |
552 | + if (argc == 3) | |
553 | + addr = simple_strtoul(argv[2], NULL, 16); | |
554 | + else | |
555 | + addr = CFG_LOAD_ADDR; | |
556 | + return nand_load_image(cmdtp, &nand_info[dev->id->num], | |
557 | + part->offset, addr, argv[0]); | |
558 | + } | |
559 | + } | |
560 | +#endif | |
561 | + | |
562 | + switch (argc) { | |
563 | + case 1: | |
564 | + addr = CFG_LOAD_ADDR; | |
565 | + boot_device = getenv("bootdevice"); | |
566 | + break; | |
567 | + case 2: | |
568 | + addr = simple_strtoul(argv[1], NULL, 16); | |
569 | + boot_device = getenv("bootdevice"); | |
570 | + break; | |
571 | + case 3: | |
572 | + addr = simple_strtoul(argv[1], NULL, 16); | |
573 | + boot_device = argv[2]; | |
574 | + break; | |
575 | + case 4: | |
576 | + addr = simple_strtoul(argv[1], NULL, 16); | |
577 | + boot_device = argv[2]; | |
578 | + offset = simple_strtoul(argv[3], NULL, 16); | |
579 | + break; | |
580 | + default: | |
581 | +#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE) | |
582 | +usage: | |
583 | +#endif | |
584 | + printf("Usage:\n%s\n", cmdtp->usage); | |
585 | + SHOW_BOOT_PROGRESS(-1); | |
586 | + return 1; | |
587 | + } | |
588 | + | |
589 | + if (!boot_device) { | |
590 | + puts("\n** No boot device **\n"); | |
591 | + SHOW_BOOT_PROGRESS(-1); | |
592 | + return 1; | |
593 | + } | |
594 | + | |
595 | + idx = simple_strtoul(boot_device, NULL, 16); | |
596 | + | |
597 | + if (idx < 0 || idx >= CFG_MAX_NAND_DEVICE || !nand_info[idx].name) { | |
598 | + printf("\n** Device %d not available\n", idx); | |
599 | + SHOW_BOOT_PROGRESS(-1); | |
600 | + return 1; | |
601 | + } | |
602 | + | |
603 | + return nand_load_image(cmdtp, &nand_info[idx], offset, addr, argv[0]); | |
604 | +} | |
605 | + | |
606 | +U_BOOT_CMD(nboot, 4, 1, do_nandboot, | |
607 | + "nboot - boot from NAND device\n", | |
608 | + "[partition] | [[[loadAddr] dev] offset]\n"); | |
567 | 609 | |
568 | 610 | #endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */ |
569 | 611 |
doc/README.nand
... | ... | @@ -34,14 +34,19 @@ |
34 | 34 | nand device num |
35 | 35 | Make device `num' the current device and print information about it. |
36 | 36 | |
37 | - nand erase off size | |
38 | - nand erase clean [off size] | |
39 | - Erase `size' bytes starting at offset `off'. Only complete erase | |
40 | - blocks can be erased. | |
37 | + nand erase off|partition size | |
38 | + nand erase clean [off|partition size] | |
39 | + Erase `size' bytes starting at offset `off'. Alternatively partition | |
40 | + name can be specified, in this case size will be eventually limited | |
41 | + to not exceed partition size (this behaviour applies also to read | |
42 | + and write commands). Only complete erase blocks can be erased. | |
41 | 43 | |
44 | + If `erase' is specified without an offset or size, the entire flash | |
45 | + is erased. If `erase' is specified with partition but without an | |
46 | + size, the entire partition is erased. | |
47 | + | |
42 | 48 | If `clean' is specified, a JFFS2-style clean marker is written to |
43 | - each block after it is erased. If `clean' is specified without an | |
44 | - offset or size, the entire flash is erased. | |
49 | + each block after it is erased. | |
45 | 50 | |
46 | 51 | This command will not erase blocks that are marked bad. There is |
47 | 52 | a debug option in cmd_nand.c to allow bad blocks to be erased. |
48 | 53 | |
49 | 54 | |
50 | 55 | |
51 | 56 | |
... | ... | @@ -51,28 +56,28 @@ |
51 | 56 | nand info |
52 | 57 | Print information about all of the NAND devices found. |
53 | 58 | |
54 | - nand read addr ofs size | |
59 | + nand read addr ofs|partition size | |
55 | 60 | Read `size' bytes from `ofs' in NAND flash to `addr'. If a page |
56 | 61 | cannot be read because it is marked bad or an uncorrectable data |
57 | 62 | error is found the command stops with an error. |
58 | 63 | |
59 | - nand read.jffs2 addr ofs size | |
64 | + nand read.jffs2 addr ofs|partition size | |
60 | 65 | Like `read', but the data for blocks that are marked bad is read as |
61 | 66 | 0xff. This gives a readable JFFS2 image that can be processed by |
62 | 67 | the JFFS2 commands such as ls and fsload. |
63 | 68 | |
64 | - nand read.oob addr ofs size | |
69 | + nand read.oob addr ofs|partition size | |
65 | 70 | Read `size' bytes from the out-of-band data area corresponding to |
66 | 71 | `ofs' in NAND flash to `addr'. This is limited to the 16 bytes of |
67 | 72 | data for one 512-byte page or 2 256-byte pages. There is no check |
68 | 73 | for bad blocks or ECC errors. |
69 | 74 | |
70 | - nand write addr ofs size | |
75 | + nand write addr ofs|partition size | |
71 | 76 | Write `size' bytes from `addr' to `ofs' in NAND flash. If a page |
72 | 77 | cannot be written because it is marked bad or the write fails the |
73 | 78 | command stops with an error. |
74 | 79 | |
75 | - nand write.jffs2 addr ofs size | |
80 | + nand write.jffs2 addr ofs|partition size | |
76 | 81 | Like `write', but blocks that are marked bad are skipped and the |
77 | 82 | is written to the next block instead. This allows writing writing |
78 | 83 | a JFFS2 image, as long as the image is short enough to fit even |
... | ... | @@ -80,7 +85,7 @@ |
80 | 85 | produced by mkfs.jffs2 should work well, but loading an image copied |
81 | 86 | from another flash is going to be trouble if there are any bad blocks. |
82 | 87 | |
83 | - nand write.oob addr ofs size | |
88 | + nand write.oob addr ofs|partition size | |
84 | 89 | Write `size' bytes from `addr' to the out-of-band data area |
85 | 90 | corresponding to `ofs' in NAND flash. This is limited to the 16 bytes |
86 | 91 | of data for one 512-byte page or 2 256-byte pages. There is no check |
drivers/nand/nand_util.c
... | ... | @@ -83,15 +83,8 @@ |
83 | 83 | |
84 | 84 | erase.mtd = meminfo; |
85 | 85 | erase.len = meminfo->erasesize; |
86 | - if (opts->offset == 0 && opts->length == 0) { | |
87 | - /* erase complete chip */ | |
88 | - erase.addr = 0; | |
89 | - erase_length = meminfo->size; | |
90 | - } else { | |
91 | - /* erase specified region */ | |
92 | - erase.addr = opts->offset; | |
93 | - erase_length = opts->length; | |
94 | - } | |
86 | + erase.addr = opts->offset; | |
87 | + erase_length = opts->length; | |
95 | 88 | |
96 | 89 | isNAND = meminfo->type == MTD_NANDFLASH ? 1 : 0; |
97 | 90 |