mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-21 08:19:28 +00:00
mtd: nand: remove multiplied-by-2 block logic
The parent commit 771c568bcf
("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>
This commit is contained in:
parent
771c568bcf
commit
b4d20d601f
1 changed files with 35 additions and 48 deletions
|
@ -181,7 +181,7 @@ static u32 add_marker_len(struct nand_bbt_descr *td)
|
|||
* @page: the starting page
|
||||
* @num: the number of bbt descriptors to read
|
||||
* @td: the bbt describtion table
|
||||
* @offs: offset in the memory table
|
||||
* @offs: block number offset in the table
|
||||
*
|
||||
* Read the bad block table starting from page.
|
||||
*/
|
||||
|
@ -231,15 +231,15 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
|
|||
/* Analyse data */
|
||||
for (i = 0; i < len; i++) {
|
||||
uint8_t dat = buf[i];
|
||||
for (j = 0; j < 8; j += bits, act += 2) {
|
||||
for (j = 0; j < 8; j += bits, act++) {
|
||||
uint8_t tmp = (dat >> j) & msk;
|
||||
if (tmp == msk)
|
||||
continue;
|
||||
if (reserved_block_code && (tmp == reserved_block_code)) {
|
||||
pr_info("nand_read_bbt: reserved block at 0x%012llx\n",
|
||||
(loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
|
||||
bbt_mark_entry(this, (offs << 2) +
|
||||
(act >> 1),
|
||||
(loff_t)(offs + act) <<
|
||||
this->bbt_erase_shift);
|
||||
bbt_mark_entry(this, offs + act,
|
||||
BBT_BLOCK_RESERVED);
|
||||
mtd->ecc_stats.bbtblocks++;
|
||||
continue;
|
||||
|
@ -249,15 +249,14 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
|
|||
* move this message to pr_debug.
|
||||
*/
|
||||
pr_info("nand_read_bbt: bad block at 0x%012llx\n",
|
||||
(loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
|
||||
(loff_t)(offs + act) <<
|
||||
this->bbt_erase_shift);
|
||||
/* Factory marked bad or worn out? */
|
||||
if (tmp == 0)
|
||||
bbt_mark_entry(this, (offs << 2) +
|
||||
(act >> 1),
|
||||
bbt_mark_entry(this, offs + act,
|
||||
BBT_BLOCK_FACTORY_BAD);
|
||||
else
|
||||
bbt_mark_entry(this, (offs << 2) +
|
||||
(act >> 1),
|
||||
bbt_mark_entry(this, offs + act,
|
||||
BBT_BLOCK_WORN);
|
||||
mtd->ecc_stats.badblocks++;
|
||||
}
|
||||
|
@ -293,7 +292,7 @@ static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
|
|||
td, offs);
|
||||
if (res)
|
||||
return res;
|
||||
offs += this->chipsize >> (this->bbt_erase_shift + 2);
|
||||
offs += this->chipsize >> this->bbt_erase_shift;
|
||||
}
|
||||
} else {
|
||||
res = read_bbt(mtd, buf, td->pages[0],
|
||||
|
@ -517,11 +516,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
|
|||
}
|
||||
|
||||
if (chip == -1) {
|
||||
/*
|
||||
* Note that numblocks is 2 * (real numblocks) here, see i+=2
|
||||
* below as it makes shifting and masking less painful
|
||||
*/
|
||||
numblocks = mtd->size >> (this->bbt_erase_shift - 1);
|
||||
numblocks = mtd->size >> this->bbt_erase_shift;
|
||||
startblock = 0;
|
||||
from = 0;
|
||||
} else {
|
||||
|
@ -530,16 +525,16 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
|
|||
chip + 1, this->numchips);
|
||||
return -EINVAL;
|
||||
}
|
||||
numblocks = this->chipsize >> (this->bbt_erase_shift - 1);
|
||||
numblocks = this->chipsize >> this->bbt_erase_shift;
|
||||
startblock = chip * numblocks;
|
||||
numblocks += startblock;
|
||||
from = (loff_t)startblock << (this->bbt_erase_shift - 1);
|
||||
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;) {
|
||||
for (i = startblock; i < numblocks; i++) {
|
||||
int ret;
|
||||
|
||||
BUG_ON(bd->options & NAND_BBT_NO_OOB);
|
||||
|
@ -554,13 +549,12 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
|
|||
return ret;
|
||||
|
||||
if (ret) {
|
||||
bbt_mark_entry(this, i >> 1, BBT_BLOCK_FACTORY_BAD);
|
||||
bbt_mark_entry(this, i, BBT_BLOCK_FACTORY_BAD);
|
||||
pr_warn("Bad eraseblock %d at 0x%012llx\n",
|
||||
i >> 1, (unsigned long long)from);
|
||||
i, (unsigned long long)from);
|
||||
mtd->ecc_stats.badblocks++;
|
||||
}
|
||||
|
||||
i += 2;
|
||||
from += (1 << this->bbt_erase_shift);
|
||||
}
|
||||
return 0;
|
||||
|
@ -683,9 +677,9 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
|
|||
{
|
||||
struct nand_chip *this = mtd->priv;
|
||||
struct erase_info einfo;
|
||||
int i, j, res, chip = 0;
|
||||
int i, res, chip = 0;
|
||||
int bits, startblock, dir, page, offs, numblocks, sft, sftmsk;
|
||||
int nrchips, bbtoffs, pageoffs, ooboffs;
|
||||
int nrchips, pageoffs, ooboffs;
|
||||
uint8_t msk[4];
|
||||
uint8_t rcode = td->reserved_block_code;
|
||||
size_t retlen, len = 0;
|
||||
|
@ -775,8 +769,6 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
|
|||
default: return -EINVAL;
|
||||
}
|
||||
|
||||
bbtoffs = chip * (numblocks >> 2);
|
||||
|
||||
to = ((loff_t)page) << this->page_shift;
|
||||
|
||||
/* Must we save the block contents? */
|
||||
|
@ -841,16 +833,12 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
|
|||
buf[ooboffs + td->veroffs] = td->version[chip];
|
||||
|
||||
/* Walk through the memory table */
|
||||
for (i = 0; i < numblocks;) {
|
||||
for (i = 0; i < numblocks; i++) {
|
||||
uint8_t dat;
|
||||
dat = bbt_get_entry(this, (bbtoffs << 2) + i);
|
||||
for (j = 0; j < 4; j++, i++) {
|
||||
int sftcnt = (i << (3 - sft)) & sftmsk;
|
||||
/* Do not store the reserved bbt blocks! */
|
||||
buf[offs + (i >> sft)] &=
|
||||
~(msk[dat & 0x03] << sftcnt);
|
||||
dat >>= 2;
|
||||
}
|
||||
int sftcnt = (i << (3 - sft)) & sftmsk;
|
||||
dat = bbt_get_entry(this, chip * numblocks + i);
|
||||
/* Do not store the reserved bbt blocks! */
|
||||
buf[offs + (i >> sft)] &= ~(msk[dat] << sftcnt);
|
||||
}
|
||||
|
||||
memset(&einfo, 0, sizeof(einfo));
|
||||
|
@ -1053,12 +1041,12 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
|
|||
if (td->pages[i] == -1)
|
||||
continue;
|
||||
block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift);
|
||||
block <<= 1;
|
||||
oldval = bbt_get_entry(this, block >> 1);
|
||||
bbt_mark_entry(this, block >> 1, BBT_BLOCK_RESERVED);
|
||||
oldval = bbt_get_entry(this, block);
|
||||
bbt_mark_entry(this, block, BBT_BLOCK_RESERVED);
|
||||
if ((oldval != BBT_BLOCK_RESERVED) &&
|
||||
td->reserved_block_code)
|
||||
nand_update_bbt(mtd, (loff_t)block << (this->bbt_erase_shift - 1));
|
||||
nand_update_bbt(mtd, (loff_t)block <<
|
||||
this->bbt_erase_shift);
|
||||
continue;
|
||||
}
|
||||
update = 0;
|
||||
|
@ -1066,13 +1054,12 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
|
|||
block = ((i + 1) * nrblocks) - td->maxblocks;
|
||||
else
|
||||
block = i * nrblocks;
|
||||
block <<= 1;
|
||||
for (j = 0; j < td->maxblocks; j++) {
|
||||
oldval = bbt_get_entry(this, block >> 1);
|
||||
bbt_mark_entry(this, block >> 1, BBT_BLOCK_RESERVED);
|
||||
oldval = bbt_get_entry(this, block);
|
||||
bbt_mark_entry(this, block, BBT_BLOCK_RESERVED);
|
||||
if (oldval != BBT_BLOCK_RESERVED)
|
||||
update = 1;
|
||||
block += 2;
|
||||
block++;
|
||||
}
|
||||
/*
|
||||
* 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)
|
|||
* bbts. This should only happen once.
|
||||
*/
|
||||
if (update && td->reserved_block_code)
|
||||
nand_update_bbt(mtd, (loff_t)(block - 2) << (this->bbt_erase_shift - 1));
|
||||
nand_update_bbt(mtd, (loff_t)(block - 1) <<
|
||||
this->bbt_erase_shift);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1385,13 +1373,12 @@ int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
|
|||
int block;
|
||||
uint8_t res;
|
||||
|
||||
/* Get block number * 2 */
|
||||
block = (int)(offs >> (this->bbt_erase_shift - 1));
|
||||
res = bbt_get_entry(this, block >> 1);
|
||||
block = (int)(offs >> this->bbt_erase_shift);
|
||||
res = bbt_get_entry(this, block);
|
||||
|
||||
pr_debug("nand_isbad_bbt(): bbt info for offs 0x%08x: "
|
||||
"(block %d) 0x%02x\n",
|
||||
(unsigned int)offs, block >> 1, res);
|
||||
(unsigned int)offs, block, res);
|
||||
|
||||
switch ((int)res) {
|
||||
case BBT_BLOCK_GOOD:
|
||||
|
|
Loading…
Reference in a new issue