aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/nand_bbt.c
diff options
context:
space:
mode:
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;