Commit 7bc3312b authored by Thomas Gleixner's avatar Thomas Gleixner Committed by David Woodhouse

[MTD] NAND: Fix breakage all over the place

Following problems are addressed:

- wrong status caused early break out of nand_wait()
- removed the bogus status check in nand_wait() which
  is a relict of the abandoned support for interrupted
  erase.
- status check moved to the correct place in read_oob
- oob support for syndrom based ecc with strange layouts
- use given offset in the AUTOOOB based oob operations

Partially based on a patch from Vitaly Vool <vwool@ru.mvista.com>
Thanks to Savin Zlobec <savin@epico.si> for tracking down the
status problem.
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 7e4178f9
...@@ -504,12 +504,12 @@ static int mtd_ioctl(struct inode *inode, struct file *file, ...@@ -504,12 +504,12 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
return ret; return ret;
ops.len = buf.length; ops.len = buf.length;
ops.ooblen = mtd->oobsize; ops.ooblen = buf.length;
ops.ooboffs = buf.start & (mtd->oobsize - 1); ops.ooboffs = buf.start & (mtd->oobsize - 1);
ops.datbuf = NULL; ops.datbuf = NULL;
ops.mode = MTD_OOB_PLACE; ops.mode = MTD_OOB_PLACE;
if (ops.ooboffs && ops.len > (ops.ooblen - ops.ooboffs)) if (ops.ooboffs && ops.len > (mtd->oobsize - ops.ooboffs))
return -EINVAL; return -EINVAL;
ops.oobbuf = kmalloc(buf.length, GFP_KERNEL); ops.oobbuf = kmalloc(buf.length, GFP_KERNEL);
...@@ -553,12 +553,12 @@ static int mtd_ioctl(struct inode *inode, struct file *file, ...@@ -553,12 +553,12 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
return ret; return ret;
ops.len = buf.length; ops.len = buf.length;
ops.ooblen = mtd->oobsize; ops.ooblen = buf.length;
ops.ooboffs = buf.start & (mtd->oobsize - 1); ops.ooboffs = buf.start & (mtd->oobsize - 1);
ops.datbuf = NULL; ops.datbuf = NULL;
ops.mode = MTD_OOB_PLACE; ops.mode = MTD_OOB_PLACE;
if (ops.ooboffs && ops.len > (ops.ooblen - ops.ooboffs)) if (ops.ooboffs && ops.len > (mtd->oobsize - ops.ooboffs))
return -EINVAL; return -EINVAL;
ops.oobbuf = kmalloc(buf.length, GFP_KERNEL); ops.oobbuf = kmalloc(buf.length, GFP_KERNEL);
......
...@@ -464,7 +464,7 @@ static void __init doc2000_count_chips(struct mtd_info *mtd) ...@@ -464,7 +464,7 @@ static void __init doc2000_count_chips(struct mtd_info *mtd)
printk(KERN_DEBUG "Detected %d chips per floor.\n", i); printk(KERN_DEBUG "Detected %d chips per floor.\n", i);
} }
static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this, int state) static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this)
{ {
struct doc_priv *doc = this->priv; struct doc_priv *doc = this->priv;
......
This diff is collapsed.
...@@ -63,18 +63,21 @@ extern void nand_release (struct mtd_info *mtd); ...@@ -63,18 +63,21 @@ extern void nand_release (struct mtd_info *mtd);
*/ */
#define NAND_CMD_READ0 0 #define NAND_CMD_READ0 0
#define NAND_CMD_READ1 1 #define NAND_CMD_READ1 1
#define NAND_CMD_RNDOUT 5
#define NAND_CMD_PAGEPROG 0x10 #define NAND_CMD_PAGEPROG 0x10
#define NAND_CMD_READOOB 0x50 #define NAND_CMD_READOOB 0x50
#define NAND_CMD_ERASE1 0x60 #define NAND_CMD_ERASE1 0x60
#define NAND_CMD_STATUS 0x70 #define NAND_CMD_STATUS 0x70
#define NAND_CMD_STATUS_MULTI 0x71 #define NAND_CMD_STATUS_MULTI 0x71
#define NAND_CMD_SEQIN 0x80 #define NAND_CMD_SEQIN 0x80
#define NAND_CMD_RNDIN 0x85
#define NAND_CMD_READID 0x90 #define NAND_CMD_READID 0x90
#define NAND_CMD_ERASE2 0xd0 #define NAND_CMD_ERASE2 0xd0
#define NAND_CMD_RESET 0xff #define NAND_CMD_RESET 0xff
/* Extended commands for large page devices */ /* Extended commands for large page devices */
#define NAND_CMD_READSTART 0x30 #define NAND_CMD_READSTART 0x30
#define NAND_CMD_RNDOUTSTART 0xE0
#define NAND_CMD_CACHEDPROG 0x15 #define NAND_CMD_CACHEDPROG 0x15
/* Extended commands for AG-AND device */ /* Extended commands for AG-AND device */
...@@ -250,6 +253,13 @@ struct nand_ecc_ctrl { ...@@ -250,6 +253,13 @@ struct nand_ecc_ctrl {
void (*write_page)(struct mtd_info *mtd, void (*write_page)(struct mtd_info *mtd,
struct nand_chip *chip, struct nand_chip *chip,
const uint8_t *buf); const uint8_t *buf);
int (*read_oob)(struct mtd_info *mtd,
struct nand_chip *chip,
int page,
int sndcmd);
int (*write_oob)(struct mtd_info *mtd,
struct nand_chip *chip,
int page);
}; };
/** /**
...@@ -339,7 +349,7 @@ struct nand_chip { ...@@ -339,7 +349,7 @@ struct nand_chip {
unsigned int ctrl); unsigned int ctrl);
int (*dev_ready)(struct mtd_info *mtd); int (*dev_ready)(struct mtd_info *mtd);
void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr); void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr);
int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this, int state); int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this);
void (*erase_cmd)(struct mtd_info *mtd, int page); void (*erase_cmd)(struct mtd_info *mtd, int page);
int (*scan_bbt)(struct mtd_info *mtd); int (*scan_bbt)(struct mtd_info *mtd);
int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page); int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment