Commit 5bd34c09 authored by Thomas Gleixner's avatar Thomas Gleixner

[MTD] NAND Replace oobinfo by ecclayout

The nand_oobinfo structure is not fitting the newer error correction
demands anymore. Replace it by struct nand_ecclayout and fixup the users
all over the place. Keep the nand_oobinfo based ioctl for user space
compability reasons.
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent ff268fb8
...@@ -512,14 +512,36 @@ static int mtd_ioctl(struct inode *inode, struct file *file, ...@@ -512,14 +512,36 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
break; break;
} }
/* Legacy interface */
case MEMGETOOBSEL: case MEMGETOOBSEL:
{ {
if (copy_to_user(argp, mtd->oobinfo, struct nand_oobinfo oi;
sizeof(struct nand_oobinfo)))
if (!mtd->ecclayout)
return -EOPNOTSUPP;
if (mtd->ecclayout->eccbytes > ARRAY_SIZE(oi.eccpos))
return -EINVAL;
oi.useecc = MTD_NANDECC_AUTOPLACE;
memcpy(&oi.eccpos, mtd->ecclayout->eccpos, sizeof(oi.eccpos));
memcpy(&oi.oobfree, mtd->ecclayout->oobfree,
sizeof(oi.oobfree));
if (copy_to_user(argp, &oi, sizeof(struct nand_oobinfo)))
return -EFAULT; return -EFAULT;
break; break;
} }
case ECCGETLAYOUT:
if (!mtd->ecclayout)
return -EOPNOTSUPP;
if (copy_to_user(argp, &mtd->ecclayout,
sizeof(struct nand_ecclayout)))
return -EFAULT;
break;
case MEMGETBADBLOCK: case MEMGETBADBLOCK:
{ {
loff_t offs; loff_t offs;
......
...@@ -766,7 +766,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c ...@@ -766,7 +766,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
} }
concat->mtd.oobinfo = subdev[0]->oobinfo; concat->mtd.ecclayout = subdev[0]->ecclayout;
concat->num_subdev = num_devs; concat->num_subdev = num_devs;
concat->mtd.name = name; concat->mtd.name = name;
......
...@@ -434,7 +434,7 @@ int add_mtd_partitions(struct mtd_info *master, ...@@ -434,7 +434,7 @@ int add_mtd_partitions(struct mtd_info *master,
parts[i].name); parts[i].name);
} }
slave->mtd.oobinfo = master->oobinfo; slave->mtd.ecclayout = master->ecclayout;
if(parts[i].mtdp) if(parts[i].mtdp)
{ /* store the object pointer (caller may or may not register it */ { /* store the object pointer (caller may or may not register it */
......
...@@ -1058,8 +1058,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, ...@@ -1058,8 +1058,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat,
* safer. The only problem with it is that any code that parses oobfree must * safer. The only problem with it is that any code that parses oobfree must
* be able to handle out-of-order segments. * be able to handle out-of-order segments.
*/ */
static struct nand_oobinfo doc200x_oobinfo = { static struct nand_ecclayout doc200x_oobinfo = {
.useecc = MTD_NANDECC_AUTOPLACE,
.eccbytes = 6, .eccbytes = 6,
.eccpos = {0, 1, 2, 3, 4, 5}, .eccpos = {0, 1, 2, 3, 4, 5},
.oobfree = {{8, 8}, {6, 2}} .oobfree = {{8, 8}, {6, 2}}
...@@ -1662,7 +1661,7 @@ static int __init doc_probe(unsigned long physadr) ...@@ -1662,7 +1661,7 @@ static int __init doc_probe(unsigned long physadr)
nand->ecc.calculate = doc200x_calculate_ecc; nand->ecc.calculate = doc200x_calculate_ecc;
nand->ecc.correct = doc200x_correct_data; nand->ecc.correct = doc200x_correct_data;
nand->autooob = &doc200x_oobinfo; nand->ecc.layout = &doc200x_oobinfo;
nand->ecc.mode = NAND_ECC_HW_SYNDROME; nand->ecc.mode = NAND_ECC_HW_SYNDROME;
nand->ecc.size = 512; nand->ecc.size = 512;
nand->ecc.bytes = 6; nand->ecc.bytes = 6;
......
...@@ -52,28 +52,33 @@ ...@@ -52,28 +52,33 @@
#endif #endif
/* Define default oob placement schemes for large and small page devices */ /* Define default oob placement schemes for large and small page devices */
static struct nand_oobinfo nand_oob_8 = { static struct nand_ecclayout nand_oob_8 = {
.useecc = MTD_NANDECC_AUTOPLACE,
.eccbytes = 3, .eccbytes = 3,
.eccpos = {0, 1, 2}, .eccpos = {0, 1, 2},
.oobfree = {{3, 2}, {6, 2}} .oobfree = {
{.offset = 3,
.length = 2},
{.offset = 6,
.length = 2}}
}; };
static struct nand_oobinfo nand_oob_16 = { static struct nand_ecclayout nand_oob_16 = {
.useecc = MTD_NANDECC_AUTOPLACE,
.eccbytes = 6, .eccbytes = 6,
.eccpos = {0, 1, 2, 3, 6, 7}, .eccpos = {0, 1, 2, 3, 6, 7},
.oobfree = {{8, 8}} .oobfree = {
{.offset = 8,
. length = 8}}
}; };
static struct nand_oobinfo nand_oob_64 = { static struct nand_ecclayout nand_oob_64 = {
.useecc = MTD_NANDECC_AUTOPLACE,
.eccbytes = 24, .eccbytes = 24,
.eccpos = { .eccpos = {
40, 41, 42, 43, 44, 45, 46, 47, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 58, 59, 60, 61, 62, 63}, 56, 57, 58, 59, 60, 61, 62, 63},
.oobfree = {{2, 38}} .oobfree = {
{.offset = 2,
.length = 38}}
}; };
/* This is used for padding purposes in nand_write_oob */ /* This is used for padding purposes in nand_write_oob */
...@@ -749,7 +754,7 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, ...@@ -749,7 +754,7 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
uint8_t *p = buf; uint8_t *p = buf;
uint8_t *ecc_calc = chip->buffers.ecccalc; uint8_t *ecc_calc = chip->buffers.ecccalc;
uint8_t *ecc_code = chip->buffers.ecccode; uint8_t *ecc_code = chip->buffers.ecccode;
int *eccpos = chip->autooob->eccpos; int *eccpos = chip->ecc.layout->eccpos;
chip->read_buf(mtd, buf, mtd->writesize); chip->read_buf(mtd, buf, mtd->writesize);
chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
...@@ -795,7 +800,7 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, ...@@ -795,7 +800,7 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
uint8_t *p = buf; uint8_t *p = buf;
uint8_t *ecc_calc = chip->buffers.ecccalc; uint8_t *ecc_calc = chip->buffers.ecccalc;
uint8_t *ecc_code = chip->buffers.ecccode; uint8_t *ecc_code = chip->buffers.ecccode;
int *eccpos = chip->autooob->eccpos; int *eccpos = chip->ecc.layout->eccpos;
for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
chip->ecc.hwctl(mtd, NAND_ECC_READ); chip->ecc.hwctl(mtd, NAND_ECC_READ);
...@@ -1198,7 +1203,7 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, ...@@ -1198,7 +1203,7 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
int eccsteps = chip->ecc.steps; int eccsteps = chip->ecc.steps;
uint8_t *ecc_calc = chip->buffers.ecccalc; uint8_t *ecc_calc = chip->buffers.ecccalc;
const uint8_t *p = buf; const uint8_t *p = buf;
int *eccpos = chip->autooob->eccpos; int *eccpos = chip->ecc.layout->eccpos;
if (chip->ecc.mode != NAND_ECC_NONE) { if (chip->ecc.mode != NAND_ECC_NONE) {
/* Software ecc calculation */ /* Software ecc calculation */
...@@ -1227,7 +1232,7 @@ static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, ...@@ -1227,7 +1232,7 @@ static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
int eccsteps = chip->ecc.steps; int eccsteps = chip->ecc.steps;
uint8_t *ecc_calc = chip->buffers.ecccalc; uint8_t *ecc_calc = chip->buffers.ecccalc;
const uint8_t *p = buf; const uint8_t *p = buf;
int *eccpos = chip->autooob->eccpos; int *eccpos = chip->ecc.layout->eccpos;
for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
chip->ecc.hwctl(mtd, NAND_ECC_WRITE); chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
...@@ -2124,16 +2129,16 @@ int nand_scan(struct mtd_info *mtd, int maxchips) ...@@ -2124,16 +2129,16 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
/* /*
* If no default placement scheme is given, select an appropriate one * If no default placement scheme is given, select an appropriate one
*/ */
if (!chip->autooob) { if (!chip->ecc.layout) {
switch (mtd->oobsize) { switch (mtd->oobsize) {
case 8: case 8:
chip->autooob = &nand_oob_8; chip->ecc.layout = &nand_oob_8;
break; break;
case 16: case 16:
chip->autooob = &nand_oob_16; chip->ecc.layout = &nand_oob_16;
break; break;
case 64: case 64:
chip->autooob = &nand_oob_64; chip->ecc.layout = &nand_oob_64;
break; break;
default: default:
printk(KERN_WARNING "No oob scheme defined for " printk(KERN_WARNING "No oob scheme defined for "
...@@ -2197,6 +2202,15 @@ int nand_scan(struct mtd_info *mtd, int maxchips) ...@@ -2197,6 +2202,15 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
BUG(); BUG();
} }
/*
* The number of bytes available for a client to place data into
* the out of band area
*/
chip->ecc.layout->oobavail = 0;
for (i = 0; chip->ecc.layout->oobfree[i].length; i++)
chip->ecc.layout->oobavail +=
chip->ecc.layout->oobfree[i].length;
/* /*
* Set the number of read / write steps for one page depending on ECC * Set the number of read / write steps for one page depending on ECC
* mode * mode
...@@ -2236,8 +2250,8 @@ int nand_scan(struct mtd_info *mtd, int maxchips) ...@@ -2236,8 +2250,8 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
mtd->block_isbad = nand_block_isbad; mtd->block_isbad = nand_block_isbad;
mtd->block_markbad = nand_block_markbad; mtd->block_markbad = nand_block_markbad;
/* and make the autooob the default one */ /* propagate ecc.layout to mtd_info */
mtd->oobinfo = chip->autooob; mtd->ecclayout = chip->ecc.layout;
/* Check, if we should skip the bad block table scan */ /* Check, if we should skip the bad block table scan */
if (chip->options & NAND_SKIP_BBTSCAN) if (chip->options & NAND_SKIP_BBTSCAN)
......
...@@ -168,7 +168,7 @@ static void ndfc_chip_init(struct ndfc_nand_mtd *mtd) ...@@ -168,7 +168,7 @@ static void ndfc_chip_init(struct ndfc_nand_mtd *mtd)
chip->ecc.mode = NAND_ECC_HW; chip->ecc.mode = NAND_ECC_HW;
chip->ecc.size = 256; chip->ecc.size = 256;
chip->ecc.bytes = 3; chip->ecc.bytes = 3;
chip->autooob = mtd->pl_chip->oobinfo; chip->ecclayout = mtd->pl_chip->ecclayout;
mtd->mtd.priv = chip; mtd->mtd.priv = chip;
mtd->mtd.owner = THIS_MODULE; mtd->mtd.owner = THIS_MODULE;
} }
......
...@@ -142,8 +142,7 @@ static struct rs_control *rs_decoder; ...@@ -142,8 +142,7 @@ static struct rs_control *rs_decoder;
/* /*
* hardware specific Out Of Band information * hardware specific Out Of Band information
*/ */
static struct nand_oobinfo rtc_from4_nand_oobinfo = { static struct nand_ecclayout rtc_from4_nand_oobinfo = {
.useecc = MTD_NANDECC_AUTOPLACE,
.eccbytes = 32, .eccbytes = 32,
.eccpos = { .eccpos = {
0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7,
...@@ -574,7 +573,7 @@ static int __init rtc_from4_init(void) ...@@ -574,7 +573,7 @@ static int __init rtc_from4_init(void)
/* return the status of extra status and ECC checks */ /* return the status of extra status and ECC checks */
this->errstat = rtc_from4_errstat; this->errstat = rtc_from4_errstat;
/* set the nand_oobinfo to support FPGA H/W error detection */ /* set the nand_oobinfo to support FPGA H/W error detection */
this->autooob = &rtc_from4_nand_oobinfo; this->ecc.layout = &rtc_from4_nand_oobinfo;
this->ecc.hwctl = rtc_from4_enable_hwecc; this->ecc.hwctl = rtc_from4_enable_hwecc;
this->ecc.calculate = rtc_from4_calculate_ecc; this->ecc.calculate = rtc_from4_calculate_ecc;
this->ecc.correct = rtc_from4_correct_data; this->ecc.correct = rtc_from4_correct_data;
......
...@@ -76,8 +76,7 @@ static int hardware_ecc = 0; ...@@ -76,8 +76,7 @@ static int hardware_ecc = 0;
/* new oob placement block for use with hardware ecc generation /* new oob placement block for use with hardware ecc generation
*/ */
static struct nand_oobinfo nand_hw_eccoob = { static struct nand_ecclayout nand_hw_eccoob = {
.useecc = MTD_NANDECC_AUTOPLACE,
.eccbytes = 3, .eccbytes = 3,
.eccpos = {0, 1, 2}, .eccpos = {0, 1, 2},
.oobfree = {{8, 8}} .oobfree = {{8, 8}}
...@@ -502,7 +501,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, ...@@ -502,7 +501,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
chip->ecc.mode = NAND_ECC_HW; chip->ecc.mode = NAND_ECC_HW;
chip->ecc.size = 512; chip->ecc.size = 512;
chip->ecc.bytes = 3; chip->ecc.bytes = 3;
chip->autooob = &nand_hw_eccoob; chip->ecc.layout = &nand_hw_eccoob;
if (info->is_s3c2440) { if (info->is_s3c2440) {
chip->ecc.hwctl = s3c2440_nand_enable_hwecc; chip->ecc.hwctl = s3c2440_nand_enable_hwecc;
......
...@@ -115,8 +115,7 @@ static struct nand_bbt_descr sharpsl_akita_bbt = { ...@@ -115,8 +115,7 @@ static struct nand_bbt_descr sharpsl_akita_bbt = {
.pattern = scan_ff_pattern .pattern = scan_ff_pattern
}; };
static struct nand_oobinfo akita_oobinfo = { static struct nand_ecclayout akita_oobinfo = {
.useecc = MTD_NANDECC_AUTOPLACE,
.eccbytes = 24, .eccbytes = 24,
.eccpos = { .eccpos = {
0x5, 0x1, 0x2, 0x3, 0x6, 0x7, 0x15, 0x11, 0x5, 0x1, 0x2, 0x3, 0x6, 0x7, 0x15, 0x11,
...@@ -202,7 +201,7 @@ static int __init sharpsl_nand_init(void) ...@@ -202,7 +201,7 @@ static int __init sharpsl_nand_init(void)
this->badblock_pattern = &sharpsl_bbt; this->badblock_pattern = &sharpsl_bbt;
if (machine_is_akita() || machine_is_borzoi()) { if (machine_is_akita() || machine_is_borzoi()) {
this->badblock_pattern = &sharpsl_akita_bbt; this->badblock_pattern = &sharpsl_akita_bbt;
this->autooob = &akita_oobinfo; this->ecc.layout = &akita_oobinfo;
} }
this->ecc.hwctl = sharpsl_nand_enable_hwecc; this->ecc.hwctl = sharpsl_nand_enable_hwecc;
this->ecc.calculate = sharpsl_nand_calculate_ecc; this->ecc.calculate = sharpsl_nand_calculate_ecc;
......
...@@ -23,8 +23,7 @@ ...@@ -23,8 +23,7 @@
/** /**
* onenand_oob_64 - oob info for large (2KB) page * onenand_oob_64 - oob info for large (2KB) page
*/ */
static struct nand_oobinfo onenand_oob_64 = { static struct nand_ecclayout onenand_oob_64 = {
.useecc = MTD_NANDECC_AUTOPLACE,
.eccbytes = 20, .eccbytes = 20,
.eccpos = { .eccpos = {
8, 9, 10, 11, 12, 8, 9, 10, 11, 12,
...@@ -41,8 +40,7 @@ static struct nand_oobinfo onenand_oob_64 = { ...@@ -41,8 +40,7 @@ static struct nand_oobinfo onenand_oob_64 = {
/** /**
* onenand_oob_32 - oob info for middle (1KB) page * onenand_oob_32 - oob info for middle (1KB) page
*/ */
static struct nand_oobinfo onenand_oob_32 = { static struct nand_ecclayout onenand_oob_32 = {
.useecc = MTD_NANDECC_AUTOPLACE,
.eccbytes = 10, .eccbytes = 10,
.eccpos = { .eccpos = {
8, 9, 10, 11, 12, 8, 9, 10, 11, 12,
...@@ -1747,22 +1745,22 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) ...@@ -1747,22 +1745,22 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
switch (mtd->oobsize) { switch (mtd->oobsize) {
case 64: case 64:
this->autooob = &onenand_oob_64; this->ecclayout = &onenand_oob_64;
break; break;
case 32: case 32:
this->autooob = &onenand_oob_32; this->ecclayout = &onenand_oob_32;
break; break;
default: default:
printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n", printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n",
mtd->oobsize); mtd->oobsize);
/* To prevent kernel oops */ /* To prevent kernel oops */
this->autooob = &onenand_oob_32; this->ecclayout = &onenand_oob_32;
break; break;
} }
mtd->oobinfo = this->autooob; mtd->ecclayout = this->ecclayout;
/* Fill in remaining MTD driver data */ /* Fill in remaining MTD driver data */
mtd->type = MTD_NANDFLASH; mtd->type = MTD_NANDFLASH;
......
...@@ -107,7 +107,7 @@ struct jffs2_sb_info { ...@@ -107,7 +107,7 @@ struct jffs2_sb_info {
struct rw_semaphore wbuf_sem; /* Protects the write buffer */ struct rw_semaphore wbuf_sem; /* Protects the write buffer */
/* Information about out-of-band area usage... */ /* Information about out-of-band area usage... */
struct nand_oobinfo *oobinfo; struct nand_ecclayout *ecclayout;
uint32_t badblock_pos; uint32_t badblock_pos;
uint32_t fsdata_pos; uint32_t fsdata_pos;
uint32_t fsdata_len; uint32_t fsdata_len;
......
...@@ -1140,18 +1140,9 @@ int jffs2_write_nand_badblock(struct jffs2_sb_info *c, struct jffs2_eraseblock * ...@@ -1140,18 +1140,9 @@ int jffs2_write_nand_badblock(struct jffs2_sb_info *c, struct jffs2_eraseblock *
return 1; return 1;
} }
#define NAND_JFFS2_OOB16_FSDALEN 8
static struct nand_oobinfo jffs2_oobinfo_docecc = {
.useecc = MTD_NANDECC_PLACE,
.eccbytes = 6,
.eccpos = {0,1,2,3,4,5}
};
static int jffs2_nand_set_oobinfo(struct jffs2_sb_info *c) static int jffs2_nand_set_oobinfo(struct jffs2_sb_info *c)
{ {
struct nand_oobinfo *oinfo = c->mtd->oobinfo; struct nand_ecclayout *oinfo = c->mtd->ecclayout;
/* Do this only, if we have an oob buffer */ /* Do this only, if we have an oob buffer */
if (!c->mtd->oobsize) if (!c->mtd->oobsize)
...@@ -1161,33 +1152,23 @@ static int jffs2_nand_set_oobinfo(struct jffs2_sb_info *c) ...@@ -1161,33 +1152,23 @@ static int jffs2_nand_set_oobinfo(struct jffs2_sb_info *c)
c->cleanmarker_size = 0; c->cleanmarker_size = 0;
/* Should we use autoplacement ? */ /* Should we use autoplacement ? */
if (oinfo && oinfo->useecc == MTD_NANDECC_AUTOPLACE) { if (!oinfo) {
D1(printk(KERN_DEBUG "JFFS2 on NAND. No autoplacment info found\n"));
return -EINVAL;
}
D1(printk(KERN_DEBUG "JFFS2 using autoplace on NAND\n")); D1(printk(KERN_DEBUG "JFFS2 using autoplace on NAND\n"));
/* Get the position of the free bytes */ /* Get the position of the free bytes */
if (!oinfo->oobfree[0][1]) { if (!oinfo->oobfree[0].length) {
printk (KERN_WARNING "jffs2_nand_set_oobinfo(): Eeep. Autoplacement selected and no empty space in oob\n"); printk (KERN_WARNING "jffs2_nand_set_oobinfo(): Eeep."
" Autoplacement selected and no empty space in oob\n");
return -ENOSPC; return -ENOSPC;
} }
c->fsdata_pos = oinfo->oobfree[0][0]; c->fsdata_pos = oinfo->oobfree[0].offset;
c->fsdata_len = oinfo->oobfree[0][1]; c->fsdata_len = oinfo->oobfree[0].length;
if (c->fsdata_len > 8) if (c->fsdata_len > 8)
c->fsdata_len = 8; c->fsdata_len = 8;
} else {
/* This is just a legacy fallback and should go away soon */
switch(c->mtd->ecctype) {
case MTD_ECC_RS_DiskOnChip:
printk(KERN_WARNING "JFFS2 using DiskOnChip hardware ECC without autoplacement. Fix it!\n");
c->oobinfo = &jffs2_oobinfo_docecc;
c->fsdata_pos = 6;
c->fsdata_len = NAND_JFFS2_OOB16_FSDALEN;
c->badblock_pos = 15;
break;
default:
D1(printk(KERN_DEBUG "JFFS2 on NAND. No autoplacment info found\n"));
return -EINVAL;
}
}
return 0; return 0;
} }
......
...@@ -46,7 +46,7 @@ struct INFTLrecord { ...@@ -46,7 +46,7 @@ struct INFTLrecord {
unsigned int nb_blocks; /* number of physical blocks */ unsigned int nb_blocks; /* number of physical blocks */
unsigned int nb_boot_blocks; /* number of blocks used by the bios */ unsigned int nb_boot_blocks; /* number of blocks used by the bios */
struct erase_info instr; struct erase_info instr;
struct nand_oobinfo oobinfo; struct nand_ecclayout oobinfo;
}; };
int INFTL_mount(struct INFTLrecord *s); int INFTL_mount(struct INFTLrecord *s);
......
...@@ -101,8 +101,8 @@ struct mtd_info { ...@@ -101,8 +101,8 @@ struct mtd_info {
char *name; char *name;
int index; int index;
/* oobinfo structure pointer - read only ! */ /* ecc layout structure pointer - read only ! */
struct nand_oobinfo *oobinfo; struct nand_ecclayout *ecclayout;
/* Data for variable erase regions. If numeraseregions is zero, /* Data for variable erase regions. If numeraseregions is zero,
* it means that the whole device has erasesize as given above. * it means that the whole device has erasesize as given above.
......
...@@ -244,6 +244,7 @@ struct nand_ecc_ctrl { ...@@ -244,6 +244,7 @@ struct nand_ecc_ctrl {
int total; int total;
int prepad; int prepad;
int postpad; int postpad;
struct nand_ecclayout *layout;
void (*hwctl)(struct mtd_info *mtd, int mode); void (*hwctl)(struct mtd_info *mtd, int mode);
int (*calculate)(struct mtd_info *mtd, int (*calculate)(struct mtd_info *mtd,
const uint8_t *dat, const uint8_t *dat,
...@@ -318,7 +319,7 @@ struct nand_buffers { ...@@ -318,7 +319,7 @@ struct nand_buffers {
* @chipsize: [INTERN] the size of one chip for multichip arrays * @chipsize: [INTERN] the size of one chip for multichip arrays
* @pagemask: [INTERN] page number mask = number of (pages / chip) - 1 * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1
* @pagebuf: [INTERN] holds the pagenumber which is currently in data_buf * @pagebuf: [INTERN] holds the pagenumber which is currently in data_buf
* @autooob: [REPLACEABLE] the default (auto)placement scheme * @ecclayout: [REPLACEABLE] the default ecc placement scheme
* @bbt: [INTERN] bad block table pointer * @bbt: [INTERN] bad block table pointer
* @bbt_td: [REPLACEABLE] bad block table descriptor for flash lookup * @bbt_td: [REPLACEABLE] bad block table descriptor for flash lookup
* @bbt_md: [REPLACEABLE] bad block table mirror descriptor * @bbt_md: [REPLACEABLE] bad block table mirror descriptor
...@@ -368,7 +369,7 @@ struct nand_chip { ...@@ -368,7 +369,7 @@ struct nand_chip {
uint8_t *oob_poi; uint8_t *oob_poi;
struct nand_hw_control *controller; struct nand_hw_control *controller;
struct nand_oobinfo *autooob; struct nand_ecclayout *ecclayout;
struct nand_ecc_ctrl ecc; struct nand_ecc_ctrl ecc;
struct nand_buffers buffers; struct nand_buffers buffers;
...@@ -522,7 +523,7 @@ extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len, ...@@ -522,7 +523,7 @@ extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
* @partitions: mtd partition list * @partitions: mtd partition list
* @chip_delay: R/B delay value in us * @chip_delay: R/B delay value in us
* @options: Option flags, e.g. 16bit buswidth * @options: Option flags, e.g. 16bit buswidth
* @oobinfo: oob info structure (ecc placement) * @ecclayout: ecc layout info structure
* @priv: hardware controller specific settings * @priv: hardware controller specific settings
*/ */
struct platform_nand_chip { struct platform_nand_chip {
...@@ -530,7 +531,7 @@ struct platform_nand_chip { ...@@ -530,7 +531,7 @@ struct platform_nand_chip {
int chip_offset; int chip_offset;
int nr_partitions; int nr_partitions;
struct mtd_partition *partitions; struct mtd_partition *partitions;
struct nand_oobinfo *oobinfo; struct nand_ecclayout *ecclayout;
int chip_delay; int chip_delay;
unsigned int options; unsigned int options;
void *priv; void *priv;
......
...@@ -37,7 +37,7 @@ struct NFTLrecord { ...@@ -37,7 +37,7 @@ struct NFTLrecord {
unsigned int nb_blocks; /* number of physical blocks */ unsigned int nb_blocks; /* number of physical blocks */
unsigned int nb_boot_blocks; /* number of blocks used by the bios */ unsigned int nb_boot_blocks; /* number of blocks used by the bios */
struct erase_info instr; struct erase_info instr;
struct nand_oobinfo oobinfo; struct nand_ecclayout oobinfo;
}; };
int NFTL_mount(struct NFTLrecord *s); int NFTL_mount(struct NFTLrecord *s);
......
...@@ -77,7 +77,7 @@ struct onenand_bufferram { ...@@ -77,7 +77,7 @@ struct onenand_bufferram {
* @param chip_lock [INTERN] spinlock used to protect access to this structure and the chip * @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 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 state [INTERN] the current state of the OneNAND device
* @param autooob [REPLACEABLE] the default (auto)placement scheme * @param ecclayout [REPLACEABLE] the default ecc placement scheme
* @param bbm [REPLACEABLE] pointer to Bad Block Management * @param bbm [REPLACEABLE] pointer to Bad Block Management
* @param priv [OPTIONAL] pointer to private chip date * @param priv [OPTIONAL] pointer to private chip date
*/ */
...@@ -113,7 +113,7 @@ struct onenand_chip { ...@@ -113,7 +113,7 @@ struct onenand_chip {
onenand_state_t state; onenand_state_t state;
unsigned char *page_buf; unsigned char *page_buf;
struct nand_oobinfo *autooob; struct nand_ecclayout *ecclayout;
void *bbm; void *bbm;
......
...@@ -41,7 +41,7 @@ struct mtd_partition { ...@@ -41,7 +41,7 @@ struct mtd_partition {
u_int32_t size; /* partition size */ u_int32_t size; /* partition size */
u_int32_t offset; /* offset within the master MTD space */ u_int32_t offset; /* offset within the master MTD space */
u_int32_t mask_flags; /* master MTD flags to mask out for this partition */ u_int32_t mask_flags; /* master MTD flags to mask out for this partition */
struct nand_oobinfo *oobsel; /* out of band layout for this partition (NAND only)*/ struct nand_ecclayout *ecclayout; /* out of band layout for this partition (NAND only)*/
struct mtd_info **mtdp; /* pointer to store the MTD object */ struct mtd_info **mtdp; /* pointer to store the MTD object */
}; };
......
...@@ -98,7 +98,12 @@ struct otp_info { ...@@ -98,7 +98,12 @@ struct otp_info {
#define OTPGETREGIONCOUNT _IOW('M', 14, int) #define OTPGETREGIONCOUNT _IOW('M', 14, int)
#define OTPGETREGIONINFO _IOW('M', 15, struct otp_info) #define OTPGETREGIONINFO _IOW('M', 15, struct otp_info)
#define OTPLOCK _IOR('M', 16, struct otp_info) #define OTPLOCK _IOR('M', 16, struct otp_info)
#define ECCGETLAYOUT _IOR('M', 17, struct nand_ecclayout)
/*
* Obsolete legacy interface. Keep it in order not to break userspace
* interfaces
*/
struct nand_oobinfo { struct nand_oobinfo {
uint32_t useecc; uint32_t useecc;
uint32_t eccbytes; uint32_t eccbytes;
...@@ -106,4 +111,21 @@ struct nand_oobinfo { ...@@ -106,4 +111,21 @@ struct nand_oobinfo {
uint32_t eccpos[32]; uint32_t eccpos[32];
}; };
struct nand_oobfree {
uint32_t offset;
uint32_t length;
};
#define MTD_MAX_OOBFREE_ENTRIES 8
/*
* ECC layout control structure. Exported to userspace for
* diagnosis and to allow creation of raw images
*/
struct nand_ecclayout {
uint32_t eccbytes;
uint32_t eccpos[64];
uint32_t oobavail;
struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES];
};
#endif /* __MTD_ABI_H__ */ #endif /* __MTD_ABI_H__ */
...@@ -16,5 +16,6 @@ typedef struct mtd_info_user mtd_info_t; ...@@ -16,5 +16,6 @@ typedef struct mtd_info_user mtd_info_t;
typedef struct erase_info_user erase_info_t; typedef struct erase_info_user erase_info_t;
typedef struct region_info_user region_info_t; typedef struct region_info_user region_info_t;
typedef struct nand_oobinfo nand_oobinfo_t; typedef struct nand_oobinfo nand_oobinfo_t;
typedef struct nand_ecclayout nand_ecclayout_t;
#endif /* __MTD_USER_H__ */ #endif /* __MTD_USER_H__ */
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