diff options
Diffstat (limited to 'drivers/mtd/nand/raw/nand_bbt.c')
-rw-r--r-- | drivers/mtd/nand/raw/nand_bbt.c | 73 |
1 files changed, 39 insertions, 34 deletions
diff --git a/drivers/mtd/nand/raw/nand_bbt.c b/drivers/mtd/nand/raw/nand_bbt.c index 19a2b563acdf..fd3c10216eda 100644 --- a/drivers/mtd/nand/raw/nand_bbt.c +++ b/drivers/mtd/nand/raw/nand_bbt.c @@ -264,18 +264,19 @@ static int read_abs_bbt(struct nand_chip *this, uint8_t *buf, struct nand_bbt_descr *td, int chip) { struct mtd_info *mtd = nand_to_mtd(this); + u64 targetsize = nanddev_target_size(&this->base); int res = 0, i; if (td->options & NAND_BBT_PERCHIP) { int offs = 0; - for (i = 0; i < this->numchips; i++) { + for (i = 0; i < nanddev_ntargets(&this->base); i++) { if (chip == -1 || chip == i) res = read_bbt(this, buf, td->pages[i], - this->chipsize >> this->bbt_erase_shift, + targetsize >> this->bbt_erase_shift, td, offs); if (res) return res; - offs += this->chipsize >> this->bbt_erase_shift; + offs += targetsize >> this->bbt_erase_shift; } } else { res = read_bbt(this, buf, td->pages[0], @@ -415,11 +416,12 @@ static void read_abs_bbts(struct nand_chip *this, uint8_t *buf, /* Scan a given block partially */ static int scan_block_fast(struct nand_chip *this, struct nand_bbt_descr *bd, - loff_t offs, uint8_t *buf, int numpages) + loff_t offs, uint8_t *buf) { struct mtd_info *mtd = nand_to_mtd(this); + struct mtd_oob_ops ops; - int j, ret; + int ret, page_offset; ops.ooblen = mtd->oobsize; ops.oobbuf = buf; @@ -427,12 +429,15 @@ static int scan_block_fast(struct nand_chip *this, struct nand_bbt_descr *bd, ops.datbuf = NULL; ops.mode = MTD_OPS_PLACE_OOB; - for (j = 0; j < numpages; j++) { + page_offset = nand_bbm_get_next_page(this, 0); + + while (page_offset >= 0) { /* * Read the full oob until read_oob is fixed to handle single * byte reads for 16 bit buswidth. */ - ret = mtd_read_oob(mtd, offs, &ops); + ret = mtd_read_oob(mtd, offs + (page_offset * mtd->writesize), + &ops); /* Ignore ECC errors when checking for BBM */ if (ret && !mtd_is_bitflip_or_eccerr(ret)) return ret; @@ -440,8 +445,9 @@ static int scan_block_fast(struct nand_chip *this, struct nand_bbt_descr *bd, if (check_short_pattern(buf, bd)) return 1; - offs += mtd->writesize; + page_offset = nand_bbm_get_next_page(this, page_offset + 1); } + return 0; } @@ -459,43 +465,35 @@ static int scan_block_fast(struct nand_chip *this, struct nand_bbt_descr *bd, static int create_bbt(struct nand_chip *this, uint8_t *buf, struct nand_bbt_descr *bd, int chip) { + u64 targetsize = nanddev_target_size(&this->base); struct mtd_info *mtd = nand_to_mtd(this); - int i, numblocks, numpages; - int startblock; + int i, numblocks, startblock; loff_t from; pr_info("Scanning device for bad blocks\n"); - if (bd->options & NAND_BBT_SCAN2NDPAGE) - numpages = 2; - else - numpages = 1; - if (chip == -1) { numblocks = mtd->size >> this->bbt_erase_shift; startblock = 0; from = 0; } else { - if (chip >= this->numchips) { + if (chip >= nanddev_ntargets(&this->base)) { pr_warn("create_bbt(): chipnr (%d) > available chips (%d)\n", - chip + 1, this->numchips); + chip + 1, nanddev_ntargets(&this->base)); return -EINVAL; } - numblocks = this->chipsize >> this->bbt_erase_shift; + numblocks = targetsize >> this->bbt_erase_shift; startblock = chip * numblocks; numblocks += startblock; from = (loff_t)startblock << this->bbt_erase_shift; } - if (this->bbt_options & NAND_BBT_SCANLASTPAGE) - from += mtd->erasesize - (mtd->writesize * numpages); - for (i = startblock; i < numblocks; i++) { int ret; BUG_ON(bd->options & NAND_BBT_NO_OOB); - ret = scan_block_fast(this, bd, from, buf, numpages); + ret = scan_block_fast(this, bd, from, buf); if (ret < 0) return ret; @@ -529,6 +527,7 @@ static int create_bbt(struct nand_chip *this, uint8_t *buf, static int search_bbt(struct nand_chip *this, uint8_t *buf, struct nand_bbt_descr *td) { + u64 targetsize = nanddev_target_size(&this->base); struct mtd_info *mtd = nand_to_mtd(this); int i, chips; int startblock, block, dir; @@ -547,8 +546,8 @@ static int search_bbt(struct nand_chip *this, uint8_t *buf, /* Do we have a bbt per chip? */ if (td->options & NAND_BBT_PERCHIP) { - chips = this->numchips; - bbtblocks = this->chipsize >> this->bbt_erase_shift; + chips = nanddev_ntargets(&this->base); + bbtblocks = targetsize >> this->bbt_erase_shift; startblock &= bbtblocks - 1; } else { chips = 1; @@ -576,7 +575,7 @@ static int search_bbt(struct nand_chip *this, uint8_t *buf, break; } } - startblock += this->chipsize >> this->bbt_erase_shift; + startblock += targetsize >> this->bbt_erase_shift; } /* Check, if we found a bbt for each requested chip */ for (i = 0; i < chips; i++) { @@ -626,6 +625,7 @@ static void search_read_bbts(struct nand_chip *this, uint8_t *buf, static int get_bbt_block(struct nand_chip *this, struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chip) { + u64 targetsize = nanddev_target_size(&this->base); int startblock, dir, page, numblocks, i; /* @@ -637,9 +637,9 @@ static int get_bbt_block(struct nand_chip *this, struct nand_bbt_descr *td, return td->pages[chip] >> (this->bbt_erase_shift - this->page_shift); - numblocks = (int)(this->chipsize >> this->bbt_erase_shift); + numblocks = (int)(targetsize >> this->bbt_erase_shift); if (!(td->options & NAND_BBT_PERCHIP)) - numblocks *= this->numchips; + numblocks *= nanddev_ntargets(&this->base); /* * Automatic placement of the bad block table. Search direction @@ -717,6 +717,7 @@ static int write_bbt(struct nand_chip *this, uint8_t *buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel) { + u64 targetsize = nanddev_target_size(&this->base); struct mtd_info *mtd = nand_to_mtd(this); struct erase_info einfo; int i, res, chip = 0; @@ -737,10 +738,10 @@ static int write_bbt(struct nand_chip *this, uint8_t *buf, rcode = 0xff; /* Write bad block table per chip rather than per device? */ if (td->options & NAND_BBT_PERCHIP) { - numblocks = (int)(this->chipsize >> this->bbt_erase_shift); + numblocks = (int)(targetsize >> this->bbt_erase_shift); /* Full device write or specific chip? */ if (chipsel == -1) { - nrchips = this->numchips; + nrchips = nanddev_ntargets(&this->base); } else { nrchips = chipsel + 1; chip = chipsel; @@ -901,7 +902,9 @@ static int write_bbt(struct nand_chip *this, uint8_t *buf, static inline int nand_memory_bbt(struct nand_chip *this, struct nand_bbt_descr *bd) { - return create_bbt(this, this->data_buf, bd, -1); + u8 *pagebuf = nand_get_data_buf(this); + + return create_bbt(this, pagebuf, bd, -1); } /** @@ -925,7 +928,7 @@ static int check_create(struct nand_chip *this, uint8_t *buf, /* Do we have a bbt per chip? */ if (td->options & NAND_BBT_PERCHIP) - chips = this->numchips; + chips = nanddev_ntargets(&this->base); else chips = 1; @@ -1097,14 +1100,15 @@ static int nand_update_bbt(struct nand_chip *this, loff_t offs) */ static void mark_bbt_region(struct nand_chip *this, struct nand_bbt_descr *td) { + u64 targetsize = nanddev_target_size(&this->base); struct mtd_info *mtd = nand_to_mtd(this); int i, j, chips, block, nrblocks, update; uint8_t oldval; /* Do we have a bbt per chip? */ if (td->options & NAND_BBT_PERCHIP) { - chips = this->numchips; - nrblocks = (int)(this->chipsize >> this->bbt_erase_shift); + chips = nanddev_ntargets(&this->base); + nrblocks = (int)(targetsize >> this->bbt_erase_shift); } else { chips = 1; nrblocks = (int)(mtd->size >> this->bbt_erase_shift); @@ -1157,6 +1161,7 @@ static void mark_bbt_region(struct nand_chip *this, struct nand_bbt_descr *td) */ static void verify_bbt_descr(struct nand_chip *this, struct nand_bbt_descr *bd) { + u64 targetsize = nanddev_target_size(&this->base); struct mtd_info *mtd = nand_to_mtd(this); u32 pattern_len; u32 bits; @@ -1185,7 +1190,7 @@ static void verify_bbt_descr(struct nand_chip *this, struct nand_bbt_descr *bd) } if (bd->options & NAND_BBT_PERCHIP) - table_size = this->chipsize >> this->bbt_erase_shift; + table_size = targetsize >> this->bbt_erase_shift; else table_size = mtd->size >> this->bbt_erase_shift; table_size >>= 3; |