Lines Matching +full:nand +full:- +full:ecc +full:- +full:placement

1 // SPDX-License-Identifier: GPL-2.0-only
4 * Bad block table support for the NAND driver
26 * For manufacturer created BBTs like the one found on M-SYS DOC devices
32 * number which indicates which of both tables is more up to date. If the NAND
33 * controller needs the complete OOB area for the ECC information then the
52 * - bbts start at a page boundary, if autolocated on a block boundary
53 * - the space necessary for a bbt in FLASH does not exceed a block boundary
78 uint8_t entry = chip->bbt[block >> BBT_ENTRY_SHIFT]; in bbt_get_entry()
87 chip->bbt[block >> BBT_ENTRY_SHIFT] |= msk; in bbt_mark_entry()
92 if (memcmp(buf, td->pattern, td->len)) in check_pattern_no_oob()
93 return -1; in check_pattern_no_oob()
98 * check_pattern - [GENERIC] check if a pattern is in the buffer
109 if (td->options & NAND_BBT_NO_OOB) in check_pattern()
113 if (memcmp(buf + paglen + td->offs, td->pattern, td->len)) in check_pattern()
114 return -1; in check_pattern()
120 * check_short_pattern - [GENERIC] check if a pattern is in the buffer
131 if (memcmp(buf + td->offs, td->pattern, td->len)) in check_short_pattern()
132 return -1; in check_short_pattern()
137 * add_marker_len - compute the length of the marker in data area
146 if (!(td->options & NAND_BBT_NO_OOB)) in add_marker_len()
149 len = td->len; in add_marker_len()
150 if (td->options & NAND_BBT_VERSION) in add_marker_len()
156 * read_bbt - [GENERIC] Read the bad block table starting from page
157 * @this: NAND chip object
173 int bits = td->options & NAND_BBT_NRBITS_MSK; in read_bbt()
174 uint8_t msk = (uint8_t)((1 << bits) - 1); in read_bbt()
176 int reserved_block_code = td->reserved_block_code; in read_bbt()
180 from = ((loff_t)page) << this->page_shift; in read_bbt()
183 len = min(totlen, (size_t)(1 << this->bbt_erase_shift)); in read_bbt()
189 len -= marker_len; in read_bbt()
196 pr_info("nand_bbt: ECC error in BBT at 0x%012llx\n", in read_bbt()
197 from & ~mtd->writesize); in read_bbt()
201 from & ~mtd->writesize); in read_bbt()
219 this->bbt_erase_shift); in read_bbt()
222 mtd->ecc_stats.bbtblocks++; in read_bbt()
231 this->bbt_erase_shift); in read_bbt()
239 mtd->ecc_stats.badblocks++; in read_bbt()
242 totlen -= len; in read_bbt()
249 * read_abs_bbt - [GENERIC] Read the bad block table starting at a given page
250 * @this: NAND chip object
253 * @chip: read the table for a specific chip, -1 read all chips; applies only if
263 u64 targetsize = nanddev_target_size(&this->base); in read_abs_bbt()
266 if (td->options & NAND_BBT_PERCHIP) { in read_abs_bbt()
268 for (i = 0; i < nanddev_ntargets(&this->base); i++) { in read_abs_bbt()
269 if (chip == -1 || chip == i) in read_abs_bbt()
270 res = read_bbt(this, buf, td->pages[i], in read_abs_bbt()
271 targetsize >> this->bbt_erase_shift, in read_abs_bbt()
275 offs += targetsize >> this->bbt_erase_shift; in read_abs_bbt()
278 res = read_bbt(this, buf, td->pages[0], in read_abs_bbt()
279 mtd->size >> this->bbt_erase_shift, td, 0); in read_abs_bbt()
294 len = td->len; in scan_read_data()
295 if (td->options & NAND_BBT_VERSION) in scan_read_data()
302 * scan_read_oob - [GENERIC] Scan data+OOB region to buffer
303 * @this: NAND chip object
310 * ECC condition (error or bitflip). May quit on the first (non-ECC) error.
321 ops.ooblen = mtd->oobsize; in scan_read_oob()
325 ops.len = min(len, (size_t)mtd->writesize); in scan_read_oob()
336 buf += mtd->oobsize + mtd->writesize; in scan_read_oob()
337 len -= mtd->writesize; in scan_read_oob()
338 offs += mtd->writesize; in scan_read_oob()
346 if (td->options & NAND_BBT_NO_OOB) in scan_read()
361 ops.ooblen = mtd->oobsize; in scan_write_bbt()
372 u32 ver_offs = td->veroffs; in bbt_get_ver_offs()
374 if (!(td->options & NAND_BBT_NO_OOB)) in bbt_get_ver_offs()
375 ver_offs += mtd->writesize; in bbt_get_ver_offs()
380 * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page
381 * @this: NAND chip object
395 if (td->options & NAND_BBT_VERSION) { in read_abs_bbts()
396 scan_read(this, buf, (loff_t)td->pages[0] << this->page_shift, in read_abs_bbts()
397 mtd->writesize, td); in read_abs_bbts()
398 td->version[0] = buf[bbt_get_ver_offs(this, td)]; in read_abs_bbts()
400 td->pages[0], td->version[0]); in read_abs_bbts()
404 if (md && (md->options & NAND_BBT_VERSION)) { in read_abs_bbts()
405 scan_read(this, buf, (loff_t)md->pages[0] << this->page_shift, in read_abs_bbts()
406 mtd->writesize, md); in read_abs_bbts()
407 md->version[0] = buf[bbt_get_ver_offs(this, md)]; in read_abs_bbts()
409 md->pages[0], md->version[0]); in read_abs_bbts()
422 ops.ooblen = mtd->oobsize; in scan_block_fast()
435 ret = mtd_read_oob(mtd, offs + (page_offset * mtd->writesize), in scan_block_fast()
437 /* Ignore ECC errors when checking for BBM */ in scan_block_fast()
451 * create_bbt - [GENERIC] Create a bad block table by scanning the device
452 * @this: NAND chip object
455 * @chip: create the table for a specific chip, -1 read all chips; applies only
464 u64 targetsize = nanddev_target_size(&this->base); in create_bbt()
471 if (chip == -1) { in create_bbt()
472 numblocks = mtd->size >> this->bbt_erase_shift; in create_bbt()
476 if (chip >= nanddev_ntargets(&this->base)) { in create_bbt()
478 chip + 1, nanddev_ntargets(&this->base)); in create_bbt()
479 return -EINVAL; in create_bbt()
481 numblocks = targetsize >> this->bbt_erase_shift; in create_bbt()
484 from = (loff_t)startblock << this->bbt_erase_shift; in create_bbt()
490 BUG_ON(bd->options & NAND_BBT_NO_OOB); in create_bbt()
500 mtd->ecc_stats.badblocks++; in create_bbt()
503 from += (1 << this->bbt_erase_shift); in create_bbt()
509 * search_bbt - [GENERIC] scan the device for a specific bad block table
510 * @this: NAND chip object
526 u64 targetsize = nanddev_target_size(&this->base); in search_bbt()
530 int scanlen = mtd->writesize + mtd->oobsize; in search_bbt()
532 int blocktopage = this->bbt_erase_shift - this->page_shift; in search_bbt()
534 /* Search direction top -> down? */ in search_bbt()
535 if (td->options & NAND_BBT_LASTBLOCK) { in search_bbt()
536 startblock = (mtd->size >> this->bbt_erase_shift) - 1; in search_bbt()
537 dir = -1; in search_bbt()
544 if (td->options & NAND_BBT_PERCHIP) { in search_bbt()
545 chips = nanddev_ntargets(&this->base); in search_bbt()
546 bbtblocks = targetsize >> this->bbt_erase_shift; in search_bbt()
547 startblock &= bbtblocks - 1; in search_bbt()
550 bbtblocks = mtd->size >> this->bbt_erase_shift; in search_bbt()
555 td->version[i] = 0; in search_bbt()
556 td->pages[i] = -1; in search_bbt()
558 for (block = 0; block < td->maxblocks; block++) { in search_bbt()
561 loff_t offs = (loff_t)actblock << this->bbt_erase_shift; in search_bbt()
564 scan_read(this, buf, offs, mtd->writesize, td); in search_bbt()
565 if (!check_pattern(buf, scanlen, mtd->writesize, td)) { in search_bbt()
566 td->pages[i] = actblock << blocktopage; in search_bbt()
567 if (td->options & NAND_BBT_VERSION) { in search_bbt()
569 td->version[i] = buf[offs]; in search_bbt()
574 startblock += targetsize >> this->bbt_erase_shift; in search_bbt()
578 if (td->pages[i] == -1) in search_bbt()
582 td->pages[i], td->version[i]); in search_bbt()
588 * search_read_bbts - [GENERIC] scan the device for bad block table(s)
589 * @this: NAND chip object
609 * get_bbt_block - Get the first valid eraseblock suitable to store a BBT
610 * @this: the NAND device
616 * suitable to store a BBT (i.e. in the range reserved for BBT), or -ENOSPC if
617 * all blocks are already used of marked bad. If td->pages[chip] was already
618 * pointing to a valid block we re-use it, otherwise we search for the next
624 u64 targetsize = nanddev_target_size(&this->base); in get_bbt_block()
629 * applies for absolute placement too, as we have the page number in in get_bbt_block()
630 * td->pages. in get_bbt_block()
632 if (td->pages[chip] != -1) in get_bbt_block()
633 return td->pages[chip] >> in get_bbt_block()
634 (this->bbt_erase_shift - this->page_shift); in get_bbt_block()
636 numblocks = (int)(targetsize >> this->bbt_erase_shift); in get_bbt_block()
637 if (!(td->options & NAND_BBT_PERCHIP)) in get_bbt_block()
638 numblocks *= nanddev_ntargets(&this->base); in get_bbt_block()
641 * Automatic placement of the bad block table. Search direction in get_bbt_block()
642 * top -> down? in get_bbt_block()
644 if (td->options & NAND_BBT_LASTBLOCK) { in get_bbt_block()
645 startblock = numblocks * (chip + 1) - 1; in get_bbt_block()
646 dir = -1; in get_bbt_block()
652 for (i = 0; i < td->maxblocks; i++) { in get_bbt_block()
662 page = block << (this->bbt_erase_shift - this->page_shift); in get_bbt_block()
665 if (!md || md->pages[chip] != page) in get_bbt_block()
669 return -ENOSPC; in get_bbt_block()
673 * mark_bbt_block_bad - Mark one of the block reserved for BBT bad
674 * @this: the NAND device
680 * such blocks as bad. It takes care of updating the in-memory BBT, marking the
682 * td->pages[] entry.
693 to = (loff_t)block << this->bbt_erase_shift; in mark_bbt_block_bad()
699 td->pages[chip] = -1; in mark_bbt_block_bad()
703 * write_bbt - [GENERIC] (Re)write the bad block table
704 * @this: NAND chip object
708 * @chipsel: selector for a specific chip, -1 for all
716 u64 targetsize = nanddev_target_size(&this->base); in write_bbt()
723 uint8_t rcode = td->reserved_block_code; in write_bbt()
728 ops.ooblen = mtd->oobsize; in write_bbt()
736 if (td->options & NAND_BBT_PERCHIP) { in write_bbt()
737 numblocks = (int)(targetsize >> this->bbt_erase_shift); in write_bbt()
739 if (chipsel == -1) { in write_bbt()
740 nrchips = nanddev_ntargets(&this->base); in write_bbt()
746 numblocks = (int)(mtd->size >> this->bbt_erase_shift); in write_bbt()
765 page = block << (this->bbt_erase_shift - this->page_shift); in write_bbt()
768 bits = td->options & NAND_BBT_NRBITS_MSK; in write_bbt()
783 default: return -EINVAL; in write_bbt()
786 to = ((loff_t)page) << this->page_shift; in write_bbt()
789 if (td->options & NAND_BBT_SAVECONTENT) { in write_bbt()
791 to &= ~(((loff_t)1 << this->bbt_erase_shift) - 1); in write_bbt()
792 len = 1 << this->bbt_erase_shift; in write_bbt()
799 pr_warn("nand_bbt: ECC error while reading block for writing bad block table\n"); in write_bbt()
802 ops.ooblen = (len >> this->page_shift) * mtd->oobsize; in write_bbt()
804 res = mtd_read_oob(mtd, to + mtd->writesize, &ops); in write_bbt()
809 pageoffs = page - (int)(to >> this->page_shift); in write_bbt()
810 offs = pageoffs << this->page_shift; in write_bbt()
813 ooboffs = len + (pageoffs * mtd->oobsize); in write_bbt()
815 } else if (td->options & NAND_BBT_NO_OOB) { in write_bbt()
817 offs = td->len; in write_bbt()
819 if (td->options & NAND_BBT_VERSION) in write_bbt()
825 len = ALIGN(len, mtd->writesize); in write_bbt()
829 memcpy(buf, td->pattern, td->len); in write_bbt()
834 len = ALIGN(len, mtd->writesize); in write_bbt()
837 (len >> this->page_shift)* mtd->oobsize); in write_bbt()
841 memcpy(&buf[ooboffs + td->offs], td->pattern, td->len); in write_bbt()
844 if (td->options & NAND_BBT_VERSION) in write_bbt()
845 buf[ooboffs + td->veroffs] = td->version[chip]; in write_bbt()
850 int sftcnt = (i << (3 - sft)) & sftmsk; in write_bbt()
858 einfo.len = 1 << this->bbt_erase_shift; in write_bbt()
868 td->options & NAND_BBT_NO_OOB ? in write_bbt()
878 (unsigned long long)to, td->version[chip]); in write_bbt()
881 td->pages[chip++] = page; in write_bbt()
891 * nand_memory_bbt - [GENERIC] create a memory based bad block table
892 * @this: NAND chip object
903 return create_bbt(this, pagebuf, bd, -1); in nand_memory_bbt()
907 * check_create - [GENERIC] create and write bbt(s) if necessary
908 * @this: the NAND device
921 struct nand_bbt_descr *td = this->bbt_td; in check_create()
922 struct nand_bbt_descr *md = this->bbt_md; in check_create()
926 if (td->options & NAND_BBT_PERCHIP) in check_create()
927 chips = nanddev_ntargets(&this->base); in check_create()
938 chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1; in check_create()
941 if (td->pages[i] == -1 && md->pages[i] == -1) { in check_create()
944 } else if (td->pages[i] == -1) { in check_create()
947 } else if (md->pages[i] == -1) { in check_create()
950 } else if (td->version[i] == md->version[i]) { in check_create()
952 if (!(td->options & NAND_BBT_VERSION)) in check_create()
954 } else if (((int8_t)(td->version[i] - md->version[i])) > 0) { in check_create()
962 if (td->pages[i] == -1) { in check_create()
972 if (!(td->options & NAND_BBT_CREATE)) in check_create()
976 if (!(this->bbt_options & NAND_BBT_CREATE_EMPTY)) in check_create()
979 td->version[i] = 1; in check_create()
981 md->version[i] = 1; in check_create()
989 rd->pages[i] = -1; in check_create()
990 rd->version[i] = 0; in check_create()
991 i--; in check_create()
1000 rd2->pages[i] = -1; in check_create()
1001 rd2->version[i] = 0; in check_create()
1002 i--; in check_create()
1013 td->version[i] = max(td->version[i], md->version[i]); in check_create()
1014 md->version[i] = td->version[i]; in check_create()
1018 if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) { in check_create()
1025 if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) { in check_create()
1035 * nand_update_bbt - update bad block table(s)
1036 * @this: the NAND device
1047 struct nand_bbt_descr *td = this->bbt_td; in nand_update_bbt()
1048 struct nand_bbt_descr *md = this->bbt_md; in nand_update_bbt()
1050 if (!this->bbt || !td) in nand_update_bbt()
1051 return -EINVAL; in nand_update_bbt()
1054 len = (1 << this->bbt_erase_shift); in nand_update_bbt()
1055 len += (len >> this->page_shift) * mtd->oobsize; in nand_update_bbt()
1058 return -ENOMEM; in nand_update_bbt()
1061 if (td->options & NAND_BBT_PERCHIP) { in nand_update_bbt()
1062 chip = (int)(offs >> this->chip_shift); in nand_update_bbt()
1066 chipsel = -1; in nand_update_bbt()
1069 td->version[chip]++; in nand_update_bbt()
1071 md->version[chip]++; in nand_update_bbt()
1074 if (td->options & NAND_BBT_WRITE) { in nand_update_bbt()
1080 if (md && (md->options & NAND_BBT_WRITE)) { in nand_update_bbt()
1090 * mark_bbt_regions - [GENERIC] mark the bad block table regions
1091 * @this: the NAND device
1099 u64 targetsize = nanddev_target_size(&this->base); in mark_bbt_region()
1105 if (td->options & NAND_BBT_PERCHIP) { in mark_bbt_region()
1106 chips = nanddev_ntargets(&this->base); in mark_bbt_region()
1107 nrblocks = (int)(targetsize >> this->bbt_erase_shift); in mark_bbt_region()
1110 nrblocks = (int)(mtd->size >> this->bbt_erase_shift); in mark_bbt_region()
1114 if ((td->options & NAND_BBT_ABSPAGE) || in mark_bbt_region()
1115 !(td->options & NAND_BBT_WRITE)) { in mark_bbt_region()
1116 if (td->pages[i] == -1) in mark_bbt_region()
1118 block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift); in mark_bbt_region()
1122 td->reserved_block_code) in mark_bbt_region()
1124 this->bbt_erase_shift); in mark_bbt_region()
1128 if (td->options & NAND_BBT_LASTBLOCK) in mark_bbt_region()
1129 block = ((i + 1) * nrblocks) - td->maxblocks; in mark_bbt_region()
1132 for (j = 0; j < td->maxblocks; j++) { in mark_bbt_region()
1144 if (update && td->reserved_block_code) in mark_bbt_region()
1145 nand_update_bbt(this, (loff_t)(block - 1) << in mark_bbt_region()
1146 this->bbt_erase_shift); in mark_bbt_region()
1151 * verify_bbt_descr - verify the bad block description
1152 * @this: the NAND device
1160 u64 targetsize = nanddev_target_size(&this->base); in verify_bbt_descr()
1169 pattern_len = bd->len; in verify_bbt_descr()
1170 bits = bd->options & NAND_BBT_NRBITS_MSK; in verify_bbt_descr()
1172 BUG_ON((this->bbt_options & NAND_BBT_NO_OOB) && in verify_bbt_descr()
1173 !(this->bbt_options & NAND_BBT_USE_FLASH)); in verify_bbt_descr()
1176 if (bd->options & NAND_BBT_VERSION) in verify_bbt_descr()
1179 if (bd->options & NAND_BBT_NO_OOB) { in verify_bbt_descr()
1180 BUG_ON(!(this->bbt_options & NAND_BBT_USE_FLASH)); in verify_bbt_descr()
1181 BUG_ON(!(this->bbt_options & NAND_BBT_NO_OOB)); in verify_bbt_descr()
1182 BUG_ON(bd->offs); in verify_bbt_descr()
1183 if (bd->options & NAND_BBT_VERSION) in verify_bbt_descr()
1184 BUG_ON(bd->veroffs != bd->len); in verify_bbt_descr()
1185 BUG_ON(bd->options & NAND_BBT_SAVECONTENT); in verify_bbt_descr()
1188 if (bd->options & NAND_BBT_PERCHIP) in verify_bbt_descr()
1189 table_size = targetsize >> this->bbt_erase_shift; in verify_bbt_descr()
1191 table_size = mtd->size >> this->bbt_erase_shift; in verify_bbt_descr()
1194 if (bd->options & NAND_BBT_NO_OOB) in verify_bbt_descr()
1196 BUG_ON(table_size > (1 << this->bbt_erase_shift)); in verify_bbt_descr()
1200 * nand_scan_bbt - [NAND Interface] scan, find, read and maybe create bad block table(s)
1201 * @this: the NAND device
1216 struct nand_bbt_descr *td = this->bbt_td; in nand_scan_bbt()
1217 struct nand_bbt_descr *md = this->bbt_md; in nand_scan_bbt()
1219 len = (mtd->size >> (this->bbt_erase_shift + 2)) ? : 1; in nand_scan_bbt()
1224 this->bbt = kzalloc(len, GFP_KERNEL); in nand_scan_bbt()
1225 if (!this->bbt) in nand_scan_bbt()
1226 return -ENOMEM; in nand_scan_bbt()
1234 pr_err("nand_bbt: can't scan flash and build the RAM-based BBT\n"); in nand_scan_bbt()
1243 len = (1 << this->bbt_erase_shift); in nand_scan_bbt()
1244 len += (len >> this->page_shift) * mtd->oobsize; in nand_scan_bbt()
1247 res = -ENOMEM; in nand_scan_bbt()
1252 if (td->options & NAND_BBT_ABSPAGE) { in nand_scan_bbt()
1274 kfree(this->bbt); in nand_scan_bbt()
1275 this->bbt = NULL; in nand_scan_bbt()
1331 * nand_create_badblock_pattern - [INTERN] Creates a BBT descriptor structure
1332 * @this: NAND chip to create descriptor for
1336 * this->badblock_pattern. Thus, this->badblock_pattern should be NULL when
1342 if (this->badblock_pattern) { in nand_create_badblock_pattern()
1344 return -EINVAL; in nand_create_badblock_pattern()
1348 return -ENOMEM; in nand_create_badblock_pattern()
1349 bd->options = this->bbt_options & BADBLOCK_SCAN_MASK; in nand_create_badblock_pattern()
1350 bd->offs = this->badblockpos; in nand_create_badblock_pattern()
1351 bd->len = (this->options & NAND_BUSWIDTH_16) ? 2 : 1; in nand_create_badblock_pattern()
1352 bd->pattern = scan_ff_pattern; in nand_create_badblock_pattern()
1353 bd->options |= NAND_BBT_DYNAMICSTRUCT; in nand_create_badblock_pattern()
1354 this->badblock_pattern = bd; in nand_create_badblock_pattern()
1359 * nand_create_bbt - [NAND Interface] Select a default bad block table for the device
1360 * @this: NAND chip object
1370 if (this->bbt_options & NAND_BBT_USE_FLASH) { in nand_create_bbt()
1372 if (!this->bbt_td) { in nand_create_bbt()
1373 if (this->bbt_options & NAND_BBT_NO_OOB) { in nand_create_bbt()
1374 this->bbt_td = &bbt_main_no_oob_descr; in nand_create_bbt()
1375 this->bbt_md = &bbt_mirror_no_oob_descr; in nand_create_bbt()
1377 this->bbt_td = &bbt_main_descr; in nand_create_bbt()
1378 this->bbt_md = &bbt_mirror_descr; in nand_create_bbt()
1382 this->bbt_td = NULL; in nand_create_bbt()
1383 this->bbt_md = NULL; in nand_create_bbt()
1386 if (!this->badblock_pattern) { in nand_create_bbt()
1392 return nand_scan_bbt(this, this->badblock_pattern); in nand_create_bbt()
1397 * nand_isreserved_bbt - [NAND Interface] Check if a block is reserved
1398 * @this: NAND chip object
1405 block = (int)(offs >> this->bbt_erase_shift); in nand_isreserved_bbt()
1410 * nand_isbad_bbt - [NAND Interface] Check if a block is bad
1411 * @this: NAND chip object
1419 block = (int)(offs >> this->bbt_erase_shift); in nand_isbad_bbt()
1437 * nand_markbad_bbt - [NAND Interface] Mark a block bad in the BBT
1438 * @this: NAND chip object
1445 block = (int)(offs >> this->bbt_erase_shift); in nand_markbad_bbt()
1450 /* Update flash-based bad block table */ in nand_markbad_bbt()
1451 if (this->bbt_options & NAND_BBT_USE_FLASH) in nand_markbad_bbt()