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