Lines Matching refs:nand

84 static u32 bbt_nand_isbad_bypass(struct nand_device *nand, u32 block)  in bbt_nand_isbad_bypass()  argument
86 struct mtd_info *mtd = nanddev_to_mtd(nand); in bbt_nand_isbad_bypass()
89 nanddev_bbt_set_block_status(nand, block, NAND_BBT_BLOCK_STATUS_UNKNOWN); in bbt_nand_isbad_bypass()
90 nanddev_offs_to_pos(nand, block * mtd->erasesize, &pos); in bbt_nand_isbad_bypass()
92 return nanddev_isbad(nand, &pos); in bbt_nand_isbad_bypass()
106 static int nanddev_read_bbt(struct nand_device *nand, u32 block, bool update) in nanddev_read_bbt() argument
109 unsigned int nblocks = nanddev_neraseblocks(nand); in nanddev_read_bbt()
111 BITS_PER_LONG) * sizeof(*nand->bbt.cache); in nanddev_read_bbt()
112 struct mtd_info *mtd = nanddev_to_mtd(nand); in nanddev_read_bbt()
120 if (!nand->bbt.cache) in nanddev_read_bbt()
179 if (update && version > nand->bbt.version) { in nanddev_read_bbt()
180 memcpy(nand->bbt.cache, data_buf, nbytes); in nanddev_read_bbt()
181 nand->bbt.version = version; in nanddev_read_bbt()
188 bool in_scan = nand->bbt.option & NANDDEV_BBT_SCANNED; in nanddev_read_bbt()
193 memcpy(temp_buf, nand->bbt.cache, nbytes); in nanddev_read_bbt()
194 memcpy(nand->bbt.cache, data_buf, nbytes); in nanddev_read_bbt()
197 nand->bbt.option |= NANDDEV_BBT_SCANNED; in nanddev_read_bbt()
199 ret = nanddev_bbt_get_block_status(nand, block); in nanddev_read_bbt()
204 nand->bbt.option &= ~NANDDEV_BBT_SCANNED; in nanddev_read_bbt()
205 memcpy(nand->bbt.cache, temp_buf, nbytes); in nanddev_read_bbt()
218 static int nanddev_write_bbt(struct nand_device *nand, u32 block) in nanddev_write_bbt() argument
221 unsigned int nblocks = nanddev_neraseblocks(nand); in nanddev_write_bbt()
223 BITS_PER_LONG) * sizeof(*nand->bbt.cache); in nanddev_write_bbt()
224 struct mtd_info *mtd = nanddev_to_mtd(nand); in nanddev_write_bbt()
232 bbt_dbg("write_bbt to blk=%d ver=%d\n", block, nand->bbt.version); in nanddev_write_bbt()
233 if (!nand->bbt.cache) in nanddev_write_bbt()
256 memcpy(data_buf, nand->bbt.cache, nbytes); in nanddev_write_bbt()
258 bbt_info->version = nand->bbt.version; in nanddev_write_bbt()
262 nanddev_offs_to_pos(nand, block * mtd->erasesize, &pos); in nanddev_write_bbt()
263 ret = nand->ops->erase(nand, &pos); in nanddev_write_bbt()
276 nand->ops->erase(nand, &pos); in nanddev_write_bbt()
280 version = nanddev_read_bbt(nand, block, false); in nanddev_write_bbt()
284 nand->ops->erase(nand, &pos); in nanddev_write_bbt()
296 static __maybe_unused int nanddev_bbt_format(struct nand_device *nand) in nanddev_bbt_format() argument
298 unsigned int nblocks = nanddev_neraseblocks(nand); in nanddev_bbt_format()
299 struct mtd_info *mtd = nanddev_to_mtd(nand); in nanddev_bbt_format()
309 nanddev_offs_to_pos(nand, block * mtd->erasesize, &pos); in nanddev_bbt_format()
310 if (nanddev_isbad(nand, &pos)) { in nanddev_bbt_format()
311 if (bbt_nand_isbad_bypass(nand, 0)) { in nanddev_bbt_format()
312 memset(nand->bbt.cache, 0, nwords * sizeof(*nand->bbt.cache)); in nanddev_bbt_format()
317 if (!bbt_nand_isbad_bypass(nand, block)) { in nanddev_bbt_format()
318 memset(nand->bbt.cache, 0, nwords * sizeof(*nand->bbt.cache)); in nanddev_bbt_format()
323 nanddev_bbt_set_block_status(nand, block, in nanddev_bbt_format()
329 if (nanddev_bbt_get_block_status(nand, start_block + block) == in nanddev_bbt_format()
331 nanddev_bbt_set_block_status(nand, start_block + block, in nanddev_bbt_format()
338 static int nanddev_scan_bbt(struct nand_device *nand) in nanddev_scan_bbt() argument
340 unsigned int nblocks = nanddev_neraseblocks(nand); in nanddev_scan_bbt()
344 nand->bbt.version = 0; in nanddev_scan_bbt()
347 nanddev_read_bbt(nand, start_block + block, true); in nanddev_scan_bbt()
349 nand->bbt.option |= NANDDEV_BBT_SCANNED; in nanddev_scan_bbt()
351 if (nand->bbt.version == 0) { in nanddev_scan_bbt()
352 ret = nanddev_bbt_format(nand); in nanddev_scan_bbt()
354 nand->bbt.option = 0; in nanddev_scan_bbt()
360 ret = nanddev_bbt_update(nand); in nanddev_scan_bbt()
362 nand->bbt.option = 0; in nanddev_scan_bbt()
372 if (nand->bbt.version) { in nanddev_scan_bbt()
374 ret = nanddev_bbt_get_block_status(nand, block); in nanddev_scan_bbt()
393 int nanddev_bbt_init(struct nand_device *nand) in nanddev_bbt_init() argument
396 unsigned int nblocks = nanddev_neraseblocks(nand); in nanddev_bbt_init()
400 nand->bbt.cache = kcalloc(nwords, sizeof(*nand->bbt.cache), in nanddev_bbt_init()
402 if (!nand->bbt.cache) in nanddev_bbt_init()
415 void nanddev_bbt_cleanup(struct nand_device *nand) in nanddev_bbt_cleanup() argument
417 kfree(nand->bbt.cache); in nanddev_bbt_cleanup()
430 int nanddev_bbt_update(struct nand_device *nand) in nanddev_bbt_update() argument
434 struct mtd_info *mtd = nanddev_to_mtd(nand); in nanddev_bbt_update()
436 if (nand->bbt.cache && in nanddev_bbt_update()
437 nand->bbt.option & NANDDEV_BBT_USE_FLASH) { in nanddev_bbt_update()
438 unsigned int nblocks = nanddev_neraseblocks(nand); in nanddev_bbt_update()
446 status = nanddev_bbt_get_block_status(nand, start_block + block); in nanddev_bbt_update()
447 ret = nanddev_read_bbt(nand, start_block + block, false); in nanddev_bbt_update()
468 if (nand->bbt.version < min_version) in nanddev_bbt_update()
469 nand->bbt.version = min_version + 4; in nanddev_bbt_update()
472 nand->bbt.version++; in nanddev_bbt_update()
473 ret = nanddev_write_bbt(nand, block_des); in nanddev_bbt_update()
493 nanddev_offs_to_pos(nand, block_des * mtd->erasesize, &pos); in nanddev_bbt_update()
494 nand->ops->erase(nand, &pos); in nanddev_bbt_update()
513 int nanddev_bbt_get_block_status(const struct nand_device *nand, in nanddev_bbt_get_block_status() argument
517 unsigned long *pos = nand->bbt.cache + in nanddev_bbt_get_block_status()
523 if (nand->bbt.option & NANDDEV_BBT_USE_FLASH && in nanddev_bbt_get_block_status()
524 !(nand->bbt.option & NANDDEV_BBT_SCANNED)) in nanddev_bbt_get_block_status()
525 nanddev_scan_bbt((struct nand_device *)nand); in nanddev_bbt_get_block_status()
528 if (entry >= nanddev_neraseblocks(nand)) in nanddev_bbt_get_block_status()
552 int nanddev_bbt_set_block_status(struct nand_device *nand, unsigned int entry, in nanddev_bbt_set_block_status() argument
556 unsigned long *pos = nand->bbt.cache + in nanddev_bbt_set_block_status()
561 if (entry >= nanddev_neraseblocks(nand)) in nanddev_bbt_set_block_status()