Lines Matching full:this
13 * marked good / bad blocks. This information is used to create a memory BBT.
157 * @this: NAND chip object
166 static int read_bbt(struct nand_chip *this, uint8_t *buf, int page, int num, in read_bbt() argument
169 struct mtd_info *mtd = nand_to_mtd(this); 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()
219 this->bbt_erase_shift); in read_bbt()
220 bbt_mark_entry(this, offs + act, in read_bbt()
227 * move this message to pr_debug. in read_bbt()
231 this->bbt_erase_shift); in read_bbt()
234 bbt_mark_entry(this, offs + act, in read_bbt()
237 bbt_mark_entry(this, offs + act, in read_bbt()
250 * @this: NAND chip object
259 static int read_abs_bbt(struct nand_chip *this, uint8_t *buf, in read_abs_bbt() argument
262 struct mtd_info *mtd = nand_to_mtd(this); in read_abs_bbt()
263 u64 targetsize = nanddev_target_size(&this->base); in read_abs_bbt()
268 for (i = 0; i < nanddev_ntargets(&this->base); 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() argument
290 struct mtd_info *mtd = nand_to_mtd(this); in scan_read_data()
303 * @this: NAND chip object
312 static int scan_read_oob(struct nand_chip *this, uint8_t *buf, loff_t offs, in scan_read_oob() argument
315 struct mtd_info *mtd = nand_to_mtd(this); in scan_read_oob()
343 static int scan_read(struct nand_chip *this, uint8_t *buf, loff_t offs, in scan_read() argument
347 return scan_read_data(this, buf, offs, td); in scan_read()
349 return scan_read_oob(this, buf, offs, len); in scan_read()
353 static int scan_write_bbt(struct nand_chip *this, loff_t offs, size_t len, in scan_write_bbt() argument
356 struct mtd_info *mtd = nand_to_mtd(this); in scan_write_bbt()
369 static u32 bbt_get_ver_offs(struct nand_chip *this, struct nand_bbt_descr *td) in bbt_get_ver_offs() argument
371 struct mtd_info *mtd = nand_to_mtd(this); in bbt_get_ver_offs()
381 * @this: NAND chip object
389 static void read_abs_bbts(struct nand_chip *this, uint8_t *buf, in read_abs_bbts() argument
392 struct mtd_info *mtd = nand_to_mtd(this); in read_abs_bbts()
396 scan_read(this, buf, (loff_t)td->pages[0] << this->page_shift, in read_abs_bbts()
398 td->version[0] = buf[bbt_get_ver_offs(this, td)]; in read_abs_bbts()
405 scan_read(this, buf, (loff_t)md->pages[0] << this->page_shift, in read_abs_bbts()
407 md->version[0] = buf[bbt_get_ver_offs(this, md)]; in read_abs_bbts()
414 static int scan_block_fast(struct nand_chip *this, struct nand_bbt_descr *bd, in scan_block_fast() argument
417 struct mtd_info *mtd = nand_to_mtd(this); in scan_block_fast()
428 page_offset = nand_bbm_get_next_page(this, 0); in scan_block_fast()
444 page_offset = nand_bbm_get_next_page(this, page_offset + 1); in scan_block_fast()
451 static int bbt_block_checkbad(struct nand_chip *this, struct nand_bbt_descr *td, in bbt_block_checkbad() argument
454 struct nand_bbt_descr *bd = this->badblock_pattern; 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()
473 if (scan_block_fast(this, bd, offs, buf) > 0) in bbt_block_checkbad()
481 * @this: NAND chip object
490 static int create_bbt(struct nand_chip *this, uint8_t *buf, in create_bbt() argument
493 u64 targetsize = nanddev_target_size(&this->base); in create_bbt()
494 struct mtd_info *mtd = nand_to_mtd(this); 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()
510 numblocks = targetsize >> this->bbt_erase_shift; in create_bbt()
513 from = (loff_t)startblock << this->bbt_erase_shift; in create_bbt()
521 ret = scan_block_fast(this, bd, from, buf); in create_bbt()
526 bbt_mark_entry(this, i, BBT_BLOCK_FACTORY_BAD); in create_bbt()
532 from += (1 << this->bbt_erase_shift); in create_bbt()
539 * @this: NAND chip object
547 * the bad block information of this chip. This is necessary to provide support
552 static int search_bbt(struct nand_chip *this, uint8_t *buf, in search_bbt() argument
555 u64 targetsize = nanddev_target_size(&this->base); in search_bbt()
556 struct mtd_info *mtd = nand_to_mtd(this); in search_bbt()
561 int blocktopage = this->bbt_erase_shift - this->page_shift; in search_bbt()
565 startblock = (mtd->size >> this->bbt_erase_shift) - 1; in search_bbt()
574 chips = nanddev_ntargets(&this->base); in search_bbt()
575 bbtblocks = targetsize >> this->bbt_erase_shift; in search_bbt()
589 loff_t offs = (loff_t)actblock << this->bbt_erase_shift; in search_bbt()
592 if (bbt_block_checkbad(this, td, offs, buf)) in search_bbt()
596 scan_read(this, buf, offs, mtd->writesize, td); in search_bbt()
600 offs = bbt_get_ver_offs(this, td); in search_bbt()
606 startblock += targetsize >> this->bbt_erase_shift; in search_bbt()
621 * @this: NAND chip object
628 static void search_read_bbts(struct nand_chip *this, uint8_t *buf, in search_read_bbts() argument
633 search_bbt(this, buf, td); in search_read_bbts()
637 search_bbt(this, buf, md); in search_read_bbts()
642 * @this: the NAND device
647 * This functions returns a positive block number pointing a valid eraseblock
653 static int get_bbt_block(struct nand_chip *this, struct nand_bbt_descr *td, in get_bbt_block() argument
656 u64 targetsize = nanddev_target_size(&this->base); in get_bbt_block()
660 * There was already a version of the table, reuse the page. This in get_bbt_block()
666 (this->bbt_erase_shift - this->page_shift); in get_bbt_block()
668 numblocks = (int)(targetsize >> this->bbt_erase_shift); in get_bbt_block()
670 numblocks *= nanddev_ntargets(&this->base); in get_bbt_block()
688 switch (bbt_get_entry(this, block)) { in get_bbt_block()
694 page = block << (this->bbt_erase_shift - this->page_shift); in get_bbt_block()
706 * @this: the NAND device
711 * Blocks reserved for BBT can become bad. This functions is an helper to mark
716 static void mark_bbt_block_bad(struct nand_chip *this, in mark_bbt_block_bad() argument
723 bbt_mark_entry(this, block, BBT_BLOCK_WORN); in mark_bbt_block_bad()
725 to = (loff_t)block << this->bbt_erase_shift; in mark_bbt_block_bad()
726 res = nand_markbad_bbm(this, to); in mark_bbt_block_bad()
736 * @this: NAND chip object
744 static int write_bbt(struct nand_chip *this, uint8_t *buf, in write_bbt() argument
748 u64 targetsize = nanddev_target_size(&this->base); in write_bbt()
749 struct mtd_info *mtd = nand_to_mtd(this); in write_bbt()
769 numblocks = (int)(targetsize >> this->bbt_erase_shift); in write_bbt()
772 nrchips = nanddev_ntargets(&this->base); in write_bbt()
778 numblocks = (int)(mtd->size >> this->bbt_erase_shift); in write_bbt()
786 block = get_bbt_block(this, td, md, chip); in write_bbt()
797 page = block << (this->bbt_erase_shift - this->page_shift); in write_bbt()
818 to = ((loff_t)page) << this->page_shift; in write_bbt()
823 to &= ~(((loff_t)1 << this->bbt_erase_shift) - 1); in write_bbt()
824 len = 1 << this->bbt_erase_shift; in write_bbt()
834 ops.ooblen = (len >> this->page_shift) * mtd->oobsize; in write_bbt()
841 pageoffs = page - (int)(to >> this->page_shift); in write_bbt()
842 offs = pageoffs << this->page_shift; in write_bbt()
869 (len >> this->page_shift)* mtd->oobsize); in write_bbt()
883 dat = bbt_get_entry(this, chip * numblocks + i); in write_bbt()
890 einfo.len = 1 << this->bbt_erase_shift; in write_bbt()
891 res = nand_erase_nand(this, &einfo, 1); in write_bbt()
895 mark_bbt_block_bad(this, td, chip, block); in write_bbt()
899 res = scan_write_bbt(this, to, len, buf, in write_bbt()
905 mark_bbt_block_bad(this, td, chip, block); in write_bbt()
924 * @this: NAND chip object
930 static inline int nand_memory_bbt(struct nand_chip *this, in nand_memory_bbt() argument
933 u8 *pagebuf = nand_get_data_buf(this); in nand_memory_bbt()
935 return create_bbt(this, pagebuf, bd, -1); in nand_memory_bbt()
940 * @this: the NAND device
949 static int check_create(struct nand_chip *this, uint8_t *buf, in check_create() argument
953 struct nand_bbt_descr *td = this->bbt_td; in check_create()
954 struct nand_bbt_descr *md = this->bbt_md; in check_create()
959 chips = nanddev_ntargets(&this->base); in check_create()
1008 if (!(this->bbt_options & NAND_BBT_CREATE_EMPTY)) in check_create()
1009 create_bbt(this, buf, bd, chipsel); in check_create()
1018 res = read_abs_bbt(this, buf, rd, chipsel); in check_create()
1029 res2 = read_abs_bbt(this, buf, rd2, chipsel); in check_create()
1051 res = write_bbt(this, buf, td, md, chipsel); in check_create()
1058 res = write_bbt(this, buf, md, td, chipsel); in check_create()
1068 * @this: the NAND device
1073 static int nand_update_bbt(struct nand_chip *this, loff_t offs) in nand_update_bbt() argument
1075 struct mtd_info *mtd = nand_to_mtd(this); in nand_update_bbt()
1079 struct nand_bbt_descr *td = this->bbt_td; in nand_update_bbt()
1080 struct nand_bbt_descr *md = this->bbt_md; in nand_update_bbt()
1082 if (!this->bbt || !td) in nand_update_bbt()
1086 len = (1 << this->bbt_erase_shift); in nand_update_bbt()
1087 len += (len >> this->page_shift) * mtd->oobsize; in nand_update_bbt()
1094 chip = (int)(offs >> this->chip_shift); in nand_update_bbt()
1107 res = write_bbt(this, buf, td, md, chipsel); in nand_update_bbt()
1113 res = write_bbt(this, buf, md, td, chipsel); in nand_update_bbt()
1123 * @this: the NAND device
1129 static void mark_bbt_region(struct nand_chip *this, struct nand_bbt_descr *td) in mark_bbt_region() argument
1131 u64 targetsize = nanddev_target_size(&this->base); in mark_bbt_region()
1132 struct mtd_info *mtd = nand_to_mtd(this); in mark_bbt_region()
1138 chips = nanddev_ntargets(&this->base); in mark_bbt_region()
1139 nrblocks = (int)(targetsize >> this->bbt_erase_shift); in mark_bbt_region()
1142 nrblocks = (int)(mtd->size >> this->bbt_erase_shift); in mark_bbt_region()
1150 block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift); in mark_bbt_region()
1151 oldval = bbt_get_entry(this, block); in mark_bbt_region()
1152 bbt_mark_entry(this, block, BBT_BLOCK_RESERVED); in mark_bbt_region()
1155 nand_update_bbt(this, (loff_t)block << in mark_bbt_region()
1156 this->bbt_erase_shift); in mark_bbt_region()
1165 oldval = bbt_get_entry(this, block); in mark_bbt_region()
1166 bbt_mark_entry(this, block, BBT_BLOCK_RESERVED); in mark_bbt_region()
1174 * bbts. This should only happen once. in mark_bbt_region()
1177 nand_update_bbt(this, (loff_t)(block - 1) << in mark_bbt_region()
1178 this->bbt_erase_shift); in mark_bbt_region()
1184 * @this: the NAND device
1187 * This functions performs a few sanity checks on the bad block description
1190 static void verify_bbt_descr(struct nand_chip *this, struct nand_bbt_descr *bd) in verify_bbt_descr() argument
1192 u64 targetsize = nanddev_target_size(&this->base); in verify_bbt_descr()
1193 struct mtd_info *mtd = nand_to_mtd(this); in verify_bbt_descr()
1204 BUG_ON((this->bbt_options & NAND_BBT_NO_OOB) && in verify_bbt_descr()
1205 !(this->bbt_options & NAND_BBT_USE_FLASH)); in verify_bbt_descr()
1212 BUG_ON(!(this->bbt_options & NAND_BBT_USE_FLASH)); in verify_bbt_descr()
1213 BUG_ON(!(this->bbt_options & NAND_BBT_NO_OOB)); in verify_bbt_descr()
1221 table_size = targetsize >> this->bbt_erase_shift; in verify_bbt_descr()
1223 table_size = mtd->size >> this->bbt_erase_shift; in verify_bbt_descr()
1228 BUG_ON(table_size > (1 << this->bbt_erase_shift)); in verify_bbt_descr()
1233 * @this: the NAND device
1243 static int nand_scan_bbt(struct nand_chip *this, struct nand_bbt_descr *bd) in nand_scan_bbt() argument
1245 struct mtd_info *mtd = nand_to_mtd(this); in nand_scan_bbt()
1248 struct nand_bbt_descr *td = this->bbt_td; in nand_scan_bbt()
1249 struct nand_bbt_descr *md = this->bbt_md; in nand_scan_bbt()
1251 len = (mtd->size >> (this->bbt_erase_shift + 2)) ? : 1; in nand_scan_bbt()
1256 this->bbt = kzalloc(len, GFP_KERNEL); in nand_scan_bbt()
1257 if (!this->bbt) in nand_scan_bbt()
1265 if ((res = nand_memory_bbt(this, bd))) { in nand_scan_bbt()
1271 verify_bbt_descr(this, td); in nand_scan_bbt()
1272 verify_bbt_descr(this, md); in nand_scan_bbt()
1275 len = (1 << this->bbt_erase_shift); in nand_scan_bbt()
1276 len += (len >> this->page_shift) * mtd->oobsize; in nand_scan_bbt()
1285 read_abs_bbts(this, buf, td, md); in nand_scan_bbt()
1288 search_read_bbts(this, buf, td, md); in nand_scan_bbt()
1291 res = check_create(this, buf, bd); in nand_scan_bbt()
1296 mark_bbt_region(this, td); in nand_scan_bbt()
1298 mark_bbt_region(this, md); in nand_scan_bbt()
1306 kfree(this->bbt); in nand_scan_bbt()
1307 this->bbt = NULL; in nand_scan_bbt()
1364 * @this: NAND chip to create descriptor for
1366 * This function allocates and initializes a nand_bbt_descr for BBM detection
1367 * based on the properties of @this. The new descriptor is stored in
1368 * this->badblock_pattern. Thus, this->badblock_pattern should be NULL when
1369 * passed to this function.
1371 static int nand_create_badblock_pattern(struct nand_chip *this) in nand_create_badblock_pattern() argument
1374 if (this->badblock_pattern) { in nand_create_badblock_pattern()
1381 bd->options = this->bbt_options & BADBLOCK_SCAN_MASK; in nand_create_badblock_pattern()
1382 bd->offs = this->badblockpos; in nand_create_badblock_pattern()
1383 bd->len = (this->options & NAND_BUSWIDTH_16) ? 2 : 1; in nand_create_badblock_pattern()
1386 this->badblock_pattern = bd; in nand_create_badblock_pattern()
1392 * @this: NAND chip object
1394 * This function selects the default bad block table support for the device and
1397 int nand_create_bbt(struct nand_chip *this) in nand_create_bbt() argument
1402 if (this->bbt_options & NAND_BBT_USE_FLASH) { in nand_create_bbt()
1404 if (!this->bbt_td) { in nand_create_bbt()
1405 if (this->bbt_options & NAND_BBT_NO_OOB) { in nand_create_bbt()
1406 this->bbt_td = &bbt_main_no_oob_descr; in nand_create_bbt()
1407 this->bbt_md = &bbt_mirror_no_oob_descr; in nand_create_bbt()
1409 this->bbt_td = &bbt_main_descr; in nand_create_bbt()
1410 this->bbt_md = &bbt_mirror_descr; in nand_create_bbt()
1414 this->bbt_td = NULL; in nand_create_bbt()
1415 this->bbt_md = NULL; in nand_create_bbt()
1418 if (!this->badblock_pattern) { in nand_create_bbt()
1419 ret = nand_create_badblock_pattern(this); in nand_create_bbt()
1424 return nand_scan_bbt(this, this->badblock_pattern); in nand_create_bbt()
1430 * @this: NAND chip object
1433 int nand_isreserved_bbt(struct nand_chip *this, loff_t offs) in nand_isreserved_bbt() argument
1437 block = (int)(offs >> this->bbt_erase_shift); in nand_isreserved_bbt()
1438 return bbt_get_entry(this, block) == BBT_BLOCK_RESERVED; in nand_isreserved_bbt()
1443 * @this: NAND chip object
1447 int nand_isbad_bbt(struct nand_chip *this, loff_t offs, int allowbbt) in nand_isbad_bbt() argument
1451 block = (int)(offs >> this->bbt_erase_shift); in nand_isbad_bbt()
1452 res = bbt_get_entry(this, block); in nand_isbad_bbt()
1473 * @this: NAND chip object
1476 int nand_markbad_bbt(struct nand_chip *this, loff_t offs) in nand_markbad_bbt() argument
1480 block = (int)(offs >> this->bbt_erase_shift); in nand_markbad_bbt()
1483 bbt_mark_entry(this, block, BBT_BLOCK_WORN); in nand_markbad_bbt()
1486 if (this->bbt_options & NAND_BBT_USE_FLASH) in nand_markbad_bbt()
1487 ret = nand_update_bbt(this, offs); in nand_markbad_bbt()