spi nand MTD层代码流程分析

MTD层调用驱动代码流程

    read

mtd_read
	mtd->_read
		nand_read		
			nand_do_read_ops
				nand->cmdfunc
				chip->ecc.read_page
					chip->read_buf

    write

mtd_write
	mtd->_write
		nand_write
			nand_do_write_ops
				chip->write_page
					chip->cmdfunc
					chip->ecc.write_page
						chip->write_buf

driver层代码初始化

    maps/bcm963xx_mtd.c    

    mtd->priv = nand;  这个比较重要,实现nand与mtd的连接;

module_init(mtd_init);	
	struct mtd_info * mtd;
	struct nand_chip * nand;
	
	mtd = kmalloc(sizeof(struct mtd_info), GFP_KERNEL)
	nand = kmalloc(sizeof(struct nand_chip), GFP_KERNEL)
	mtd->priv = nand;
	
	bcmspinand_probe(mtd);
	nand_scan(mtd, 1)
	nand->init_size(mtd, nand, NULL)
	setup_mtd_parts(mtd);

nand层函数实现和函数指针实现赋值

    nand/bcm63xx_spinand.c

bcmspinand_probe(mtd);
	struct nand_chip * nand = mtd->priv;
	
	pSpiDevice = spi_new_device(pSpiMaster, &bcmSpiDevInfo);
	spi_register_driver(&bcmSpiDevDrv);
	
	// reset and set configuration information
	spi_nand_device_reset(); 

	nand->ecc.size = pchip->chip_page_size;
	nand->ecc.bytes = 0;
	nand->ecc.strength = 0;
	nand->ecc.layout = pchip->ecclayout;
	nand->page_shift = pchip->chip_page_shift;
	nand->phys_erase_shift = pchip->chip_block_shift;
	nand->chipsize = pchip->chip_total_size;		

	rpageBuf = kmalloc(pchip->chip_page_size + pchip->chip_spare_size, GFP_KERNEL);
	wpageBuf = kmalloc(pchip->chip_page_size + pchip->chip_spare_size, GFP_KERNEL);

	nand->options = NAND_NO_SUBPAGE_WRITE;

	nand->chip_delay = 0;
	nand->read_byte = bcm63xx_read_byte;
	nand->read_buf = bcm63xx_read_buf;
	nand->ecc.mode = NAND_ECC_NONE;

	nand->select_chip = bcm63xx_select;
	nand->write_buf  = bcm63xx_write;
	nand->scan_bbt = bcm63xx_scan_bbt;
	nand->block_bad = bcm63xx_block_isbad;
	nand->block_markbad = bcm63xx_block_markbad;
	nand->cmdfunc = bcm63xx_cmd;
	nand->waitfunc = bcm63xx_status;
	
	nand->init_size = bcm63xx_init_size;

MTD层函数实现和函数指针实现赋值

    nand/nand_base.c

nand_scan(mtd, 1)
	nand_scan_ident(mtd, maxchips, NULL)
		nand_set_defaults
			chip->scan_bbt = nand_default_bbt;
				nand_scan_bbt(mtd, this->badblock_pattern);
				
	nand_scan_tail(mtd);
		struct nand_chip *chip = mtd->priv;
		struct nand_ecc_ctrl *ecc = &chip->ecc;
		
		ecc->layout = &nand_oob_64;
		case NAND_ECC_NONE:
		pr_warn("NAND_ECC_NONE selected by board driver. This is not recommended!\n");
		ecc->read_page = nand_read_page_raw;
		ecc->write_page = nand_write_page_raw;
		ecc->read_oob = nand_read_oob_std;
		ecc->read_page_raw = nand_read_page_raw;
		ecc->write_page_raw = nand_write_page_raw;
		ecc->write_oob = nand_write_oob_std;
		ecc->size = mtd->writesize;
		ecc->bytes = 0;
		ecc->strength = 0;				
		
		mtd->_erase = nand_erase;
		mtd->_point = NULL;
		mtd->_unpoint = NULL;
		mtd->_read = nand_read;
		mtd->_write = nand_write;
		mtd->_panic_write = panic_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->_suspend = nand_suspend;
		mtd->_resume = nand_resume;
		mtd->_reboot = nand_shutdown;
		mtd->_block_isreserved = nand_block_isreserved;
		mtd->_block_isbad = nand_block_isbad;
		mtd->_block_markbad = nand_block_markbad;
		mtd->writebufsize = mtd->writesize;

		/* propagate ecc info to mtd_info */
		mtd->ecclayout = ecc->layout;
		mtd->ecc_strength = ecc->strength;
		mtd->ecc_step_size = ecc->size;				
		
		chip->write_page = nand_write_page;
		
		return chip->scan_bbt(mtd);

 

你可能感兴趣的:(Nand,Flash)