struct nand_ecc_ctrl {
nand_ecc_modes_t mode;
int steps;
int size;
int bytes;
int total;
int prepad;
int postpad;
struct nand_ecclayout *layout;
/*hwctl函数:
*这个函数用来控制硬件产生ecc
*其实它主要的工作就是控制NAND controller 向 NAND 芯片发出NAND_ECC_READ 、NAND_ECC_WRITE 和NAND_ECC_READSYN *等命令,与struct nand_chip 结构体中的cmdfunc 类似
*/
void (*hwctl)(struct mtd_info *mtd, int mode);
/*根据data 计算ecc 值*/
int (*calculate)(struct mtd_info *mtd,const uint8_t *dat,uint8_t *ecc_code);
/*根据ecc 值,判断读写数据时是否有错误发生,若有错,则立即试着纠正,纠正失败则返回错误*/
int (*correct)(struct mtd_info *mtd, uint8_t *dat,uint8_t *read_ecc,uint8_t *calc_ecc);
/*read_page_raw write_page_raw函数
*从NAND 芯片中读取一个page 的原始数据和向NAND 芯片写入一个page 的原始数据,所谓的原始数据,即不对读写的数据做ecc处理 *该读写什么值就读写什么值。另外,这两个函数会读写整个page 中的所有内容,即不但会读写一个page 中MAIN部分,还会读写OOB 部分。
*/
int (*read_page_raw)(struct mtd_info *mtd,struct nand_chip *chip,uint8_t *buf);
void (*write_page_raw)(struct mtd_info *mtd,struct nand_chip *chip,const uint8_t *buf);
/*
*read_page 和write_page 在读写过程中会加入ecc 的计算,校验,和纠正等处理。
*/
int (*read_page)(struct mtd_info *mtd,struct nand_chip *chip,uint8_t *buf);
void (*write_page)(struct mtd_info *mtd,struct nand_chip *chip,const uint8_t *buf);
/*
*读写oob 中的内容,不包括MAIN 部分。
*/
int (*read_oob)(struct mtd_info *mtd,struct nand_chip *chip,int page,int sndcmd);
int (*write_oob)(struct mtd_info *mtd,struct nand_chip *chip,int page);
};
其实,以上提到的这几个read_xxx 和write_xxx 函数,最终都会调用struct nand_chip 中的read_buf 和write_buf 这两个函数,所以如果没有特殊需求的话,我认为不必自己实现,使用MTD 提供的default 的函数即可。
--------------------------------------------------------
#include <linux/module.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/partitions.h>
#include <asm/io.h>
#include <asm/arch/regs-nand.h>
#include <asm/arch/nand.h>
struct s3c_nand_regs {
unsigned long nfconf ;
unsigned long nfcont ;
unsigned long nfcmd ;
unsigned long nfaddr ;
unsigned long nfdata ;
unsigned long nfeccd0 ;
unsigned long nfeccd1 ;
unsigned long nfeccd ;
unsigned long nfstat ;
unsigned long nfestat0;
unsigned long nfestat1;
unsigned long nfmecc0 ;
unsigned long nfmecc1 ;
unsigned long nfsecc ;
unsigned long nfsblk ;
unsigned long nfeblk ;
};
static struct nand_chip *s3c_nand_chip;
static struct mtd_info *s3c_mtd;
static struct s3c_nand_regs *s3c_nand_regs;
static struct mtd_partition s3c_nand_parts[] = {
[0] = {
.name = "bootloader",
.size = 0x00040000,
.offset = 0,
},
[1] = {
.name = "params",
.offset = MTDPART_OFS_APPEND,
.size = 0x00020000,
},
[2] = {
.name = "kernel",
.offset = MTDPART_OFS_APPEND,
.size = 0x00200000,
},
[3] = {
.name = "root",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
}
};