|
楼主 |
发表于 2007-7-5 14:25:21
|
显示全部楼层
问题已解决。所有erase NANDFlash的动作最终都是通过struct mtd_info中的erase指针实现的。
struct mtd_info {
int (*erase) (struct mtd_info *mtd, struct erase_info *instr);
int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
int (*read_ecc) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
int (*write_ecc) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
...
...
...
这个指针在 cfi_cmdset_0002.c中被调用指向了一个函数“mtd->erase = cfi_amdstd_erase_chip;”
函数也定义在 cfi_cmdset_0002.c中,所以最终可以看到erase的全部自检机制,即在erase结束后,会把刚erase过的空间里的值读两次出来,对第二次读出来的值作比较,该值必须同时满足‘等于第一次读出来的值’和‘等于0xFF’才算erase成功,不然就是坏块,做标记。
相关代码如下:
static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip)
{
struct cfi_private *cfi = map->fldrv_priv;
unsigned long timeo = jiffies + HZ;
unsigned long int adr;
DECLARE_WAITQUEUE(wait, current);
int ret = 0;
/* Did we succeed? */
if (!chip_good(map, adr, map_word_ff(map))) {
/* reset on all failures. */
map_write( map, CMD(0xF0), chip->start );
/* FIXME - should have reset delay before continuing */
ret = -EIO;
}
chip->state = FL_READY;
xip_enable(map, chip, adr);
put_chip(map, chip, adr);
spin_unlock(chip->mutex);
....
static int __xipram chip_good(struct map_info *map, unsigned long addr, map_word expected)
{
map_word oldd, curd;
oldd = map_read(map, addr);
curd = map_read(map, addr);
return map_word_equal(map, oldd, curd) &&
map_word_equal(map, curd, expected);
}
希望能给正在研究nandflash的同学一些帮助 |
|