nand_init();//nand.c
nand_init_chip
int board_nand_init(struct nand_chip *nand);//初始化nand_chip
ti81xx_nand_switch_ecc(NAND_ECC_HW, 2);
__ti81xx_nand_switch_ecc
nand->ecc.bytes = 14;
nand->ecc.layout = &hw_bch8_nand_oob;
bch->nibbles = ECC_BCH8_NIBBLES;
bch->mode = NAND_ECC_HW;
nand->ecc.mode = NAND_ECC_HW_SYNDROME;
nand->ecc.steps = 4;
nand->ecc.size = 512;
nand->ecc.total = (nand->ecc.steps * nand->ecc.bytes);
nand->ecc.write_page = ti81xx_write_page_bch;
nand->ecc.read_page = ti81xx_read_page_bch;
nand->ecc.hwctl = ti81xx_enable_ecc_bch;
nand->ecc.correct = ti81xx_correct_data_bch;
nand->ecc.calculate = ti81xx_calculate_ecc_bch;
ti81xx_hwecc_init_bch(nand, NAND_ECC_READ);
nand->options |= NAND_OWN_BUFFERS;
nand_scan_tail(mtd);
//初始化阶段,在这里调用的nand_scan_tail本质上没有作用,直接返回(因为在ti81xx_hwecc_init_bch设置了NAND_OWN_BUFFERS)
nand->options &= ~NAND_OWN_BUFFERS;
nand_scan
nand_scan_ident
nand_set_defaults
chip->cmdfunc = nand_command;//这时还是小页的nand_command
nand_get_flash_type
chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);//READID
*maf_id = chip->read_byte(mtd);//1st MID
*dev_id = chip->read_byte(mtd);//2nd PID
nand_flash_detect_onfi//不支持onfi,直接返回0;
chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1);//READID,ONFI
read_byte //4个周期 O、N、F、I
chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1);
chip->read_buf(mtd, (uint8_t *)p, sizeof(*p));//读nand_onfi_params结构体
nand_flash_detect_non_onfi//readid 3rd/4th个周期
if (mtd->writesize > 512 && chip->cmdfunc == nand_command)
chip->cmdfunc = nand_command_lp;
nand_scan_tail
chip->write_page = nand_write_page;
/* Fill in remaining MTD driver data */
mtd->type = MTD_NANDFLASH;
mtd->flags = MTD_CAP_NANDFLASH;
mtd->erase = nand_erase;
mtd->point = NULL;
mtd->unpoint = NULL;
mtd->read = nand_read;
mtd->write = nand_write;
mtd->read_oob = nand_read_oob;
mtd->write_oob = nand_write_oob;
mtd->sync = nand_sync;
mtd->lock = NULL;
mtd->unlock = NULL;
mtd->block_isbad = nand_block_isbad;
mtd->block_markbad = nand_block_markbad;
nand dump
do_nand
nand_dump
ops.mode = MTD_OOB_RAW;
i = nand->read_oob(nand, addr, &ops);=nand_read_oob
nand_do_read_ops
chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
if (unlikely(ops->mode == MTD_OOB_RAW))
ret = chip->ecc.read_page_raw(mtd, chip,bufpoi, page);=nand_read_page_raw,没有ECC保护
chip->read_buf(mtd, buf, mtd->writesize);//读data
chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);//读oob
nand read
do_nand
nand_read_skip_bad(nand, off, &rwsize,(u_char *)addr)
check_skip_len
int nand_block_isbad(struct mtd_info *mtd, loff_t offs)
int nand_block_isbad(struct mtd_info *mtd, loff_t offs)
chip->block_bad;=nand_block_bad
chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos, page);
chip->read_byte(mtd) != 0xff
nand_read (nand, offset, length, buffer);
nand_do_read_ops
chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);//READ0命令,随机读之前需要发送
ret = chip->ecc.read_page(mtd, chip, bufpoi, page);=ti81xx_read_page_bch//随机读
nand write
do_nand
nand_write_skip_bad(nand, off, &rwsize,(u_char *)addr, 0);
check_skip_len
nand_write (nand, offset, length, buffer);
nand_do_write_ops
chip->write_page(mtd, chip, wbuf, page, cached,(ops->mode == MTD_OOB_RAW));=nand_write_page
chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
chip->ecc.write_page(mtd, chip, buf);=ti81xx_write_page_bch
nand erase
do_nand
nand_erase_opts(nand, &opts);
nand_erase
nand_erase_nand
chip->erase_cmd(mtd, page & chip->pagemask);=single_erase_cmd
chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page);
chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1);
status = chip->waitfunc(mtd, chip);=nand_wait
this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
return this->read_byte(mtd);
nand markbad
do_nand
nand->block_markbad(nand, addr);=nand_block_markbad//mtd_info
chip->block_markbad(mtd, ofs);=nand_default_block_markbad//nand_chip
nand_do_write_oob
nand_fill_oob(chip, ops->oobbuf, ops);
status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask);=nand_write_oob_std