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:
Linus Torvalds 2006-07-03 21:29:08 -07:00
commit 0d1782144e
19 changed files with 331 additions and 432 deletions

View file

@ -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">

View file

@ -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);

View file

@ -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.*/

View file

@ -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);

View file

@ -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)
{

View file

@ -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

View file

@ -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);

View file

@ -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;

View file

@ -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 */

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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);
}

View file

@ -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;

View file

@ -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

View file

@ -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
*/

View file

@ -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;

View file

@ -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