aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Norris <computersforpeace@gmail.com>2013-07-30 20:52:56 -0400
committerNitin Garg <nitin.garg@freescale.com>2014-04-16 09:06:00 -0400
commit11591a5adcb4ddf9193a9154194360cc2a27850d (patch)
tree01e78e6e315dea0affaf3da4478de71bda49175b
parentb25c1205dee1c63dc49d0d9c6788fb64a3c196ca (diff)
mtd: nand: remove multiplied-by-2 block logic
The parent commit 771c568bcf915e708ae819ef9d07d862f7e2da86 ("mtd: nand: add accessors, macros for in-memory BBT") makes the following comment obsolete: /* * Note that numblocks is 2 * (real numblocks) here, see i+=2 * below as it makes shifting and masking less painful */ I don't think it ever could have been "less painful" to have to shift an extra bit (or 2, or 3) at various points in nand_bbt.c (and even outside, since we leak our in-memory format). But now it is certainly more painful, since we have nice macros and functions to retrieve the relevant portions of the BBT. This patch removes any points where the block number is doubled/halved/otherwise-shifted, instead representing the block number in its most natural form: as the actual block number. Signed-off-by: Brian Norris <computersforpeace@gmail.com> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> Signed-off-by: Huang Shijie <b32955@freescale.com>
-rw-r--r--drivers/mtd/nand/nand_bbt.c83
1 files changed, 35 insertions, 48 deletions
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 3b6aff9b26c0..873f82b0f191 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -181,7 +181,7 @@ static u32 add_marker_len(struct nand_bbt_descr *td)
181 * @page: the starting page 181 * @page: the starting page
182 * @num: the number of bbt descriptors to read 182 * @num: the number of bbt descriptors to read
183 * @td: the bbt describtion table 183 * @td: the bbt describtion table
184 * @offs: offset in the memory table 184 * @offs: block number offset in the table
185 * 185 *
186 * Read the bad block table starting from page. 186 * Read the bad block table starting from page.
187 */ 187 */
@@ -231,15 +231,15 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
231 /* Analyse data */ 231 /* Analyse data */
232 for (i = 0; i < len; i++) { 232 for (i = 0; i < len; i++) {
233 uint8_t dat = buf[i]; 233 uint8_t dat = buf[i];
234 for (j = 0; j < 8; j += bits, act += 2) { 234 for (j = 0; j < 8; j += bits, act++) {
235 uint8_t tmp = (dat >> j) & msk; 235 uint8_t tmp = (dat >> j) & msk;
236 if (tmp == msk) 236 if (tmp == msk)
237 continue; 237 continue;
238 if (reserved_block_code && (tmp == reserved_block_code)) { 238 if (reserved_block_code && (tmp == reserved_block_code)) {
239 pr_info("nand_read_bbt: reserved block at 0x%012llx\n", 239 pr_info("nand_read_bbt: reserved block at 0x%012llx\n",
240 (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift); 240 (loff_t)(offs + act) <<
241 bbt_mark_entry(this, (offs << 2) + 241 this->bbt_erase_shift);
242 (act >> 1), 242 bbt_mark_entry(this, offs + act,
243 BBT_BLOCK_RESERVED); 243 BBT_BLOCK_RESERVED);
244 mtd->ecc_stats.bbtblocks++; 244 mtd->ecc_stats.bbtblocks++;
245 continue; 245 continue;
@@ -249,15 +249,14 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
249 * move this message to pr_debug. 249 * move this message to pr_debug.
250 */ 250 */
251 pr_info("nand_read_bbt: bad block at 0x%012llx\n", 251 pr_info("nand_read_bbt: bad block at 0x%012llx\n",
252 (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift); 252 (loff_t)(offs + act) <<
253 this->bbt_erase_shift);
253 /* Factory marked bad or worn out? */ 254 /* Factory marked bad or worn out? */
254 if (tmp == 0) 255 if (tmp == 0)
255 bbt_mark_entry(this, (offs << 2) + 256 bbt_mark_entry(this, offs + act,
256 (act >> 1),
257 BBT_BLOCK_FACTORY_BAD); 257 BBT_BLOCK_FACTORY_BAD);
258 else 258 else
259 bbt_mark_entry(this, (offs << 2) + 259 bbt_mark_entry(this, offs + act,
260 (act >> 1),
261 BBT_BLOCK_WORN); 260 BBT_BLOCK_WORN);
262 mtd->ecc_stats.badblocks++; 261 mtd->ecc_stats.badblocks++;
263 } 262 }
@@ -293,7 +292,7 @@ static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
293 td, offs); 292 td, offs);
294 if (res) 293 if (res)
295 return res; 294 return res;
296 offs += this->chipsize >> (this->bbt_erase_shift + 2); 295 offs += this->chipsize >> this->bbt_erase_shift;
297 } 296 }
298 } else { 297 } else {
299 res = read_bbt(mtd, buf, td->pages[0], 298 res = read_bbt(mtd, buf, td->pages[0],
@@ -517,11 +516,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
517 } 516 }
518 517
519 if (chip == -1) { 518 if (chip == -1) {
520 /* 519 numblocks = mtd->size >> this->bbt_erase_shift;
521 * Note that numblocks is 2 * (real numblocks) here, see i+=2
522 * below as it makes shifting and masking less painful
523 */
524 numblocks = mtd->size >> (this->bbt_erase_shift - 1);
525 startblock = 0; 520 startblock = 0;
526 from = 0; 521 from = 0;
527 } else { 522 } else {
@@ -530,16 +525,16 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
530 chip + 1, this->numchips); 525 chip + 1, this->numchips);
531 return -EINVAL; 526 return -EINVAL;
532 } 527 }
533 numblocks = this->chipsize >> (this->bbt_erase_shift - 1); 528 numblocks = this->chipsize >> this->bbt_erase_shift;
534 startblock = chip * numblocks; 529 startblock = chip * numblocks;
535 numblocks += startblock; 530 numblocks += startblock;
536 from = (loff_t)startblock << (this->bbt_erase_shift - 1); 531 from = (loff_t)startblock << this->bbt_erase_shift;
537 } 532 }
538 533
539 if (this->bbt_options & NAND_BBT_SCANLASTPAGE) 534 if (this->bbt_options & NAND_BBT_SCANLASTPAGE)
540 from += mtd->erasesize - (mtd->writesize * numpages); 535 from += mtd->erasesize - (mtd->writesize * numpages);
541 536
542 for (i = startblock; i < numblocks;) { 537 for (i = startblock; i < numblocks; i++) {
543 int ret; 538 int ret;
544 539
545 BUG_ON(bd->options & NAND_BBT_NO_OOB); 540 BUG_ON(bd->options & NAND_BBT_NO_OOB);
@@ -554,13 +549,12 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
554 return ret; 549 return ret;
555 550
556 if (ret) { 551 if (ret) {
557 bbt_mark_entry(this, i >> 1, BBT_BLOCK_FACTORY_BAD); 552 bbt_mark_entry(this, i, BBT_BLOCK_FACTORY_BAD);
558 pr_warn("Bad eraseblock %d at 0x%012llx\n", 553 pr_warn("Bad eraseblock %d at 0x%012llx\n",
559 i >> 1, (unsigned long long)from); 554 i, (unsigned long long)from);
560 mtd->ecc_stats.badblocks++; 555 mtd->ecc_stats.badblocks++;
561 } 556 }
562 557
563 i += 2;
564 from += (1 << this->bbt_erase_shift); 558 from += (1 << this->bbt_erase_shift);
565 } 559 }
566 return 0; 560 return 0;
@@ -683,9 +677,9 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
683{ 677{
684 struct nand_chip *this = mtd->priv; 678 struct nand_chip *this = mtd->priv;
685 struct erase_info einfo; 679 struct erase_info einfo;
686 int i, j, res, chip = 0; 680 int i, res, chip = 0;
687 int bits, startblock, dir, page, offs, numblocks, sft, sftmsk; 681 int bits, startblock, dir, page, offs, numblocks, sft, sftmsk;
688 int nrchips, bbtoffs, pageoffs, ooboffs; 682 int nrchips, pageoffs, ooboffs;
689 uint8_t msk[4]; 683 uint8_t msk[4];
690 uint8_t rcode = td->reserved_block_code; 684 uint8_t rcode = td->reserved_block_code;
691 size_t retlen, len = 0; 685 size_t retlen, len = 0;
@@ -775,8 +769,6 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
775 default: return -EINVAL; 769 default: return -EINVAL;
776 } 770 }
777 771
778 bbtoffs = chip * (numblocks >> 2);
779
780 to = ((loff_t)page) << this->page_shift; 772 to = ((loff_t)page) << this->page_shift;
781 773
782 /* Must we save the block contents? */ 774 /* Must we save the block contents? */
@@ -841,16 +833,12 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
841 buf[ooboffs + td->veroffs] = td->version[chip]; 833 buf[ooboffs + td->veroffs] = td->version[chip];
842 834
843 /* Walk through the memory table */ 835 /* Walk through the memory table */
844 for (i = 0; i < numblocks;) { 836 for (i = 0; i < numblocks; i++) {
845 uint8_t dat; 837 uint8_t dat;
846 dat = bbt_get_entry(this, (bbtoffs << 2) + i); 838 int sftcnt = (i << (3 - sft)) & sftmsk;
847 for (j = 0; j < 4; j++, i++) { 839 dat = bbt_get_entry(this, chip * numblocks + i);
848 int sftcnt = (i << (3 - sft)) & sftmsk; 840 /* Do not store the reserved bbt blocks! */
849 /* Do not store the reserved bbt blocks! */ 841 buf[offs + (i >> sft)] &= ~(msk[dat] << sftcnt);
850 buf[offs + (i >> sft)] &=
851 ~(msk[dat & 0x03] << sftcnt);
852 dat >>= 2;
853 }
854 } 842 }
855 843
856 memset(&einfo, 0, sizeof(einfo)); 844 memset(&einfo, 0, sizeof(einfo));
@@ -1053,12 +1041,12 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
1053 if (td->pages[i] == -1) 1041 if (td->pages[i] == -1)
1054 continue; 1042 continue;
1055 block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift); 1043 block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift);
1056 block <<= 1; 1044 oldval = bbt_get_entry(this, block);
1057 oldval = bbt_get_entry(this, block >> 1); 1045 bbt_mark_entry(this, block, BBT_BLOCK_RESERVED);
1058 bbt_mark_entry(this, block >> 1, BBT_BLOCK_RESERVED);
1059 if ((oldval != BBT_BLOCK_RESERVED) && 1046 if ((oldval != BBT_BLOCK_RESERVED) &&
1060 td->reserved_block_code) 1047 td->reserved_block_code)
1061 nand_update_bbt(mtd, (loff_t)block << (this->bbt_erase_shift - 1)); 1048 nand_update_bbt(mtd, (loff_t)block <<
1049 this->bbt_erase_shift);
1062 continue; 1050 continue;
1063 } 1051 }
1064 update = 0; 1052 update = 0;
@@ -1066,13 +1054,12 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
1066 block = ((i + 1) * nrblocks) - td->maxblocks; 1054 block = ((i + 1) * nrblocks) - td->maxblocks;
1067 else 1055 else
1068 block = i * nrblocks; 1056 block = i * nrblocks;
1069 block <<= 1;
1070 for (j = 0; j < td->maxblocks; j++) { 1057 for (j = 0; j < td->maxblocks; j++) {
1071 oldval = bbt_get_entry(this, block >> 1); 1058 oldval = bbt_get_entry(this, block);
1072 bbt_mark_entry(this, block >> 1, BBT_BLOCK_RESERVED); 1059 bbt_mark_entry(this, block, BBT_BLOCK_RESERVED);
1073 if (oldval != BBT_BLOCK_RESERVED) 1060 if (oldval != BBT_BLOCK_RESERVED)
1074 update = 1; 1061 update = 1;
1075 block += 2; 1062 block++;
1076 } 1063 }
1077 /* 1064 /*
1078 * If we want reserved blocks to be recorded to flash, and some 1065 * If we want reserved blocks to be recorded to flash, and some
@@ -1080,7 +1067,8 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
1080 * bbts. This should only happen once. 1067 * bbts. This should only happen once.
1081 */ 1068 */
1082 if (update && td->reserved_block_code) 1069 if (update && td->reserved_block_code)
1083 nand_update_bbt(mtd, (loff_t)(block - 2) << (this->bbt_erase_shift - 1)); 1070 nand_update_bbt(mtd, (loff_t)(block - 1) <<
1071 this->bbt_erase_shift);
1084 } 1072 }
1085} 1073}
1086 1074
@@ -1385,13 +1373,12 @@ int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
1385 int block; 1373 int block;
1386 uint8_t res; 1374 uint8_t res;
1387 1375
1388 /* Get block number * 2 */ 1376 block = (int)(offs >> this->bbt_erase_shift);
1389 block = (int)(offs >> (this->bbt_erase_shift - 1)); 1377 res = bbt_get_entry(this, block);
1390 res = bbt_get_entry(this, block >> 1);
1391 1378
1392 pr_debug("nand_isbad_bbt(): bbt info for offs 0x%08x: " 1379 pr_debug("nand_isbad_bbt(): bbt info for offs 0x%08x: "
1393 "(block %d) 0x%02x\n", 1380 "(block %d) 0x%02x\n",
1394 (unsigned int)offs, block >> 1, res); 1381 (unsigned int)offs, block, res);
1395 1382
1396 switch ((int)res) { 1383 switch ((int)res) {
1397 case BBT_BLOCK_GOOD: 1384 case BBT_BLOCK_GOOD: