aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/nand_bbt.c
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2010-09-30 15:28:01 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2010-10-24 19:53:48 -0400
commit7cba7b14fe179969d7217cca52e28519d7d6ca89 (patch)
tree89d423a12c9f72d990b3e1a8fb394e08bbe2514b /drivers/mtd/nand/nand_bbt.c
parentdf5b4e343c52fcdc54db3f9d07068c98cda6007b (diff)
mtd: nand: add support for BBT without OOB
The first (sixt) byte in the OOB area contains vendor's bad block information. During identification of the NAND chip this information is collected by scanning the complete chip. The option NAND_USE_FLASH_BBT is used to store this information in a sector so we don't have to scan the complete flash. Unfortunately the code stores a marker in order to recognize the BBT in the OOB area. This will fail if the OOB area is completely used for ECC. This patch introduces the option NAND_USE_FLASH_BBT_NO_OOB which has to be used with NAND_USE_FLASH_BBT. It will then store BBT on flash without touching the OOB area. The BBT format on flash remains same except the first page starts with the recognition pattern followed by the version byte. This change was tested in nandsim and it looks good so far :) Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd/nand/nand_bbt.c')
-rw-r--r--drivers/mtd/nand/nand_bbt.c228
1 files changed, 202 insertions, 26 deletions
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 587297e43554..1dcafb8f47dd 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -13,28 +13,37 @@
13 * Description: 13 * Description:
14 * 14 *
15 * When nand_scan_bbt is called, then it tries to find the bad block table 15 * When nand_scan_bbt is called, then it tries to find the bad block table
16 * depending on the options in the bbt descriptor(s). If a bbt is found 16 * depending on the options in the BBT descriptor(s). If no flash based BBT
17 * then the contents are read and the memory based bbt is created. If a 17 * (NAND_USE_FLASH_BBT) is specified then the device is scanned for factory
18 * mirrored bbt is selected then the mirror is searched too and the 18 * marked good / bad blocks. This information is used to create a memory BBT.
19 * versions are compared. If the mirror has a greater version number 19 * Once a new bad block is discovered then the "factory" information is updated
20 * than the mirror bbt is used to build the memory based bbt. 20 * on the device.
21 * If a flash based BBT is specified then the function first tries to find the
22 * BBT on flash. If a BBT is found then the contents are read and the memory
23 * based BBT is created. If a mirrored BBT is selected then the mirror is
24 * searched too and the versions are compared. If the mirror has a greater
25 * version number than the mirror BBT is used to build the memory based BBT.
21 * If the tables are not versioned, then we "or" the bad block information. 26 * If the tables are not versioned, then we "or" the bad block information.
22 * If one of the bbt's is out of date or does not exist it is (re)created. 27 * If one of the BBTs is out of date or does not exist it is (re)created.
23 * If no bbt exists at all then the device is scanned for factory marked 28 * If no BBT exists at all then the device is scanned for factory marked
24 * good / bad blocks and the bad block tables are created. 29 * good / bad blocks and the bad block tables are created.
25 * 30 *
26 * For manufacturer created bbts like the one found on M-SYS DOC devices 31 * For manufacturer created BBTs like the one found on M-SYS DOC devices
27 * the bbt is searched and read but never created 32 * the BBT is searched and read but never created
28 * 33 *
29 * The autogenerated bad block table is located in the last good blocks 34 * The auto generated bad block table is located in the last good blocks
30 * of the device. The table is mirrored, so it can be updated eventually. 35 * of the device. The table is mirrored, so it can be updated eventually.
31 * The table is marked in the oob area with an ident pattern and a version 36 * The table is marked in the OOB area with an ident pattern and a version
32 * number which indicates which of both tables is more up to date. 37 * number which indicates which of both tables is more up to date. If the NAND
38 * controller needs the complete OOB area for the ECC information then the
39 * option NAND_USE_FLASH_BBT_NO_OOB should be used: it moves the ident pattern
40 * and the version byte into the data area and the OOB area will remain
41 * untouched.
33 * 42 *
34 * The table uses 2 bits per block 43 * The table uses 2 bits per block
35 * 11b: block is good 44 * 11b: block is good
36 * 00b: block is factory marked bad 45 * 00b: block is factory marked bad
37 * 01b, 10b: block is marked bad due to wear 46 * 01b, 10b: block is marked bad due to wear
38 * 47 *
39 * The memory bad block table uses the following scheme: 48 * The memory bad block table uses the following scheme:
40 * 00b: block is good 49 * 00b: block is good
@@ -59,6 +68,16 @@
59#include <linux/delay.h> 68#include <linux/delay.h>
60#include <linux/vmalloc.h> 69#include <linux/vmalloc.h>
61 70
71static int check_pattern_no_oob(uint8_t *buf, struct nand_bbt_descr *td)
72{
73 int ret;
74
75 ret = memcmp(buf, td->pattern, td->len);
76 if (!ret)
77 return ret;
78 return -1;
79}
80
62/** 81/**
63 * check_pattern - [GENERIC] check if a pattern is in the buffer 82 * check_pattern - [GENERIC] check if a pattern is in the buffer
64 * @buf: the buffer to search 83 * @buf: the buffer to search
@@ -77,6 +96,9 @@ static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_desc
77 int i, end = 0; 96 int i, end = 0;
78 uint8_t *p = buf; 97 uint8_t *p = buf;
79 98
99 if (td->options & NAND_BBT_NO_OOB)
100 return check_pattern_no_oob(buf, td);
101
80 end = paglen + td->offs; 102 end = paglen + td->offs;
81 if (td->options & NAND_BBT_SCANEMPTY) { 103 if (td->options & NAND_BBT_SCANEMPTY) {
82 for (i = 0; i < end; i++) { 104 for (i = 0; i < end; i++) {
@@ -156,6 +178,25 @@ static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td)
156} 178}
157 179
158/** 180/**
181 * add_marker_len - compute the length of the marker in data area
182 * @td: BBT descriptor used for computation
183 *
184 * The length will be 0 if the markeris located in OOB area.
185 */
186static u32 add_marker_len(struct nand_bbt_descr *td)
187{
188 u32 len;
189
190 if (!(td->options & NAND_BBT_NO_OOB))
191 return 0;
192
193 len = td->len;
194 if (td->options & NAND_BBT_VERSION)
195 len++;
196 return len;
197}
198
199/**
159 * read_bbt - [GENERIC] Read the bad block table starting from page 200 * read_bbt - [GENERIC] Read the bad block table starting from page
160 * @mtd: MTD device structure 201 * @mtd: MTD device structure
161 * @buf: temporary buffer 202 * @buf: temporary buffer
@@ -176,13 +217,24 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
176 loff_t from; 217 loff_t from;
177 int bits = td->options & NAND_BBT_NRBITS_MSK; 218 int bits = td->options & NAND_BBT_NRBITS_MSK;
178 uint8_t msk = (uint8_t) ((1 << bits) - 1); 219 uint8_t msk = (uint8_t) ((1 << bits) - 1);
220 u32 marker_len;
179 int reserved_block_code = td->reserved_block_code; 221 int reserved_block_code = td->reserved_block_code;
180 222
181 totlen = (num * bits) >> 3; 223 totlen = (num * bits) >> 3;
224 marker_len = add_marker_len(td);
182 from = ((loff_t) page) << this->page_shift; 225 from = ((loff_t) page) << this->page_shift;
183 226
184 while (totlen) { 227 while (totlen) {
185 len = min(totlen, (size_t) (1 << this->bbt_erase_shift)); 228 len = min(totlen, (size_t) (1 << this->bbt_erase_shift));
229 if (marker_len) {
230 /*
231 * In case the BBT marker is not in the OOB area it
232 * will be just in the first page.
233 */
234 len -= marker_len;
235 from += marker_len;
236 marker_len = 0;
237 }
186 res = mtd->read(mtd, from, len, &retlen, buf); 238 res = mtd->read(mtd, from, len, &retlen, buf);
187 if (res < 0) { 239 if (res < 0) {
188 if (retlen != len) { 240 if (retlen != len) {
@@ -261,9 +313,25 @@ static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
261} 313}
262 314
263/* 315/*
316 * BBT marker is in the first page, no OOB.
317 */
318static int scan_read_raw_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
319 struct nand_bbt_descr *td)
320{
321 size_t retlen;
322 size_t len;
323
324 len = td->len;
325 if (td->options & NAND_BBT_VERSION)
326 len++;
327
328 return mtd->read(mtd, offs, len, &retlen, buf);
329}
330
331/*
264 * Scan read raw data from flash 332 * Scan read raw data from flash
265 */ 333 */
266static int scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t offs, 334static int scan_read_raw_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
267 size_t len) 335 size_t len)
268{ 336{
269 struct mtd_oob_ops ops; 337 struct mtd_oob_ops ops;
@@ -296,6 +364,15 @@ static int scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
296 return 0; 364 return 0;
297} 365}
298 366
367static int scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
368 size_t len, struct nand_bbt_descr *td)
369{
370 if (td->options & NAND_BBT_NO_OOB)
371 return scan_read_raw_data(mtd, buf, offs, td);
372 else
373 return scan_read_raw_oob(mtd, buf, offs, len);
374}
375
299/* 376/*
300 * Scan write data with oob to flash 377 * Scan write data with oob to flash
301 */ 378 */
@@ -314,6 +391,15 @@ static int scan_write_bbt(struct mtd_info *mtd, loff_t offs, size_t len,
314 return mtd->write_oob(mtd, offs, &ops); 391 return mtd->write_oob(mtd, offs, &ops);
315} 392}
316 393
394static u32 bbt_get_ver_offs(struct mtd_info *mtd, struct nand_bbt_descr *td)
395{
396 u32 ver_offs = td->veroffs;
397
398 if (!(td->options & NAND_BBT_NO_OOB))
399 ver_offs += mtd->writesize;
400 return ver_offs;
401}
402
317/** 403/**
318 * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page 404 * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page
319 * @mtd: MTD device structure 405 * @mtd: MTD device structure
@@ -333,8 +419,8 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
333 /* Read the primary version, if available */ 419 /* Read the primary version, if available */
334 if (td->options & NAND_BBT_VERSION) { 420 if (td->options & NAND_BBT_VERSION) {
335 scan_read_raw(mtd, buf, (loff_t)td->pages[0] << this->page_shift, 421 scan_read_raw(mtd, buf, (loff_t)td->pages[0] << this->page_shift,
336 mtd->writesize); 422 mtd->writesize, td);
337 td->version[0] = buf[mtd->writesize + td->veroffs]; 423 td->version[0] = buf[bbt_get_ver_offs(mtd, td)];
338 printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", 424 printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
339 td->pages[0], td->version[0]); 425 td->pages[0], td->version[0]);
340 } 426 }
@@ -342,8 +428,8 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
342 /* Read the mirror version, if available */ 428 /* Read the mirror version, if available */
343 if (md && (md->options & NAND_BBT_VERSION)) { 429 if (md && (md->options & NAND_BBT_VERSION)) {
344 scan_read_raw(mtd, buf, (loff_t)md->pages[0] << this->page_shift, 430 scan_read_raw(mtd, buf, (loff_t)md->pages[0] << this->page_shift,
345 mtd->writesize); 431 mtd->writesize, td);
346 md->version[0] = buf[mtd->writesize + md->veroffs]; 432 md->version[0] = buf[bbt_get_ver_offs(mtd, md)];
347 printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", 433 printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
348 md->pages[0], md->version[0]); 434 md->pages[0], md->version[0]);
349 } 435 }
@@ -359,7 +445,7 @@ static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd,
359{ 445{
360 int ret, j; 446 int ret, j;
361 447
362 ret = scan_read_raw(mtd, buf, offs, readlen); 448 ret = scan_read_raw_oob(mtd, buf, offs, readlen);
363 if (ret) 449 if (ret)
364 return ret; 450 return ret;
365 451
@@ -466,6 +552,8 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
466 for (i = startblock; i < numblocks;) { 552 for (i = startblock; i < numblocks;) {
467 int ret; 553 int ret;
468 554
555 BUG_ON(bd->options & NAND_BBT_NO_OOB);
556
469 if (bd->options & NAND_BBT_SCANALLPAGES) 557 if (bd->options & NAND_BBT_SCANALLPAGES)
470 ret = scan_block_full(mtd, bd, from, buf, readlen, 558 ret = scan_block_full(mtd, bd, from, buf, readlen,
471 scanlen, len); 559 scanlen, len);
@@ -547,11 +635,12 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
547 loff_t offs = (loff_t)actblock << this->bbt_erase_shift; 635 loff_t offs = (loff_t)actblock << this->bbt_erase_shift;
548 636
549 /* Read first page */ 637 /* Read first page */
550 scan_read_raw(mtd, buf, offs, mtd->writesize); 638 scan_read_raw(mtd, buf, offs, mtd->writesize, td);
551 if (!check_pattern(buf, scanlen, mtd->writesize, td)) { 639 if (!check_pattern(buf, scanlen, mtd->writesize, td)) {
552 td->pages[i] = actblock << blocktopage; 640 td->pages[i] = actblock << blocktopage;
553 if (td->options & NAND_BBT_VERSION) { 641 if (td->options & NAND_BBT_VERSION) {
554 td->version[i] = buf[mtd->writesize + td->veroffs]; 642 offs = bbt_get_ver_offs(mtd, td);
643 td->version[i] = buf[offs];
555 } 644 }
556 break; 645 break;
557 } 646 }
@@ -735,6 +824,21 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
735 memset(&buf[offs], 0xff, (size_t) (numblocks >> sft)); 824 memset(&buf[offs], 0xff, (size_t) (numblocks >> sft));
736 ooboffs = len + (pageoffs * mtd->oobsize); 825 ooboffs = len + (pageoffs * mtd->oobsize);
737 826
827 } else if (td->options & NAND_BBT_NO_OOB) {
828 ooboffs = 0;
829 offs = td->len;
830 /* the version byte */
831 if (td->options & NAND_BBT_VERSION)
832 offs++;
833 /* Calc length */
834 len = (size_t) (numblocks >> sft);
835 len += offs;
836 /* Make it page aligned ! */
837 len = ALIGN(len, mtd->writesize);
838 /* Preset the buffer with 0xff */
839 memset(buf, 0xff, len);
840 /* Pattern is located at the begin of first page */
841 memcpy(buf, td->pattern, td->len);
738 } else { 842 } else {
739 /* Calc length */ 843 /* Calc length */
740 len = (size_t) (numblocks >> sft); 844 len = (size_t) (numblocks >> sft);
@@ -773,7 +877,9 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
773 if (res < 0) 877 if (res < 0)
774 goto outerr; 878 goto outerr;
775 879
776 res = scan_write_bbt(mtd, to, len, buf, &buf[len]); 880 res = scan_write_bbt(mtd, to, len, buf,
881 td->options & NAND_BBT_NO_OOB ? NULL :
882 &buf[len]);
777 if (res < 0) 883 if (res < 0)
778 goto outerr; 884 goto outerr;
779 885
@@ -984,6 +1090,49 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
984} 1090}
985 1091
986/** 1092/**
1093 * verify_bbt_descr - verify the bad block description
1094 * @bd: the table to verify
1095 *
1096 * This functions performs a few sanity checks on the bad block description
1097 * table.
1098 */
1099static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd)
1100{
1101 struct nand_chip *this = mtd->priv;
1102 u32 pattern_len = bd->len;
1103 u32 bits = bd->options & NAND_BBT_NRBITS_MSK;
1104 u32 table_size;
1105
1106 if (!bd)
1107 return;
1108 BUG_ON((this->options & NAND_USE_FLASH_BBT_NO_OOB) &&
1109 !(this->options & NAND_USE_FLASH_BBT));
1110 BUG_ON(!bits);
1111
1112 if (bd->options & NAND_BBT_VERSION)
1113 pattern_len++;
1114
1115 if (bd->options & NAND_BBT_NO_OOB) {
1116 BUG_ON(!(this->options & NAND_USE_FLASH_BBT));
1117 BUG_ON(!(this->options & NAND_USE_FLASH_BBT_NO_OOB));
1118 BUG_ON(bd->offs);
1119 if (bd->options & NAND_BBT_VERSION)
1120 BUG_ON(bd->veroffs != bd->len);
1121 BUG_ON(bd->options & NAND_BBT_SAVECONTENT);
1122 }
1123
1124 if (bd->options & NAND_BBT_PERCHIP)
1125 table_size = this->chipsize >> this->bbt_erase_shift;
1126 else
1127 table_size = mtd->size >> this->bbt_erase_shift;
1128 table_size >>= 3;
1129 table_size *= bits;
1130 if (bd->options & NAND_BBT_NO_OOB)
1131 table_size += pattern_len;
1132 BUG_ON(table_size > (1 << this->bbt_erase_shift));
1133}
1134
1135/**
987 * nand_scan_bbt - [NAND Interface] scan, find, read and maybe create bad block table(s) 1136 * nand_scan_bbt - [NAND Interface] scan, find, read and maybe create bad block table(s)
988 * @mtd: MTD device structure 1137 * @mtd: MTD device structure
989 * @bd: descriptor for the good/bad block search pattern 1138 * @bd: descriptor for the good/bad block search pattern
@@ -1024,6 +1173,8 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
1024 } 1173 }
1025 return res; 1174 return res;
1026 } 1175 }
1176 verify_bbt_descr(mtd, td);
1177 verify_bbt_descr(mtd, md);
1027 1178
1028 /* Allocate a temporary buffer for one eraseblock incl. oob */ 1179 /* Allocate a temporary buffer for one eraseblock incl. oob */
1029 len = (1 << this->bbt_erase_shift); 1180 len = (1 << this->bbt_erase_shift);
@@ -1167,6 +1318,26 @@ static struct nand_bbt_descr bbt_mirror_descr = {
1167 .pattern = mirror_pattern 1318 .pattern = mirror_pattern
1168}; 1319};
1169 1320
1321static struct nand_bbt_descr bbt_main_no_bbt_descr = {
1322 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
1323 | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP
1324 | NAND_BBT_NO_OOB,
1325 .len = 4,
1326 .veroffs = 4,
1327 .maxblocks = 4,
1328 .pattern = bbt_pattern
1329};
1330
1331static struct nand_bbt_descr bbt_mirror_no_bbt_descr = {
1332 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
1333 | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP
1334 | NAND_BBT_NO_OOB,
1335 .len = 4,
1336 .veroffs = 4,
1337 .maxblocks = 4,
1338 .pattern = mirror_pattern
1339};
1340
1170#define BBT_SCAN_OPTIONS (NAND_BBT_SCANLASTPAGE | NAND_BBT_SCAN2NDPAGE | \ 1341#define BBT_SCAN_OPTIONS (NAND_BBT_SCANLASTPAGE | NAND_BBT_SCAN2NDPAGE | \
1171 NAND_BBT_SCANBYTE1AND6) 1342 NAND_BBT_SCANBYTE1AND6)
1172/** 1343/**
@@ -1237,8 +1408,13 @@ int nand_default_bbt(struct mtd_info *mtd)
1237 if (this->options & NAND_USE_FLASH_BBT) { 1408 if (this->options & NAND_USE_FLASH_BBT) {
1238 /* Use the default pattern descriptors */ 1409 /* Use the default pattern descriptors */
1239 if (!this->bbt_td) { 1410 if (!this->bbt_td) {
1240 this->bbt_td = &bbt_main_descr; 1411 if (this->options & NAND_USE_FLASH_BBT_NO_OOB) {
1241 this->bbt_md = &bbt_mirror_descr; 1412 this->bbt_td = &bbt_main_no_bbt_descr;
1413 this->bbt_md = &bbt_mirror_no_bbt_descr;
1414 } else {
1415 this->bbt_td = &bbt_main_descr;
1416 this->bbt_md = &bbt_mirror_descr;
1417 }
1242 } 1418 }
1243 if (!this->badblock_pattern) { 1419 if (!this->badblock_pattern) {
1244 this->badblock_pattern = (mtd->writesize > 512) ? &largepage_flashbased : &smallpage_flashbased; 1420 this->badblock_pattern = (mtd->writesize > 512) ? &largepage_flashbased : &smallpage_flashbased;