mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-24 21:54:01 +00:00
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:
parent
8d765456c1
commit
bfd7f38614
7 changed files with 785 additions and 241 deletions
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue