Commit 47fc18f1e72ef1fc68a179c2b674a4c58646afc9

Authored by Lei Wen
Committed by Scott Wood
1 parent 7fab9dfffa

NAND: add the ability to directly write yaffs image

This patch add addition suffix to nand write to give the uboot
the power to directly burn the yaffs image to nand.

Signed-off-by: Lei Wen <leiwen@marvell.com>

Showing 3 changed files with 70 additions and 10 deletions Side-by-side Diff

... ... @@ -574,7 +574,15 @@
574 574 (u_char *)addr);
575 575 else
576 576 ret = nand_write_skip_bad(nand, off, &rwsize,
577   - (u_char *)addr);
  577 + (u_char *)addr, 0);
  578 +#ifdef CONFIG_CMD_NAND_YAFFS
  579 + } else if (!strcmp(s, ".yaffs")) {
  580 + if (read) {
  581 + printf("Unknown nand command suffix '%s'.\n", s);
  582 + return 1;
  583 + }
  584 + ret = nand_write_skip_bad(nand, off, &rwsize, (u_char *)addr, 1);
  585 +#endif
578 586 } else if (!strcmp(s, ".oob")) {
579 587 /* out-of-band data */
580 588 mtd_oob_ops_t ops = {
... ... @@ -680,6 +688,11 @@
680 688 "nand write - addr off|partition size\n"
681 689 " read/write 'size' bytes starting at offset 'off'\n"
682 690 " to/from memory address 'addr', skipping bad blocks.\n"
  691 +#ifdef CONFIG_CMD_NAND_YAFFS
  692 + "nand write.yaffs - addr off|partition size\n"
  693 + " write 'size' bytes starting at offset 'off' with yaffs format\n"
  694 + " from memory address 'addr', skipping bad blocks.\n"
  695 +#endif
683 696 "nand erase[.spread] [clean] [off [size]] - erase 'size' bytes "
684 697 "from offset 'off'\n"
685 698 " With '.spread', erase enough for given file size, otherwise,\n"
drivers/mtd/nand/nand_util.c
... ... @@ -447,17 +447,34 @@
447 447 * @param nand NAND device
448 448 * @param offset offset in flash
449 449 * @param length buffer length
450   - * @param buf buffer to read from
  450 + * @param buffer buffer to read from
  451 + * @param withoob whether write with yaffs format
451 452 * @return 0 in case of success
452 453 */
453 454 int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
454   - u_char *buffer)
  455 + u_char *buffer, int withoob)
455 456 {
456   - int rval;
  457 + int rval = 0, blocksize;
457 458 size_t left_to_write = *length;
458 459 u_char *p_buffer = buffer;
459 460 int need_skip;
460 461  
  462 +#ifdef CONFIG_CMD_NAND_YAFFS
  463 + if (withoob) {
  464 + int pages;
  465 + pages = nand->erasesize / nand->writesize;
  466 + blocksize = (pages * nand->oobsize) + nand->erasesize;
  467 + if (*length % (nand->writesize + nand->oobsize)) {
  468 + printf ("Attempt to write incomplete page"
  469 + " in yaffs mode\n");
  470 + return -EINVAL;
  471 + }
  472 + } else
  473 +#endif
  474 + {
  475 + blocksize = nand->erasesize;
  476 + }
  477 +
461 478 /*
462 479 * nand_write() handles unaligned, partial page writes.
463 480 *
464 481  
465 482  
... ... @@ -506,12 +523,44 @@
506 523 continue;
507 524 }
508 525  
509   - if (left_to_write < (nand->erasesize - block_offset))
  526 + if (left_to_write < (blocksize - block_offset))
510 527 write_size = left_to_write;
511 528 else
512   - write_size = nand->erasesize - block_offset;
  529 + write_size = blocksize - block_offset;
513 530  
514   - rval = nand_write (nand, offset, &write_size, p_buffer);
  531 +#ifdef CONFIG_CMD_NAND_YAFFS
  532 + if (withoob) {
  533 + int page, pages;
  534 + size_t pagesize = nand->writesize;
  535 + size_t pagesize_oob = pagesize + nand->oobsize;
  536 + struct mtd_oob_ops ops;
  537 +
  538 + ops.len = pagesize;
  539 + ops.ooblen = nand->oobsize;
  540 + ops.mode = MTD_OOB_AUTO;
  541 + ops.ooboffs = 0;
  542 +
  543 + pages = write_size / pagesize_oob;
  544 + for (page = 0; page < pages; page++) {
  545 + ops.datbuf = p_buffer;
  546 + ops.oobbuf = ops.datbuf + pagesize;
  547 +
  548 + rval = nand->write_oob(nand, offset, &ops);
  549 + if (!rval)
  550 + break;
  551 +
  552 + offset += pagesize;
  553 + p_buffer += pagesize_oob;
  554 + }
  555 + }
  556 + else
  557 +#endif
  558 + {
  559 + rval = nand_write (nand, offset, &write_size, p_buffer);
  560 + offset += write_size;
  561 + p_buffer += write_size;
  562 + }
  563 +
515 564 if (rval != 0) {
516 565 printf ("NAND write to offset %llx failed %d\n",
517 566 offset, rval);
... ... @@ -520,8 +569,6 @@
520 569 }
521 570  
522 571 left_to_write -= write_size;
523   - offset += write_size;
524   - p_buffer += write_size;
525 572 }
526 573  
527 574 return 0;
... ... @@ -115,7 +115,7 @@
115 115 int nand_read_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
116 116 u_char *buffer);
117 117 int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
118   - u_char *buffer);
  118 + u_char *buffer, int withoob);
119 119 int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts);
120 120  
121 121 #define NAND_LOCK_STATUS_TIGHT 0x01