yaffs and ecc

1. yaffs文件系统中yaffs自身的ECC与MTD的ECC之间联系分析:
   从yaffs_mtdif.c文件中的这个函数,可以很容易看出它们的联系:
int nandmtd_ReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare)
{
 struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
 size_t dummy;
    int retval = 0;
 
 loff_t addr = ((loff_t)chunkInNAND) * dev->nBytesPerChunk;
 
 __u8 *spareAsBytes = (__u8 *)spare;
 
#ifndef CONFIG_YAFFS_USE_OLD_MTD
 if(data && spare)
 {
  if(dev->useNANDECC) /* 如果配置CONFIG_YAFFS_USE_NANDECC的话,此值为1,否则为0 */
  {   // Careful, this call adds 2 ints to the end of the spare data.  Calling function should
            // allocate enough memory for spare, i.e. [YAFFS_BYTES_PER_SPARE+2*sizeof(int)].
      retval = mtd->read_ecc(mtd,addr,dev->nBytesPerChunk,&dummy,data,spareAsBytes,&yaffs_oobinfo);           
  }
  else
  {
   retval = mtd->read_ecc(mtd,addr,dev->nBytesPerChunk,&dummy,data,spareAsBytes,&yaffs_noeccinfo);
  }
 }
 else
 {
#endif
 if(data)
  retval = mtd->read(mtd,addr,dev->nBytesPerChunk,&dummy,data);
 if(spare)
  retval = mtd->read_oob(mtd,addr,YAFFS_BYTES_PER_SPARE,&dummy,spareAsBytes);
#ifndef CONFIG_YAFFS_USE_OLD_MTD
 }
#endif
    if (retval == 0)
     return YAFFS_OK;
    else
        return YAFFS_FAIL;
}
  上面mtd->read_ecc、mtd->write_ecc在drivers/mtd/nand/nand.c中定义,与ECC有关的代码摘录如下:
 // use chip default if zero
 if (oobsel == NULL) /* oobsel来自上面mtd->read_ecc调用的最后一个参数 */
  oobsel = &mtd->oobinfo; 
  
    /* 如果配置CONFIG_YAFFS_USE_NANDECC的话,
     * 从mtd->read_ecc传入的oobsel->useecc为1,否则为0
     * this->eccmode的值是在nand.c中自己指定的,它确定所指mtd设备使用的ECC类型
     */
 eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
    ......
    switch (eccmode) {
        case NAND_ECC_NONE:
            this->read_buf(mtd, data_poi, end);
            ......
            break;
  case NAND_ECC_SOFT: /* Software ECC 3/256: Read in a page + oob data */
   this->read_buf(mtd, data_poi, end);
   
   /* 计算出ECC码 */
   this->calculate_ecc(mtd, &data_poi[0], &ecc_calc[0]);
   ......
   break;
        case NAND_ECC_HW3_256:
            ..........
            通过硬件机制得到ECC码   
   ..........
    }
    ......
   
    /* OOB里面包含ECC,如果eccmode != NAND_ECC_NONE的话,
     * 这些ECC码将和上面计算得到的ECC码进行校验
     */
    读OOB
    ......
    /* Skip ECC, if not active */
    if (eccmode == NAND_ECC_NONE)
        goto readdata; 
    ......       
    根据ECC进行校验   
    ......
yaffs中的ECC代码有两部分,一是512字节的数据的ECC码,一是OOB里面8字节的tags的ECC码。
1. 对于512字节的数据的ECC码:
    以flash上的一个chunk为例,前面512字节存放数据,后面16字节的OOB中,有根据这512字节
数据计算出来的ECC码。当yaffs文件系统需要读出一个chunk数据时,对于不同版本的MTD驱动,有
如下两种方法:
1.1 当在yaffs中配置CONFIG_YAFFS_USE_OLD_MTD时,使用如下语句读出数据,没有MTD的ECC校验。
   至于是否作ECC校验,取决于yaffs是否配置CONFIG_YAFFS_USE_NANDECC:
        配置了CONFIG_YAFFS_USE_NANDECC,则yaffs自身的ECC功能未使用,所以没有任何ECC校验
        未配置CONFIG_YAFFS_USE_NANDECC,则使用yaffs自身的ECC功能
  retval = mtd->read(mtd,addr,dev->nBytesPerChunk,&dummy,data);
 if(spare)
  retval = mtd->read_oob(mtd,addr,YAFFS_BYTES_PER_SPARE,&dummy,spareAsBytes);
1.2 在yaffs中未配置CONFIG_YAFFS_USE_OLD_MTD时,使用如下语句读出数据,要么使用MTD的ECC功能,
   要么使用yaffs自身的ECC功能,取决与是否配置CONFIG_YAFFS_USE_NANDECC:
  if(dev->useNANDECC)
  {   // Careful, this call adds 2 ints to the end of the spare data.  Calling function should
            // allocate enough memory for spare, i.e. [YAFFS_BYTES_PER_SPARE+2*sizeof(int)].
      retval = mtd->read_ecc(mtd,addr,dev->nBytesPerChunk,&dummy,data,spareAsBytes,&yaffs_oobinfo);           
  }
  else
  {
   retval = mtd->read_ecc(mtd,addr,dev->nBytesPerChunk,&dummy,data,spareAsBytes,&yaffs_noeccinfo);
  }
2. 对于OOB里面8字节的tags的ECC码:
   使用yaffs自身的ECC功能
  
ECC总结如下:
1. 使用谁的ECC功能:
    CONFIG_YAFFS_USE_OLD_MTD    CONFIG_YAFFS_USE_NANDECC    512字节的ECC    TAGS的ECC
                y                       y                       none            yaffs
                y                       n                       yaffs           yaffs
                n                       y                       mtd             yaffs
                n                       n                       yaffs           yaffs
2. MTD的ECC功能类型,可以在nand.c中指定某个nand flash使用何种类型的mtd ECC功能:
2.1 NAND_ECC_NONE       /* 不使用ECC */
2.2 NAND_ECC_SOFT
2.3 NAND_ECC_HW3_256
2.4 NAND_ECC_HW3_512
2.5 NAND_ECC_HW6_512
2.6 NAND_ECC_DISKONCHIP

你可能感兴趣的:(struct,function,Flash,null,tags)