mtd/drivers/mtd/nand nand_bbt.c,1.21,1.22
dbrown at infradead.org
dbrown at infradead.org
Thu Jun 24 10:24:27 EDT 2004
Update of /home/cvs/mtd/drivers/mtd/nand
In directory phoenix.infradead.org:/tmp/cvs-serv14384
Modified Files:
nand_bbt.c
Log Message:
Always read both BBTs if not versioned. Add support for versioned BBTs with absolute placement.
Index: nand_bbt.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/nand/nand_bbt.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- nand_bbt.c 24 Jun 2004 12:58:22 -0000 1.21
+++ nand_bbt.c 24 Jun 2004 14:24:24 -0000 1.22
@@ -221,17 +221,23 @@
static int read_abs_bbts (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td,
struct nand_bbt_descr *md)
{
- int res;
+ struct nand_chip *this = mtd->priv;
+
+ /* Read the primary version, if available */
+ if (td->options & NAND_BBT_VERSION) {
+ nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
+ td->version[0] = *((char *) &buf[mtd->oobblock + td->veroffs]);
+ printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]);
+ }
+
+ /* Read the mirror version, if available */
+ if (md && (md->options & NAND_BBT_VERSION)) {
+ nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
+ md->version[0] = *((char *) &buf[mtd->oobblock + md->veroffs]);
+ printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]);
+ }
- /* Read the primary table */
- res = read_abs_bbt (mtd, buf, td, -1);
- if (res < 0)
- return res;
-
- if (!md)
- return 0;
- /* Read the mirrored table */
- return read_abs_bbt (mtd, buf, md, -1);
+ return 1;
}
/**
@@ -420,13 +426,14 @@
struct erase_info einfo;
int i, j, res, chip = 0;
int bits, startblock, dir, page, offs, numblocks, sft, sftmsk;
- int nrchips, bbtoffs;
+ int nrchips, bbtoffs, pageoffs;
uint8_t msk[4];
uint8_t rcode = td->reserved_block_code;
size_t retlen, len = 0;
loff_t to;
- if (!rcode) rcode = 0xff;
+ if (!rcode)
+ 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);
@@ -512,15 +519,21 @@
printk (KERN_WARNING "nand_bbt: ECC error while reading block for writing bad block table\n");
}
/* Calc the byte offset in the buffer */
- offs = page - (int)(to >> this->page_shift);
- offs <<= this->page_shift;
+ pageoffs = page - (int)(to >> this->page_shift);
+ offs = pageoffs << this->page_shift;
/* Preset the bbt area with 0xff */
memset (&buf[offs], 0xff, (size_t)(numblocks >> sft));
+ /* Preset the bbt's oob area with 0xff */
+ memset (&buf[len + pageoffs * mtd->oobsize], 0xff,
+ ((len >> this->page_shift) - pageoffs) * mtd->oobsize);
+ if (td->options & NAND_BBT_VERSION) {
+ *((char *) &buf[len + (pageoffs * mtd->oobsize) + td->veroffs]) = td->version[chip];
+ }
} else {
/* Calc length */
len = (size_t) (numblocks >> sft);
/* Make it page aligned ! */
- len += len % mtd->oobblock;
+ len = (len + (mtd->oobblock-1)) & ~(mtd->oobblock-1);
/* Preset the buffer with 0xff */
memset (buf, 0xff, len + (len >> this->page_shift) * mtd->oobsize);
offs = 0;
@@ -603,7 +616,7 @@
struct nand_chip *this = mtd->priv;
struct nand_bbt_descr *td = this->bbt_td;
struct nand_bbt_descr *md = this->bbt_md;
- struct nand_bbt_descr *rd;
+ struct nand_bbt_descr *rd, *rd2;
/* Do we have a bbt per chip ? */
if (td->options & NAND_BBT_PERCHIP)
@@ -614,6 +627,7 @@
for (i = 0; i < chips; i++) {
writeops = 0;
rd = NULL;
+ rd2 = NULL;
/* Per chip or per device ? */
chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1;
/* Mirrored table avilable ? */
@@ -639,6 +653,8 @@
if (td->version[i] == md->version[i]) {
rd = td;
+ if (!(td->options & NAND_BBT_VERSION))
+ rd2 = md;
goto writecheck;
}
@@ -677,6 +693,9 @@
/* read back first ? */
if (rd)
read_abs_bbt (mtd, buf, rd, chipsel);
+ /* If they weren't versioned, read both. */
+ if (rd2)
+ read_abs_bbt (mtd, buf, rd2, chipsel);
/* Write the bad block table to the device ? */
if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
More information about the linux-mtd-cvs
mailing list