Commit 8cd852824d91e232f1f820a0772c3c1d8af84b05
Committed by
Wolfgang Denk
1 parent
3882d7a5a5
Exists in
master
and in
54 other branches
cmd_onenand.c: moved to standard subcommand handling
On the fly also fixed the following things: - write help talked about a parameter oob, but that one was not used, so removed it from the help message. - the test command also allowed a force subcommand but didn't use it. eliminated the code. - do_onenand made static - do_onenand contained int blocksize; ... mtd = &onenand_mtd; this = mtd->priv; blocksize = (1 << this->erase_shift); As blocksize was not used the last two statements were unneeded so removed them. The first statement (mtd = ....) assigns to a global. Not sure if it is needed, and since I could not test this, left the line for now Signed-off-by: Frans Meulenbroeks <fransmeulenbroeks@gmail.com>
Showing 1 changed file with 192 additions and 115 deletions Side-by-side Diff
common/cmd_onenand.c
... | ... | @@ -330,163 +330,240 @@ |
330 | 330 | return 0; |
331 | 331 | } |
332 | 332 | |
333 | -int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | |
333 | +static int do_onenand_info(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | |
334 | 334 | { |
335 | - struct onenand_chip *this; | |
336 | - int blocksize; | |
335 | + printf("%s\n", mtd->name); | |
336 | + return 0; | |
337 | +} | |
338 | + | |
339 | +static int do_onenand_bad(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | |
340 | +{ | |
341 | + ulong ofs; | |
342 | + | |
343 | + mtd = &onenand_mtd; | |
344 | + /* Currently only one OneNAND device is supported */ | |
345 | + printf("\nDevice %d bad blocks:\n", 0); | |
346 | + for (ofs = 0; ofs < mtd->size; ofs += mtd->erasesize) { | |
347 | + if (mtd->block_isbad(mtd, ofs)) | |
348 | + printf(" %08x\n", (u32)ofs); | |
349 | + } | |
350 | + | |
351 | + return 0; | |
352 | +} | |
353 | + | |
354 | +static int do_onenand_read(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | |
355 | +{ | |
356 | + char *s; | |
357 | + int oob = 0; | |
337 | 358 | ulong addr, ofs; |
338 | - size_t len, retlen = 0; | |
359 | + size_t len; | |
339 | 360 | int ret = 0; |
340 | - char *cmd, *s; | |
361 | + size_t retlen = 0; | |
341 | 362 | |
342 | - mtd = &onenand_mtd; | |
343 | - this = mtd->priv; | |
344 | - blocksize = (1 << this->erase_shift); | |
363 | + if (argc < 3) | |
364 | + { | |
365 | + cmd_usage(cmdtp); | |
366 | + return 1; | |
367 | + } | |
345 | 368 | |
346 | - cmd = argv[1]; | |
369 | + s = strchr(argv[0], '.'); | |
370 | + if ((s != NULL) && (!strcmp(s, ".oob"))) | |
371 | + oob = 1; | |
347 | 372 | |
348 | - switch (argc) { | |
349 | - case 0: | |
350 | - case 1: | |
351 | - goto usage; | |
373 | + addr = (ulong)simple_strtoul(argv[1], NULL, 16); | |
352 | 374 | |
353 | - case 2: | |
354 | - if (strcmp(cmd, "info") == 0) { | |
355 | - printf("%s\n", mtd->name); | |
356 | - return 0; | |
357 | - } | |
375 | + printf("\nOneNAND read: "); | |
376 | + if (arg_off_size(argc - 2, argv + 2, &ofs, &len) != 0) | |
377 | + return 1; | |
358 | 378 | |
359 | - if (strcmp(cmd, "bad") == 0) { | |
360 | - /* Currently only one OneNAND device is supported */ | |
361 | - printf("\nDevice %d bad blocks:\n", 0); | |
362 | - for (ofs = 0; ofs < mtd->size; ofs += mtd->erasesize) { | |
363 | - if (mtd->block_isbad(mtd, ofs)) | |
364 | - printf(" %08x\n", (u32)ofs); | |
365 | - } | |
379 | + ret = onenand_block_read(ofs, len, &retlen, (u8 *)addr, oob); | |
366 | 380 | |
367 | - return 0; | |
368 | - } | |
381 | + printf(" %d bytes read: %s\n", retlen, ret ? "ERROR" : "OK"); | |
369 | 382 | |
370 | - default: | |
371 | - /* At least 4 args */ | |
383 | + return ret == 0 ? 0 : 1; | |
384 | +} | |
372 | 385 | |
373 | - /* | |
374 | - * Syntax is: | |
375 | - * 0 1 2 3 4 | |
376 | - * onenand erase [force] [off size] | |
377 | - */ | |
378 | - if ((strcmp(cmd, "erase") == 0) || (strcmp(cmd, "test") == 0)) { | |
379 | - int force = argc > 2 && !strcmp("force", argv[2]); | |
380 | - int o = force ? 3 : 2; | |
381 | - int erase; | |
386 | +static int do_onenand_write(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | |
387 | +{ | |
388 | + ulong addr, ofs; | |
389 | + size_t len; | |
390 | + int ret = 0; | |
391 | + size_t retlen = 0; | |
382 | 392 | |
383 | - erase = strcmp(cmd, "erase") == 0; /* 1 = erase, 0 = test */ | |
384 | - printf("\nOneNAND %s: ", erase ? "erase" : "test"); | |
393 | + if (argc < 3) | |
394 | + { | |
395 | + cmd_usage(cmdtp); | |
396 | + return 1; | |
397 | + } | |
385 | 398 | |
386 | - /* skip first two or three arguments, look for offset and size */ | |
387 | - if (arg_off_size(argc - o, argv + o, &ofs, &len) != 0) | |
388 | - return 1; | |
399 | + addr = (ulong)simple_strtoul(argv[1], NULL, 16); | |
389 | 400 | |
390 | - if (erase) | |
391 | - ret = onenand_block_erase(ofs, len, force); | |
392 | - else | |
393 | - ret = onenand_block_test(ofs, len); | |
401 | + printf("\nOneNAND write: "); | |
402 | + if (arg_off_size(argc - 2, argv + 2, &ofs, &len) != 0) | |
403 | + return 1; | |
394 | 404 | |
395 | - printf("%s\n", ret ? "ERROR" : "OK"); | |
405 | + ret = onenand_block_write(ofs, len, &retlen, (u8 *)addr); | |
396 | 406 | |
397 | - return ret == 0 ? 0 : 1; | |
407 | + printf(" %d bytes written: %s\n", retlen, ret ? "ERROR" : "OK"); | |
408 | + | |
409 | + return ret == 0 ? 0 : 1; | |
410 | +} | |
411 | + | |
412 | +static int do_onenand_erase(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | |
413 | +{ | |
414 | + ulong ofs; | |
415 | + int ret = 0; | |
416 | + size_t len; | |
417 | + int force; | |
418 | + | |
419 | + /* | |
420 | + * Syntax is: | |
421 | + * 0 1 2 3 4 | |
422 | + * onenand erase [force] [off size] | |
423 | + */ | |
424 | + argc--; | |
425 | + argv++; | |
426 | + if (argc) | |
427 | + { | |
428 | + if (!strcmp("force", argv[0])) | |
429 | + { | |
430 | + force = 1; | |
431 | + argc--; | |
432 | + argv++; | |
398 | 433 | } |
434 | + } | |
435 | + printf("\nOneNAND erase: "); | |
399 | 436 | |
400 | - if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) { | |
401 | - int read; | |
402 | - int oob = 0; | |
437 | + /* skip first two or three arguments, look for offset and size */ | |
438 | + if (arg_off_size(argc, argv, &ofs, &len) != 0) | |
439 | + return 1; | |
403 | 440 | |
404 | - if (argc < 4) | |
405 | - goto usage; | |
441 | + ret = onenand_block_erase(ofs, len, force); | |
406 | 442 | |
407 | - addr = (ulong)simple_strtoul(argv[2], NULL, 16); | |
443 | + printf("%s\n", ret ? "ERROR" : "OK"); | |
408 | 444 | |
409 | - read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */ | |
410 | - printf("\nOneNAND %s: ", read ? "read" : "write"); | |
411 | - if (arg_off_size(argc - 3, argv + 3, &ofs, &len) != 0) | |
412 | - return 1; | |
445 | + return ret == 0 ? 0 : 1; | |
446 | +} | |
413 | 447 | |
414 | - s = strchr(cmd, '.'); | |
415 | - if ((s != NULL) && (!strcmp(s, ".oob"))) | |
416 | - oob = 1; | |
448 | +static int do_onenand_test(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | |
449 | +{ | |
450 | + ulong ofs; | |
451 | + int ret = 0; | |
452 | + size_t len; | |
417 | 453 | |
418 | - if (read) { | |
419 | - ret = onenand_block_read(ofs, len, &retlen, | |
420 | - (u8 *)addr, oob); | |
421 | - } else { | |
422 | - ret = onenand_block_write(ofs, len, &retlen, | |
423 | - (u8 *)addr); | |
424 | - } | |
454 | + /* | |
455 | + * Syntax is: | |
456 | + * 0 1 2 3 4 | |
457 | + * onenand test [force] [off size] | |
458 | + */ | |
425 | 459 | |
426 | - printf(" %d bytes %s: %s\n", retlen, | |
427 | - read ? "read" : "written", ret ? "ERROR" : "OK"); | |
460 | + printf("\nOneNAND test: "); | |
428 | 461 | |
429 | - return ret == 0 ? 0 : 1; | |
430 | - } | |
462 | + /* skip first two or three arguments, look for offset and size */ | |
463 | + if (arg_off_size(argc - 1, argv + 1, &ofs, &len) != 0) | |
464 | + return 1; | |
431 | 465 | |
432 | - if (strcmp(cmd, "markbad") == 0) { | |
433 | - argc -= 2; | |
434 | - argv += 2; | |
466 | + ret = onenand_block_test(ofs, len); | |
435 | 467 | |
436 | - if (argc <= 0) | |
437 | - goto usage; | |
468 | + printf("%s\n", ret ? "ERROR" : "OK"); | |
438 | 469 | |
439 | - while (argc > 0) { | |
440 | - addr = simple_strtoul(*argv, NULL, 16); | |
470 | + return ret == 0 ? 0 : 1; | |
471 | +} | |
441 | 472 | |
442 | - if (mtd->block_markbad(mtd, addr)) { | |
443 | - printf("block 0x%08lx NOT marked " | |
444 | - "as bad! ERROR %d\n", | |
445 | - addr, ret); | |
446 | - ret = 1; | |
447 | - } else { | |
448 | - printf("block 0x%08lx successfully " | |
449 | - "marked as bad\n", | |
450 | - addr); | |
451 | - } | |
452 | - --argc; | |
453 | - ++argv; | |
454 | - } | |
455 | - return ret; | |
456 | - } | |
473 | +static int do_onenand_dump(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | |
474 | +{ | |
475 | + ulong ofs; | |
476 | + int ret = 0; | |
477 | + char *s; | |
457 | 478 | |
458 | - if (strncmp(cmd, "dump", 4) == 0) { | |
459 | - if (argc < 3) | |
460 | - goto usage; | |
479 | + if (argc < 2) | |
480 | + { | |
481 | + cmd_usage(cmdtp); | |
482 | + return 1; | |
483 | + } | |
461 | 484 | |
462 | - s = strchr(cmd, '.'); | |
463 | - ofs = (int)simple_strtoul(argv[2], NULL, 16); | |
485 | + s = strchr(argv[0], '.'); | |
486 | + ofs = (int)simple_strtoul(argv[1], NULL, 16); | |
464 | 487 | |
465 | - if (s != NULL && strcmp(s, ".oob") == 0) | |
466 | - ret = onenand_dump(mtd, ofs, 1); | |
467 | - else | |
468 | - ret = onenand_dump(mtd, ofs, 0); | |
488 | + if (s != NULL && strcmp(s, ".oob") == 0) | |
489 | + ret = onenand_dump(mtd, ofs, 1); | |
490 | + else | |
491 | + ret = onenand_dump(mtd, ofs, 0); | |
469 | 492 | |
470 | - return ret == 0 ? 1 : 0; | |
471 | - } | |
493 | + return ret == 0 ? 1 : 0; | |
494 | +} | |
472 | 495 | |
473 | - break; | |
496 | +static int do_onenand_markbad(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | |
497 | +{ | |
498 | + int ret = 0; | |
499 | + ulong addr; | |
500 | + | |
501 | + argc -= 2; | |
502 | + argv += 2; | |
503 | + | |
504 | + if (argc <= 0) | |
505 | + { | |
506 | + cmd_usage(cmdtp); | |
507 | + return 1; | |
474 | 508 | } |
475 | 509 | |
476 | - return 0; | |
510 | + while (argc > 0) { | |
511 | + addr = simple_strtoul(*argv, NULL, 16); | |
477 | 512 | |
478 | -usage: | |
479 | - cmd_usage(cmdtp); | |
480 | - return 1; | |
513 | + if (mtd->block_markbad(mtd, addr)) { | |
514 | + printf("block 0x%08lx NOT marked " | |
515 | + "as bad! ERROR %d\n", | |
516 | + addr, ret); | |
517 | + ret = 1; | |
518 | + } else { | |
519 | + printf("block 0x%08lx successfully " | |
520 | + "marked as bad\n", | |
521 | + addr); | |
522 | + } | |
523 | + --argc; | |
524 | + ++argv; | |
525 | + } | |
526 | + return ret; | |
481 | 527 | } |
482 | 528 | |
529 | +static cmd_tbl_t cmd_onenand_sub[] = { | |
530 | + U_BOOT_CMD_MKENT(info, 1, 0, do_onenand_info, "", ""), | |
531 | + U_BOOT_CMD_MKENT(bad, 1, 0, do_onenand_bad, "", ""), | |
532 | + U_BOOT_CMD_MKENT(read, 4, 0, do_onenand_read, "", ""), | |
533 | + U_BOOT_CMD_MKENT(write, 4, 0, do_onenand_write, "", ""), | |
534 | + U_BOOT_CMD_MKENT(erase, 3, 0, do_onenand_erase, "", ""), | |
535 | + U_BOOT_CMD_MKENT(test, 3, 0, do_onenand_test, "", ""), | |
536 | + U_BOOT_CMD_MKENT(dump, 2, 0, do_onenand_dump, "", ""), | |
537 | + U_BOOT_CMD_MKENT(markbad, CONFIG_SYS_MAXARGS, 0, do_onenand_markbad, "", ""), | |
538 | +}; | |
539 | + | |
540 | +static int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | |
541 | +{ | |
542 | + cmd_tbl_t *c; | |
543 | + | |
544 | + mtd = &onenand_mtd; | |
545 | + | |
546 | + /* Strip off leading 'onenand' command argument */ | |
547 | + argc--; | |
548 | + argv++; | |
549 | + | |
550 | + c = find_cmd_tbl(argv[0], &cmd_onenand_sub[0], ARRAY_SIZE(cmd_onenand_sub)); | |
551 | + | |
552 | + if (c) { | |
553 | + return c->cmd(cmdtp, flag, argc, argv); | |
554 | + } else { | |
555 | + cmd_usage(cmdtp); | |
556 | + return 1; | |
557 | + } | |
558 | +} | |
559 | + | |
483 | 560 | U_BOOT_CMD( |
484 | 561 | onenand, CONFIG_SYS_MAXARGS, 1, do_onenand, |
485 | 562 | "OneNAND sub-system", |
486 | 563 | "info - show available OneNAND devices\n" |
487 | 564 | "onenand bad - show bad blocks\n" |
488 | 565 | "onenand read[.oob] addr off size\n" |
489 | - "onenand write[.oob] addr off size\n" | |
566 | + "onenand write addr off size\n" | |
490 | 567 | " read/write 'size' bytes starting at offset 'off'\n" |
491 | 568 | " to/from memory address 'addr', skipping bad blocks.\n" |
492 | 569 | "onenand erase [force] [off size] - erase 'size' bytes from\n" |