1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 293db446aSBoris Brezillon /* 393db446aSBoris Brezillon * Overview: 493db446aSBoris Brezillon * Bad block table support for the NAND driver 593db446aSBoris Brezillon * 693db446aSBoris Brezillon * Copyright © 2004 Thomas Gleixner (tglx@linutronix.de) 793db446aSBoris Brezillon * 893db446aSBoris Brezillon * Description: 993db446aSBoris Brezillon * 1093db446aSBoris Brezillon * When nand_scan_bbt is called, then it tries to find the bad block table 1193db446aSBoris Brezillon * depending on the options in the BBT descriptor(s). If no flash based BBT 1293db446aSBoris Brezillon * (NAND_BBT_USE_FLASH) is specified then the device is scanned for factory 1393db446aSBoris Brezillon * marked good / bad blocks. This information is used to create a memory BBT. 1493db446aSBoris Brezillon * Once a new bad block is discovered then the "factory" information is updated 1593db446aSBoris Brezillon * on the device. 1693db446aSBoris Brezillon * If a flash based BBT is specified then the function first tries to find the 1793db446aSBoris Brezillon * BBT on flash. If a BBT is found then the contents are read and the memory 1893db446aSBoris Brezillon * based BBT is created. If a mirrored BBT is selected then the mirror is 1993db446aSBoris Brezillon * searched too and the versions are compared. If the mirror has a greater 2093db446aSBoris Brezillon * version number, then the mirror BBT is used to build the memory based BBT. 2193db446aSBoris Brezillon * If the tables are not versioned, then we "or" the bad block information. 2293db446aSBoris Brezillon * If one of the BBTs is out of date or does not exist it is (re)created. 2393db446aSBoris Brezillon * If no BBT exists at all then the device is scanned for factory marked 2493db446aSBoris Brezillon * good / bad blocks and the bad block tables are created. 2593db446aSBoris Brezillon * 2693db446aSBoris Brezillon * For manufacturer created BBTs like the one found on M-SYS DOC devices 2793db446aSBoris Brezillon * the BBT is searched and read but never created 2893db446aSBoris Brezillon * 2993db446aSBoris Brezillon * The auto generated bad block table is located in the last good blocks 3093db446aSBoris Brezillon * of the device. The table is mirrored, so it can be updated eventually. 3193db446aSBoris Brezillon * The table is marked in the OOB area with an ident pattern and a version 3293db446aSBoris Brezillon * number which indicates which of both tables is more up to date. If the NAND 3393db446aSBoris Brezillon * controller needs the complete OOB area for the ECC information then the 3493db446aSBoris Brezillon * option NAND_BBT_NO_OOB should be used (along with NAND_BBT_USE_FLASH, of 3593db446aSBoris Brezillon * course): it moves the ident pattern and the version byte into the data area 3693db446aSBoris Brezillon * and the OOB area will remain untouched. 3793db446aSBoris Brezillon * 3893db446aSBoris Brezillon * The table uses 2 bits per block 3993db446aSBoris Brezillon * 11b: block is good 4093db446aSBoris Brezillon * 00b: block is factory marked bad 4193db446aSBoris Brezillon * 01b, 10b: block is marked bad due to wear 4293db446aSBoris Brezillon * 4393db446aSBoris Brezillon * The memory bad block table uses the following scheme: 4493db446aSBoris Brezillon * 00b: block is good 4593db446aSBoris Brezillon * 01b: block is marked bad due to wear 4693db446aSBoris Brezillon * 10b: block is reserved (to protect the bbt area) 4793db446aSBoris Brezillon * 11b: block is factory marked bad 4893db446aSBoris Brezillon * 4993db446aSBoris Brezillon * Multichip devices like DOC store the bad block info per floor. 5093db446aSBoris Brezillon * 5193db446aSBoris Brezillon * Following assumptions are made: 5293db446aSBoris Brezillon * - bbts start at a page boundary, if autolocated on a block boundary 5393db446aSBoris Brezillon * - the space necessary for a bbt in FLASH does not exceed a block boundary 5493db446aSBoris Brezillon */ 5593db446aSBoris Brezillon 5693db446aSBoris Brezillon #include <linux/slab.h> 5793db446aSBoris Brezillon #include <linux/types.h> 5893db446aSBoris Brezillon #include <linux/mtd/mtd.h> 5993db446aSBoris Brezillon #include <linux/mtd/bbm.h> 6093db446aSBoris Brezillon #include <linux/bitops.h> 6193db446aSBoris Brezillon #include <linux/delay.h> 6293db446aSBoris Brezillon #include <linux/vmalloc.h> 6393db446aSBoris Brezillon #include <linux/export.h> 6493db446aSBoris Brezillon #include <linux/string.h> 6593db446aSBoris Brezillon 66348d56a8SBoris Brezillon #include "internals.h" 67348d56a8SBoris Brezillon 6893db446aSBoris Brezillon #define BBT_BLOCK_GOOD 0x00 6993db446aSBoris Brezillon #define BBT_BLOCK_WORN 0x01 7093db446aSBoris Brezillon #define BBT_BLOCK_RESERVED 0x02 7193db446aSBoris Brezillon #define BBT_BLOCK_FACTORY_BAD 0x03 7293db446aSBoris Brezillon 7393db446aSBoris Brezillon #define BBT_ENTRY_MASK 0x03 7493db446aSBoris Brezillon #define BBT_ENTRY_SHIFT 2 7593db446aSBoris Brezillon 7693db446aSBoris Brezillon static inline uint8_t bbt_get_entry(struct nand_chip *chip, int block) 7793db446aSBoris Brezillon { 7893db446aSBoris Brezillon uint8_t entry = chip->bbt[block >> BBT_ENTRY_SHIFT]; 7993db446aSBoris Brezillon entry >>= (block & BBT_ENTRY_MASK) * 2; 8093db446aSBoris Brezillon return entry & BBT_ENTRY_MASK; 8193db446aSBoris Brezillon } 8293db446aSBoris Brezillon 8393db446aSBoris Brezillon static inline void bbt_mark_entry(struct nand_chip *chip, int block, 8493db446aSBoris Brezillon uint8_t mark) 8593db446aSBoris Brezillon { 8693db446aSBoris Brezillon uint8_t msk = (mark & BBT_ENTRY_MASK) << ((block & BBT_ENTRY_MASK) * 2); 8793db446aSBoris Brezillon chip->bbt[block >> BBT_ENTRY_SHIFT] |= msk; 8893db446aSBoris Brezillon } 8993db446aSBoris Brezillon 9093db446aSBoris Brezillon static int check_pattern_no_oob(uint8_t *buf, struct nand_bbt_descr *td) 9193db446aSBoris Brezillon { 9293db446aSBoris Brezillon if (memcmp(buf, td->pattern, td->len)) 9393db446aSBoris Brezillon return -1; 9493db446aSBoris Brezillon return 0; 9593db446aSBoris Brezillon } 9693db446aSBoris Brezillon 9793db446aSBoris Brezillon /** 9893db446aSBoris Brezillon * check_pattern - [GENERIC] check if a pattern is in the buffer 9993db446aSBoris Brezillon * @buf: the buffer to search 10093db446aSBoris Brezillon * @len: the length of buffer to search 10193db446aSBoris Brezillon * @paglen: the pagelength 10293db446aSBoris Brezillon * @td: search pattern descriptor 10393db446aSBoris Brezillon * 10493db446aSBoris Brezillon * Check for a pattern at the given place. Used to search bad block tables and 10593db446aSBoris Brezillon * good / bad block identifiers. 10693db446aSBoris Brezillon */ 10793db446aSBoris Brezillon static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td) 10893db446aSBoris Brezillon { 10993db446aSBoris Brezillon if (td->options & NAND_BBT_NO_OOB) 11093db446aSBoris Brezillon return check_pattern_no_oob(buf, td); 11193db446aSBoris Brezillon 11293db446aSBoris Brezillon /* Compare the pattern */ 11393db446aSBoris Brezillon if (memcmp(buf + paglen + td->offs, td->pattern, td->len)) 11493db446aSBoris Brezillon return -1; 11593db446aSBoris Brezillon 11693db446aSBoris Brezillon return 0; 11793db446aSBoris Brezillon } 11893db446aSBoris Brezillon 11993db446aSBoris Brezillon /** 12093db446aSBoris Brezillon * check_short_pattern - [GENERIC] check if a pattern is in the buffer 12193db446aSBoris Brezillon * @buf: the buffer to search 12293db446aSBoris Brezillon * @td: search pattern descriptor 12393db446aSBoris Brezillon * 12493db446aSBoris Brezillon * Check for a pattern at the given place. Used to search bad block tables and 12593db446aSBoris Brezillon * good / bad block identifiers. Same as check_pattern, but no optional empty 12693db446aSBoris Brezillon * check. 12793db446aSBoris Brezillon */ 12893db446aSBoris Brezillon static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td) 12993db446aSBoris Brezillon { 13093db446aSBoris Brezillon /* Compare the pattern */ 13193db446aSBoris Brezillon if (memcmp(buf + td->offs, td->pattern, td->len)) 13293db446aSBoris Brezillon return -1; 13393db446aSBoris Brezillon return 0; 13493db446aSBoris Brezillon } 13593db446aSBoris Brezillon 13693db446aSBoris Brezillon /** 13793db446aSBoris Brezillon * add_marker_len - compute the length of the marker in data area 13893db446aSBoris Brezillon * @td: BBT descriptor used for computation 13993db446aSBoris Brezillon * 14093db446aSBoris Brezillon * The length will be 0 if the marker is located in OOB area. 14193db446aSBoris Brezillon */ 14293db446aSBoris Brezillon static u32 add_marker_len(struct nand_bbt_descr *td) 14393db446aSBoris Brezillon { 14493db446aSBoris Brezillon u32 len; 14593db446aSBoris Brezillon 14693db446aSBoris Brezillon if (!(td->options & NAND_BBT_NO_OOB)) 14793db446aSBoris Brezillon return 0; 14893db446aSBoris Brezillon 14993db446aSBoris Brezillon len = td->len; 15093db446aSBoris Brezillon if (td->options & NAND_BBT_VERSION) 15193db446aSBoris Brezillon len++; 15293db446aSBoris Brezillon return len; 15393db446aSBoris Brezillon } 15493db446aSBoris Brezillon 15593db446aSBoris Brezillon /** 15693db446aSBoris Brezillon * read_bbt - [GENERIC] Read the bad block table starting from page 157455e7b38SRandy Dunlap * @this: NAND chip object 15893db446aSBoris Brezillon * @buf: temporary buffer 15993db446aSBoris Brezillon * @page: the starting page 16093db446aSBoris Brezillon * @num: the number of bbt descriptors to read 16193db446aSBoris Brezillon * @td: the bbt describtion table 16293db446aSBoris Brezillon * @offs: block number offset in the table 16393db446aSBoris Brezillon * 16493db446aSBoris Brezillon * Read the bad block table starting from page. 16593db446aSBoris Brezillon */ 1660813621bSBoris Brezillon static int read_bbt(struct nand_chip *this, uint8_t *buf, int page, int num, 16793db446aSBoris Brezillon struct nand_bbt_descr *td, int offs) 16893db446aSBoris Brezillon { 1690813621bSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(this); 17093db446aSBoris Brezillon int res, ret = 0, i, j, act = 0; 17193db446aSBoris Brezillon size_t retlen, len, totlen; 17293db446aSBoris Brezillon loff_t from; 17393db446aSBoris Brezillon int bits = td->options & NAND_BBT_NRBITS_MSK; 17493db446aSBoris Brezillon uint8_t msk = (uint8_t)((1 << bits) - 1); 17593db446aSBoris Brezillon u32 marker_len; 17693db446aSBoris Brezillon int reserved_block_code = td->reserved_block_code; 17793db446aSBoris Brezillon 17893db446aSBoris Brezillon totlen = (num * bits) >> 3; 17993db446aSBoris Brezillon marker_len = add_marker_len(td); 18093db446aSBoris Brezillon from = ((loff_t)page) << this->page_shift; 18193db446aSBoris Brezillon 18293db446aSBoris Brezillon while (totlen) { 18393db446aSBoris Brezillon len = min(totlen, (size_t)(1 << this->bbt_erase_shift)); 18493db446aSBoris Brezillon if (marker_len) { 18593db446aSBoris Brezillon /* 18693db446aSBoris Brezillon * In case the BBT marker is not in the OOB area it 18793db446aSBoris Brezillon * will be just in the first page. 18893db446aSBoris Brezillon */ 18993db446aSBoris Brezillon len -= marker_len; 19093db446aSBoris Brezillon from += marker_len; 19193db446aSBoris Brezillon marker_len = 0; 19293db446aSBoris Brezillon } 19393db446aSBoris Brezillon res = mtd_read(mtd, from, len, &retlen, buf); 19493db446aSBoris Brezillon if (res < 0) { 19593db446aSBoris Brezillon if (mtd_is_eccerr(res)) { 19693db446aSBoris Brezillon pr_info("nand_bbt: ECC error in BBT at 0x%012llx\n", 19793db446aSBoris Brezillon from & ~mtd->writesize); 19893db446aSBoris Brezillon return res; 19993db446aSBoris Brezillon } else if (mtd_is_bitflip(res)) { 20093db446aSBoris Brezillon pr_info("nand_bbt: corrected error in BBT at 0x%012llx\n", 20193db446aSBoris Brezillon from & ~mtd->writesize); 20293db446aSBoris Brezillon ret = res; 20393db446aSBoris Brezillon } else { 20493db446aSBoris Brezillon pr_info("nand_bbt: error reading BBT\n"); 20593db446aSBoris Brezillon return res; 20693db446aSBoris Brezillon } 20793db446aSBoris Brezillon } 20893db446aSBoris Brezillon 20993db446aSBoris Brezillon /* Analyse data */ 21093db446aSBoris Brezillon for (i = 0; i < len; i++) { 21193db446aSBoris Brezillon uint8_t dat = buf[i]; 21293db446aSBoris Brezillon for (j = 0; j < 8; j += bits, act++) { 21393db446aSBoris Brezillon uint8_t tmp = (dat >> j) & msk; 21493db446aSBoris Brezillon if (tmp == msk) 21593db446aSBoris Brezillon continue; 21693db446aSBoris Brezillon if (reserved_block_code && (tmp == reserved_block_code)) { 21793db446aSBoris Brezillon pr_info("nand_read_bbt: reserved block at 0x%012llx\n", 21893db446aSBoris Brezillon (loff_t)(offs + act) << 21993db446aSBoris Brezillon this->bbt_erase_shift); 22093db446aSBoris Brezillon bbt_mark_entry(this, offs + act, 22193db446aSBoris Brezillon BBT_BLOCK_RESERVED); 22293db446aSBoris Brezillon mtd->ecc_stats.bbtblocks++; 22393db446aSBoris Brezillon continue; 22493db446aSBoris Brezillon } 22593db446aSBoris Brezillon /* 22693db446aSBoris Brezillon * Leave it for now, if it's matured we can 22793db446aSBoris Brezillon * move this message to pr_debug. 22893db446aSBoris Brezillon */ 22993db446aSBoris Brezillon pr_info("nand_read_bbt: bad block at 0x%012llx\n", 23093db446aSBoris Brezillon (loff_t)(offs + act) << 23193db446aSBoris Brezillon this->bbt_erase_shift); 23293db446aSBoris Brezillon /* Factory marked bad or worn out? */ 23393db446aSBoris Brezillon if (tmp == 0) 23493db446aSBoris Brezillon bbt_mark_entry(this, offs + act, 23593db446aSBoris Brezillon BBT_BLOCK_FACTORY_BAD); 23693db446aSBoris Brezillon else 23793db446aSBoris Brezillon bbt_mark_entry(this, offs + act, 23893db446aSBoris Brezillon BBT_BLOCK_WORN); 23993db446aSBoris Brezillon mtd->ecc_stats.badblocks++; 24093db446aSBoris Brezillon } 24193db446aSBoris Brezillon } 24293db446aSBoris Brezillon totlen -= len; 24393db446aSBoris Brezillon from += len; 24493db446aSBoris Brezillon } 24593db446aSBoris Brezillon return ret; 24693db446aSBoris Brezillon } 24793db446aSBoris Brezillon 24893db446aSBoris Brezillon /** 24993db446aSBoris Brezillon * read_abs_bbt - [GENERIC] Read the bad block table starting at a given page 2500813621bSBoris Brezillon * @this: NAND chip object 25193db446aSBoris Brezillon * @buf: temporary buffer 25293db446aSBoris Brezillon * @td: descriptor for the bad block table 25393db446aSBoris Brezillon * @chip: read the table for a specific chip, -1 read all chips; applies only if 25493db446aSBoris Brezillon * NAND_BBT_PERCHIP option is set 25593db446aSBoris Brezillon * 25693db446aSBoris Brezillon * Read the bad block table for all chips starting at a given page. We assume 25793db446aSBoris Brezillon * that the bbt bits are in consecutive order. 25893db446aSBoris Brezillon */ 2590813621bSBoris Brezillon static int read_abs_bbt(struct nand_chip *this, uint8_t *buf, 2600813621bSBoris Brezillon struct nand_bbt_descr *td, int chip) 26193db446aSBoris Brezillon { 2620813621bSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(this); 2636c836d51SBoris Brezillon u64 targetsize = nanddev_target_size(&this->base); 26493db446aSBoris Brezillon int res = 0, i; 26593db446aSBoris Brezillon 26693db446aSBoris Brezillon if (td->options & NAND_BBT_PERCHIP) { 26793db446aSBoris Brezillon int offs = 0; 26832813e28SBoris Brezillon for (i = 0; i < nanddev_ntargets(&this->base); i++) { 26993db446aSBoris Brezillon if (chip == -1 || chip == i) 2700813621bSBoris Brezillon res = read_bbt(this, buf, td->pages[i], 2716c836d51SBoris Brezillon targetsize >> this->bbt_erase_shift, 27293db446aSBoris Brezillon td, offs); 27393db446aSBoris Brezillon if (res) 27493db446aSBoris Brezillon return res; 2756c836d51SBoris Brezillon offs += targetsize >> this->bbt_erase_shift; 27693db446aSBoris Brezillon } 27793db446aSBoris Brezillon } else { 2780813621bSBoris Brezillon res = read_bbt(this, buf, td->pages[0], 27993db446aSBoris Brezillon mtd->size >> this->bbt_erase_shift, td, 0); 28093db446aSBoris Brezillon if (res) 28193db446aSBoris Brezillon return res; 28293db446aSBoris Brezillon } 28393db446aSBoris Brezillon return 0; 28493db446aSBoris Brezillon } 28593db446aSBoris Brezillon 28693db446aSBoris Brezillon /* BBT marker is in the first page, no OOB */ 2870813621bSBoris Brezillon static int scan_read_data(struct nand_chip *this, uint8_t *buf, loff_t offs, 28893db446aSBoris Brezillon struct nand_bbt_descr *td) 28993db446aSBoris Brezillon { 2900813621bSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(this); 29193db446aSBoris Brezillon size_t retlen; 29293db446aSBoris Brezillon size_t len; 29393db446aSBoris Brezillon 29493db446aSBoris Brezillon len = td->len; 29593db446aSBoris Brezillon if (td->options & NAND_BBT_VERSION) 29693db446aSBoris Brezillon len++; 29793db446aSBoris Brezillon 29893db446aSBoris Brezillon return mtd_read(mtd, offs, len, &retlen, buf); 29993db446aSBoris Brezillon } 30093db446aSBoris Brezillon 30193db446aSBoris Brezillon /** 30293db446aSBoris Brezillon * scan_read_oob - [GENERIC] Scan data+OOB region to buffer 3030813621bSBoris Brezillon * @this: NAND chip object 30493db446aSBoris Brezillon * @buf: temporary buffer 30593db446aSBoris Brezillon * @offs: offset at which to scan 30693db446aSBoris Brezillon * @len: length of data region to read 30793db446aSBoris Brezillon * 30893db446aSBoris Brezillon * Scan read data from data+OOB. May traverse multiple pages, interleaving 30993db446aSBoris Brezillon * page,OOB,page,OOB,... in buf. Completes transfer and returns the "strongest" 31093db446aSBoris Brezillon * ECC condition (error or bitflip). May quit on the first (non-ECC) error. 31193db446aSBoris Brezillon */ 3120813621bSBoris Brezillon static int scan_read_oob(struct nand_chip *this, uint8_t *buf, loff_t offs, 31393db446aSBoris Brezillon size_t len) 31493db446aSBoris Brezillon { 3150813621bSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(this); 31693db446aSBoris Brezillon struct mtd_oob_ops ops; 31793db446aSBoris Brezillon int res, ret = 0; 31893db446aSBoris Brezillon 31993db446aSBoris Brezillon ops.mode = MTD_OPS_PLACE_OOB; 32093db446aSBoris Brezillon ops.ooboffs = 0; 32193db446aSBoris Brezillon ops.ooblen = mtd->oobsize; 32293db446aSBoris Brezillon 32393db446aSBoris Brezillon while (len > 0) { 32493db446aSBoris Brezillon ops.datbuf = buf; 32593db446aSBoris Brezillon ops.len = min(len, (size_t)mtd->writesize); 32693db446aSBoris Brezillon ops.oobbuf = buf + ops.len; 32793db446aSBoris Brezillon 32893db446aSBoris Brezillon res = mtd_read_oob(mtd, offs, &ops); 32993db446aSBoris Brezillon if (res) { 33093db446aSBoris Brezillon if (!mtd_is_bitflip_or_eccerr(res)) 33193db446aSBoris Brezillon return res; 33293db446aSBoris Brezillon else if (mtd_is_eccerr(res) || !ret) 33393db446aSBoris Brezillon ret = res; 33493db446aSBoris Brezillon } 33593db446aSBoris Brezillon 33693db446aSBoris Brezillon buf += mtd->oobsize + mtd->writesize; 33793db446aSBoris Brezillon len -= mtd->writesize; 33893db446aSBoris Brezillon offs += mtd->writesize; 33993db446aSBoris Brezillon } 34093db446aSBoris Brezillon return ret; 34193db446aSBoris Brezillon } 34293db446aSBoris Brezillon 3430813621bSBoris Brezillon static int scan_read(struct nand_chip *this, uint8_t *buf, loff_t offs, 34493db446aSBoris Brezillon size_t len, struct nand_bbt_descr *td) 34593db446aSBoris Brezillon { 34693db446aSBoris Brezillon if (td->options & NAND_BBT_NO_OOB) 3470813621bSBoris Brezillon return scan_read_data(this, buf, offs, td); 34893db446aSBoris Brezillon else 3490813621bSBoris Brezillon return scan_read_oob(this, buf, offs, len); 35093db446aSBoris Brezillon } 35193db446aSBoris Brezillon 35293db446aSBoris Brezillon /* Scan write data with oob to flash */ 3530813621bSBoris Brezillon static int scan_write_bbt(struct nand_chip *this, loff_t offs, size_t len, 35493db446aSBoris Brezillon uint8_t *buf, uint8_t *oob) 35593db446aSBoris Brezillon { 3560813621bSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(this); 35793db446aSBoris Brezillon struct mtd_oob_ops ops; 35893db446aSBoris Brezillon 35993db446aSBoris Brezillon ops.mode = MTD_OPS_PLACE_OOB; 36093db446aSBoris Brezillon ops.ooboffs = 0; 36193db446aSBoris Brezillon ops.ooblen = mtd->oobsize; 36293db446aSBoris Brezillon ops.datbuf = buf; 36393db446aSBoris Brezillon ops.oobbuf = oob; 36493db446aSBoris Brezillon ops.len = len; 36593db446aSBoris Brezillon 36693db446aSBoris Brezillon return mtd_write_oob(mtd, offs, &ops); 36793db446aSBoris Brezillon } 36893db446aSBoris Brezillon 3690813621bSBoris Brezillon static u32 bbt_get_ver_offs(struct nand_chip *this, struct nand_bbt_descr *td) 37093db446aSBoris Brezillon { 3710813621bSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(this); 37293db446aSBoris Brezillon u32 ver_offs = td->veroffs; 37393db446aSBoris Brezillon 37493db446aSBoris Brezillon if (!(td->options & NAND_BBT_NO_OOB)) 37593db446aSBoris Brezillon ver_offs += mtd->writesize; 37693db446aSBoris Brezillon return ver_offs; 37793db446aSBoris Brezillon } 37893db446aSBoris Brezillon 37993db446aSBoris Brezillon /** 38093db446aSBoris Brezillon * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page 3810813621bSBoris Brezillon * @this: NAND chip object 38293db446aSBoris Brezillon * @buf: temporary buffer 38393db446aSBoris Brezillon * @td: descriptor for the bad block table 38493db446aSBoris Brezillon * @md: descriptor for the bad block table mirror 38593db446aSBoris Brezillon * 38693db446aSBoris Brezillon * Read the bad block table(s) for all chips starting at a given page. We 38793db446aSBoris Brezillon * assume that the bbt bits are in consecutive order. 38893db446aSBoris Brezillon */ 3890813621bSBoris Brezillon static void read_abs_bbts(struct nand_chip *this, uint8_t *buf, 39093db446aSBoris Brezillon struct nand_bbt_descr *td, struct nand_bbt_descr *md) 39193db446aSBoris Brezillon { 3920813621bSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(this); 39393db446aSBoris Brezillon 39493db446aSBoris Brezillon /* Read the primary version, if available */ 39593db446aSBoris Brezillon if (td->options & NAND_BBT_VERSION) { 3960813621bSBoris Brezillon scan_read(this, buf, (loff_t)td->pages[0] << this->page_shift, 39793db446aSBoris Brezillon mtd->writesize, td); 3980813621bSBoris Brezillon td->version[0] = buf[bbt_get_ver_offs(this, td)]; 39993db446aSBoris Brezillon pr_info("Bad block table at page %d, version 0x%02X\n", 40093db446aSBoris Brezillon td->pages[0], td->version[0]); 40193db446aSBoris Brezillon } 40293db446aSBoris Brezillon 40393db446aSBoris Brezillon /* Read the mirror version, if available */ 40493db446aSBoris Brezillon if (md && (md->options & NAND_BBT_VERSION)) { 4050813621bSBoris Brezillon scan_read(this, buf, (loff_t)md->pages[0] << this->page_shift, 40693db446aSBoris Brezillon mtd->writesize, md); 4070813621bSBoris Brezillon md->version[0] = buf[bbt_get_ver_offs(this, md)]; 40893db446aSBoris Brezillon pr_info("Bad block table at page %d, version 0x%02X\n", 40993db446aSBoris Brezillon md->pages[0], md->version[0]); 41093db446aSBoris Brezillon } 41193db446aSBoris Brezillon } 41293db446aSBoris Brezillon 41393db446aSBoris Brezillon /* Scan a given block partially */ 4140813621bSBoris Brezillon static int scan_block_fast(struct nand_chip *this, struct nand_bbt_descr *bd, 415f90da781SFrieder Schrempf loff_t offs, uint8_t *buf) 41693db446aSBoris Brezillon { 4170813621bSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(this); 418f90da781SFrieder Schrempf 41993db446aSBoris Brezillon struct mtd_oob_ops ops; 420f90da781SFrieder Schrempf int ret, page_offset; 42193db446aSBoris Brezillon 42293db446aSBoris Brezillon ops.ooblen = mtd->oobsize; 42393db446aSBoris Brezillon ops.oobbuf = buf; 42493db446aSBoris Brezillon ops.ooboffs = 0; 42593db446aSBoris Brezillon ops.datbuf = NULL; 42693db446aSBoris Brezillon ops.mode = MTD_OPS_PLACE_OOB; 42793db446aSBoris Brezillon 428f90da781SFrieder Schrempf page_offset = nand_bbm_get_next_page(this, 0); 429f90da781SFrieder Schrempf 430f90da781SFrieder Schrempf while (page_offset >= 0) { 43193db446aSBoris Brezillon /* 43293db446aSBoris Brezillon * Read the full oob until read_oob is fixed to handle single 43393db446aSBoris Brezillon * byte reads for 16 bit buswidth. 43493db446aSBoris Brezillon */ 435f90da781SFrieder Schrempf ret = mtd_read_oob(mtd, offs + (page_offset * mtd->writesize), 436f90da781SFrieder Schrempf &ops); 43793db446aSBoris Brezillon /* Ignore ECC errors when checking for BBM */ 43893db446aSBoris Brezillon if (ret && !mtd_is_bitflip_or_eccerr(ret)) 43993db446aSBoris Brezillon return ret; 44093db446aSBoris Brezillon 44193db446aSBoris Brezillon if (check_short_pattern(buf, bd)) 44293db446aSBoris Brezillon return 1; 44393db446aSBoris Brezillon 444f90da781SFrieder Schrempf page_offset = nand_bbm_get_next_page(this, page_offset + 1); 44593db446aSBoris Brezillon } 446f90da781SFrieder Schrempf 44793db446aSBoris Brezillon return 0; 44893db446aSBoris Brezillon } 44993db446aSBoris Brezillon 4501a57b13eSStefan Riedmueller /* Check if a potential BBT block is marked as bad */ 4511a57b13eSStefan Riedmueller static int bbt_block_checkbad(struct nand_chip *this, struct nand_bbt_descr *td, 4521a57b13eSStefan Riedmueller loff_t offs, uint8_t *buf) 4531a57b13eSStefan Riedmueller { 4541a57b13eSStefan Riedmueller struct nand_bbt_descr *bd = this->badblock_pattern; 4551a57b13eSStefan Riedmueller 4561a57b13eSStefan Riedmueller /* 4571a57b13eSStefan Riedmueller * No need to check for a bad BBT block if the BBM area overlaps with 4581a57b13eSStefan Riedmueller * the bad block table marker area in OOB since writing a BBM here 4591a57b13eSStefan Riedmueller * invalidates the bad block table marker anyway. 4601a57b13eSStefan Riedmueller */ 4611a57b13eSStefan Riedmueller if (!(td->options & NAND_BBT_NO_OOB) && 4621a57b13eSStefan Riedmueller td->offs >= bd->offs && td->offs < bd->offs + bd->len) 4631a57b13eSStefan Riedmueller return 0; 4641a57b13eSStefan Riedmueller 4651a57b13eSStefan Riedmueller /* 4661a57b13eSStefan Riedmueller * There is no point in checking for a bad block marker if writing 4671a57b13eSStefan Riedmueller * such marker is not supported 4681a57b13eSStefan Riedmueller */ 4691a57b13eSStefan Riedmueller if (this->bbt_options & NAND_BBT_NO_OOB_BBM || 4701a57b13eSStefan Riedmueller this->options & NAND_NO_BBM_QUIRK) 4711a57b13eSStefan Riedmueller return 0; 4721a57b13eSStefan Riedmueller 4731a57b13eSStefan Riedmueller if (scan_block_fast(this, bd, offs, buf) > 0) 4741a57b13eSStefan Riedmueller return 1; 4751a57b13eSStefan Riedmueller 4761a57b13eSStefan Riedmueller return 0; 4771a57b13eSStefan Riedmueller } 4781a57b13eSStefan Riedmueller 47993db446aSBoris Brezillon /** 48093db446aSBoris Brezillon * create_bbt - [GENERIC] Create a bad block table by scanning the device 4810813621bSBoris Brezillon * @this: NAND chip object 48293db446aSBoris Brezillon * @buf: temporary buffer 48393db446aSBoris Brezillon * @bd: descriptor for the good/bad block search pattern 48493db446aSBoris Brezillon * @chip: create the table for a specific chip, -1 read all chips; applies only 48593db446aSBoris Brezillon * if NAND_BBT_PERCHIP option is set 48693db446aSBoris Brezillon * 48793db446aSBoris Brezillon * Create a bad block table by scanning the device for the given good/bad block 48893db446aSBoris Brezillon * identify pattern. 48993db446aSBoris Brezillon */ 4900813621bSBoris Brezillon static int create_bbt(struct nand_chip *this, uint8_t *buf, 49193db446aSBoris Brezillon struct nand_bbt_descr *bd, int chip) 49293db446aSBoris Brezillon { 4936c836d51SBoris Brezillon u64 targetsize = nanddev_target_size(&this->base); 4940813621bSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(this); 495f90da781SFrieder Schrempf int i, numblocks, startblock; 49693db446aSBoris Brezillon loff_t from; 49793db446aSBoris Brezillon 49893db446aSBoris Brezillon pr_info("Scanning device for bad blocks\n"); 49993db446aSBoris Brezillon 50093db446aSBoris Brezillon if (chip == -1) { 50193db446aSBoris Brezillon numblocks = mtd->size >> this->bbt_erase_shift; 50293db446aSBoris Brezillon startblock = 0; 50393db446aSBoris Brezillon from = 0; 50493db446aSBoris Brezillon } else { 50532813e28SBoris Brezillon if (chip >= nanddev_ntargets(&this->base)) { 50693db446aSBoris Brezillon pr_warn("create_bbt(): chipnr (%d) > available chips (%d)\n", 50732813e28SBoris Brezillon chip + 1, nanddev_ntargets(&this->base)); 50893db446aSBoris Brezillon return -EINVAL; 50993db446aSBoris Brezillon } 5106c836d51SBoris Brezillon numblocks = targetsize >> this->bbt_erase_shift; 51193db446aSBoris Brezillon startblock = chip * numblocks; 51293db446aSBoris Brezillon numblocks += startblock; 51393db446aSBoris Brezillon from = (loff_t)startblock << this->bbt_erase_shift; 51493db446aSBoris Brezillon } 51593db446aSBoris Brezillon 51693db446aSBoris Brezillon for (i = startblock; i < numblocks; i++) { 51793db446aSBoris Brezillon int ret; 51893db446aSBoris Brezillon 51993db446aSBoris Brezillon BUG_ON(bd->options & NAND_BBT_NO_OOB); 52093db446aSBoris Brezillon 521f90da781SFrieder Schrempf ret = scan_block_fast(this, bd, from, buf); 52293db446aSBoris Brezillon if (ret < 0) 52393db446aSBoris Brezillon return ret; 52493db446aSBoris Brezillon 52593db446aSBoris Brezillon if (ret) { 52693db446aSBoris Brezillon bbt_mark_entry(this, i, BBT_BLOCK_FACTORY_BAD); 52793db446aSBoris Brezillon pr_warn("Bad eraseblock %d at 0x%012llx\n", 52893db446aSBoris Brezillon i, (unsigned long long)from); 52993db446aSBoris Brezillon mtd->ecc_stats.badblocks++; 53093db446aSBoris Brezillon } 53193db446aSBoris Brezillon 53293db446aSBoris Brezillon from += (1 << this->bbt_erase_shift); 53393db446aSBoris Brezillon } 53493db446aSBoris Brezillon return 0; 53593db446aSBoris Brezillon } 53693db446aSBoris Brezillon 53793db446aSBoris Brezillon /** 53893db446aSBoris Brezillon * search_bbt - [GENERIC] scan the device for a specific bad block table 5390813621bSBoris Brezillon * @this: NAND chip object 54093db446aSBoris Brezillon * @buf: temporary buffer 54193db446aSBoris Brezillon * @td: descriptor for the bad block table 54293db446aSBoris Brezillon * 54393db446aSBoris Brezillon * Read the bad block table by searching for a given ident pattern. Search is 54493db446aSBoris Brezillon * preformed either from the beginning up or from the end of the device 54593db446aSBoris Brezillon * downwards. The search starts always at the start of a block. If the option 54693db446aSBoris Brezillon * NAND_BBT_PERCHIP is given, each chip is searched for a bbt, which contains 54793db446aSBoris Brezillon * the bad block information of this chip. This is necessary to provide support 54893db446aSBoris Brezillon * for certain DOC devices. 54993db446aSBoris Brezillon * 55093db446aSBoris Brezillon * The bbt ident pattern resides in the oob area of the first page in a block. 55193db446aSBoris Brezillon */ 5520813621bSBoris Brezillon static int search_bbt(struct nand_chip *this, uint8_t *buf, 5530813621bSBoris Brezillon struct nand_bbt_descr *td) 55493db446aSBoris Brezillon { 5556c836d51SBoris Brezillon u64 targetsize = nanddev_target_size(&this->base); 5560813621bSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(this); 55793db446aSBoris Brezillon int i, chips; 55893db446aSBoris Brezillon int startblock, block, dir; 55993db446aSBoris Brezillon int scanlen = mtd->writesize + mtd->oobsize; 56093db446aSBoris Brezillon int bbtblocks; 56193db446aSBoris Brezillon int blocktopage = this->bbt_erase_shift - this->page_shift; 56293db446aSBoris Brezillon 56393db446aSBoris Brezillon /* Search direction top -> down? */ 56493db446aSBoris Brezillon if (td->options & NAND_BBT_LASTBLOCK) { 56593db446aSBoris Brezillon startblock = (mtd->size >> this->bbt_erase_shift) - 1; 56693db446aSBoris Brezillon dir = -1; 56793db446aSBoris Brezillon } else { 56893db446aSBoris Brezillon startblock = 0; 56993db446aSBoris Brezillon dir = 1; 57093db446aSBoris Brezillon } 57193db446aSBoris Brezillon 57293db446aSBoris Brezillon /* Do we have a bbt per chip? */ 57393db446aSBoris Brezillon if (td->options & NAND_BBT_PERCHIP) { 57432813e28SBoris Brezillon chips = nanddev_ntargets(&this->base); 5756c836d51SBoris Brezillon bbtblocks = targetsize >> this->bbt_erase_shift; 57693db446aSBoris Brezillon startblock &= bbtblocks - 1; 57793db446aSBoris Brezillon } else { 57893db446aSBoris Brezillon chips = 1; 57993db446aSBoris Brezillon bbtblocks = mtd->size >> this->bbt_erase_shift; 58093db446aSBoris Brezillon } 58193db446aSBoris Brezillon 58293db446aSBoris Brezillon for (i = 0; i < chips; i++) { 58393db446aSBoris Brezillon /* Reset version information */ 58493db446aSBoris Brezillon td->version[i] = 0; 58593db446aSBoris Brezillon td->pages[i] = -1; 58693db446aSBoris Brezillon /* Scan the maximum number of blocks */ 58793db446aSBoris Brezillon for (block = 0; block < td->maxblocks; block++) { 58893db446aSBoris Brezillon 58993db446aSBoris Brezillon int actblock = startblock + dir * block; 59093db446aSBoris Brezillon loff_t offs = (loff_t)actblock << this->bbt_erase_shift; 59193db446aSBoris Brezillon 5921a57b13eSStefan Riedmueller /* Check if block is marked bad */ 5931a57b13eSStefan Riedmueller if (bbt_block_checkbad(this, td, offs, buf)) 5941a57b13eSStefan Riedmueller continue; 5951a57b13eSStefan Riedmueller 59693db446aSBoris Brezillon /* Read first page */ 5970813621bSBoris Brezillon scan_read(this, buf, offs, mtd->writesize, td); 59893db446aSBoris Brezillon if (!check_pattern(buf, scanlen, mtd->writesize, td)) { 59993db446aSBoris Brezillon td->pages[i] = actblock << blocktopage; 60093db446aSBoris Brezillon if (td->options & NAND_BBT_VERSION) { 6010813621bSBoris Brezillon offs = bbt_get_ver_offs(this, td); 60293db446aSBoris Brezillon td->version[i] = buf[offs]; 60393db446aSBoris Brezillon } 60493db446aSBoris Brezillon break; 60593db446aSBoris Brezillon } 60693db446aSBoris Brezillon } 6076c836d51SBoris Brezillon startblock += targetsize >> this->bbt_erase_shift; 60893db446aSBoris Brezillon } 60993db446aSBoris Brezillon /* Check, if we found a bbt for each requested chip */ 61093db446aSBoris Brezillon for (i = 0; i < chips; i++) { 61193db446aSBoris Brezillon if (td->pages[i] == -1) 61293db446aSBoris Brezillon pr_warn("Bad block table not found for chip %d\n", i); 61393db446aSBoris Brezillon else 61493db446aSBoris Brezillon pr_info("Bad block table found at page %d, version 0x%02X\n", 61593db446aSBoris Brezillon td->pages[i], td->version[i]); 61693db446aSBoris Brezillon } 61793db446aSBoris Brezillon return 0; 61893db446aSBoris Brezillon } 61993db446aSBoris Brezillon 62093db446aSBoris Brezillon /** 62193db446aSBoris Brezillon * search_read_bbts - [GENERIC] scan the device for bad block table(s) 6220813621bSBoris Brezillon * @this: NAND chip object 62393db446aSBoris Brezillon * @buf: temporary buffer 62493db446aSBoris Brezillon * @td: descriptor for the bad block table 62593db446aSBoris Brezillon * @md: descriptor for the bad block table mirror 62693db446aSBoris Brezillon * 62793db446aSBoris Brezillon * Search and read the bad block table(s). 62893db446aSBoris Brezillon */ 6290813621bSBoris Brezillon static void search_read_bbts(struct nand_chip *this, uint8_t *buf, 63093db446aSBoris Brezillon struct nand_bbt_descr *td, 63193db446aSBoris Brezillon struct nand_bbt_descr *md) 63293db446aSBoris Brezillon { 63393db446aSBoris Brezillon /* Search the primary table */ 6340813621bSBoris Brezillon search_bbt(this, buf, td); 63593db446aSBoris Brezillon 63693db446aSBoris Brezillon /* Search the mirror table */ 63793db446aSBoris Brezillon if (md) 6380813621bSBoris Brezillon search_bbt(this, buf, md); 63993db446aSBoris Brezillon } 64093db446aSBoris Brezillon 64193db446aSBoris Brezillon /** 64293db446aSBoris Brezillon * get_bbt_block - Get the first valid eraseblock suitable to store a BBT 64393db446aSBoris Brezillon * @this: the NAND device 64493db446aSBoris Brezillon * @td: the BBT description 64593db446aSBoris Brezillon * @md: the mirror BBT descriptor 64693db446aSBoris Brezillon * @chip: the CHIP selector 64793db446aSBoris Brezillon * 64893db446aSBoris Brezillon * This functions returns a positive block number pointing a valid eraseblock 64993db446aSBoris Brezillon * suitable to store a BBT (i.e. in the range reserved for BBT), or -ENOSPC if 65093db446aSBoris Brezillon * all blocks are already used of marked bad. If td->pages[chip] was already 65193db446aSBoris Brezillon * pointing to a valid block we re-use it, otherwise we search for the next 65293db446aSBoris Brezillon * valid one. 65393db446aSBoris Brezillon */ 65493db446aSBoris Brezillon static int get_bbt_block(struct nand_chip *this, struct nand_bbt_descr *td, 65593db446aSBoris Brezillon struct nand_bbt_descr *md, int chip) 65693db446aSBoris Brezillon { 6576c836d51SBoris Brezillon u64 targetsize = nanddev_target_size(&this->base); 65893db446aSBoris Brezillon int startblock, dir, page, numblocks, i; 65993db446aSBoris Brezillon 66093db446aSBoris Brezillon /* 66193db446aSBoris Brezillon * There was already a version of the table, reuse the page. This 66293db446aSBoris Brezillon * applies for absolute placement too, as we have the page number in 66393db446aSBoris Brezillon * td->pages. 66493db446aSBoris Brezillon */ 66593db446aSBoris Brezillon if (td->pages[chip] != -1) 66693db446aSBoris Brezillon return td->pages[chip] >> 66793db446aSBoris Brezillon (this->bbt_erase_shift - this->page_shift); 66893db446aSBoris Brezillon 6696c836d51SBoris Brezillon numblocks = (int)(targetsize >> this->bbt_erase_shift); 67093db446aSBoris Brezillon if (!(td->options & NAND_BBT_PERCHIP)) 67132813e28SBoris Brezillon numblocks *= nanddev_ntargets(&this->base); 67293db446aSBoris Brezillon 67393db446aSBoris Brezillon /* 67493db446aSBoris Brezillon * Automatic placement of the bad block table. Search direction 67593db446aSBoris Brezillon * top -> down? 67693db446aSBoris Brezillon */ 67793db446aSBoris Brezillon if (td->options & NAND_BBT_LASTBLOCK) { 67893db446aSBoris Brezillon startblock = numblocks * (chip + 1) - 1; 67993db446aSBoris Brezillon dir = -1; 68093db446aSBoris Brezillon } else { 68193db446aSBoris Brezillon startblock = chip * numblocks; 68293db446aSBoris Brezillon dir = 1; 68393db446aSBoris Brezillon } 68493db446aSBoris Brezillon 68593db446aSBoris Brezillon for (i = 0; i < td->maxblocks; i++) { 68693db446aSBoris Brezillon int block = startblock + dir * i; 68793db446aSBoris Brezillon 68893db446aSBoris Brezillon /* Check, if the block is bad */ 68993db446aSBoris Brezillon switch (bbt_get_entry(this, block)) { 69093db446aSBoris Brezillon case BBT_BLOCK_WORN: 69193db446aSBoris Brezillon case BBT_BLOCK_FACTORY_BAD: 69293db446aSBoris Brezillon continue; 69393db446aSBoris Brezillon } 69493db446aSBoris Brezillon 69593db446aSBoris Brezillon page = block << (this->bbt_erase_shift - this->page_shift); 69693db446aSBoris Brezillon 69793db446aSBoris Brezillon /* Check, if the block is used by the mirror table */ 69893db446aSBoris Brezillon if (!md || md->pages[chip] != page) 69993db446aSBoris Brezillon return block; 70093db446aSBoris Brezillon } 70193db446aSBoris Brezillon 70293db446aSBoris Brezillon return -ENOSPC; 70393db446aSBoris Brezillon } 70493db446aSBoris Brezillon 70593db446aSBoris Brezillon /** 70693db446aSBoris Brezillon * mark_bbt_block_bad - Mark one of the block reserved for BBT bad 70793db446aSBoris Brezillon * @this: the NAND device 70893db446aSBoris Brezillon * @td: the BBT description 70993db446aSBoris Brezillon * @chip: the CHIP selector 71093db446aSBoris Brezillon * @block: the BBT block to mark 71193db446aSBoris Brezillon * 71293db446aSBoris Brezillon * Blocks reserved for BBT can become bad. This functions is an helper to mark 71393db446aSBoris Brezillon * such blocks as bad. It takes care of updating the in-memory BBT, marking the 71493db446aSBoris Brezillon * block as bad using a bad block marker and invalidating the associated 71593db446aSBoris Brezillon * td->pages[] entry. 71693db446aSBoris Brezillon */ 71793db446aSBoris Brezillon static void mark_bbt_block_bad(struct nand_chip *this, 71893db446aSBoris Brezillon struct nand_bbt_descr *td, 71993db446aSBoris Brezillon int chip, int block) 72093db446aSBoris Brezillon { 72193db446aSBoris Brezillon loff_t to; 72293db446aSBoris Brezillon int res; 72393db446aSBoris Brezillon 72493db446aSBoris Brezillon bbt_mark_entry(this, block, BBT_BLOCK_WORN); 72593db446aSBoris Brezillon 72693db446aSBoris Brezillon to = (loff_t)block << this->bbt_erase_shift; 727cdc784c7SBoris Brezillon res = nand_markbad_bbm(this, to); 72893db446aSBoris Brezillon if (res) 72993db446aSBoris Brezillon pr_warn("nand_bbt: error %d while marking block %d bad\n", 73093db446aSBoris Brezillon res, block); 73193db446aSBoris Brezillon 73293db446aSBoris Brezillon td->pages[chip] = -1; 73393db446aSBoris Brezillon } 73493db446aSBoris Brezillon 73593db446aSBoris Brezillon /** 73693db446aSBoris Brezillon * write_bbt - [GENERIC] (Re)write the bad block table 7370813621bSBoris Brezillon * @this: NAND chip object 73893db446aSBoris Brezillon * @buf: temporary buffer 73993db446aSBoris Brezillon * @td: descriptor for the bad block table 74093db446aSBoris Brezillon * @md: descriptor for the bad block table mirror 74193db446aSBoris Brezillon * @chipsel: selector for a specific chip, -1 for all 74293db446aSBoris Brezillon * 74393db446aSBoris Brezillon * (Re)write the bad block table. 74493db446aSBoris Brezillon */ 7450813621bSBoris Brezillon static int write_bbt(struct nand_chip *this, uint8_t *buf, 74693db446aSBoris Brezillon struct nand_bbt_descr *td, struct nand_bbt_descr *md, 74793db446aSBoris Brezillon int chipsel) 74893db446aSBoris Brezillon { 7496c836d51SBoris Brezillon u64 targetsize = nanddev_target_size(&this->base); 7500813621bSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(this); 75193db446aSBoris Brezillon struct erase_info einfo; 75293db446aSBoris Brezillon int i, res, chip = 0; 75393db446aSBoris Brezillon int bits, page, offs, numblocks, sft, sftmsk; 75493db446aSBoris Brezillon int nrchips, pageoffs, ooboffs; 75593db446aSBoris Brezillon uint8_t msk[4]; 75693db446aSBoris Brezillon uint8_t rcode = td->reserved_block_code; 75793db446aSBoris Brezillon size_t retlen, len = 0; 75893db446aSBoris Brezillon loff_t to; 75993db446aSBoris Brezillon struct mtd_oob_ops ops; 76093db446aSBoris Brezillon 76193db446aSBoris Brezillon ops.ooblen = mtd->oobsize; 76293db446aSBoris Brezillon ops.ooboffs = 0; 76393db446aSBoris Brezillon ops.datbuf = NULL; 76493db446aSBoris Brezillon ops.mode = MTD_OPS_PLACE_OOB; 76593db446aSBoris Brezillon 76693db446aSBoris Brezillon if (!rcode) 76793db446aSBoris Brezillon rcode = 0xff; 76893db446aSBoris Brezillon /* Write bad block table per chip rather than per device? */ 76993db446aSBoris Brezillon if (td->options & NAND_BBT_PERCHIP) { 7706c836d51SBoris Brezillon numblocks = (int)(targetsize >> this->bbt_erase_shift); 77193db446aSBoris Brezillon /* Full device write or specific chip? */ 77293db446aSBoris Brezillon if (chipsel == -1) { 77332813e28SBoris Brezillon nrchips = nanddev_ntargets(&this->base); 77493db446aSBoris Brezillon } else { 77593db446aSBoris Brezillon nrchips = chipsel + 1; 77693db446aSBoris Brezillon chip = chipsel; 77793db446aSBoris Brezillon } 77893db446aSBoris Brezillon } else { 77993db446aSBoris Brezillon numblocks = (int)(mtd->size >> this->bbt_erase_shift); 78093db446aSBoris Brezillon nrchips = 1; 78193db446aSBoris Brezillon } 78293db446aSBoris Brezillon 78393db446aSBoris Brezillon /* Loop through the chips */ 78493db446aSBoris Brezillon while (chip < nrchips) { 78593db446aSBoris Brezillon int block; 78693db446aSBoris Brezillon 78793db446aSBoris Brezillon block = get_bbt_block(this, td, md, chip); 78893db446aSBoris Brezillon if (block < 0) { 78993db446aSBoris Brezillon pr_err("No space left to write bad block table\n"); 79093db446aSBoris Brezillon res = block; 79193db446aSBoris Brezillon goto outerr; 79293db446aSBoris Brezillon } 79393db446aSBoris Brezillon 79493db446aSBoris Brezillon /* 79593db446aSBoris Brezillon * get_bbt_block() returns a block number, shift the value to 79693db446aSBoris Brezillon * get a page number. 79793db446aSBoris Brezillon */ 79893db446aSBoris Brezillon page = block << (this->bbt_erase_shift - this->page_shift); 79993db446aSBoris Brezillon 80093db446aSBoris Brezillon /* Set up shift count and masks for the flash table */ 80193db446aSBoris Brezillon bits = td->options & NAND_BBT_NRBITS_MSK; 80293db446aSBoris Brezillon msk[2] = ~rcode; 80393db446aSBoris Brezillon switch (bits) { 80493db446aSBoris Brezillon case 1: sft = 3; sftmsk = 0x07; msk[0] = 0x00; msk[1] = 0x01; 80593db446aSBoris Brezillon msk[3] = 0x01; 80693db446aSBoris Brezillon break; 80793db446aSBoris Brezillon case 2: sft = 2; sftmsk = 0x06; msk[0] = 0x00; msk[1] = 0x01; 80893db446aSBoris Brezillon msk[3] = 0x03; 80993db446aSBoris Brezillon break; 81093db446aSBoris Brezillon case 4: sft = 1; sftmsk = 0x04; msk[0] = 0x00; msk[1] = 0x0C; 81193db446aSBoris Brezillon msk[3] = 0x0f; 81293db446aSBoris Brezillon break; 81393db446aSBoris Brezillon case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F; 81493db446aSBoris Brezillon msk[3] = 0xff; 81593db446aSBoris Brezillon break; 81693db446aSBoris Brezillon default: return -EINVAL; 81793db446aSBoris Brezillon } 81893db446aSBoris Brezillon 81993db446aSBoris Brezillon to = ((loff_t)page) << this->page_shift; 82093db446aSBoris Brezillon 82193db446aSBoris Brezillon /* Must we save the block contents? */ 82293db446aSBoris Brezillon if (td->options & NAND_BBT_SAVECONTENT) { 82393db446aSBoris Brezillon /* Make it block aligned */ 82493db446aSBoris Brezillon to &= ~(((loff_t)1 << this->bbt_erase_shift) - 1); 82593db446aSBoris Brezillon len = 1 << this->bbt_erase_shift; 82693db446aSBoris Brezillon res = mtd_read(mtd, to, len, &retlen, buf); 82793db446aSBoris Brezillon if (res < 0) { 82893db446aSBoris Brezillon if (retlen != len) { 82993db446aSBoris Brezillon pr_info("nand_bbt: error reading block for writing the bad block table\n"); 83093db446aSBoris Brezillon return res; 83193db446aSBoris Brezillon } 83293db446aSBoris Brezillon pr_warn("nand_bbt: ECC error while reading block for writing bad block table\n"); 83393db446aSBoris Brezillon } 83493db446aSBoris Brezillon /* Read oob data */ 83593db446aSBoris Brezillon ops.ooblen = (len >> this->page_shift) * mtd->oobsize; 83693db446aSBoris Brezillon ops.oobbuf = &buf[len]; 83793db446aSBoris Brezillon res = mtd_read_oob(mtd, to + mtd->writesize, &ops); 83893db446aSBoris Brezillon if (res < 0 || ops.oobretlen != ops.ooblen) 83993db446aSBoris Brezillon goto outerr; 84093db446aSBoris Brezillon 84193db446aSBoris Brezillon /* Calc the byte offset in the buffer */ 84293db446aSBoris Brezillon pageoffs = page - (int)(to >> this->page_shift); 84393db446aSBoris Brezillon offs = pageoffs << this->page_shift; 84493db446aSBoris Brezillon /* Preset the bbt area with 0xff */ 84593db446aSBoris Brezillon memset(&buf[offs], 0xff, (size_t)(numblocks >> sft)); 84693db446aSBoris Brezillon ooboffs = len + (pageoffs * mtd->oobsize); 84793db446aSBoris Brezillon 84893db446aSBoris Brezillon } else if (td->options & NAND_BBT_NO_OOB) { 84993db446aSBoris Brezillon ooboffs = 0; 85093db446aSBoris Brezillon offs = td->len; 85193db446aSBoris Brezillon /* The version byte */ 85293db446aSBoris Brezillon if (td->options & NAND_BBT_VERSION) 85393db446aSBoris Brezillon offs++; 85493db446aSBoris Brezillon /* Calc length */ 85593db446aSBoris Brezillon len = (size_t)(numblocks >> sft); 85693db446aSBoris Brezillon len += offs; 85793db446aSBoris Brezillon /* Make it page aligned! */ 85893db446aSBoris Brezillon len = ALIGN(len, mtd->writesize); 85993db446aSBoris Brezillon /* Preset the buffer with 0xff */ 86093db446aSBoris Brezillon memset(buf, 0xff, len); 86193db446aSBoris Brezillon /* Pattern is located at the begin of first page */ 86293db446aSBoris Brezillon memcpy(buf, td->pattern, td->len); 86393db446aSBoris Brezillon } else { 86493db446aSBoris Brezillon /* Calc length */ 86593db446aSBoris Brezillon len = (size_t)(numblocks >> sft); 86693db446aSBoris Brezillon /* Make it page aligned! */ 86793db446aSBoris Brezillon len = ALIGN(len, mtd->writesize); 86893db446aSBoris Brezillon /* Preset the buffer with 0xff */ 86993db446aSBoris Brezillon memset(buf, 0xff, len + 87093db446aSBoris Brezillon (len >> this->page_shift)* mtd->oobsize); 87193db446aSBoris Brezillon offs = 0; 87293db446aSBoris Brezillon ooboffs = len; 87393db446aSBoris Brezillon /* Pattern is located in oob area of first page */ 87493db446aSBoris Brezillon memcpy(&buf[ooboffs + td->offs], td->pattern, td->len); 87593db446aSBoris Brezillon } 87693db446aSBoris Brezillon 87793db446aSBoris Brezillon if (td->options & NAND_BBT_VERSION) 87893db446aSBoris Brezillon buf[ooboffs + td->veroffs] = td->version[chip]; 87993db446aSBoris Brezillon 88093db446aSBoris Brezillon /* Walk through the memory table */ 88193db446aSBoris Brezillon for (i = 0; i < numblocks; i++) { 88293db446aSBoris Brezillon uint8_t dat; 88393db446aSBoris Brezillon int sftcnt = (i << (3 - sft)) & sftmsk; 88493db446aSBoris Brezillon dat = bbt_get_entry(this, chip * numblocks + i); 88593db446aSBoris Brezillon /* Do not store the reserved bbt blocks! */ 88693db446aSBoris Brezillon buf[offs + (i >> sft)] &= ~(msk[dat] << sftcnt); 88793db446aSBoris Brezillon } 88893db446aSBoris Brezillon 88993db446aSBoris Brezillon memset(&einfo, 0, sizeof(einfo)); 89093db446aSBoris Brezillon einfo.addr = to; 89193db446aSBoris Brezillon einfo.len = 1 << this->bbt_erase_shift; 892e4cdf9cbSBoris Brezillon res = nand_erase_nand(this, &einfo, 1); 89393db446aSBoris Brezillon if (res < 0) { 89493db446aSBoris Brezillon pr_warn("nand_bbt: error while erasing BBT block %d\n", 89593db446aSBoris Brezillon res); 89693db446aSBoris Brezillon mark_bbt_block_bad(this, td, chip, block); 89793db446aSBoris Brezillon continue; 89893db446aSBoris Brezillon } 89993db446aSBoris Brezillon 9000813621bSBoris Brezillon res = scan_write_bbt(this, to, len, buf, 9010813621bSBoris Brezillon td->options & NAND_BBT_NO_OOB ? 9020813621bSBoris Brezillon NULL : &buf[len]); 90393db446aSBoris Brezillon if (res < 0) { 90493db446aSBoris Brezillon pr_warn("nand_bbt: error while writing BBT block %d\n", 90593db446aSBoris Brezillon res); 90693db446aSBoris Brezillon mark_bbt_block_bad(this, td, chip, block); 90793db446aSBoris Brezillon continue; 90893db446aSBoris Brezillon } 90993db446aSBoris Brezillon 91093db446aSBoris Brezillon pr_info("Bad block table written to 0x%012llx, version 0x%02X\n", 91193db446aSBoris Brezillon (unsigned long long)to, td->version[chip]); 91293db446aSBoris Brezillon 91393db446aSBoris Brezillon /* Mark it as used */ 91493db446aSBoris Brezillon td->pages[chip++] = page; 91593db446aSBoris Brezillon } 91693db446aSBoris Brezillon return 0; 91793db446aSBoris Brezillon 91893db446aSBoris Brezillon outerr: 91993db446aSBoris Brezillon pr_warn("nand_bbt: error while writing bad block table %d\n", res); 92093db446aSBoris Brezillon return res; 92193db446aSBoris Brezillon } 92293db446aSBoris Brezillon 92393db446aSBoris Brezillon /** 92493db446aSBoris Brezillon * nand_memory_bbt - [GENERIC] create a memory based bad block table 9250813621bSBoris Brezillon * @this: NAND chip object 92693db446aSBoris Brezillon * @bd: descriptor for the good/bad block search pattern 92793db446aSBoris Brezillon * 92893db446aSBoris Brezillon * The function creates a memory based bbt by scanning the device for 92993db446aSBoris Brezillon * manufacturer / software marked good / bad blocks. 93093db446aSBoris Brezillon */ 9310813621bSBoris Brezillon static inline int nand_memory_bbt(struct nand_chip *this, 9320813621bSBoris Brezillon struct nand_bbt_descr *bd) 93393db446aSBoris Brezillon { 934eeab7174SBoris Brezillon u8 *pagebuf = nand_get_data_buf(this); 935eeab7174SBoris Brezillon 936eeab7174SBoris Brezillon return create_bbt(this, pagebuf, bd, -1); 93793db446aSBoris Brezillon } 93893db446aSBoris Brezillon 93993db446aSBoris Brezillon /** 94093db446aSBoris Brezillon * check_create - [GENERIC] create and write bbt(s) if necessary 9410813621bSBoris Brezillon * @this: the NAND device 94293db446aSBoris Brezillon * @buf: temporary buffer 94393db446aSBoris Brezillon * @bd: descriptor for the good/bad block search pattern 94493db446aSBoris Brezillon * 94593db446aSBoris Brezillon * The function checks the results of the previous call to read_bbt and creates 94693db446aSBoris Brezillon * / updates the bbt(s) if necessary. Creation is necessary if no bbt was found 94793db446aSBoris Brezillon * for the chip/device. Update is necessary if one of the tables is missing or 94893db446aSBoris Brezillon * the version nr. of one table is less than the other. 94993db446aSBoris Brezillon */ 9500813621bSBoris Brezillon static int check_create(struct nand_chip *this, uint8_t *buf, 9510813621bSBoris Brezillon struct nand_bbt_descr *bd) 95293db446aSBoris Brezillon { 95393db446aSBoris Brezillon int i, chips, writeops, create, chipsel, res, res2; 95493db446aSBoris Brezillon struct nand_bbt_descr *td = this->bbt_td; 95593db446aSBoris Brezillon struct nand_bbt_descr *md = this->bbt_md; 95693db446aSBoris Brezillon struct nand_bbt_descr *rd, *rd2; 95793db446aSBoris Brezillon 95893db446aSBoris Brezillon /* Do we have a bbt per chip? */ 95993db446aSBoris Brezillon if (td->options & NAND_BBT_PERCHIP) 96032813e28SBoris Brezillon chips = nanddev_ntargets(&this->base); 96193db446aSBoris Brezillon else 96293db446aSBoris Brezillon chips = 1; 96393db446aSBoris Brezillon 96493db446aSBoris Brezillon for (i = 0; i < chips; i++) { 96593db446aSBoris Brezillon writeops = 0; 96693db446aSBoris Brezillon create = 0; 96793db446aSBoris Brezillon rd = NULL; 96893db446aSBoris Brezillon rd2 = NULL; 96993db446aSBoris Brezillon res = res2 = 0; 97093db446aSBoris Brezillon /* Per chip or per device? */ 97193db446aSBoris Brezillon chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1; 97293db446aSBoris Brezillon /* Mirrored table available? */ 97393db446aSBoris Brezillon if (md) { 97493db446aSBoris Brezillon if (td->pages[i] == -1 && md->pages[i] == -1) { 97593db446aSBoris Brezillon create = 1; 97693db446aSBoris Brezillon writeops = 0x03; 97793db446aSBoris Brezillon } else if (td->pages[i] == -1) { 97893db446aSBoris Brezillon rd = md; 97993db446aSBoris Brezillon writeops = 0x01; 98093db446aSBoris Brezillon } else if (md->pages[i] == -1) { 98193db446aSBoris Brezillon rd = td; 98293db446aSBoris Brezillon writeops = 0x02; 98393db446aSBoris Brezillon } else if (td->version[i] == md->version[i]) { 98493db446aSBoris Brezillon rd = td; 98593db446aSBoris Brezillon if (!(td->options & NAND_BBT_VERSION)) 98693db446aSBoris Brezillon rd2 = md; 98793db446aSBoris Brezillon } else if (((int8_t)(td->version[i] - md->version[i])) > 0) { 98893db446aSBoris Brezillon rd = td; 98993db446aSBoris Brezillon writeops = 0x02; 99093db446aSBoris Brezillon } else { 99193db446aSBoris Brezillon rd = md; 99293db446aSBoris Brezillon writeops = 0x01; 99393db446aSBoris Brezillon } 99493db446aSBoris Brezillon } else { 99593db446aSBoris Brezillon if (td->pages[i] == -1) { 99693db446aSBoris Brezillon create = 1; 99793db446aSBoris Brezillon writeops = 0x01; 99893db446aSBoris Brezillon } else { 99993db446aSBoris Brezillon rd = td; 100093db446aSBoris Brezillon } 100193db446aSBoris Brezillon } 100293db446aSBoris Brezillon 100393db446aSBoris Brezillon if (create) { 100493db446aSBoris Brezillon /* Create the bad block table by scanning the device? */ 100593db446aSBoris Brezillon if (!(td->options & NAND_BBT_CREATE)) 100693db446aSBoris Brezillon continue; 100793db446aSBoris Brezillon 100893db446aSBoris Brezillon /* Create the table in memory by scanning the chip(s) */ 100993db446aSBoris Brezillon if (!(this->bbt_options & NAND_BBT_CREATE_EMPTY)) 10100813621bSBoris Brezillon create_bbt(this, buf, bd, chipsel); 101193db446aSBoris Brezillon 101293db446aSBoris Brezillon td->version[i] = 1; 101393db446aSBoris Brezillon if (md) 101493db446aSBoris Brezillon md->version[i] = 1; 101593db446aSBoris Brezillon } 101693db446aSBoris Brezillon 101793db446aSBoris Brezillon /* Read back first? */ 101893db446aSBoris Brezillon if (rd) { 10190813621bSBoris Brezillon res = read_abs_bbt(this, buf, rd, chipsel); 102093db446aSBoris Brezillon if (mtd_is_eccerr(res)) { 102193db446aSBoris Brezillon /* Mark table as invalid */ 102293db446aSBoris Brezillon rd->pages[i] = -1; 102393db446aSBoris Brezillon rd->version[i] = 0; 102493db446aSBoris Brezillon i--; 102593db446aSBoris Brezillon continue; 102693db446aSBoris Brezillon } 102793db446aSBoris Brezillon } 102893db446aSBoris Brezillon /* If they weren't versioned, read both */ 102993db446aSBoris Brezillon if (rd2) { 10300813621bSBoris Brezillon res2 = read_abs_bbt(this, buf, rd2, chipsel); 103193db446aSBoris Brezillon if (mtd_is_eccerr(res2)) { 103293db446aSBoris Brezillon /* Mark table as invalid */ 103393db446aSBoris Brezillon rd2->pages[i] = -1; 103493db446aSBoris Brezillon rd2->version[i] = 0; 103593db446aSBoris Brezillon i--; 103693db446aSBoris Brezillon continue; 103793db446aSBoris Brezillon } 103893db446aSBoris Brezillon } 103993db446aSBoris Brezillon 104093db446aSBoris Brezillon /* Scrub the flash table(s)? */ 104193db446aSBoris Brezillon if (mtd_is_bitflip(res) || mtd_is_bitflip(res2)) 104293db446aSBoris Brezillon writeops = 0x03; 104393db446aSBoris Brezillon 104493db446aSBoris Brezillon /* Update version numbers before writing */ 104593db446aSBoris Brezillon if (md) { 104693db446aSBoris Brezillon td->version[i] = max(td->version[i], md->version[i]); 104793db446aSBoris Brezillon md->version[i] = td->version[i]; 104893db446aSBoris Brezillon } 104993db446aSBoris Brezillon 105093db446aSBoris Brezillon /* Write the bad block table to the device? */ 105193db446aSBoris Brezillon if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) { 10520813621bSBoris Brezillon res = write_bbt(this, buf, td, md, chipsel); 105393db446aSBoris Brezillon if (res < 0) 105493db446aSBoris Brezillon return res; 105593db446aSBoris Brezillon } 105693db446aSBoris Brezillon 105793db446aSBoris Brezillon /* Write the mirror bad block table to the device? */ 105893db446aSBoris Brezillon if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) { 10590813621bSBoris Brezillon res = write_bbt(this, buf, md, td, chipsel); 106093db446aSBoris Brezillon if (res < 0) 106193db446aSBoris Brezillon return res; 106293db446aSBoris Brezillon } 106393db446aSBoris Brezillon } 106493db446aSBoris Brezillon return 0; 106593db446aSBoris Brezillon } 106693db446aSBoris Brezillon 106793db446aSBoris Brezillon /** 106899f3351aSBoris Brezillon * nand_update_bbt - update bad block table(s) 106999f3351aSBoris Brezillon * @this: the NAND device 107099f3351aSBoris Brezillon * @offs: the offset of the newly marked block 107199f3351aSBoris Brezillon * 107299f3351aSBoris Brezillon * The function updates the bad block table(s). 107399f3351aSBoris Brezillon */ 107499f3351aSBoris Brezillon static int nand_update_bbt(struct nand_chip *this, loff_t offs) 107599f3351aSBoris Brezillon { 107699f3351aSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(this); 107799f3351aSBoris Brezillon int len, res = 0; 107899f3351aSBoris Brezillon int chip, chipsel; 107999f3351aSBoris Brezillon uint8_t *buf; 108099f3351aSBoris Brezillon struct nand_bbt_descr *td = this->bbt_td; 108199f3351aSBoris Brezillon struct nand_bbt_descr *md = this->bbt_md; 108299f3351aSBoris Brezillon 108399f3351aSBoris Brezillon if (!this->bbt || !td) 108499f3351aSBoris Brezillon return -EINVAL; 108599f3351aSBoris Brezillon 108699f3351aSBoris Brezillon /* Allocate a temporary buffer for one eraseblock incl. oob */ 108799f3351aSBoris Brezillon len = (1 << this->bbt_erase_shift); 108899f3351aSBoris Brezillon len += (len >> this->page_shift) * mtd->oobsize; 108999f3351aSBoris Brezillon buf = kmalloc(len, GFP_KERNEL); 109099f3351aSBoris Brezillon if (!buf) 109199f3351aSBoris Brezillon return -ENOMEM; 109299f3351aSBoris Brezillon 109399f3351aSBoris Brezillon /* Do we have a bbt per chip? */ 109499f3351aSBoris Brezillon if (td->options & NAND_BBT_PERCHIP) { 109599f3351aSBoris Brezillon chip = (int)(offs >> this->chip_shift); 109699f3351aSBoris Brezillon chipsel = chip; 109799f3351aSBoris Brezillon } else { 109899f3351aSBoris Brezillon chip = 0; 109999f3351aSBoris Brezillon chipsel = -1; 110099f3351aSBoris Brezillon } 110199f3351aSBoris Brezillon 110299f3351aSBoris Brezillon td->version[chip]++; 110399f3351aSBoris Brezillon if (md) 110499f3351aSBoris Brezillon md->version[chip]++; 110599f3351aSBoris Brezillon 110699f3351aSBoris Brezillon /* Write the bad block table to the device? */ 110799f3351aSBoris Brezillon if (td->options & NAND_BBT_WRITE) { 110899f3351aSBoris Brezillon res = write_bbt(this, buf, td, md, chipsel); 110999f3351aSBoris Brezillon if (res < 0) 111099f3351aSBoris Brezillon goto out; 111199f3351aSBoris Brezillon } 111299f3351aSBoris Brezillon /* Write the mirror bad block table to the device? */ 111399f3351aSBoris Brezillon if (md && (md->options & NAND_BBT_WRITE)) { 111499f3351aSBoris Brezillon res = write_bbt(this, buf, md, td, chipsel); 111599f3351aSBoris Brezillon } 111699f3351aSBoris Brezillon 111799f3351aSBoris Brezillon out: 111899f3351aSBoris Brezillon kfree(buf); 111999f3351aSBoris Brezillon return res; 112099f3351aSBoris Brezillon } 112199f3351aSBoris Brezillon 112299f3351aSBoris Brezillon /** 11237998d898SMauro Carvalho Chehab * mark_bbt_region - [GENERIC] mark the bad block table regions 11240813621bSBoris Brezillon * @this: the NAND device 112593db446aSBoris Brezillon * @td: bad block table descriptor 112693db446aSBoris Brezillon * 112793db446aSBoris Brezillon * The bad block table regions are marked as "bad" to prevent accidental 112893db446aSBoris Brezillon * erasures / writes. The regions are identified by the mark 0x02. 112993db446aSBoris Brezillon */ 11300813621bSBoris Brezillon static void mark_bbt_region(struct nand_chip *this, struct nand_bbt_descr *td) 113193db446aSBoris Brezillon { 11326c836d51SBoris Brezillon u64 targetsize = nanddev_target_size(&this->base); 11330813621bSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(this); 113493db446aSBoris Brezillon int i, j, chips, block, nrblocks, update; 113593db446aSBoris Brezillon uint8_t oldval; 113693db446aSBoris Brezillon 113793db446aSBoris Brezillon /* Do we have a bbt per chip? */ 113893db446aSBoris Brezillon if (td->options & NAND_BBT_PERCHIP) { 113932813e28SBoris Brezillon chips = nanddev_ntargets(&this->base); 11406c836d51SBoris Brezillon nrblocks = (int)(targetsize >> this->bbt_erase_shift); 114193db446aSBoris Brezillon } else { 114293db446aSBoris Brezillon chips = 1; 114393db446aSBoris Brezillon nrblocks = (int)(mtd->size >> this->bbt_erase_shift); 114493db446aSBoris Brezillon } 114593db446aSBoris Brezillon 114693db446aSBoris Brezillon for (i = 0; i < chips; i++) { 114793db446aSBoris Brezillon if ((td->options & NAND_BBT_ABSPAGE) || 114893db446aSBoris Brezillon !(td->options & NAND_BBT_WRITE)) { 114993db446aSBoris Brezillon if (td->pages[i] == -1) 115093db446aSBoris Brezillon continue; 115193db446aSBoris Brezillon block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift); 115293db446aSBoris Brezillon oldval = bbt_get_entry(this, block); 115393db446aSBoris Brezillon bbt_mark_entry(this, block, BBT_BLOCK_RESERVED); 115493db446aSBoris Brezillon if ((oldval != BBT_BLOCK_RESERVED) && 115593db446aSBoris Brezillon td->reserved_block_code) 11560813621bSBoris Brezillon nand_update_bbt(this, (loff_t)block << 115793db446aSBoris Brezillon this->bbt_erase_shift); 115893db446aSBoris Brezillon continue; 115993db446aSBoris Brezillon } 116093db446aSBoris Brezillon update = 0; 116193db446aSBoris Brezillon if (td->options & NAND_BBT_LASTBLOCK) 116293db446aSBoris Brezillon block = ((i + 1) * nrblocks) - td->maxblocks; 116393db446aSBoris Brezillon else 116493db446aSBoris Brezillon block = i * nrblocks; 116593db446aSBoris Brezillon for (j = 0; j < td->maxblocks; j++) { 116693db446aSBoris Brezillon oldval = bbt_get_entry(this, block); 116793db446aSBoris Brezillon bbt_mark_entry(this, block, BBT_BLOCK_RESERVED); 116893db446aSBoris Brezillon if (oldval != BBT_BLOCK_RESERVED) 116993db446aSBoris Brezillon update = 1; 117093db446aSBoris Brezillon block++; 117193db446aSBoris Brezillon } 117293db446aSBoris Brezillon /* 117393db446aSBoris Brezillon * If we want reserved blocks to be recorded to flash, and some 117493db446aSBoris Brezillon * new ones have been marked, then we need to update the stored 117593db446aSBoris Brezillon * bbts. This should only happen once. 117693db446aSBoris Brezillon */ 117793db446aSBoris Brezillon if (update && td->reserved_block_code) 11780813621bSBoris Brezillon nand_update_bbt(this, (loff_t)(block - 1) << 117993db446aSBoris Brezillon this->bbt_erase_shift); 118093db446aSBoris Brezillon } 118193db446aSBoris Brezillon } 118293db446aSBoris Brezillon 118393db446aSBoris Brezillon /** 118493db446aSBoris Brezillon * verify_bbt_descr - verify the bad block description 11850813621bSBoris Brezillon * @this: the NAND device 118693db446aSBoris Brezillon * @bd: the table to verify 118793db446aSBoris Brezillon * 118893db446aSBoris Brezillon * This functions performs a few sanity checks on the bad block description 118993db446aSBoris Brezillon * table. 119093db446aSBoris Brezillon */ 11910813621bSBoris Brezillon static void verify_bbt_descr(struct nand_chip *this, struct nand_bbt_descr *bd) 119293db446aSBoris Brezillon { 11936c836d51SBoris Brezillon u64 targetsize = nanddev_target_size(&this->base); 11940813621bSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(this); 119593db446aSBoris Brezillon u32 pattern_len; 119693db446aSBoris Brezillon u32 bits; 119793db446aSBoris Brezillon u32 table_size; 119893db446aSBoris Brezillon 119993db446aSBoris Brezillon if (!bd) 120093db446aSBoris Brezillon return; 120193db446aSBoris Brezillon 120293db446aSBoris Brezillon pattern_len = bd->len; 120393db446aSBoris Brezillon bits = bd->options & NAND_BBT_NRBITS_MSK; 120493db446aSBoris Brezillon 120593db446aSBoris Brezillon BUG_ON((this->bbt_options & NAND_BBT_NO_OOB) && 120693db446aSBoris Brezillon !(this->bbt_options & NAND_BBT_USE_FLASH)); 120793db446aSBoris Brezillon BUG_ON(!bits); 120893db446aSBoris Brezillon 120993db446aSBoris Brezillon if (bd->options & NAND_BBT_VERSION) 121093db446aSBoris Brezillon pattern_len++; 121193db446aSBoris Brezillon 121293db446aSBoris Brezillon if (bd->options & NAND_BBT_NO_OOB) { 121393db446aSBoris Brezillon BUG_ON(!(this->bbt_options & NAND_BBT_USE_FLASH)); 121493db446aSBoris Brezillon BUG_ON(!(this->bbt_options & NAND_BBT_NO_OOB)); 121593db446aSBoris Brezillon BUG_ON(bd->offs); 121693db446aSBoris Brezillon if (bd->options & NAND_BBT_VERSION) 121793db446aSBoris Brezillon BUG_ON(bd->veroffs != bd->len); 121893db446aSBoris Brezillon BUG_ON(bd->options & NAND_BBT_SAVECONTENT); 121993db446aSBoris Brezillon } 122093db446aSBoris Brezillon 122193db446aSBoris Brezillon if (bd->options & NAND_BBT_PERCHIP) 12226c836d51SBoris Brezillon table_size = targetsize >> this->bbt_erase_shift; 122393db446aSBoris Brezillon else 122493db446aSBoris Brezillon table_size = mtd->size >> this->bbt_erase_shift; 122593db446aSBoris Brezillon table_size >>= 3; 122693db446aSBoris Brezillon table_size *= bits; 122793db446aSBoris Brezillon if (bd->options & NAND_BBT_NO_OOB) 122893db446aSBoris Brezillon table_size += pattern_len; 122993db446aSBoris Brezillon BUG_ON(table_size > (1 << this->bbt_erase_shift)); 123093db446aSBoris Brezillon } 123193db446aSBoris Brezillon 123293db446aSBoris Brezillon /** 123393db446aSBoris Brezillon * nand_scan_bbt - [NAND Interface] scan, find, read and maybe create bad block table(s) 12340813621bSBoris Brezillon * @this: the NAND device 123593db446aSBoris Brezillon * @bd: descriptor for the good/bad block search pattern 123693db446aSBoris Brezillon * 123793db446aSBoris Brezillon * The function checks, if a bad block table(s) is/are already available. If 123893db446aSBoris Brezillon * not it scans the device for manufacturer marked good / bad blocks and writes 123993db446aSBoris Brezillon * the bad block table(s) to the selected place. 124093db446aSBoris Brezillon * 124193db446aSBoris Brezillon * The bad block table memory is allocated here. It must be freed by calling 124293db446aSBoris Brezillon * the nand_free_bbt function. 124393db446aSBoris Brezillon */ 12440813621bSBoris Brezillon static int nand_scan_bbt(struct nand_chip *this, struct nand_bbt_descr *bd) 124593db446aSBoris Brezillon { 12460813621bSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(this); 124793db446aSBoris Brezillon int len, res; 124893db446aSBoris Brezillon uint8_t *buf; 124993db446aSBoris Brezillon struct nand_bbt_descr *td = this->bbt_td; 125093db446aSBoris Brezillon struct nand_bbt_descr *md = this->bbt_md; 125193db446aSBoris Brezillon 125293db446aSBoris Brezillon len = (mtd->size >> (this->bbt_erase_shift + 2)) ? : 1; 125393db446aSBoris Brezillon /* 125493db446aSBoris Brezillon * Allocate memory (2bit per block) and clear the memory bad block 125593db446aSBoris Brezillon * table. 125693db446aSBoris Brezillon */ 125793db446aSBoris Brezillon this->bbt = kzalloc(len, GFP_KERNEL); 125893db446aSBoris Brezillon if (!this->bbt) 125993db446aSBoris Brezillon return -ENOMEM; 126093db446aSBoris Brezillon 126193db446aSBoris Brezillon /* 1262735bf220SKieran Bingham * If no primary table descriptor is given, scan the device to build a 126393db446aSBoris Brezillon * memory based bad block table. 126493db446aSBoris Brezillon */ 126593db446aSBoris Brezillon if (!td) { 12660813621bSBoris Brezillon if ((res = nand_memory_bbt(this, bd))) { 126793db446aSBoris Brezillon pr_err("nand_bbt: can't scan flash and build the RAM-based BBT\n"); 126886aa04f4SWenwen Wang goto err_free_bbt; 126993db446aSBoris Brezillon } 127093db446aSBoris Brezillon return 0; 127193db446aSBoris Brezillon } 12720813621bSBoris Brezillon verify_bbt_descr(this, td); 12730813621bSBoris Brezillon verify_bbt_descr(this, md); 127493db446aSBoris Brezillon 127593db446aSBoris Brezillon /* Allocate a temporary buffer for one eraseblock incl. oob */ 127693db446aSBoris Brezillon len = (1 << this->bbt_erase_shift); 127793db446aSBoris Brezillon len += (len >> this->page_shift) * mtd->oobsize; 127893db446aSBoris Brezillon buf = vmalloc(len); 127993db446aSBoris Brezillon if (!buf) { 128093db446aSBoris Brezillon res = -ENOMEM; 128186aa04f4SWenwen Wang goto err_free_bbt; 128293db446aSBoris Brezillon } 128393db446aSBoris Brezillon 128493db446aSBoris Brezillon /* Is the bbt at a given page? */ 128593db446aSBoris Brezillon if (td->options & NAND_BBT_ABSPAGE) { 12860813621bSBoris Brezillon read_abs_bbts(this, buf, td, md); 128793db446aSBoris Brezillon } else { 128893db446aSBoris Brezillon /* Search the bad block table using a pattern in oob */ 12890813621bSBoris Brezillon search_read_bbts(this, buf, td, md); 129093db446aSBoris Brezillon } 129193db446aSBoris Brezillon 12920813621bSBoris Brezillon res = check_create(this, buf, bd); 129393db446aSBoris Brezillon if (res) 129486aa04f4SWenwen Wang goto err_free_buf; 129593db446aSBoris Brezillon 129693db446aSBoris Brezillon /* Prevent the bbt regions from erasing / writing */ 12970813621bSBoris Brezillon mark_bbt_region(this, td); 129893db446aSBoris Brezillon if (md) 12990813621bSBoris Brezillon mark_bbt_region(this, md); 130093db446aSBoris Brezillon 130193db446aSBoris Brezillon vfree(buf); 130293db446aSBoris Brezillon return 0; 130393db446aSBoris Brezillon 130486aa04f4SWenwen Wang err_free_buf: 130586aa04f4SWenwen Wang vfree(buf); 130686aa04f4SWenwen Wang err_free_bbt: 130793db446aSBoris Brezillon kfree(this->bbt); 130893db446aSBoris Brezillon this->bbt = NULL; 130993db446aSBoris Brezillon return res; 131093db446aSBoris Brezillon } 131193db446aSBoris Brezillon 131293db446aSBoris Brezillon /* 131393db446aSBoris Brezillon * Define some generic bad / good block scan pattern which are used 131493db446aSBoris Brezillon * while scanning a device for factory marked good / bad blocks. 131593db446aSBoris Brezillon */ 131693db446aSBoris Brezillon static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; 131793db446aSBoris Brezillon 131893db446aSBoris Brezillon /* Generic flash bbt descriptors */ 131993db446aSBoris Brezillon static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' }; 132093db446aSBoris Brezillon static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' }; 132193db446aSBoris Brezillon 132293db446aSBoris Brezillon static struct nand_bbt_descr bbt_main_descr = { 132393db446aSBoris Brezillon .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE 132493db446aSBoris Brezillon | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, 132593db446aSBoris Brezillon .offs = 8, 132693db446aSBoris Brezillon .len = 4, 132793db446aSBoris Brezillon .veroffs = 12, 132893db446aSBoris Brezillon .maxblocks = NAND_BBT_SCAN_MAXBLOCKS, 132993db446aSBoris Brezillon .pattern = bbt_pattern 133093db446aSBoris Brezillon }; 133193db446aSBoris Brezillon 133293db446aSBoris Brezillon static struct nand_bbt_descr bbt_mirror_descr = { 133393db446aSBoris Brezillon .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE 133493db446aSBoris Brezillon | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, 133593db446aSBoris Brezillon .offs = 8, 133693db446aSBoris Brezillon .len = 4, 133793db446aSBoris Brezillon .veroffs = 12, 133893db446aSBoris Brezillon .maxblocks = NAND_BBT_SCAN_MAXBLOCKS, 133993db446aSBoris Brezillon .pattern = mirror_pattern 134093db446aSBoris Brezillon }; 134193db446aSBoris Brezillon 134293db446aSBoris Brezillon static struct nand_bbt_descr bbt_main_no_oob_descr = { 134393db446aSBoris Brezillon .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE 134493db446aSBoris Brezillon | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP 134593db446aSBoris Brezillon | NAND_BBT_NO_OOB, 134693db446aSBoris Brezillon .len = 4, 134793db446aSBoris Brezillon .veroffs = 4, 134893db446aSBoris Brezillon .maxblocks = NAND_BBT_SCAN_MAXBLOCKS, 134993db446aSBoris Brezillon .pattern = bbt_pattern 135093db446aSBoris Brezillon }; 135193db446aSBoris Brezillon 135293db446aSBoris Brezillon static struct nand_bbt_descr bbt_mirror_no_oob_descr = { 135393db446aSBoris Brezillon .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE 135493db446aSBoris Brezillon | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP 135593db446aSBoris Brezillon | NAND_BBT_NO_OOB, 135693db446aSBoris Brezillon .len = 4, 135793db446aSBoris Brezillon .veroffs = 4, 135893db446aSBoris Brezillon .maxblocks = NAND_BBT_SCAN_MAXBLOCKS, 135993db446aSBoris Brezillon .pattern = mirror_pattern 136093db446aSBoris Brezillon }; 136193db446aSBoris Brezillon 136293db446aSBoris Brezillon #define BADBLOCK_SCAN_MASK (~NAND_BBT_NO_OOB) 136393db446aSBoris Brezillon /** 136493db446aSBoris Brezillon * nand_create_badblock_pattern - [INTERN] Creates a BBT descriptor structure 136593db446aSBoris Brezillon * @this: NAND chip to create descriptor for 136693db446aSBoris Brezillon * 136793db446aSBoris Brezillon * This function allocates and initializes a nand_bbt_descr for BBM detection 136893db446aSBoris Brezillon * based on the properties of @this. The new descriptor is stored in 136993db446aSBoris Brezillon * this->badblock_pattern. Thus, this->badblock_pattern should be NULL when 137093db446aSBoris Brezillon * passed to this function. 137193db446aSBoris Brezillon */ 137293db446aSBoris Brezillon static int nand_create_badblock_pattern(struct nand_chip *this) 137393db446aSBoris Brezillon { 137493db446aSBoris Brezillon struct nand_bbt_descr *bd; 137593db446aSBoris Brezillon if (this->badblock_pattern) { 137693db446aSBoris Brezillon pr_warn("Bad block pattern already allocated; not replacing\n"); 137793db446aSBoris Brezillon return -EINVAL; 137893db446aSBoris Brezillon } 137993db446aSBoris Brezillon bd = kzalloc(sizeof(*bd), GFP_KERNEL); 138093db446aSBoris Brezillon if (!bd) 138193db446aSBoris Brezillon return -ENOMEM; 138293db446aSBoris Brezillon bd->options = this->bbt_options & BADBLOCK_SCAN_MASK; 138393db446aSBoris Brezillon bd->offs = this->badblockpos; 138493db446aSBoris Brezillon bd->len = (this->options & NAND_BUSWIDTH_16) ? 2 : 1; 138593db446aSBoris Brezillon bd->pattern = scan_ff_pattern; 138693db446aSBoris Brezillon bd->options |= NAND_BBT_DYNAMICSTRUCT; 138793db446aSBoris Brezillon this->badblock_pattern = bd; 138893db446aSBoris Brezillon return 0; 138993db446aSBoris Brezillon } 139093db446aSBoris Brezillon 139193db446aSBoris Brezillon /** 139244b07b92SBoris Brezillon * nand_create_bbt - [NAND Interface] Select a default bad block table for the device 139344b07b92SBoris Brezillon * @this: NAND chip object 139493db446aSBoris Brezillon * 139593db446aSBoris Brezillon * This function selects the default bad block table support for the device and 139693db446aSBoris Brezillon * calls the nand_scan_bbt function. 139793db446aSBoris Brezillon */ 139844b07b92SBoris Brezillon int nand_create_bbt(struct nand_chip *this) 139993db446aSBoris Brezillon { 140093db446aSBoris Brezillon int ret; 140193db446aSBoris Brezillon 140293db446aSBoris Brezillon /* Is a flash based bad block table requested? */ 140393db446aSBoris Brezillon if (this->bbt_options & NAND_BBT_USE_FLASH) { 140493db446aSBoris Brezillon /* Use the default pattern descriptors */ 140593db446aSBoris Brezillon if (!this->bbt_td) { 140693db446aSBoris Brezillon if (this->bbt_options & NAND_BBT_NO_OOB) { 140793db446aSBoris Brezillon this->bbt_td = &bbt_main_no_oob_descr; 140893db446aSBoris Brezillon this->bbt_md = &bbt_mirror_no_oob_descr; 140993db446aSBoris Brezillon } else { 141093db446aSBoris Brezillon this->bbt_td = &bbt_main_descr; 141193db446aSBoris Brezillon this->bbt_md = &bbt_mirror_descr; 141293db446aSBoris Brezillon } 141393db446aSBoris Brezillon } 141493db446aSBoris Brezillon } else { 141593db446aSBoris Brezillon this->bbt_td = NULL; 141693db446aSBoris Brezillon this->bbt_md = NULL; 141793db446aSBoris Brezillon } 141893db446aSBoris Brezillon 141993db446aSBoris Brezillon if (!this->badblock_pattern) { 142093db446aSBoris Brezillon ret = nand_create_badblock_pattern(this); 142193db446aSBoris Brezillon if (ret) 142293db446aSBoris Brezillon return ret; 142393db446aSBoris Brezillon } 142493db446aSBoris Brezillon 14250813621bSBoris Brezillon return nand_scan_bbt(this, this->badblock_pattern); 142693db446aSBoris Brezillon } 142744b07b92SBoris Brezillon EXPORT_SYMBOL(nand_create_bbt); 142893db446aSBoris Brezillon 142993db446aSBoris Brezillon /** 143093db446aSBoris Brezillon * nand_isreserved_bbt - [NAND Interface] Check if a block is reserved 14315740d4c4SBoris Brezillon * @this: NAND chip object 143293db446aSBoris Brezillon * @offs: offset in the device 143393db446aSBoris Brezillon */ 14345740d4c4SBoris Brezillon int nand_isreserved_bbt(struct nand_chip *this, loff_t offs) 143593db446aSBoris Brezillon { 143693db446aSBoris Brezillon int block; 143793db446aSBoris Brezillon 143893db446aSBoris Brezillon block = (int)(offs >> this->bbt_erase_shift); 143993db446aSBoris Brezillon return bbt_get_entry(this, block) == BBT_BLOCK_RESERVED; 144093db446aSBoris Brezillon } 144193db446aSBoris Brezillon 144293db446aSBoris Brezillon /** 144393db446aSBoris Brezillon * nand_isbad_bbt - [NAND Interface] Check if a block is bad 14445740d4c4SBoris Brezillon * @this: NAND chip object 144593db446aSBoris Brezillon * @offs: offset in the device 144693db446aSBoris Brezillon * @allowbbt: allow access to bad block table region 144793db446aSBoris Brezillon */ 14485740d4c4SBoris Brezillon int nand_isbad_bbt(struct nand_chip *this, loff_t offs, int allowbbt) 144993db446aSBoris Brezillon { 145093db446aSBoris Brezillon int block, res; 145193db446aSBoris Brezillon 145293db446aSBoris Brezillon block = (int)(offs >> this->bbt_erase_shift); 145393db446aSBoris Brezillon res = bbt_get_entry(this, block); 145493db446aSBoris Brezillon 145593db446aSBoris Brezillon pr_debug("nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n", 145693db446aSBoris Brezillon (unsigned int)offs, block, res); 145793db446aSBoris Brezillon 1458*ad5e35f5SMiquel Raynal if (mtd_check_expert_analysis_mode()) 145967b967ddSMiquel Raynal return 0; 146067b967ddSMiquel Raynal 146193db446aSBoris Brezillon switch (res) { 146293db446aSBoris Brezillon case BBT_BLOCK_GOOD: 146393db446aSBoris Brezillon return 0; 146493db446aSBoris Brezillon case BBT_BLOCK_WORN: 146593db446aSBoris Brezillon return 1; 146693db446aSBoris Brezillon case BBT_BLOCK_RESERVED: 146793db446aSBoris Brezillon return allowbbt ? 0 : 1; 146893db446aSBoris Brezillon } 146993db446aSBoris Brezillon return 1; 147093db446aSBoris Brezillon } 147193db446aSBoris Brezillon 147293db446aSBoris Brezillon /** 147393db446aSBoris Brezillon * nand_markbad_bbt - [NAND Interface] Mark a block bad in the BBT 14745740d4c4SBoris Brezillon * @this: NAND chip object 147593db446aSBoris Brezillon * @offs: offset of the bad block 147693db446aSBoris Brezillon */ 14775740d4c4SBoris Brezillon int nand_markbad_bbt(struct nand_chip *this, loff_t offs) 147893db446aSBoris Brezillon { 147993db446aSBoris Brezillon int block, ret = 0; 148093db446aSBoris Brezillon 148193db446aSBoris Brezillon block = (int)(offs >> this->bbt_erase_shift); 148293db446aSBoris Brezillon 148393db446aSBoris Brezillon /* Mark bad block in memory */ 148493db446aSBoris Brezillon bbt_mark_entry(this, block, BBT_BLOCK_WORN); 148593db446aSBoris Brezillon 148693db446aSBoris Brezillon /* Update flash-based bad block table */ 148793db446aSBoris Brezillon if (this->bbt_options & NAND_BBT_USE_FLASH) 14880813621bSBoris Brezillon ret = nand_update_bbt(this, offs); 148993db446aSBoris Brezillon 149093db446aSBoris Brezillon return ret; 149193db446aSBoris Brezillon } 1492