diff options
Diffstat (limited to 'drivers/mtd/nand/nand_bbt.c')
-rw-r--r-- | drivers/mtd/nand/nand_bbt.c | 228 |
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 | ||
71 | static 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 | */ | ||
186 | static 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 | */ | ||
318 | static 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 | */ |
266 | static int scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t offs, | 334 | static 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 | ||
367 | static 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 | ||
394 | static 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 | */ | ||
1099 | static 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 | ||
1321 | static 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 | |||
1331 | static 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; |