Fix OneNAND read_oob/write_oob functions compatability

Also sync with kernel OneNAND codes

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Scott Wood <scottwood@freescale.com>
This commit is contained in:
Kyungmin Park 2008-08-19 08:42:53 +09:00 committed by Scott Wood
parent 8d765456c1
commit bfd7f38614
7 changed files with 785 additions and 241 deletions

View file

@ -85,15 +85,25 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
ulong addr = simple_strtoul(argv[2], NULL, 16);
ulong ofs = simple_strtoul(argv[3], NULL, 16);
size_t len = simple_strtoul(argv[4], NULL, 16);
size_t retlen = 0;
int oob = strncmp(argv[1], "read.oob", 8) ? 0 : 1;
struct mtd_oob_ops ops;
if (oob)
onenand_read_oob(&onenand_mtd, ofs, len,
&retlen, (u_char *) addr);
else
onenand_read(&onenand_mtd, ofs, len, &retlen,
(u_char *) addr);
ops.mode = MTD_OOB_PLACE;
if (oob) {
ops.len = 0;
ops.datbuf = NULL;
ops.ooblen = len;
ops.oobbuf = (u_char *) addr;
} else {
ops.len = len;
ops.datbuf = (u_char *) addr;
ops.ooblen = 0;
ops.oobbuf = NULL;
}
ops.retlen = ops.oobretlen = 0;
onenand_mtd.read_oob(&onenand_mtd, ofs, &ops);
printf("Done\n");
return 0;
@ -117,9 +127,12 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
ulong block = simple_strtoul(argv[3], NULL, 10);
ulong page = simple_strtoul(argv[4], NULL, 10);
size_t len = simple_strtol(argv[5], NULL, 10);
size_t retlen = 0;
ulong ofs;
int oob = strncmp(argv[1], "block.oob", 9) ? 0 : 1;
struct mtd_oob_ops ops;
ops.mode = MTD_OOB_PLACE;
ofs = block << onenand_chip.erase_shift;
if (page)
@ -127,17 +140,21 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
if (!len) {
if (oob)
len = 64;
ops.ooblen = 64;
else
len = 512;
ops.len = 512;
}
if (oob)
onenand_read_oob(&onenand_mtd, ofs, len,
&retlen, (u_char *) addr);
else
onenand_read(&onenand_mtd, ofs, len, &retlen,
(u_char *) addr);
if (oob) {
ops.datbuf = NULL;
ops.oobbuf = (u_char *) addr;
} else {
ops.datbuf = (u_char *) addr;
ops.oobbuf = NULL;
}
ops.retlen = ops.oobretlen = 0;
onenand_read_oob(&onenand_mtd, ofs, &ops);
return 0;
}

File diff suppressed because it is too large Load diff

View file

