Lines Matching +full:nand +full:- +full:int +full:- +full:base
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
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
76 static inline uint8_t bbt_get_entry(struct nand_chip *chip, int block) in bbt_get_entry()
78 uint8_t entry = chip->bbt[block >> BBT_ENTRY_SHIFT]; in bbt_get_entry()
83 static inline void bbt_mark_entry(struct nand_chip *chip, int block, in bbt_mark_entry()
87 chip->bbt[block >> BBT_ENTRY_SHIFT] |= msk; in bbt_mark_entry()
90 static int check_pattern_no_oob(uint8_t *buf, struct nand_bbt_descr *td) in check_pattern_no_oob()
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
107 static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td) in check_pattern()
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
128 static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td) in check_short_pattern()
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
166 static int read_bbt(struct nand_chip *this, uint8_t *buf, int page, int num, in read_bbt()
167 struct nand_bbt_descr *td, int offs) in read_bbt()
170 int res, ret = 0, i, j, act = 0; in read_bbt()
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()
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
259 static int read_abs_bbt(struct nand_chip *this, uint8_t *buf, in read_abs_bbt()
260 struct nand_bbt_descr *td, int chip) in read_abs_bbt()
263 u64 targetsize = nanddev_target_size(&this->base); in read_abs_bbt()
264 int res = 0, i; in read_abs_bbt()
266 if (td->options & NAND_BBT_PERCHIP) { in read_abs_bbt()
267 int offs = 0; 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()
287 static int scan_read_data(struct nand_chip *this, uint8_t *buf, loff_t offs, in scan_read_data()
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.
312 static int scan_read_oob(struct nand_chip *this, uint8_t *buf, loff_t offs, in scan_read_oob()
317 int res, ret = 0; in scan_read_oob()
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()
343 static int scan_read(struct nand_chip *this, uint8_t *buf, loff_t offs, in scan_read()
346 if (td->options & NAND_BBT_NO_OOB) in scan_read()
353 static int scan_write_bbt(struct nand_chip *this, loff_t offs, size_t len, in scan_write_bbt()
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()
414 static int scan_block_fast(struct nand_chip *this, struct nand_bbt_descr *bd, in scan_block_fast()
420 int ret, page_offset; in scan_block_fast()
422 ops.ooblen = mtd->oobsize; in scan_block_fast()
435 ret = mtd_read_oob(mtd, offs + (page_offset * mtd->writesize), in scan_block_fast()
451 static int bbt_block_checkbad(struct nand_chip *this, struct nand_bbt_descr *td, in bbt_block_checkbad()
454 struct nand_bbt_descr *bd = this->badblock_pattern; in bbt_block_checkbad()
461 if (!(td->options & NAND_BBT_NO_OOB) && in bbt_block_checkbad()
462 td->offs >= bd->offs && td->offs < bd->offs + bd->len) in bbt_block_checkbad()
469 if (this->bbt_options & NAND_BBT_NO_OOB_BBM || in bbt_block_checkbad()
470 this->options & NAND_NO_BBM_QUIRK) in bbt_block_checkbad()
480 * create_bbt - [GENERIC] Create a bad block table by scanning the device
481 * @this: NAND chip object
484 * @chip: create the table for a specific chip, -1 read all chips; applies only
490 static int create_bbt(struct nand_chip *this, uint8_t *buf, in create_bbt()
491 struct nand_bbt_descr *bd, int chip) in create_bbt()
493 u64 targetsize = nanddev_target_size(&this->base); in create_bbt()
495 int i, numblocks, startblock; in create_bbt()
500 if (chip == -1) { in create_bbt()
501 numblocks = mtd->size >> this->bbt_erase_shift; in create_bbt()
505 if (chip >= nanddev_ntargets(&this->base)) { in create_bbt()
507 chip + 1, nanddev_ntargets(&this->base)); in create_bbt()
508 return -EINVAL; in create_bbt()
510 numblocks = targetsize >> this->bbt_erase_shift; in create_bbt()
513 from = (loff_t)startblock << this->bbt_erase_shift; in create_bbt()
517 int ret; in create_bbt()
519 BUG_ON(bd->options & NAND_BBT_NO_OOB); in create_bbt()
529 mtd->ecc_stats.badblocks++; in create_bbt()
532 from += (1 << this->bbt_erase_shift); in create_bbt()
538 * search_bbt - [GENERIC] scan the device for a specific bad block table
539 * @this: NAND chip object
552 static int search_bbt(struct nand_chip *this, uint8_t *buf, in search_bbt()
555 u64 targetsize = nanddev_target_size(&this->base); in search_bbt()
557 int i, chips; in search_bbt()
558 int startblock, block, dir; in search_bbt()
559 int scanlen = mtd->writesize + mtd->oobsize; in search_bbt()
560 int bbtblocks; in search_bbt()
561 int blocktopage = this->bbt_erase_shift - this->page_shift; in search_bbt()
563 /* Search direction top -> down? */ in search_bbt()
564 if (td->options & NAND_BBT_LASTBLOCK) { in search_bbt()
565 startblock = (mtd->size >> this->bbt_erase_shift) - 1; in search_bbt()
566 dir = -1; in search_bbt()
573 if (td->options & NAND_BBT_PERCHIP) { in search_bbt()
574 chips = nanddev_ntargets(&this->base); in search_bbt()
575 bbtblocks = targetsize >> this->bbt_erase_shift; in search_bbt()
576 startblock &= bbtblocks - 1; in search_bbt()
579 bbtblocks = mtd->size >> this->bbt_erase_shift; in search_bbt()
584 td->version[i] = 0; in search_bbt()
585 td->pages[i] = -1; in search_bbt()
587 for (block = 0; block < td->maxblocks; block++) { in search_bbt()
589 int actblock = startblock + dir * block; in search_bbt()
590 loff_t offs = (loff_t)actblock << this->bbt_erase_shift; in search_bbt()
597 scan_read(this, buf, offs, mtd->writesize, td); in search_bbt()
598 if (!check_pattern(buf, scanlen, mtd->writesize, td)) { in search_bbt()
599 td->pages[i] = actblock << blocktopage; in search_bbt()
600 if (td->options & NAND_BBT_VERSION) { in search_bbt()
602 td->version[i] = buf[offs]; in search_bbt()
607 startblock += targetsize >> this->bbt_erase_shift; in search_bbt()
611 if (td->pages[i] == -1) in search_bbt()
615 td->pages[i], td->version[i]); in search_bbt()
621 * search_read_bbts - [GENERIC] scan the device for bad block table(s)
622 * @this: NAND chip object
642 * get_bbt_block - Get the first valid eraseblock suitable to store a BBT
643 * @this: the NAND device
649 * suitable to store a BBT (i.e. in the range reserved for BBT), or -ENOSPC if
650 * all blocks are already used of marked bad. If td->pages[chip] was already
651 * pointing to a valid block we re-use it, otherwise we search for the next
654 static int get_bbt_block(struct nand_chip *this, struct nand_bbt_descr *td, in get_bbt_block()
655 struct nand_bbt_descr *md, int chip) in get_bbt_block()
657 u64 targetsize = nanddev_target_size(&this->base); in get_bbt_block()
658 int startblock, dir, page, numblocks, i; in get_bbt_block()
663 * td->pages. in get_bbt_block()
665 if (td->pages[chip] != -1) in get_bbt_block()
666 return td->pages[chip] >> in get_bbt_block()
667 (this->bbt_erase_shift - this->page_shift); in get_bbt_block()
669 numblocks = (int)(targetsize >> this->bbt_erase_shift); in get_bbt_block()
670 if (!(td->options & NAND_BBT_PERCHIP)) in get_bbt_block()
671 numblocks *= nanddev_ntargets(&this->base); in get_bbt_block()
675 * top -> down? in get_bbt_block()
677 if (td->options & NAND_BBT_LASTBLOCK) { in get_bbt_block()
678 startblock = numblocks * (chip + 1) - 1; in get_bbt_block()
679 dir = -1; in get_bbt_block()
685 for (i = 0; i < td->maxblocks; i++) { in get_bbt_block()
686 int block = startblock + dir * i; in get_bbt_block()
695 page = block << (this->bbt_erase_shift - this->page_shift); in get_bbt_block()
698 if (!md || md->pages[chip] != page) in get_bbt_block()
702 return -ENOSPC; in get_bbt_block()
706 * mark_bbt_block_bad - Mark one of the block reserved for BBT bad
707 * @this: the NAND device
713 * such blocks as bad. It takes care of updating the in-memory BBT, marking the
715 * td->pages[] entry.
719 int chip, int block) in mark_bbt_block_bad()
722 int res; in mark_bbt_block_bad()
726 to = (loff_t)block << this->bbt_erase_shift; in mark_bbt_block_bad()
732 td->pages[chip] = -1; in mark_bbt_block_bad()
736 * write_bbt - [GENERIC] (Re)write the bad block table
737 * @this: NAND chip object
741 * @chipsel: selector for a specific chip, -1 for all
745 static int write_bbt(struct nand_chip *this, uint8_t *buf, in write_bbt()
747 int chipsel) in write_bbt()
749 u64 targetsize = nanddev_target_size(&this->base); in write_bbt()
752 int i, res, chip = 0; in write_bbt()
753 int bits, page, offs, numblocks, sft, sftmsk; in write_bbt()
754 int nrchips, pageoffs, ooboffs; in write_bbt()
756 uint8_t rcode = td->reserved_block_code; in write_bbt()
761 ops.ooblen = mtd->oobsize; in write_bbt()
769 if (td->options & NAND_BBT_PERCHIP) { in write_bbt()
770 numblocks = (int)(targetsize >> this->bbt_erase_shift); in write_bbt()
772 if (chipsel == -1) { in write_bbt()
773 nrchips = nanddev_ntargets(&this->base); in write_bbt()
779 numblocks = (int)(mtd->size >> this->bbt_erase_shift); in write_bbt()
785 int block; in write_bbt()
798 page = block << (this->bbt_erase_shift - this->page_shift); in write_bbt()
801 bits = td->options & NAND_BBT_NRBITS_MSK; in write_bbt()
816 default: return -EINVAL; in write_bbt()
819 to = ((loff_t)page) << this->page_shift; in write_bbt()
822 if (td->options & NAND_BBT_SAVECONTENT) { in write_bbt()
824 to &= ~(((loff_t)1 << this->bbt_erase_shift) - 1); in write_bbt()
825 len = 1 << this->bbt_erase_shift; in write_bbt()
835 ops.ooblen = (len >> this->page_shift) * mtd->oobsize; in write_bbt()
837 res = mtd_read_oob(mtd, to + mtd->writesize, &ops); in write_bbt()
842 pageoffs = page - (int)(to >> this->page_shift); in write_bbt()
843 offs = pageoffs << this->page_shift; in write_bbt()
846 ooboffs = len + (pageoffs * mtd->oobsize); in write_bbt()
848 } else if (td->options & NAND_BBT_NO_OOB) { in write_bbt()
850 offs = td->len; in write_bbt()
852 if (td->options & NAND_BBT_VERSION) in write_bbt()
858 len = ALIGN(len, mtd->writesize); in write_bbt()
862 memcpy(buf, td->pattern, td->len); in write_bbt()
867 len = ALIGN(len, mtd->writesize); in write_bbt()
870 (len >> this->page_shift)* mtd->oobsize); in write_bbt()
874 memcpy(&buf[ooboffs + td->offs], td->pattern, td->len); in write_bbt()
877 if (td->options & NAND_BBT_VERSION) in write_bbt()
878 buf[ooboffs + td->veroffs] = td->version[chip]; in write_bbt()
883 int sftcnt = (i << (3 - sft)) & sftmsk; in write_bbt()
891 einfo.len = 1 << this->bbt_erase_shift; in write_bbt()
901 td->options & NAND_BBT_NO_OOB ? in write_bbt()
911 (unsigned long long)to, td->version[chip]); in write_bbt()
914 td->pages[chip++] = page; in write_bbt()
924 * nand_memory_bbt - [GENERIC] create a memory based bad block table
925 * @this: NAND chip object
931 static inline int nand_memory_bbt(struct nand_chip *this, in nand_memory_bbt()
936 return create_bbt(this, pagebuf, bd, -1); in nand_memory_bbt()
940 * check_create - [GENERIC] create and write bbt(s) if necessary
941 * @this: the NAND device
950 static int check_create(struct nand_chip *this, uint8_t *buf, in check_create()
953 int i, chips, writeops, create, chipsel, res, res2; in check_create()
954 struct nand_bbt_descr *td = this->bbt_td; in check_create()
955 struct nand_bbt_descr *md = this->bbt_md; in check_create()
959 if (td->options & NAND_BBT_PERCHIP) in check_create()
960 chips = nanddev_ntargets(&this->base); in check_create()
971 chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1; in check_create()
974 if (td->pages[i] == -1 && md->pages[i] == -1) { in check_create()
977 } else if (td->pages[i] == -1) { in check_create()
980 } else if (md->pages[i] == -1) { in check_create()
983 } else if (td->version[i] == md->version[i]) { in check_create()
985 if (!(td->options & NAND_BBT_VERSION)) in check_create()
987 } else if (((int8_t)(td->version[i] - md->version[i])) > 0) { in check_create()
995 if (td->pages[i] == -1) { in check_create()
1005 if (!(td->options & NAND_BBT_CREATE)) in check_create()
1009 if (!(this->bbt_options & NAND_BBT_CREATE_EMPTY)) in check_create()
1012 td->version[i] = 1; in check_create()
1014 md->version[i] = 1; in check_create()
1022 rd->pages[i] = -1; in check_create()
1023 rd->version[i] = 0; in check_create()
1024 i--; in check_create()
1033 rd2->pages[i] = -1; in check_create()
1034 rd2->version[i] = 0; in check_create()
1035 i--; in check_create()
1046 td->version[i] = max(td->version[i], md->version[i]); in check_create()
1047 md->version[i] = td->version[i]; in check_create()
1051 if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) { in check_create()
1058 if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) { in check_create()
1068 * nand_update_bbt - update bad block table(s)
1069 * @this: the NAND device
1074 static int nand_update_bbt(struct nand_chip *this, loff_t offs) in nand_update_bbt()
1077 int len, res = 0; in nand_update_bbt()
1078 int chip, chipsel; in nand_update_bbt()
1080 struct nand_bbt_descr *td = this->bbt_td; in nand_update_bbt()
1081 struct nand_bbt_descr *md = this->bbt_md; in nand_update_bbt()
1083 if (!this->bbt || !td) in nand_update_bbt()
1084 return -EINVAL; in nand_update_bbt()
1087 len = (1 << this->bbt_erase_shift); in nand_update_bbt()
1088 len += (len >> this->page_shift) * mtd->oobsize; in nand_update_bbt()
1091 return -ENOMEM; in nand_update_bbt()
1094 if (td->options & NAND_BBT_PERCHIP) { in nand_update_bbt()
1095 chip = (int)(offs >> this->chip_shift); in nand_update_bbt()
1099 chipsel = -1; in nand_update_bbt()
1102 td->version[chip]++; in nand_update_bbt()
1104 md->version[chip]++; in nand_update_bbt()
1107 if (td->options & NAND_BBT_WRITE) { in nand_update_bbt()
1113 if (md && (md->options & NAND_BBT_WRITE)) { in nand_update_bbt()
1123 * mark_bbt_region - [GENERIC] mark the bad block table regions
1124 * @this: the NAND device
1132 u64 targetsize = nanddev_target_size(&this->base); in mark_bbt_region()
1134 int i, j, chips, block, nrblocks, update; in mark_bbt_region()
1138 if (td->options & NAND_BBT_PERCHIP) { in mark_bbt_region()
1139 chips = nanddev_ntargets(&this->base); in mark_bbt_region()
1140 nrblocks = (int)(targetsize >> this->bbt_erase_shift); in mark_bbt_region()
1143 nrblocks = (int)(mtd->size >> this->bbt_erase_shift); in mark_bbt_region()
1147 if ((td->options & NAND_BBT_ABSPAGE) || in mark_bbt_region()
1148 !(td->options & NAND_BBT_WRITE)) { in mark_bbt_region()
1149 if (td->pages[i] == -1) in mark_bbt_region()
1151 block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift); in mark_bbt_region()
1155 td->reserved_block_code) in mark_bbt_region()
1157 this->bbt_erase_shift); in mark_bbt_region()
1161 if (td->options & NAND_BBT_LASTBLOCK) in mark_bbt_region()
1162 block = ((i + 1) * nrblocks) - td->maxblocks; in mark_bbt_region()
1165 for (j = 0; j < td->maxblocks; j++) { in mark_bbt_region()
1177 if (update && td->reserved_block_code) in mark_bbt_region()
1178 nand_update_bbt(this, (loff_t)(block - 1) << in mark_bbt_region()
1179 this->bbt_erase_shift); in mark_bbt_region()
1184 * verify_bbt_descr - verify the bad block description
1185 * @this: the NAND device
1193 u64 targetsize = nanddev_target_size(&this->base); in verify_bbt_descr()
1202 pattern_len = bd->len; in verify_bbt_descr()
1203 bits = bd->options & NAND_BBT_NRBITS_MSK; in verify_bbt_descr()
1205 BUG_ON((this->bbt_options & NAND_BBT_NO_OOB) && in verify_bbt_descr()
1206 !(this->bbt_options & NAND_BBT_USE_FLASH)); in verify_bbt_descr()
1209 if (bd->options & NAND_BBT_VERSION) in verify_bbt_descr()
1212 if (bd->options & NAND_BBT_NO_OOB) { in verify_bbt_descr()
1213 BUG_ON(!(this->bbt_options & NAND_BBT_USE_FLASH)); in verify_bbt_descr()
1214 BUG_ON(!(this->bbt_options & NAND_BBT_NO_OOB)); in verify_bbt_descr()
1215 BUG_ON(bd->offs); in verify_bbt_descr()
1216 if (bd->options & NAND_BBT_VERSION) in verify_bbt_descr()
1217 BUG_ON(bd->veroffs != bd->len); in verify_bbt_descr()
1218 BUG_ON(bd->options & NAND_BBT_SAVECONTENT); in verify_bbt_descr()
1221 if (bd->options & NAND_BBT_PERCHIP) in verify_bbt_descr()
1222 table_size = targetsize >> this->bbt_erase_shift; in verify_bbt_descr()
1224 table_size = mtd->size >> this->bbt_erase_shift; in verify_bbt_descr()
1227 if (bd->options & NAND_BBT_NO_OOB) in verify_bbt_descr()
1229 BUG_ON(table_size > (1 << this->bbt_erase_shift)); in verify_bbt_descr()
1233 * nand_scan_bbt - [NAND Interface] scan, find, read and maybe create bad block table(s)
1234 * @this: the NAND device
1244 static int nand_scan_bbt(struct nand_chip *this, struct nand_bbt_descr *bd) in nand_scan_bbt()
1247 int len, res; in nand_scan_bbt()
1249 struct nand_bbt_descr *td = this->bbt_td; in nand_scan_bbt()
1250 struct nand_bbt_descr *md = this->bbt_md; in nand_scan_bbt()
1252 len = (mtd->size >> (this->bbt_erase_shift + 2)) ? : 1; in nand_scan_bbt()
1257 this->bbt = kzalloc(len, GFP_KERNEL); in nand_scan_bbt()
1258 if (!this->bbt) in nand_scan_bbt()
1259 return -ENOMEM; in nand_scan_bbt()
1267 pr_err("nand_bbt: can't scan flash and build the RAM-based BBT\n"); in nand_scan_bbt()
1276 len = (1 << this->bbt_erase_shift); in nand_scan_bbt()
1277 len += (len >> this->page_shift) * mtd->oobsize; in nand_scan_bbt()
1280 res = -ENOMEM; in nand_scan_bbt()
1285 if (td->options & NAND_BBT_ABSPAGE) { in nand_scan_bbt()
1307 kfree(this->bbt); in nand_scan_bbt()
1308 this->bbt = NULL; in nand_scan_bbt()
1364 * nand_create_badblock_pattern - [INTERN] Creates a BBT descriptor structure
1365 * @this: NAND chip to create descriptor for
1369 * this->badblock_pattern. Thus, this->badblock_pattern should be NULL when
1372 static int nand_create_badblock_pattern(struct nand_chip *this) in nand_create_badblock_pattern()
1375 if (this->badblock_pattern) { in nand_create_badblock_pattern()
1377 return -EINVAL; in nand_create_badblock_pattern()
1381 return -ENOMEM; in nand_create_badblock_pattern()
1382 bd->options = this->bbt_options & BADBLOCK_SCAN_MASK; in nand_create_badblock_pattern()
1383 bd->offs = this->badblockpos; in nand_create_badblock_pattern()
1384 bd->len = (this->options & NAND_BUSWIDTH_16) ? 2 : 1; in nand_create_badblock_pattern()
1385 bd->pattern = scan_ff_pattern; in nand_create_badblock_pattern()
1386 bd->options |= NAND_BBT_DYNAMICSTRUCT; in nand_create_badblock_pattern()
1387 this->badblock_pattern = bd; in nand_create_badblock_pattern()
1392 * nand_create_bbt - [NAND Interface] Select a default bad block table for the device
1393 * @this: NAND chip object
1398 int nand_create_bbt(struct nand_chip *this) in nand_create_bbt()
1400 int ret; in nand_create_bbt()
1403 if (this->bbt_options & NAND_BBT_USE_FLASH) { in nand_create_bbt()
1405 if (!this->bbt_td) { in nand_create_bbt()
1406 if (this->bbt_options & NAND_BBT_NO_OOB) { in nand_create_bbt()
1407 this->bbt_td = &bbt_main_no_oob_descr; in nand_create_bbt()
1408 this->bbt_md = &bbt_mirror_no_oob_descr; in nand_create_bbt()
1410 this->bbt_td = &bbt_main_descr; in nand_create_bbt()
1411 this->bbt_md = &bbt_mirror_descr; in nand_create_bbt()
1415 this->bbt_td = NULL; in nand_create_bbt()
1416 this->bbt_md = NULL; in nand_create_bbt()
1419 if (!this->badblock_pattern) { in nand_create_bbt()
1425 return nand_scan_bbt(this, this->badblock_pattern); in nand_create_bbt()
1430 * nand_isreserved_bbt - [NAND Interface] Check if a block is reserved
1431 * @this: NAND chip object
1434 int nand_isreserved_bbt(struct nand_chip *this, loff_t offs) in nand_isreserved_bbt()
1436 int block; in nand_isreserved_bbt()
1438 block = (int)(offs >> this->bbt_erase_shift); in nand_isreserved_bbt()
1443 * nand_isbad_bbt - [NAND Interface] Check if a block is bad
1444 * @this: NAND chip object
1448 int nand_isbad_bbt(struct nand_chip *this, loff_t offs, int allowbbt) in nand_isbad_bbt()
1450 int block, res; in nand_isbad_bbt()
1452 block = (int)(offs >> this->bbt_erase_shift); in nand_isbad_bbt()
1456 (unsigned int)offs, block, res); in nand_isbad_bbt()
1473 * nand_markbad_bbt - [NAND Interface] Mark a block bad in the BBT
1474 * @this: NAND chip object
1477 int nand_markbad_bbt(struct nand_chip *this, loff_t offs) in nand_markbad_bbt()
1479 int block, ret = 0; in nand_markbad_bbt()
1481 block = (int)(offs >> this->bbt_erase_shift); in nand_markbad_bbt()
1486 /* Update flash-based bad block table */ in nand_markbad_bbt()
1487 if (this->bbt_options & NAND_BBT_USE_FLASH) in nand_markbad_bbt()