2、上一篇中,nand_scan(s3c_mtd, 1)函数没有细说,这一篇说下这个函数,源码如下: /** * nand_scan - [NAND Interface] Scan for the NAND device * @mtd: MTD device structure * @maxchips: Number of chips to scan for * * This fills out all the uninitialized function pointers * with the defaults. * The flash ID is read and the mtd/chip structures are * filled with the appropriate values. * The mtd->owner field must be set to the module of the caller * */ int nand_scan(struct mtd_info *mtd, int maxchips) { int ret;
/* Many callers got this wrong, so check for it for a while... */ if (!mtd->owner && caller_is_module()) { printk(KERN_CRIT "nand_scan() called with NULL mtd->owner!
"); BUG(); }
ret = nand_scan_ident(mtd, maxchips); if (!ret) 如果上面的函数成功,这执行nand_scan_tail函数。这个函数的分析,看下面: ret = nand_scan_tail(mtd); return ret; } 主要就是上面那个函数:nand_scan_ident,源码如下:/** * nand_scan_ident - [NAND Interface] Scan for the NAND device * @mtd: MTD device structure * @maxchips: Number of chips to scan for * * This is the first phase of the normal nand_scan() function. It * reads the flash ID and sets up MTD fields accordingly. * * The mtd->owner field must be set to the module of the caller. */ int nand_scan_ident(struct mtd_info *mtd, int maxchips) { int i, busw, nand_maf_id; struct nand_chip *chip = mtd->priv; 得到struct nand_chip结构体 struct nand_flash_dev *type;
/* Get buswidth to select the correct functions */ busw = chip->options & NAND_BUSWIDTH_16; 和数据宽度有关,看下面这个图: /* Set the default functions */ 根据数据宽度设置默认函数: nand_set_defaults(chip, busw);此函数源码如下:/* * Set default functions */ static void nand_set_defaults(struct nand_chip *chip, int busw) { /* check for proper chip_delay setup, set 20us if not */ if (!chip->chip_delay) chip->chip_delay = 20;
/* check, if a user supplied command function given */ if (chip->cmdfunc == NULL) chip->cmdfunc = nand_command;
/* check, if a user supplied wait function given */ if (chip->waitfunc == NULL) chip->waitfunc = nand_wait;
if (!chip->select_chip) chip->select_chip = nand_select_chip; if (!chip->read_byte) chip->read_byte = busw ? nand_read_byte16 : nand_read_byte; if (!chip->read_word) chip->read_word = nand_read_word; if (!chip->block_bad) chip->block_bad = nand_block_bad; if (!chip->block_markbad) chip->block_markbad = nand_default_block_markbad; if (!chip->write_buf) chip->write_buf = busw ? nand_write_buf16 : nand_write_buf; if (!chip->read_buf) chip->read_buf = busw ? nand_read_buf16 : nand_read_buf; if (!chip->verify_buf) chip->verify_buf = busw ? nand_verify_buf16 : nand_verify_buf; if (!chip->scan_bbt) chip->scan_bbt = nand_default_bbt;
if (!chip->controller) { chip->controller = &chip->hwcontrol; spin_lock_init(&chip->controller->lock); init_waitqueue_head(&chip->controller->wq); }
}
/* Read the flash type */ 读取NAND芯片的信息,并进行一些结构体成员的赋值 type = nand_get_flash_type(mtd, chip, busw, &nand_maf_id);
if (IS_ERR(type)) { printk(KERN_WARNING "No NAND device found!!!
"); chip->select_chip(mtd, -1); return PTR_ERR(type); }
/* Check for a chip array */ 和多芯片有关 for (i = 1; i < maxchips; i++) { chip->select_chip(mtd, i); /* See comment in nand_get_flash_type for reset */ chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); /* Send the command for reading device ID */ chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); /* Read manufacturer and device IDs */ if (nand_maf_id != chip->read_byte(mtd) || type->id != chip->read_byte(mtd)) break; } if (i > 1) printk(KERN_INFO "%d NAND chips detected
", i);
/* Store the number of chips and calc total size for mtd */ chip->numchips = i; mtd->size = i * chip->chipsize;
return 0; } 3、nand_scan_tail函数:源码如下:/** * nand_scan_tail - [NAND Interface] Scan for the NAND device */