Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 298114
b: refs/heads/master
c: e2414f4
h: refs/heads/master
v: v3
  • Loading branch information
Brian Norris authored and David Woodhouse committed Mar 26, 2012
1 parent 4c7680b commit 6ff49c6
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 16 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 050c0c1bb2604a62bb250ff6181e9c00727da510
refs/heads/master: e2414f4c20bd4dc62186fbfd7bdec50bce6d2ead
46 changes: 31 additions & 15 deletions trunk/drivers/mtd/nand/nand_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,15 +392,23 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
* @ofs: offset from device start
*
* This is the default implementation, which can be overridden by a hardware
* specific driver.
* specific driver. We try operations in the following order, according to our
* bbt_options (NAND_BBT_NO_OOB_BBM and NAND_BBT_USE_FLASH):
* (1) erase the affected block, to allow OOB marker to be written cleanly
* (2) update in-memory BBT
* (3) write bad block marker to OOB area of affected block
* (4) update flash-based BBT
* Note that we retain the first error encountered in (3) or (4), finish the
* procedures, and dump the error in the end.
*/
static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
{
struct nand_chip *chip = mtd->priv;
uint8_t buf[2] = { 0, 0 };
int block, ret, i = 0;
int block, res, ret = 0, i = 0;
int write_oob = !(chip->bbt_options & NAND_BBT_NO_OOB_BBM);

if (!(chip->bbt_options & NAND_BBT_USE_FLASH)) {
if (write_oob) {
struct erase_info einfo;

/* Attempt erase before marking OOB */
Expand All @@ -413,23 +421,17 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)

/* Get block number */
block = (int)(ofs >> chip->bbt_erase_shift);
/* Mark block bad in memory-based BBT */
if (chip->bbt)
chip->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);

/* Do we have a flash based bad block table? */
if (chip->bbt_options & NAND_BBT_USE_FLASH)
ret = nand_update_bbt(mtd, ofs);
else {
/* Write bad block marker to OOB */
if (write_oob) {
struct mtd_oob_ops ops;
loff_t wr_ofs = ofs;

nand_get_device(chip, mtd, FL_WRITING);

/*
* Write to first/last page(s) if necessary. If we write to more
* than one location, the first error encountered quits the
* procedure.
*/
ops.datbuf = NULL;
ops.oobbuf = buf;
ops.ooboffs = chip->badblockpos;
Expand All @@ -441,18 +443,28 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
}
ops.mode = MTD_OPS_PLACE_OOB;

/* Write to first/last page(s) if necessary */
if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
wr_ofs += mtd->erasesize - mtd->writesize;
do {
ret = nand_do_write_oob(mtd, wr_ofs, &ops);
res = nand_do_write_oob(mtd, wr_ofs, &ops);
if (!ret)
ret = res;

i++;
wr_ofs += mtd->writesize;
} while (!ret && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE) &&
i < 2);
} while ((chip->bbt_options & NAND_BBT_SCAN2NDPAGE) && i < 2);

nand_release_device(mtd);
}

/* Update flash-based bad block table */
if (chip->bbt_options & NAND_BBT_USE_FLASH) {
res = nand_update_bbt(mtd, ofs);
if (!ret)
ret = res;
}

if (!ret)
mtd->ecc_stats.badblocks++;

Expand Down Expand Up @@ -3260,6 +3272,10 @@ int nand_scan_tail(struct mtd_info *mtd)
int i;
struct nand_chip *chip = mtd->priv;

/* New bad blocks should be marked in OOB, flash-based BBT, or both */
BUG_ON((chip->bbt_options & NAND_BBT_NO_OOB_BBM) &&
!(chip->bbt_options & NAND_BBT_USE_FLASH));

if (!(chip->options & NAND_OWN_BUFFERS))
chip->buffers = kmalloc(sizeof(*chip->buffers), GFP_KERNEL);
if (!chip->buffers)
Expand Down
5 changes: 5 additions & 0 deletions trunk/include/linux/mtd/bbm.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ struct nand_bbt_descr {
#define NAND_BBT_USE_FLASH 0x00020000
/* Do not store flash based bad block table in OOB area; store it in-band */
#define NAND_BBT_NO_OOB 0x00040000
/*
* Do not write new bad block markers to OOB; useful, e.g., when ECC covers
* entire spare area. Must be used with NAND_BBT_USE_FLASH.
*/
#define NAND_BBT_NO_OOB_BBM 0x00080000

/*
* Flag set by nand_create_default_bbt_descr(), marking that the nand_bbt_descr
Expand Down

0 comments on commit 6ff49c6

Please sign in to comment.