@ -68,6 +68,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t * buf,
int startblock;
loff_t from;
size_t readlen, ooblen;
struct mtd_oob_ops ops;
printk(KERN_INFO "Scanning device for bad blocks\n");
@ -85,25 +86,26 @@ static int create_bbt(struct mtd_info *mtd, uint8_t * buf,
startblock = 0;
from = 0;
ops.mode = MTD_OOB_PLACE;
ops.ooblen = readlen;
ops.oobbuf = buf;
ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
for (i = startblock; i < numblocks;) {
int ret;
for (j = 0; j < len; j++) {
size_t retlen;
/* No need to read pages fully,
* just read required OOB bytes */
ret = onenand_read_oob(mtd,
ret = onenand_bbt_read_oob(mtd,
from + j * mtd->writesize +
bd->offs, readlen, &retlen,
&buf[0]);
bd->offs, &ops);
if (ret && ret != -EAGAIN) {
printk("ret = %d\n", ret);
return ret;
}
/* If it is a initial bad block, just ignore it */
if (ret == ONENAND_BBT_READ_FATAL_ERROR)
return -EIO;
if (check_short_pattern
if (ret || check_short_pattern
(&buf[j * scanlen], scanlen, mtd->writesize, bd)) {
bbm->bbt[i >> 3] |= 0x03 << (i & 0x6);
printk(KERN_WARNING

View file

@ -97,6 +97,13 @@ struct nand_bbt_descr {
*/
#define ONENAND_BADBLOCK_POS 0
/*
* Bad block scanning errors
*/
#define ONENAND_BBT_READ_ERROR 1
#define ONENAND_BBT_READ_ECC_ERROR 2
#define ONENAND_BBT_READ_FATAL_ERROR 4
/**
* struct bbt_info - [GENERIC] Bad Block Table data structure
* @param bbt_erase_shift [INTERN] number of address bits in a bbt entry

View file

@ -75,6 +75,7 @@ struct onenand_chip {
unsigned int page_shift;
unsigned int ppb_shift; /* Pages per block shift */
unsigned int page_mask;
unsigned int writesize;
unsigned int bufferram_index;
struct onenand_bufferram bufferram[MAX_BUFFERRAM];
@ -93,25 +94,39 @@ struct onenand_chip {
int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
int (*scan_bbt)(struct mtd_info *mtd);
spinlock_t chip_lock;
wait_queue_head_t wq;
int state;
unsigned char *page_buf;
unsigned char *oob_buf;
struct nand_oobinfo *autooob;
struct nand_ecclayout *ecclayout;
void *bbm;
void *priv;
};
/*
* Helper macros
*/
#define ONENAND_CURRENT_BUFFERRAM(this) (this->bufferram_index)
#define ONENAND_NEXT_BUFFERRAM(this) (this->bufferram_index ^ 1)
#define ONENAND_SET_NEXT_BUFFERRAM(this) (this->bufferram_index ^= 1)
#define ONENAND_SET_PREV_BUFFERRAM(this) (this->bufferram_index ^= 1)
#define ONENAND_SET_BUFFERRAM0(this) (this->bufferram_index = 0)
#define ONENAND_SET_BUFFERRAM1(this) (this->bufferram_index = 1)
#define ONENAND_IS_DDP(this) \
(this->device_id & ONENAND_DEVICE_IS_DDP)
#define ONENAND_IS_2PLANE(this) (0)
/*
* Options bits
*/
#define ONENAND_CONT_LOCK (0x0001)
#define ONENAND_PAGEBUF_ALLOC (0x1000)
#define ONENAND_OOBBUF_ALLOC (0x2000)
/*
* OneNAND Flash Manufacturer ID Codes
@ -129,4 +144,7 @@ struct onenand_manufacturers {
char *name;
};
int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
struct mtd_oob_ops *ops);
#endif /* __LINUX_MTD_ONENAND_H */

View file

@ -83,6 +83,8 @@
* Start Address 1 F100h (R/W)
*/
#define ONENAND_DDP_SHIFT (15)
#define ONENAND_DDP_CHIP0 (0)
#define ONENAND_DDP_CHIP1 (1 << ONENAND_DDP_SHIFT)
/*
* Start Address 8 F107h (R/W)

View file

@ -16,23 +16,17 @@
#include <linux/types.h>
struct kvec {
void *iov_base;
size_t iov_len;
};
typedef int spinlock_t;
typedef int wait_queue_head_t;
struct mtd_info;
struct erase_info;
extern struct mtd_info onenand_mtd;
/* Functions */
extern void onenand_init(void);
extern int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t * retlen, u_char * buf);
extern int onenand_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
size_t * retlen, u_char * buf);
extern int onenand_read_oob(struct mtd_info *mtd, loff_t from,
struct mtd_oob_ops *ops);
extern int onenand_write(struct mtd_info *mtd, loff_t from, size_t len,
size_t * retlen, const u_char * buf);
extern int onenand_erase(struct mtd_info *mtd, struct erase_info *instr);