diff options
author | Boris Brezillon <boris.brezillon@free-electrons.com> | 2016-08-15 19:22:01 -0400 |
---|---|---|
committer | Boris Brezillon <boris.brezillon@free-electrons.com> | 2016-09-23 03:35:16 -0400 |
commit | c3baf278d3bf8d628df0b28aa4921c5457d40211 (patch) | |
tree | 114a342f131c90b268b03da8edd9dd3e70dffc2a /drivers/mtd | |
parent | 57d419a42c501713fd023bc21f8798c14ad4e005 (diff) |
mtd: nand_bbt: Move BBT block selection logic out of write_bbt()
This clarifies the write_bbt() function by removing the write label
and simplifying the error/exit path.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Tested-by: Kyle Roeschley <kyle.roeschley@ni.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/nand/nand_bbt.c | 110 |
1 files changed, 74 insertions, 36 deletions
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 2fbb523df066..9fbd66482403 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c | |||
@@ -605,6 +605,69 @@ static void search_read_bbts(struct mtd_info *mtd, uint8_t *buf, | |||
605 | } | 605 | } |
606 | 606 | ||
607 | /** | 607 | /** |
608 | * get_bbt_block - Get the first valid eraseblock suitable to store a BBT | ||
609 | * @this: the NAND device | ||
610 | * @td: the BBT description | ||
611 | * @md: the mirror BBT descriptor | ||
612 | * @chip: the CHIP selector | ||
613 | * | ||
614 | * This functions returns a positive block number pointing a valid eraseblock | ||
615 | * suitable to store a BBT (i.e. in the range reserved for BBT), or -ENOSPC if | ||
616 | * all blocks are already used of marked bad. If td->pages[chip] was already | ||
617 | * pointing to a valid block we re-use it, otherwise we search for the next | ||
618 | * valid one. | ||
619 | */ | ||
620 | static int get_bbt_block(struct nand_chip *this, struct nand_bbt_descr *td, | ||
621 | struct nand_bbt_descr *md, int chip) | ||
622 | { | ||
623 | int startblock, dir, page, numblocks, i; | ||
624 | |||
625 | /* | ||
626 | * There was already a version of the table, reuse the page. This | ||
627 | * applies for absolute placement too, as we have the page number in | ||
628 | * td->pages. | ||
629 | */ | ||
630 | if (td->pages[chip] != -1) | ||
631 | return td->pages[chip] >> | ||
632 | (this->bbt_erase_shift - this->page_shift); | ||
633 | |||
634 | numblocks = (int)(this->chipsize >> this->bbt_erase_shift); | ||
635 | if (!(td->options & NAND_BBT_PERCHIP)) | ||
636 | numblocks *= this->numchips; | ||
637 | |||
638 | /* | ||
639 | * Automatic placement of the bad block table. Search direction | ||
640 | * top -> down? | ||
641 | */ | ||
642 | if (td->options & NAND_BBT_LASTBLOCK) { | ||
643 | startblock = numblocks * (chip + 1) - 1; | ||
644 | dir = -1; | ||
645 | } else { | ||
646 | startblock = chip * numblocks; | ||
647 | dir = 1; | ||
648 | } | ||
649 | |||
650 | for (i = 0; i < td->maxblocks; i++) { | ||
651 | int block = startblock + dir * i; | ||
652 | |||
653 | /* Check, if the block is bad */ | ||
654 | switch (bbt_get_entry(this, block)) { | ||
655 | case BBT_BLOCK_WORN: | ||
656 | case BBT_BLOCK_FACTORY_BAD: | ||
657 | continue; | ||
658 | } | ||
659 | |||
660 | page = block << (this->bbt_erase_shift - this->page_shift); | ||
661 | |||
662 | /* Check, if the block is used by the mirror table */ | ||
663 | if (!md || md->pages[chip] != page) | ||
664 | return block; | ||
665 | } | ||
666 | |||
667 | return -ENOSPC; | ||
668 | } | ||
669 | |||
670 | /** | ||
608 | * write_bbt - [GENERIC] (Re)write the bad block table | 671 | * write_bbt - [GENERIC] (Re)write the bad block table |
609 | * @mtd: MTD device structure | 672 | * @mtd: MTD device structure |
610 | * @buf: temporary buffer | 673 | * @buf: temporary buffer |
@@ -621,7 +684,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, | |||
621 | struct nand_chip *this = mtd_to_nand(mtd); | 684 | struct nand_chip *this = mtd_to_nand(mtd); |
622 | struct erase_info einfo; | 685 | struct erase_info einfo; |
623 | int i, res, chip = 0; | 686 | int i, res, chip = 0; |
624 | int bits, startblock, dir, page, offs, numblocks, sft, sftmsk; | 687 | int bits, page, offs, numblocks, sft, sftmsk; |
625 | int nrchips, pageoffs, ooboffs; | 688 | int nrchips, pageoffs, ooboffs; |
626 | uint8_t msk[4]; | 689 | uint8_t msk[4]; |
627 | uint8_t rcode = td->reserved_block_code; | 690 | uint8_t rcode = td->reserved_block_code; |
@@ -653,45 +716,20 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, | |||
653 | 716 | ||
654 | /* Loop through the chips */ | 717 | /* Loop through the chips */ |
655 | for (; chip < nrchips; chip++) { | 718 | for (; chip < nrchips; chip++) { |
656 | /* | 719 | int block; |
657 | * There was already a version of the table, reuse the page | 720 | |
658 | * This applies for absolute placement too, as we have the | 721 | block = get_bbt_block(this, td, md, chip); |
659 | * page nr. in td->pages. | 722 | if (block < 0) { |
660 | */ | 723 | pr_err("No space left to write bad block table\n"); |
661 | if (td->pages[chip] != -1) { | 724 | res = block; |
662 | page = td->pages[chip]; | 725 | goto outerr; |
663 | goto write; | ||
664 | } | 726 | } |
665 | 727 | ||
666 | /* | 728 | /* |
667 | * Automatic placement of the bad block table. Search direction | 729 | * get_bbt_block() returns a block number, shift the value to |
668 | * top -> down? | 730 | * get a page number. |
669 | */ | 731 | */ |
670 | if (td->options & NAND_BBT_LASTBLOCK) { | 732 | page = block << (this->bbt_erase_shift - this->page_shift); |
671 | startblock = numblocks * (chip + 1) - 1; | ||
672 | dir = -1; | ||
673 | } else { | ||
674 | startblock = chip * numblocks; | ||
675 | dir = 1; | ||
676 | } | ||
677 | |||
678 | for (i = 0; i < td->maxblocks; i++) { | ||
679 | int block = startblock + dir * i; | ||
680 | /* Check, if the block is bad */ | ||
681 | switch (bbt_get_entry(this, block)) { | ||
682 | case BBT_BLOCK_WORN: | ||
683 | case BBT_BLOCK_FACTORY_BAD: | ||
684 | continue; | ||
685 | } | ||
686 | page = block << | ||
687 | (this->bbt_erase_shift - this->page_shift); | ||
688 | /* Check, if the block is used by the mirror table */ | ||
689 | if (!md || md->pages[chip] != page) | ||
690 | goto write; | ||
691 | } | ||
692 | pr_err("No space left to write bad block table\n"); | ||
693 | return -ENOSPC; | ||
694 | write: | ||
695 | 733 | ||
696 | /* Set up shift count and masks for the flash table */ | 734 | /* Set up shift count and masks for the flash table */ |
697 | bits = td->options & NAND_BBT_NRBITS_MSK; | 735 | bits = td->options & NAND_BBT_NRBITS_MSK; |