mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 11:46:19 +00:00
Merge git://git.infradead.org/mtd-2.6
* git://git.infradead.org/mtd-2.6: [JFFS2][XATTR] Fix memory leak in POSIX-ACL support fs/jffs2/: make 2 functions static [MTD] NAND: Fix broken sharpsl driver [JFFS2][XATTR] Fix xd->refcnt race condition MTD: kernel-doc fixes + additions MTD: fix all kernel-doc warnings [MTD] DOC: Fixup read functions and do a little cleanup
This commit is contained in:
commit
0d1782144e
19 changed files with 331 additions and 432 deletions
|
@ -109,7 +109,7 @@
|
|||
for most of the implementations. These functions can be replaced by the
|
||||
board driver if neccecary. Those functions are called via pointers in the
|
||||
NAND chip description structure. The board driver can set the functions which
|
||||
should be replaced by board dependend functions before calling nand_scan().
|
||||
should be replaced by board dependent functions before calling nand_scan().
|
||||
If the function pointer is NULL on entry to nand_scan() then the pointer
|
||||
is set to the default function which is suitable for the detected chip type.
|
||||
</para></listitem>
|
||||
|
@ -133,7 +133,7 @@
|
|||
[REPLACEABLE]</para><para>
|
||||
Replaceable members hold hardware related functions which can be
|
||||
provided by the board driver. The board driver can set the functions which
|
||||
should be replaced by board dependend functions before calling nand_scan().
|
||||
should be replaced by board dependent functions before calling nand_scan().
|
||||
If the function pointer is NULL on entry to nand_scan() then the pointer
|
||||
is set to the default function which is suitable for the detected chip type.
|
||||
</para></listitem>
|
||||
|
@ -156,9 +156,8 @@
|
|||
<title>Basic board driver</title>
|
||||
<para>
|
||||
For most boards it will be sufficient to provide just the
|
||||
basic functions and fill out some really board dependend
|
||||
basic functions and fill out some really board dependent
|
||||
members in the nand chip description structure.
|
||||
See drivers/mtd/nand/skeleton for reference.
|
||||
</para>
|
||||
<sect1>
|
||||
<title>Basic defines</title>
|
||||
|
@ -1295,7 +1294,9 @@ in this page</entry>
|
|||
</para>
|
||||
!Idrivers/mtd/nand/nand_base.c
|
||||
!Idrivers/mtd/nand/nand_bbt.c
|
||||
!Idrivers/mtd/nand/nand_ecc.c
|
||||
<!-- No internal functions for kernel-doc:
|
||||
X!Idrivers/mtd/nand/nand_ecc.c
|
||||
-->
|
||||
</chapter>
|
||||
|
||||
<chapter id="credits">
|
||||
|
|
|
@ -55,10 +55,6 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
|
|||
size_t *retlen, u_char *buf);
|
||||
static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
|
||||
size_t *retlen, const u_char *buf);
|
||||
static int doc_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);
|
||||
static int doc_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);
|
||||
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
|
||||
struct mtd_oob_ops *ops);
|
||||
static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
|
||||
|
@ -614,18 +610,11 @@ EXPORT_SYMBOL_GPL(DoC2k_init);
|
|||
|
||||
static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
|
||||
size_t * retlen, u_char * buf)
|
||||
{
|
||||
/* Just a special case of doc_read_ecc */
|
||||
return doc_read_ecc(mtd, from, len, retlen, buf, NULL, NULL);
|
||||
}
|
||||
|
||||
static int doc_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)
|
||||
{
|
||||
struct DiskOnChip *this = mtd->priv;
|
||||
void __iomem *docptr = this->virtadr;
|
||||
struct Nand *mychip;
|
||||
unsigned char syndrome[6];
|
||||
unsigned char syndrome[6], eccbuf[6];
|
||||
volatile char dummy;
|
||||
int i, len256 = 0, ret=0;
|
||||
size_t left = len;
|
||||
|
@ -673,15 +662,9 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
|
|||
DoC_Address(this, ADDR_COLUMN_PAGE, from, CDSN_CTRL_WP,
|
||||
CDSN_CTRL_ECC_IO);
|
||||
|
||||
if (eccbuf) {
|
||||
/* Prime the ECC engine */
|
||||
WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
|
||||
WriteDOC(DOC_ECC_EN, docptr, ECCConf);
|
||||
} else {
|
||||
/* disable the ECC engine */
|
||||
WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
|
||||
WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
|
||||
}
|
||||
/* Prime the ECC engine */
|
||||
WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
|
||||
WriteDOC(DOC_ECC_EN, docptr, ECCConf);
|
||||
|
||||
/* treat crossing 256-byte sector for 2M x 8bits devices */
|
||||
if (this->page256 && from + len > (from | 0xff) + 1) {
|
||||
|
@ -698,58 +681,59 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
|
|||
/* Let the caller know we completed it */
|
||||
*retlen += len;
|
||||
|
||||
if (eccbuf) {
|
||||
/* Read the ECC data through the DiskOnChip ECC logic */
|
||||
/* Note: this will work even with 2M x 8bit devices as */
|
||||
/* they have 8 bytes of OOB per 256 page. mf. */
|
||||
DoC_ReadBuf(this, eccbuf, 6);
|
||||
/* Read the ECC data through the DiskOnChip ECC logic */
|
||||
/* Note: this will work even with 2M x 8bit devices as */
|
||||
/* they have 8 bytes of OOB per 256 page. mf. */
|
||||
DoC_ReadBuf(this, eccbuf, 6);
|
||||
|
||||
/* Flush the pipeline */
|
||||
if (DoC_is_Millennium(this)) {
|
||||
dummy = ReadDOC(docptr, ECCConf);
|
||||
dummy = ReadDOC(docptr, ECCConf);
|
||||
i = ReadDOC(docptr, ECCConf);
|
||||
} else {
|
||||
dummy = ReadDOC(docptr, 2k_ECCStatus);
|
||||
dummy = ReadDOC(docptr, 2k_ECCStatus);
|
||||
i = ReadDOC(docptr, 2k_ECCStatus);
|
||||
}
|
||||
/* Flush the pipeline */
|
||||
if (DoC_is_Millennium(this)) {
|
||||
dummy = ReadDOC(docptr, ECCConf);
|
||||
dummy = ReadDOC(docptr, ECCConf);
|
||||
i = ReadDOC(docptr, ECCConf);
|
||||
} else {
|
||||
dummy = ReadDOC(docptr, 2k_ECCStatus);
|
||||
dummy = ReadDOC(docptr, 2k_ECCStatus);
|
||||
i = ReadDOC(docptr, 2k_ECCStatus);
|
||||
}
|
||||
|
||||
/* Check the ECC Status */
|
||||
if (i & 0x80) {
|
||||
int nb_errors;
|
||||
/* There was an ECC error */
|
||||
/* Check the ECC Status */
|
||||
if (i & 0x80) {
|
||||
int nb_errors;
|
||||
/* There was an ECC error */
|
||||
#ifdef ECC_DEBUG
|
||||
printk(KERN_ERR "DiskOnChip ECC Error: Read at %lx\n", (long)from);
|
||||
printk(KERN_ERR "DiskOnChip ECC Error: Read at %lx\n", (long)from);
|
||||
#endif
|
||||
/* Read the ECC syndrom through the DiskOnChip ECC logic.
|
||||
These syndrome will be all ZERO when there is no error */
|
||||
for (i = 0; i < 6; i++) {
|
||||
syndrome[i] =
|
||||
ReadDOC(docptr, ECCSyndrome0 + i);
|
||||
}
|
||||
nb_errors = doc_decode_ecc(buf, syndrome);
|
||||
/* Read the ECC syndrom through the DiskOnChip ECC
|
||||
logic. These syndrome will be all ZERO when there
|
||||
is no error */
|
||||
for (i = 0; i < 6; i++) {
|
||||
syndrome[i] =
|
||||
ReadDOC(docptr, ECCSyndrome0 + i);
|
||||
}
|
||||
nb_errors = doc_decode_ecc(buf, syndrome);
|
||||
|
||||
#ifdef ECC_DEBUG
|
||||
printk(KERN_ERR "Errors corrected: %x\n", nb_errors);
|
||||
printk(KERN_ERR "Errors corrected: %x\n", nb_errors);
|
||||
#endif
|
||||
if (nb_errors < 0) {
|
||||
/* We return error, but have actually done the read. Not that
|
||||
this can be told to user-space, via sys_read(), but at least
|
||||
MTD-aware stuff can know about it by checking *retlen */
|
||||
ret = -EIO;
|
||||
}
|
||||
if (nb_errors < 0) {
|
||||
/* We return error, but have actually done the
|
||||
read. Not that this can be told to
|
||||
user-space, via sys_read(), but at least
|
||||
MTD-aware stuff can know about it by
|
||||
checking *retlen */
|
||||
ret = -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PSYCHO_DEBUG
|
||||
printk(KERN_DEBUG "ECC DATA at %lxB: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
|
||||
(long)from, eccbuf[0], eccbuf[1], eccbuf[2],
|
||||
eccbuf[3], eccbuf[4], eccbuf[5]);
|
||||
printk(KERN_DEBUG "ECC DATA at %lxB: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
|
||||
(long)from, eccbuf[0], eccbuf[1], eccbuf[2],
|
||||
eccbuf[3], eccbuf[4], eccbuf[5]);
|
||||
#endif
|
||||
|
||||
/* disable the ECC engine */
|
||||
WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
|
||||
}
|
||||
/* disable the ECC engine */
|
||||
WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
|
||||
|
||||
/* according to 11.4.1, we need to wait for the busy line
|
||||
* drop if we read to the end of the page. */
|
||||
|
@ -770,18 +754,11 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
|
|||
|
||||
static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
|
||||
size_t * retlen, const u_char * buf)
|
||||
{
|
||||
char eccbuf[6];
|
||||
return doc_write_ecc(mtd, to, len, retlen, buf, eccbuf, NULL);
|
||||
}
|
||||
|
||||
static int doc_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)
|
||||
{
|
||||
struct DiskOnChip *this = mtd->priv;
|
||||
int di; /* Yes, DI is a hangover from when I was disassembling the binary driver */
|
||||
void __iomem *docptr = this->virtadr;
|
||||
unsigned char eccbuf[6];
|
||||
volatile char dummy;
|
||||
int len256 = 0;
|
||||
struct Nand *mychip;
|
||||
|
@ -835,15 +812,9 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
|
|||
DoC_Command(this, NAND_CMD_SEQIN, 0);
|
||||
DoC_Address(this, ADDR_COLUMN_PAGE, to, 0, CDSN_CTRL_ECC_IO);
|
||||
|
||||
if (eccbuf) {
|
||||
/* Prime the ECC engine */
|
||||
WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
|
||||
WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
|
||||
} else {
|
||||
/* disable the ECC engine */
|
||||
WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
|
||||
WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
|
||||
}
|
||||
/* Prime the ECC engine */
|
||||
WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
|
||||
WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
|
||||
|
||||
/* treat crossing 256-byte sector for 2M x 8bits devices */
|
||||
if (this->page256 && to + len > (to | 0xff) + 1) {
|
||||
|
@ -873,39 +844,35 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
|
|||
|
||||
DoC_WriteBuf(this, &buf[len256], len - len256);
|
||||
|
||||
if (eccbuf) {
|
||||
WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_CE, docptr,
|
||||
CDSNControl);
|
||||
WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_CE, docptr, CDSNControl);
|
||||
|
||||
if (DoC_is_Millennium(this)) {
|
||||
WriteDOC(0, docptr, NOP);
|
||||
WriteDOC(0, docptr, NOP);
|
||||
WriteDOC(0, docptr, NOP);
|
||||
} else {
|
||||
WriteDOC_(0, docptr, this->ioreg);
|
||||
WriteDOC_(0, docptr, this->ioreg);
|
||||
WriteDOC_(0, docptr, this->ioreg);
|
||||
}
|
||||
|
||||
WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_FLASH_IO | CDSN_CTRL_CE, docptr,
|
||||
CDSNControl);
|
||||
|
||||
/* Read the ECC data through the DiskOnChip ECC logic */
|
||||
for (di = 0; di < 6; di++) {
|
||||
eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di);
|
||||
}
|
||||
|
||||
/* Reset the ECC engine */
|
||||
WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
|
||||
|
||||
#ifdef PSYCHO_DEBUG
|
||||
printk
|
||||
("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
|
||||
(long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
|
||||
eccbuf[4], eccbuf[5]);
|
||||
#endif
|
||||
if (DoC_is_Millennium(this)) {
|
||||
WriteDOC(0, docptr, NOP);
|
||||
WriteDOC(0, docptr, NOP);
|
||||
WriteDOC(0, docptr, NOP);
|
||||
} else {
|
||||
WriteDOC_(0, docptr, this->ioreg);
|
||||
WriteDOC_(0, docptr, this->ioreg);
|
||||
WriteDOC_(0, docptr, this->ioreg);
|
||||
}
|
||||
|
||||
WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_FLASH_IO | CDSN_CTRL_CE, docptr,
|
||||
CDSNControl);
|
||||
|
||||
/* Read the ECC data through the DiskOnChip ECC logic */
|
||||
for (di = 0; di < 6; di++) {
|
||||
eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di);
|
||||
}
|
||||
|
||||
/* Reset the ECC engine */
|
||||
WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
|
||||
|
||||
#ifdef PSYCHO_DEBUG
|
||||
printk
|
||||
("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
|
||||
(long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
|
||||
eccbuf[4], eccbuf[5]);
|
||||
#endif
|
||||
DoC_Command(this, NAND_CMD_PAGEPROG, 0);
|
||||
|
||||
DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
|
||||
|
|
|
@ -37,12 +37,6 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
|
|||
size_t *retlen, u_char *buf);
|
||||
static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
|
||||
size_t *retlen, const u_char *buf);
|
||||
static int doc_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);
|
||||
static int doc_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);
|
||||
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
|
||||
struct mtd_oob_ops *ops);
|
||||
static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
|
||||
|
@ -396,18 +390,10 @@ EXPORT_SYMBOL_GPL(DoCMil_init);
|
|||
|
||||
static int doc_read (struct mtd_info *mtd, loff_t from, size_t len,
|
||||
size_t *retlen, u_char *buf)
|
||||
{
|
||||
/* Just a special case of doc_read_ecc */
|
||||
return doc_read_ecc(mtd, from, len, retlen, buf, NULL, NULL);
|
||||
}
|
||||
|
||||
static int doc_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 i, ret;
|
||||
volatile char dummy;
|
||||
unsigned char syndrome[6];
|
||||
unsigned char syndrome[6], eccbuf[6];
|
||||
struct DiskOnChip *this = mtd->priv;
|
||||
void __iomem *docptr = this->virtadr;
|
||||
struct Nand *mychip = &this->chips[from >> (this->chipshift)];
|
||||
|
@ -437,15 +423,9 @@ static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
|
|||
DoC_Address(docptr, 3, from, CDSN_CTRL_WP, 0x00);
|
||||
DoC_WaitReady(docptr);
|
||||
|
||||
if (eccbuf) {
|
||||
/* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
|
||||
WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
|
||||
WriteDOC (DOC_ECC_EN, docptr, ECCConf);
|
||||
} else {
|
||||
/* disable the ECC engine */
|
||||
WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
|
||||
WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
|
||||
}
|
||||
/* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
|
||||
WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
|
||||
WriteDOC (DOC_ECC_EN, docptr, ECCConf);
|
||||
|
||||
/* Read the data via the internal pipeline through CDSN IO register,
|
||||
see Pipelined Read Operations 11.3 */
|
||||
|
@ -465,74 +445,65 @@ static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
|
|||
*retlen = len;
|
||||
ret = 0;
|
||||
|
||||
if (eccbuf) {
|
||||
/* Read the ECC data from Spare Data Area,
|
||||
see Reed-Solomon EDC/ECC 11.1 */
|
||||
dummy = ReadDOC(docptr, ReadPipeInit);
|
||||
/* Read the ECC data from Spare Data Area,
|
||||
see Reed-Solomon EDC/ECC 11.1 */
|
||||
dummy = ReadDOC(docptr, ReadPipeInit);
|
||||
#ifndef USE_MEMCPY
|
||||
for (i = 0; i < 5; i++) {
|
||||
/* N.B. you have to increase the source address in this way or the
|
||||
ECC logic will not work properly */
|
||||
eccbuf[i] = ReadDOC(docptr, Mil_CDSN_IO + i);
|
||||
}
|
||||
for (i = 0; i < 5; i++) {
|
||||
/* N.B. you have to increase the source address in this way or the
|
||||
ECC logic will not work properly */
|
||||
eccbuf[i] = ReadDOC(docptr, Mil_CDSN_IO + i);
|
||||
}
|
||||
#else
|
||||
memcpy_fromio(eccbuf, docptr + DoC_Mil_CDSN_IO, 5);
|
||||
memcpy_fromio(eccbuf, docptr + DoC_Mil_CDSN_IO, 5);
|
||||
#endif
|
||||
eccbuf[5] = ReadDOC(docptr, LastDataRead);
|
||||
eccbuf[5] = ReadDOC(docptr, LastDataRead);
|
||||
|
||||
/* Flush the pipeline */
|
||||
dummy = ReadDOC(docptr, ECCConf);
|
||||
dummy = ReadDOC(docptr, ECCConf);
|
||||
/* Flush the pipeline */
|
||||
dummy = ReadDOC(docptr, ECCConf);
|
||||
dummy = ReadDOC(docptr, ECCConf);
|
||||
|
||||
/* Check the ECC Status */
|
||||
if (ReadDOC(docptr, ECCConf) & 0x80) {
|
||||
int nb_errors;
|
||||
/* There was an ECC error */
|
||||
/* Check the ECC Status */
|
||||
if (ReadDOC(docptr, ECCConf) & 0x80) {
|
||||
int nb_errors;
|
||||
/* There was an ECC error */
|
||||
#ifdef ECC_DEBUG
|
||||
printk("DiskOnChip ECC Error: Read at %lx\n", (long)from);
|
||||
printk("DiskOnChip ECC Error: Read at %lx\n", (long)from);
|
||||
#endif
|
||||
/* Read the ECC syndrom through the DiskOnChip ECC logic.
|
||||
These syndrome will be all ZERO when there is no error */
|
||||
for (i = 0; i < 6; i++) {
|
||||
syndrome[i] = ReadDOC(docptr, ECCSyndrome0 + i);
|
||||
}
|
||||
nb_errors = doc_decode_ecc(buf, syndrome);
|
||||
#ifdef ECC_DEBUG
|
||||
printk("ECC Errors corrected: %x\n", nb_errors);
|
||||
#endif
|
||||
if (nb_errors < 0) {
|
||||
/* We return error, but have actually done the read. Not that
|
||||
this can be told to user-space, via sys_read(), but at least
|
||||
MTD-aware stuff can know about it by checking *retlen */
|
||||
ret = -EIO;
|
||||
}
|
||||
/* Read the ECC syndrom through the DiskOnChip ECC logic.
|
||||
These syndrome will be all ZERO when there is no error */
|
||||
for (i = 0; i < 6; i++) {
|
||||
syndrome[i] = ReadDOC(docptr, ECCSyndrome0 + i);
|
||||
}
|
||||
nb_errors = doc_decode_ecc(buf, syndrome);
|
||||
#ifdef ECC_DEBUG
|
||||
printk("ECC Errors corrected: %x\n", nb_errors);
|
||||
#endif
|
||||
if (nb_errors < 0) {
|
||||
/* We return error, but have actually done the read. Not that
|
||||
this can be told to user-space, via sys_read(), but at least
|
||||
MTD-aware stuff can know about it by checking *retlen */
|
||||
ret = -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PSYCHO_DEBUG
|
||||
printk("ECC DATA at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
|
||||
(long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
|
||||
eccbuf[4], eccbuf[5]);
|
||||
printk("ECC DATA at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
|
||||
(long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
|
||||
eccbuf[4], eccbuf[5]);
|
||||
#endif
|
||||
|
||||
/* disable the ECC engine */
|
||||
WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
|
||||
}
|
||||
/* disable the ECC engine */
|
||||
WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int doc_write (struct mtd_info *mtd, loff_t to, size_t len,
|
||||
size_t *retlen, const u_char *buf)
|
||||
{
|
||||
char eccbuf[6];
|
||||
return doc_write_ecc(mtd, to, len, retlen, buf, eccbuf, NULL);
|
||||
}
|
||||
|
||||
static int doc_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)
|
||||
{
|
||||
int i,ret = 0;
|
||||
char eccbuf[6];
|
||||
volatile char dummy;
|
||||
struct DiskOnChip *this = mtd->priv;
|
||||
void __iomem *docptr = this->virtadr;
|
||||
|
@ -573,15 +544,9 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
|
|||
DoC_Address(docptr, 3, to, 0x00, 0x00);
|
||||
DoC_WaitReady(docptr);
|
||||
|
||||
if (eccbuf) {
|
||||
/* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
|
||||
WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
|
||||
WriteDOC (DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
|
||||
} else {
|
||||
/* disable the ECC engine */
|
||||
WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
|
||||
WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
|
||||
}
|
||||
/* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
|
||||
WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
|
||||
WriteDOC (DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
|
||||
|
||||
/* Write the data via the internal pipeline through CDSN IO register,
|
||||
see Pipelined Write Operations 11.2 */
|
||||
|
@ -596,46 +561,44 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
|
|||
#endif
|
||||
WriteDOC(0x00, docptr, WritePipeTerm);
|
||||
|
||||
if (eccbuf) {
|
||||
/* Write ECC data to flash, the ECC info is generated by the DiskOnChip ECC logic
|
||||
see Reed-Solomon EDC/ECC 11.1 */
|
||||
WriteDOC(0, docptr, NOP);
|
||||
WriteDOC(0, docptr, NOP);
|
||||
WriteDOC(0, docptr, NOP);
|
||||
/* Write ECC data to flash, the ECC info is generated by the DiskOnChip ECC logic
|
||||
see Reed-Solomon EDC/ECC 11.1 */
|
||||
WriteDOC(0, docptr, NOP);
|
||||
WriteDOC(0, docptr, NOP);
|
||||
WriteDOC(0, docptr, NOP);
|
||||
|
||||
/* Read the ECC data through the DiskOnChip ECC logic */
|
||||
for (i = 0; i < 6; i++) {
|
||||
eccbuf[i] = ReadDOC(docptr, ECCSyndrome0 + i);
|
||||
}
|
||||
/* Read the ECC data through the DiskOnChip ECC logic */
|
||||
for (i = 0; i < 6; i++) {
|
||||
eccbuf[i] = ReadDOC(docptr, ECCSyndrome0 + i);
|
||||
}
|
||||
|
||||
/* ignore the ECC engine */
|
||||
WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
|
||||
/* ignore the ECC engine */
|
||||
WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
|
||||
|
||||
#ifndef USE_MEMCPY
|
||||
/* Write the ECC data to flash */
|
||||
for (i = 0; i < 6; i++) {
|
||||
/* N.B. you have to increase the source address in this way or the
|
||||
ECC logic will not work properly */
|
||||
WriteDOC(eccbuf[i], docptr, Mil_CDSN_IO + i);
|
||||
}
|
||||
/* Write the ECC data to flash */
|
||||
for (i = 0; i < 6; i++) {
|
||||
/* N.B. you have to increase the source address in this way or the
|
||||
ECC logic will not work properly */
|
||||
WriteDOC(eccbuf[i], docptr, Mil_CDSN_IO + i);
|
||||
}
|
||||
#else
|
||||
memcpy_toio(docptr + DoC_Mil_CDSN_IO, eccbuf, 6);
|
||||
memcpy_toio(docptr + DoC_Mil_CDSN_IO, eccbuf, 6);
|
||||
#endif
|
||||
|
||||
/* write the block status BLOCK_USED (0x5555) at the end of ECC data
|
||||
FIXME: this is only a hack for programming the IPL area for LinuxBIOS
|
||||
and should be replace with proper codes in user space utilities */
|
||||
WriteDOC(0x55, docptr, Mil_CDSN_IO);
|
||||
WriteDOC(0x55, docptr, Mil_CDSN_IO + 1);
|
||||
/* write the block status BLOCK_USED (0x5555) at the end of ECC data
|
||||
FIXME: this is only a hack for programming the IPL area for LinuxBIOS
|
||||
and should be replace with proper codes in user space utilities */
|
||||
WriteDOC(0x55, docptr, Mil_CDSN_IO);
|
||||
WriteDOC(0x55, docptr, Mil_CDSN_IO + 1);
|
||||
|
||||
WriteDOC(0x00, docptr, WritePipeTerm);
|
||||
WriteDOC(0x00, docptr, WritePipeTerm);
|
||||
|
||||
#ifdef PSYCHO_DEBUG
|
||||
printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
|
||||
(long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
|
||||
eccbuf[4], eccbuf[5]);
|
||||
printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
|
||||
(long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
|
||||
eccbuf[4], eccbuf[5]);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Commit the Page Program command and wait for ready
|
||||
see Software Requirement 11.4 item 1.*/
|
||||
|
|
|
@ -41,12 +41,6 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
|
|||
size_t *retlen, u_char *buf);
|
||||
static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
|
||||
size_t *retlen, const u_char *buf);
|
||||
static int doc_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);
|
||||
static int doc_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);
|
||||
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
|
||||
struct mtd_oob_ops *ops);
|
||||
static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
|
||||
|
@ -594,19 +588,11 @@ static int doc_dumpblk(struct mtd_info *mtd, loff_t from)
|
|||
|
||||
static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
|
||||
size_t *retlen, u_char *buf)
|
||||
{
|
||||
/* Just a special case of doc_read_ecc */
|
||||
return doc_read_ecc(mtd, from, len, retlen, buf, NULL, NULL);
|
||||
}
|
||||
|
||||
static int doc_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 ret, i;
|
||||
volatile char dummy;
|
||||
loff_t fofs;
|
||||
unsigned char syndrome[6];
|
||||
unsigned char syndrome[6], eccbuf[6];
|
||||
struct DiskOnChip *this = mtd->priv;
|
||||
void __iomem * docptr = this->virtadr;
|
||||
struct Nand *mychip = &this->chips[from >> (this->chipshift)];
|
||||
|
@ -644,56 +630,51 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
|
|||
WriteDOC(0, docptr, Mplus_FlashControl);
|
||||
DoC_WaitReady(docptr);
|
||||
|
||||
if (eccbuf) {
|
||||
/* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
|
||||
WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
|
||||
WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf);
|
||||
} else {
|
||||
/* disable the ECC engine */
|
||||
WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
|
||||
}
|
||||
/* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
|
||||
WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
|
||||
WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf);
|
||||
|
||||
/* Let the caller know we completed it */
|
||||
*retlen = len;
|
||||
ret = 0;
|
||||
ret = 0;
|
||||
|
||||
ReadDOC(docptr, Mplus_ReadPipeInit);
|
||||
ReadDOC(docptr, Mplus_ReadPipeInit);
|
||||
|
||||
if (eccbuf) {
|
||||
/* Read the data via the internal pipeline through CDSN IO
|
||||
register, see Pipelined Read Operations 11.3 */
|
||||
MemReadDOC(docptr, buf, len);
|
||||
/* Read the data via the internal pipeline through CDSN IO
|
||||
register, see Pipelined Read Operations 11.3 */
|
||||
MemReadDOC(docptr, buf, len);
|
||||
|
||||
/* Read the ECC data following raw data */
|
||||
MemReadDOC(docptr, eccbuf, 4);
|
||||
eccbuf[4] = ReadDOC(docptr, Mplus_LastDataRead);
|
||||
eccbuf[5] = ReadDOC(docptr, Mplus_LastDataRead);
|
||||
/* Read the ECC data following raw data */
|
||||
MemReadDOC(docptr, eccbuf, 4);
|
||||
eccbuf[4] = ReadDOC(docptr, Mplus_LastDataRead);
|
||||
eccbuf[5] = ReadDOC(docptr, Mplus_LastDataRead);
|
||||
|
||||
/* Flush the pipeline */
|
||||
dummy = ReadDOC(docptr, Mplus_ECCConf);
|
||||
dummy = ReadDOC(docptr, Mplus_ECCConf);
|
||||
/* Flush the pipeline */
|
||||
dummy = ReadDOC(docptr, Mplus_ECCConf);
|
||||
dummy = ReadDOC(docptr, Mplus_ECCConf);
|
||||
|
||||
/* Check the ECC Status */
|
||||
if (ReadDOC(docptr, Mplus_ECCConf) & 0x80) {
|
||||
int nb_errors;
|
||||
/* There was an ECC error */
|
||||
/* Check the ECC Status */
|
||||
if (ReadDOC(docptr, Mplus_ECCConf) & 0x80) {
|
||||
int nb_errors;
|
||||
/* There was an ECC error */
|
||||
#ifdef ECC_DEBUG
|
||||
printk("DiskOnChip ECC Error: Read at %lx\n", (long)from);
|
||||
printk("DiskOnChip ECC Error: Read at %lx\n", (long)from);
|
||||
#endif
|
||||
/* Read the ECC syndrom through the DiskOnChip ECC logic.
|
||||
These syndrome will be all ZERO when there is no error */
|
||||
for (i = 0; i < 6; i++)
|
||||
syndrome[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i);
|
||||
/* Read the ECC syndrom through the DiskOnChip ECC logic.
|
||||
These syndrome will be all ZERO when there is no error */
|
||||
for (i = 0; i < 6; i++)
|
||||
syndrome[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i);
|
||||
|
||||
nb_errors = doc_decode_ecc(buf, syndrome);
|
||||
nb_errors = doc_decode_ecc(buf, syndrome);
|
||||
#ifdef ECC_DEBUG
|
||||
printk("ECC Errors corrected: %x\n", nb_errors);
|
||||
printk("ECC Errors corrected: %x\n", nb_errors);
|
||||
#endif
|
||||
if (nb_errors < 0) {
|
||||
/* We return error, but have actually done the read. Not that
|
||||
this can be told to user-space, via sys_read(), but at least
|
||||
MTD-aware stuff can know about it by checking *retlen */
|
||||
if (nb_errors < 0) {
|
||||
/* We return error, but have actually done the
|
||||
read. Not that this can be told to user-space, via
|
||||
sys_read(), but at least MTD-aware stuff can know
|
||||
about it by checking *retlen */
|
||||
#ifdef ECC_DEBUG
|
||||
printk("%s(%d): Millennium Plus ECC error (from=0x%x:\n",
|
||||
__FILE__, __LINE__, (int)from);
|
||||
|
@ -707,24 +688,16 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
|
|||
eccbuf[3], eccbuf[4], eccbuf[5]);
|
||||
#endif
|
||||
ret = -EIO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PSYCHO_DEBUG
|
||||
printk("ECC DATA at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
|
||||
(long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
|
||||
eccbuf[4], eccbuf[5]);
|
||||
printk("ECC DATA at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
|
||||
(long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
|
||||
eccbuf[4], eccbuf[5]);
|
||||
#endif
|
||||
|
||||
/* disable the ECC engine */
|
||||
WriteDOC(DOC_ECC_DIS, docptr , Mplus_ECCConf);
|
||||
} else {
|
||||
/* Read the data via the internal pipeline through CDSN IO
|
||||
register, see Pipelined Read Operations 11.3 */
|
||||
MemReadDOC(docptr, buf, len-2);
|
||||
buf[len-2] = ReadDOC(docptr, Mplus_LastDataRead);
|
||||
buf[len-1] = ReadDOC(docptr, Mplus_LastDataRead);
|
||||
}
|
||||
/* disable the ECC engine */
|
||||
WriteDOC(DOC_ECC_DIS, docptr , Mplus_ECCConf);
|
||||
|
||||
/* Disable flash internally */
|
||||
WriteDOC(0, docptr, Mplus_FlashSelect);
|
||||
|
@ -734,18 +707,11 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
|
|||
|
||||
static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
|
||||
size_t *retlen, const u_char *buf)
|
||||
{
|
||||
char eccbuf[6];
|
||||
return doc_write_ecc(mtd, to, len, retlen, buf, eccbuf, NULL);
|
||||
}
|
||||
|
||||
static int doc_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)
|
||||
{
|
||||
int i, before, ret = 0;
|
||||
loff_t fto;
|
||||
volatile char dummy;
|
||||
char eccbuf[6];
|
||||
struct DiskOnChip *this = mtd->priv;
|
||||
void __iomem * docptr = this->virtadr;
|
||||
struct Nand *mychip = &this->chips[to >> (this->chipshift)];
|
||||
|
@ -795,46 +761,42 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
|
|||
/* Disable the ECC engine */
|
||||
WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
|
||||
|
||||
if (eccbuf) {
|
||||
if (before) {
|
||||
/* Write the block status BLOCK_USED (0x5555) */
|
||||
WriteDOC(0x55, docptr, Mil_CDSN_IO);
|
||||
WriteDOC(0x55, docptr, Mil_CDSN_IO);
|
||||
}
|
||||
|
||||
/* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
|
||||
WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, Mplus_ECCConf);
|
||||
if (before) {
|
||||
/* Write the block status BLOCK_USED (0x5555) */
|
||||
WriteDOC(0x55, docptr, Mil_CDSN_IO);
|
||||
WriteDOC(0x55, docptr, Mil_CDSN_IO);
|
||||
}
|
||||
|
||||
/* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
|
||||
WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, Mplus_ECCConf);
|
||||
|
||||
MemWriteDOC(docptr, (unsigned char *) buf, len);
|
||||
|
||||
if (eccbuf) {
|
||||
/* Write ECC data to flash, the ECC info is generated by
|
||||
the DiskOnChip ECC logic see Reed-Solomon EDC/ECC 11.1 */
|
||||
DoC_Delay(docptr, 3);
|
||||
/* Write ECC data to flash, the ECC info is generated by
|
||||
the DiskOnChip ECC logic see Reed-Solomon EDC/ECC 11.1 */
|
||||
DoC_Delay(docptr, 3);
|
||||
|
||||
/* Read the ECC data through the DiskOnChip ECC logic */
|
||||
for (i = 0; i < 6; i++)
|
||||
eccbuf[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i);
|
||||
/* Read the ECC data through the DiskOnChip ECC logic */
|
||||
for (i = 0; i < 6; i++)
|
||||
eccbuf[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i);
|
||||
|
||||
/* disable the ECC engine */
|
||||
WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
|
||||
/* disable the ECC engine */
|
||||
WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
|
||||
|
||||
/* Write the ECC data to flash */
|
||||
MemWriteDOC(docptr, eccbuf, 6);
|
||||
/* Write the ECC data to flash */
|
||||
MemWriteDOC(docptr, eccbuf, 6);
|
||||
|
||||
if (!before) {
|
||||
/* Write the block status BLOCK_USED (0x5555) */
|
||||
WriteDOC(0x55, docptr, Mil_CDSN_IO+6);
|
||||
WriteDOC(0x55, docptr, Mil_CDSN_IO+7);
|
||||
}
|
||||
if (!before) {
|
||||
/* Write the block status BLOCK_USED (0x5555) */
|
||||
WriteDOC(0x55, docptr, Mil_CDSN_IO+6);
|
||||
WriteDOC(0x55, docptr, Mil_CDSN_IO+7);
|
||||
}
|
||||
|
||||
#ifdef PSYCHO_DEBUG
|
||||
printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
|
||||
(long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
|
||||
eccbuf[4], eccbuf[5]);
|
||||
printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
|
||||
(long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
|
||||
eccbuf[4], eccbuf[5]);
|
||||
#endif
|
||||
}
|
||||
|
||||
WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
|
||||
WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
|
||||
|
|
|
@ -155,7 +155,7 @@ static u16 nand_read_word(struct mtd_info *mtd)
|
|||
/**
|
||||
* nand_select_chip - [DEFAULT] control CE line
|
||||
* @mtd: MTD device structure
|
||||
* @chip: chipnumber to select, -1 for deselect
|
||||
* @chipnr: chipnumber to select, -1 for deselect
|
||||
*
|
||||
* Default select function for 1 chip devices.
|
||||
*/
|
||||
|
@ -542,7 +542,6 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
|
|||
* Send command to NAND device. This is the version for the new large page
|
||||
* devices We dont have the separate regions as we have in the small page
|
||||
* devices. We must emulate NAND_CMD_READOOB to keep the code compatible.
|
||||
*
|
||||
*/
|
||||
static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
|
||||
int column, int page_addr)
|
||||
|
@ -656,7 +655,7 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
|
|||
|
||||
/**
|
||||
* nand_get_device - [GENERIC] Get chip for selected access
|
||||
* @this: the nand chip descriptor
|
||||
* @chip: the nand chip descriptor
|
||||
* @mtd: MTD device structure
|
||||
* @new_state: the state which is requested
|
||||
*
|
||||
|
@ -696,13 +695,12 @@ nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state)
|
|||
/**
|
||||
* nand_wait - [DEFAULT] wait until the command is done
|
||||
* @mtd: MTD device structure
|
||||
* @this: NAND chip structure
|
||||
* @chip: NAND chip structure
|
||||
*
|
||||
* Wait for command done. This applies to erase and program only
|
||||
* Erase can take up to 400ms and program up to 20ms according to
|
||||
* general NAND and SmartMedia specs
|
||||
*
|
||||
*/
|
||||
*/
|
||||
static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
|
||||
{
|
||||
|
||||
|
@ -896,6 +894,7 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
|
|||
/**
|
||||
* nand_transfer_oob - [Internal] Transfer oob to client buffer
|
||||
* @chip: nand chip structure
|
||||
* @oob: oob destination address
|
||||
* @ops: oob ops structure
|
||||
*/
|
||||
static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
|
||||
|
@ -946,6 +945,7 @@ static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
|
|||
*
|
||||
* @mtd: MTD device structure
|
||||
* @from: offset to read from
|
||||
* @ops: oob ops structure
|
||||
*
|
||||
* Internal function. Called with chip held.
|
||||
*/
|
||||
|
@ -1760,7 +1760,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
|
|||
/**
|
||||
* nand_write_oob - [MTD Interface] NAND write data and/or out-of-band
|
||||
* @mtd: MTD device structure
|
||||
* @from: offset to read from
|
||||
* @to: offset to write to
|
||||
* @ops: oob operation description structure
|
||||
*/
|
||||
static int nand_write_oob(struct mtd_info *mtd, loff_t to,
|
||||
|
@ -2055,7 +2055,7 @@ static void nand_sync(struct mtd_info *mtd)
|
|||
/**
|
||||
* nand_block_isbad - [MTD Interface] Check if block at offset is bad
|
||||
* @mtd: MTD device structure
|
||||
* @ofs: offset relative to mtd start
|
||||
* @offs: offset relative to mtd start
|
||||
*/
|
||||
static int nand_block_isbad(struct mtd_info *mtd, loff_t offs)
|
||||
{
|
||||
|
|
|
@ -65,8 +65,7 @@ static const u_char nand_ecc_precalc_table[] = {
|
|||
};
|
||||
|
||||
/**
|
||||
* nand_calculate_ecc - [NAND Interface] Calculate 3 byte ECC code
|
||||
* for 256 byte block
|
||||
* nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256-byte block
|
||||
* @mtd: MTD block structure
|
||||
* @dat: raw data
|
||||
* @ecc_code: buffer for ECC
|
||||
|
|
|
@ -237,11 +237,6 @@ static int __init sharpsl_nand_init(void)
|
|||
}
|
||||
}
|
||||
|
||||
if (machine_is_husky() || machine_is_borzoi() || machine_is_akita()) {
|
||||
/* Need to use small eraseblock size for backward compatibility */
|
||||
sharpsl_mtd->flags |= MTD_NO_VIRTBLOCKS;
|
||||
}
|
||||
|
||||
add_mtd_partitions(sharpsl_mtd, sharpsl_partition_info, nr_partitions);
|
||||
|
||||
/* Return happy */
|
||||
|
@ -255,8 +250,6 @@ module_init(sharpsl_nand_init);
|
|||
*/
|
||||
static void __exit sharpsl_nand_cleanup(void)
|
||||
{
|
||||
struct nand_chip *this = (struct nand_chip *)&sharpsl_mtd[1];
|
||||
|
||||
/* Release resources, unregister device */
|
||||
nand_release(sharpsl_mtd);
|
||||
|
||||
|
|
|
@ -345,10 +345,8 @@ int jffs2_init_acl(struct inode *inode, struct inode *dir)
|
|||
return rc;
|
||||
}
|
||||
|
||||
void jffs2_clear_acl(struct inode *inode)
|
||||
void jffs2_clear_acl(struct jffs2_inode_info *f)
|
||||
{
|
||||
struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
|
||||
|
||||
if (f->i_acl_access && f->i_acl_access != JFFS2_ACL_NOT_CACHED) {
|
||||
posix_acl_release(f->i_acl_access);
|
||||
f->i_acl_access = JFFS2_ACL_NOT_CACHED;
|
||||
|
|
|
@ -30,7 +30,7 @@ struct jffs2_acl_header {
|
|||
extern int jffs2_permission(struct inode *, int, struct nameidata *);
|
||||
extern int jffs2_acl_chmod(struct inode *);
|
||||
extern int jffs2_init_acl(struct inode *, struct inode *);
|
||||
extern void jffs2_clear_acl(struct inode *);
|
||||
extern void jffs2_clear_acl(struct jffs2_inode_info *);
|
||||
|
||||
extern struct xattr_handler jffs2_acl_access_xattr_handler;
|
||||
extern struct xattr_handler jffs2_acl_default_xattr_handler;
|
||||
|
@ -40,6 +40,6 @@ extern struct xattr_handler jffs2_acl_default_xattr_handler;
|
|||
#define jffs2_permission NULL
|
||||
#define jffs2_acl_chmod(inode) (0)
|
||||
#define jffs2_init_acl(inode,dir) (0)
|
||||
#define jffs2_clear_acl(inode)
|
||||
#define jffs2_clear_acl(f)
|
||||
|
||||
#endif /* CONFIG_JFFS2_FS_POSIX_ACL */
|
||||
|
|
|
@ -190,7 +190,7 @@ void jffs2_free_tmp_dnode_info(struct jffs2_tmp_dnode_info *x)
|
|||
kmem_cache_free(tmp_dnode_info_slab, x);
|
||||
}
|
||||
|
||||
struct jffs2_raw_node_ref *jffs2_alloc_refblock(void)
|
||||
static struct jffs2_raw_node_ref *jffs2_alloc_refblock(void)
|
||||
{
|
||||
struct jffs2_raw_node_ref *ret;
|
||||
|
||||
|
|
|
@ -426,8 +426,6 @@ char *jffs2_getlink(struct jffs2_sb_info *c, struct jffs2_inode_info *f);
|
|||
/* scan.c */
|
||||
int jffs2_scan_medium(struct jffs2_sb_info *c);
|
||||
void jffs2_rotate_lists(struct jffs2_sb_info *c);
|
||||
int jffs2_fill_scan_buf(struct jffs2_sb_info *c, void *buf,
|
||||
uint32_t ofs, uint32_t len);
|
||||
struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino);
|
||||
int jffs2_scan_classify_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
|
||||
int jffs2_scan_dirty_space(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t size);
|
||||
|
|
|
@ -968,6 +968,7 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
|
|||
struct jffs2_full_dirent *fd, *fds;
|
||||
int deleted;
|
||||
|
||||
jffs2_clear_acl(f);
|
||||
jffs2_xattr_delete_inode(c, f->inocache);
|
||||
down(&f->sem);
|
||||
deleted = f->inocache && !f->inocache->nlink;
|
||||
|
|
|
@ -274,8 +274,8 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int jffs2_fill_scan_buf (struct jffs2_sb_info *c, void *buf,
|
||||
uint32_t ofs, uint32_t len)
|
||||
static int jffs2_fill_scan_buf(struct jffs2_sb_info *c, void *buf,
|
||||
uint32_t ofs, uint32_t len)
|
||||
{
|
||||
int ret;
|
||||
size_t retlen;
|
||||
|
|
|
@ -50,9 +50,10 @@
|
|||
* is used to write xdatum to medium. xd->version will be incremented.
|
||||
* create_xattr_datum(c, xprefix, xname, xvalue, xsize)
|
||||
* is used to create new xdatum and write to medium.
|
||||
* delete_xattr_datum(c, xd)
|
||||
* is used to delete a xdatum. It marks xd JFFS2_XFLAGS_DEAD, and allows
|
||||
* GC to reclaim those physical nodes.
|
||||
* unrefer_xattr_datum(c, xd)
|
||||
* is used to delete a xdatum. When nobody refers this xdatum, JFFS2_XFLAGS_DEAD
|
||||
* is set on xd->flags and chained xattr_dead_list or release it immediately.
|
||||
* In the first case, the garbage collector release it later.
|
||||
* -------------------------------------------------- */
|
||||
static uint32_t xattr_datum_hashkey(int xprefix, const char *xname, const char *xvalue, int xsize)
|
||||
{
|
||||
|
@ -394,22 +395,24 @@ static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c,
|
|||
return xd;
|
||||
}
|
||||
|
||||
static void delete_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
|
||||
static void unrefer_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
|
||||
{
|
||||
/* must be called under down_write(xattr_sem) */
|
||||
BUG_ON(atomic_read(&xd->refcnt));
|
||||
if (atomic_dec_and_lock(&xd->refcnt, &c->erase_completion_lock)) {
|
||||
uint32_t xid = xd->xid, version = xd->version;
|
||||
|
||||
unload_xattr_datum(c, xd);
|
||||
xd->flags |= JFFS2_XFLAGS_DEAD;
|
||||
spin_lock(&c->erase_completion_lock);
|
||||
if (xd->node == (void *)xd) {
|
||||
BUG_ON(!(xd->flags & JFFS2_XFLAGS_INVALID));
|
||||
jffs2_free_xattr_datum(xd);
|
||||
} else {
|
||||
list_add(&xd->xindex, &c->xattr_dead_list);
|
||||
unload_xattr_datum(c, xd);
|
||||
xd->flags |= JFFS2_XFLAGS_DEAD;
|
||||
if (xd->node == (void *)xd) {
|
||||
BUG_ON(!(xd->flags & JFFS2_XFLAGS_INVALID));
|
||||
jffs2_free_xattr_datum(xd);
|
||||
} else {
|
||||
list_add(&xd->xindex, &c->xattr_dead_list);
|
||||
}
|
||||
spin_unlock(&c->erase_completion_lock);
|
||||
|
||||
dbg_xattr("xdatum(xid=%u, version=%u) was removed.\n", xid, version);
|
||||
}
|
||||
spin_unlock(&c->erase_completion_lock);
|
||||
dbg_xattr("xdatum(xid=%u, version=%u) was removed.\n", xd->xid, xd->version);
|
||||
}
|
||||
|
||||
/* -------- xref related functions ------------------
|
||||
|
@ -580,8 +583,7 @@ static void delete_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *re
|
|||
dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) was removed.\n",
|
||||
ref->ino, ref->xid, ref->xseqno);
|
||||
|
||||
if (atomic_dec_and_test(&xd->refcnt))
|
||||
delete_xattr_datum(c, xd);
|
||||
unrefer_xattr_datum(c, xd);
|
||||
}
|
||||
|
||||
void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
|
||||
|
@ -1119,8 +1121,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
|
|||
ref->next = c->xref_dead_list;
|
||||
c->xref_dead_list = ref;
|
||||
spin_unlock(&c->erase_completion_lock);
|
||||
if (atomic_dec_and_test(&xd->refcnt))
|
||||
delete_xattr_datum(c, xd);
|
||||
unrefer_xattr_datum(c, xd);
|
||||
} else {
|
||||
ref->ic = ic;
|
||||
ref->xd = xd;
|
||||
|
@ -1156,8 +1157,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
|
|||
down_write(&c->xattr_sem);
|
||||
if (rc) {
|
||||
JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request);
|
||||
if (atomic_dec_and_test(&xd->refcnt))
|
||||
delete_xattr_datum(c, xd);
|
||||
unrefer_xattr_datum(c, xd);
|
||||
up_write(&c->xattr_sem);
|
||||
return rc;
|
||||
}
|
||||
|
@ -1170,8 +1170,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
|
|||
ic->xref = ref;
|
||||
}
|
||||
rc = PTR_ERR(newref);
|
||||
if (atomic_dec_and_test(&xd->refcnt))
|
||||
delete_xattr_datum(c, xd);
|
||||
unrefer_xattr_datum(c, xd);
|
||||
} else if (ref) {
|
||||
delete_xattr_ref(c, ref);
|
||||
}
|
||||
|
|
|
@ -19,21 +19,21 @@
|
|||
|
||||
/**
|
||||
* struct nand_bbt_descr - bad block table descriptor
|
||||
* @param options options for this descriptor
|
||||
* @param pages the page(s) where we find the bbt, used with
|
||||
* @options: options for this descriptor
|
||||
* @pages: the page(s) where we find the bbt, used with
|
||||
* option BBT_ABSPAGE when bbt is searched,
|
||||
* then we store the found bbts pages here.
|
||||
* Its an array and supports up to 8 chips now
|
||||
* @param offs offset of the pattern in the oob area of the page
|
||||
* @param veroffs offset of the bbt version counter in the oob are of the page
|
||||
* @param version version read from the bbt page during scan
|
||||
* @param len length of the pattern, if 0 no pattern check is performed
|
||||
* @param maxblocks maximum number of blocks to search for a bbt. This number of
|
||||
* blocks is reserved at the end of the device
|
||||
* @offs: offset of the pattern in the oob area of the page
|
||||
* @veroffs: offset of the bbt version counter in the oob area of the page
|
||||
* @version: version read from the bbt page during scan
|
||||
* @len: length of the pattern, if 0 no pattern check is performed
|
||||
* @maxblocks: maximum number of blocks to search for a bbt. This
|
||||
* number of blocks is reserved at the end of the device
|
||||
* where the tables are written.
|
||||
* @param reserved_block_code if non-0, this pattern denotes a reserved
|
||||
* @reserved_block_code: if non-0, this pattern denotes a reserved
|
||||
* (rather than bad) block in the stored bbt
|
||||
* @param pattern pattern to identify bad block table or factory marked
|
||||
* @pattern: pattern to identify bad block table or factory marked
|
||||
* good / bad blocks, can be NULL, if len = 0
|
||||
*
|
||||
* Descriptor for the bad block table marker and the descriptor for the
|
||||
|
@ -93,12 +93,15 @@ struct nand_bbt_descr {
|
|||
#define ONENAND_BADBLOCK_POS 0
|
||||
|
||||
/**
|
||||
* struct bbt_info - [GENERIC] Bad Block Table data structure
|
||||
* @param bbt_erase_shift [INTERN] number of address bits in a bbt entry
|
||||
* @param badblockpos [INTERN] position of the bad block marker in the oob area
|
||||
* @param bbt [INTERN] bad block table pointer
|
||||
* @param badblock_pattern [REPLACEABLE] bad block scan pattern used for initial bad block scan
|
||||
* @param priv [OPTIONAL] pointer to private bbm date
|
||||
* struct bbm_info - [GENERIC] Bad Block Table data structure
|
||||
* @bbt_erase_shift: [INTERN] number of address bits in a bbt entry
|
||||
* @badblockpos: [INTERN] position of the bad block marker in the oob area
|
||||
* @options: options for this descriptor
|
||||
* @bbt: [INTERN] bad block table pointer
|
||||
* @isbad_bbt: function to determine if a block is bad
|
||||
* @badblock_pattern: [REPLACEABLE] bad block scan pattern used for
|
||||
* initial bad block scan
|
||||
* @priv: [OPTIONAL] pointer to private bbm date
|
||||
*/
|
||||
struct bbm_info {
|
||||
int bbt_erase_shift;
|
||||
|
|
|
@ -77,11 +77,11 @@ typedef enum {
|
|||
*
|
||||
* @len: number of bytes to write/read. When a data buffer is given
|
||||
* (datbuf != NULL) this is the number of data bytes. When
|
||||
+ no data buffer is available this is the number of oob bytes.
|
||||
* no data buffer is available this is the number of oob bytes.
|
||||
*
|
||||
* @retlen: number of bytes written/read. When a data buffer is given
|
||||
* (datbuf != NULL) this is the number of data bytes. When
|
||||
+ no data buffer is available this is the number of oob bytes.
|
||||
* no data buffer is available this is the number of oob bytes.
|
||||
*
|
||||
* @ooblen: number of oob bytes per page
|
||||
* @ooboffs: offset of oob data in the oob area (only relevant when
|
||||
|
|
|
@ -202,7 +202,7 @@ typedef enum {
|
|||
struct nand_chip;
|
||||
|
||||
/**
|
||||
* struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independend devices
|
||||
* struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independent devices
|
||||
* @lock: protection lock
|
||||
* @active: the mtd device which holds the controller currently
|
||||
* @wq: wait queue to sleep on if a NAND operation is in progress
|
||||
|
@ -223,12 +223,15 @@ struct nand_hw_control {
|
|||
* @total: total number of ecc bytes per page
|
||||
* @prepad: padding information for syndrome based ecc generators
|
||||
* @postpad: padding information for syndrome based ecc generators
|
||||
* @layout: ECC layout control struct pointer
|
||||
* @hwctl: function to control hardware ecc generator. Must only
|
||||
* be provided if an hardware ECC is available
|
||||
* @calculate: function for ecc calculation or readback from ecc hardware
|
||||
* @correct: function for ecc correction, matching to ecc generator (sw/hw)
|
||||
* @read_page: function to read a page according to the ecc generator requirements
|
||||
* @write_page: function to write a page according to the ecc generator requirements
|
||||
* @read_oob: function to read chip OOB data
|
||||
* @write_oob: function to write chip OOB data
|
||||
*/
|
||||
struct nand_ecc_ctrl {
|
||||
nand_ecc_modes_t mode;
|
||||
|
@ -300,11 +303,15 @@ struct nand_buffers {
|
|||
* @cmdfunc: [REPLACEABLE] hardwarespecific function for writing commands to the chip
|
||||
* @waitfunc: [REPLACEABLE] hardwarespecific function for wait on ready
|
||||
* @ecc: [BOARDSPECIFIC] ecc control ctructure
|
||||
* @buffers: buffer structure for read/write
|
||||
* @hwcontrol: platform-specific hardware control structure
|
||||
* @ops: oob operation operands
|
||||
* @erase_cmd: [INTERN] erase command write function, selectable due to AND support
|
||||
* @scan_bbt: [REPLACEABLE] function to scan bad block table
|
||||
* @chip_delay: [BOARDSPECIFIC] chip dependent delay for transfering data from array to read regs (tR)
|
||||
* @wq: [INTERN] wait queue to sleep on if a NAND operation is in progress
|
||||
* @state: [INTERN] the current state of the NAND device
|
||||
* @oob_poi: poison value buffer
|
||||
* @page_shift: [INTERN] number of address bits in a page (column address bits)
|
||||
* @phys_erase_shift: [INTERN] number of address bits in a physical eraseblock
|
||||
* @bbt_erase_shift: [INTERN] number of address bits in a bbt entry
|
||||
|
@ -400,7 +407,6 @@ struct nand_chip {
|
|||
|
||||
/**
|
||||
* struct nand_flash_dev - NAND Flash Device ID Structure
|
||||
*
|
||||
* @name: Identify the device type
|
||||
* @id: device ID code
|
||||
* @pagesize: Pagesize in bytes. Either 256 or 512 or 0
|
||||
|
@ -519,9 +525,8 @@ extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
|
|||
|
||||
/**
|
||||
* struct platform_nand_chip - chip level device structure
|
||||
*
|
||||
* @nr_chips: max. number of chips to scan for
|
||||
* @chip_offs: chip number offset
|
||||
* @chip_offset: chip number offset
|
||||
* @nr_partitions: number of partitions pointed to by partitions (or zero)
|
||||
* @partitions: mtd partition list
|
||||
* @chip_delay: R/B delay value in us
|
||||
|
@ -542,11 +547,10 @@ struct platform_nand_chip {
|
|||
|
||||
/**
|
||||
* struct platform_nand_ctrl - controller level device structure
|
||||
*
|
||||
* @hwcontrol: platform specific hardware control structure
|
||||
* @dev_ready: platform specific function to read ready/busy pin
|
||||
* @select_chip: platform specific chip select function
|
||||
* @priv_data: private data to transport driver specific settings
|
||||
* @priv: private data to transport driver specific settings
|
||||
*
|
||||
* All fields are optional and depend on the hardware driver requirements
|
||||
*/
|
||||
|
|
|
@ -23,7 +23,7 @@ extern int onenand_scan(struct mtd_info *mtd, int max_chips);
|
|||
/* Free resources held by the OneNAND device */
|
||||
extern void onenand_release(struct mtd_info *mtd);
|
||||
|
||||
/**
|
||||
/*
|
||||
* onenand_state_t - chip states
|
||||
* Enumeration for OneNAND flash chip state
|
||||
*/
|
||||
|
@ -42,9 +42,9 @@ typedef enum {
|
|||
|
||||
/**
|
||||
* struct onenand_bufferram - OneNAND BufferRAM Data
|
||||
* @param block block address in BufferRAM
|
||||
* @param page page address in BufferRAM
|
||||
* @param valid valid flag
|
||||
* @block: block address in BufferRAM
|
||||
* @page: page address in BufferRAM
|
||||
* @valid: valid flag
|
||||
*/
|
||||
struct onenand_bufferram {
|
||||
int block;
|
||||
|
@ -54,32 +54,43 @@ struct onenand_bufferram {
|
|||
|
||||
/**
|
||||
* struct onenand_chip - OneNAND Private Flash Chip Data
|
||||
* @param base [BOARDSPECIFIC] address to access OneNAND
|
||||
* @param chipsize [INTERN] the size of one chip for multichip arrays
|
||||
* @param device_id [INTERN] device ID
|
||||
* @param verstion_id [INTERN] version ID
|
||||
* @param options [BOARDSPECIFIC] various chip options. They can partly be set to inform onenand_scan about
|
||||
* @param erase_shift [INTERN] number of address bits in a block
|
||||
* @param page_shift [INTERN] number of address bits in a page
|
||||
* @param ppb_shift [INTERN] number of address bits in a pages per block
|
||||
* @param page_mask [INTERN] a page per block mask
|
||||
* @param bufferam_index [INTERN] BufferRAM index
|
||||
* @param bufferam [INTERN] BufferRAM info
|
||||
* @param readw [REPLACEABLE] hardware specific function for read short
|
||||
* @param writew [REPLACEABLE] hardware specific function for write short
|
||||
* @param command [REPLACEABLE] hardware specific function for writing commands to the chip
|
||||
* @param wait [REPLACEABLE] hardware specific function for wait on ready
|
||||
* @param read_bufferram [REPLACEABLE] hardware specific function for BufferRAM Area
|
||||
* @param write_bufferram [REPLACEABLE] hardware specific function for BufferRAM Area
|
||||
* @param read_word [REPLACEABLE] hardware specific function for read register of OneNAND
|
||||
* @param write_word [REPLACEABLE] hardware specific function for write register of OneNAND
|
||||
* @param scan_bbt [REPLACEALBE] hardware specific function for scaning Bad block Table
|
||||
* @param chip_lock [INTERN] spinlock used to protect access to this structure and the chip
|
||||
* @param wq [INTERN] wait queue to sleep on if a OneNAND operation is in progress
|
||||
* @param state [INTERN] the current state of the OneNAND device
|
||||
* @param ecclayout [REPLACEABLE] the default ecc placement scheme
|
||||
* @param bbm [REPLACEABLE] pointer to Bad Block Management
|
||||
* @param priv [OPTIONAL] pointer to private chip date
|
||||
* @base: [BOARDSPECIFIC] address to access OneNAND
|
||||
* @chipsize: [INTERN] the size of one chip for multichip arrays
|
||||
* @device_id: [INTERN] device ID
|
||||
* @density_mask: chip density, used for DDP devices
|
||||
* @verstion_id: [INTERN] version ID
|
||||
* @options: [BOARDSPECIFIC] various chip options. They can
|
||||
* partly be set to inform onenand_scan about
|
||||
* @erase_shift: [INTERN] number of address bits in a block
|
||||
* @page_shift: [INTERN] number of address bits in a page
|
||||
* @ppb_shift: [INTERN] number of address bits in a pages per block
|
||||
* @page_mask: [INTERN] a page per block mask
|
||||
* @bufferram_index: [INTERN] BufferRAM index
|
||||
* @bufferram: [INTERN] BufferRAM info
|
||||
* @readw: [REPLACEABLE] hardware specific function for read short
|
||||
* @writew: [REPLACEABLE] hardware specific function for write short
|
||||
* @command: [REPLACEABLE] hardware specific function for writing
|
||||
* commands to the chip
|
||||
* @wait: [REPLACEABLE] hardware specific function for wait on ready
|
||||
* @read_bufferram: [REPLACEABLE] hardware specific function for BufferRAM Area
|
||||
* @write_bufferram: [REPLACEABLE] hardware specific function for BufferRAM Area
|
||||
* @read_word: [REPLACEABLE] hardware specific function for read
|
||||
* register of OneNAND
|
||||
* @write_word: [REPLACEABLE] hardware specific function for write
|
||||
* register of OneNAND
|
||||
* @mmcontrol: sync burst read function
|
||||
* @block_markbad: function to mark a block as bad
|
||||
* @scan_bbt: [REPLACEALBE] hardware specific function for scanning
|
||||
* Bad block Table
|
||||
* @chip_lock: [INTERN] spinlock used to protect access to this
|
||||
* structure and the chip
|
||||
* @wq: [INTERN] wait queue to sleep on if a OneNAND
|
||||
* operation is in progress
|
||||
* @state: [INTERN] the current state of the OneNAND device
|
||||
* @page_buf: data buffer
|
||||
* @ecclayout: [REPLACEABLE] the default ecc placement scheme
|
||||
* @bbm: [REPLACEABLE] pointer to Bad Block Management
|
||||
* @priv: [OPTIONAL] pointer to private chip date
|
||||
*/
|
||||
struct onenand_chip {
|
||||
void __iomem *base;
|
||||
|
@ -147,9 +158,9 @@ struct onenand_chip {
|
|||
#define ONENAND_MFR_SAMSUNG 0xec
|
||||
|
||||
/**
|
||||
* struct nand_manufacturers - NAND Flash Manufacturer ID Structure
|
||||
* @param name: Manufacturer name
|
||||
* @param id: manufacturer ID code of device.
|
||||
* struct onenand_manufacturers - NAND Flash Manufacturer ID Structure
|
||||
* @name: Manufacturer name
|
||||
* @id: manufacturer ID code of device.
|
||||
*/
|
||||
struct onenand_manufacturers {
|
||||
int id;
|
||||
|
|
|
@ -133,7 +133,7 @@ struct nand_ecclayout {
|
|||
};
|
||||
|
||||
/**
|
||||
* struct mtd_ecc_stats - error correction status
|
||||
* struct mtd_ecc_stats - error correction stats
|
||||
*
|
||||
* @corrected: number of corrected bits
|
||||
* @failed: number of uncorrectable errors
|
||||
|
|
Loading…
Reference in a new issue