From 5bd34c091a044d130601370c370f84b1c59f1627 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 27 May 2006 22:16:10 +0200 Subject: [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: Thomas Gleixner --- drivers/mtd/mtdchar.c | 26 +++++++++++++++++-- drivers/mtd/mtdconcat.c | 2 +- drivers/mtd/mtdpart.c | 2 +- drivers/mtd/nand/diskonchip.c | 5 ++-- drivers/mtd/nand/nand_base.c | 52 ++++++++++++++++++++++++-------------- drivers/mtd/nand/ndfc.c | 2 +- drivers/mtd/nand/rtc_from4.c | 5 ++-- drivers/mtd/nand/s3c2410.c | 5 ++-- drivers/mtd/nand/sharpsl.c | 5 ++-- drivers/mtd/onenand/onenand_base.c | 14 +++++----- fs/jffs2/jffs2_fs_sb.h | 2 +- fs/jffs2/wbuf.c | 51 ++++++++++++------------------------- include/linux/mtd/inftl.h | 2 +- include/linux/mtd/mtd.h | 4 +-- include/linux/mtd/nand.h | 9 ++++--- include/linux/mtd/nftl.h | 2 +- include/linux/mtd/onenand.h | 6 ++--- include/linux/mtd/partitions.h | 2 +- include/mtd/mtd-abi.h | 36 +++++++++++++++++++++----- include/mtd/mtd-user.h | 1 + 20 files changed, 134 insertions(+), 99 deletions(-) diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 608f7af679cb..e75ec5fe7760 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -512,14 +512,36 @@ static int mtd_ioctl(struct inode *inode, struct file *file, break; } + /* Legacy interface */ case MEMGETOOBSEL: { - if (copy_to_user(argp, mtd->oobinfo, - sizeof(struct nand_oobinfo))) + struct nand_oobinfo oi; + + 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; break; } + case ECCGETLAYOUT: + + if (!mtd->ecclayout) + return -EOPNOTSUPP; + + if (copy_to_user(argp, &mtd->ecclayout, + sizeof(struct nand_ecclayout))) + return -EFAULT; + break; + case MEMGETBADBLOCK: { loff_t offs; diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c index 699fce7770de..ec15abcdbdfa 100644 --- a/drivers/mtd/mtdconcat.c +++ b/drivers/mtd/mtdconcat.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->mtd.name = name; diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index b6b218952d49..6d7639b98eab 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -434,7 +434,7 @@ int add_mtd_partitions(struct mtd_info *master, parts[i].name); } - slave->mtd.oobinfo = master->oobinfo; + slave->mtd.ecclayout = master->ecclayout; if(parts[i].mtdp) { /* store the object pointer (caller may or may not register it */ diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index 82262a4a4208..463e12ced1b3 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c @@ -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 * be able to handle out-of-order segments. */ -static struct nand_oobinfo doc200x_oobinfo = { - .useecc = MTD_NANDECC_AUTOPLACE, +static struct nand_ecclayout doc200x_oobinfo = { .eccbytes = 6, .eccpos = {0, 1, 2, 3, 4, 5}, .oobfree = {{8, 8}, {6, 2}} @@ -1662,7 +1661,7 @@ static int __init doc_probe(unsigned long physadr) nand->ecc.calculate = doc200x_calculate_ecc; nand->ecc.correct = doc200x_correct_data; - nand->autooob = &doc200x_oobinfo; + nand->ecc.layout = &doc200x_oobinfo; nand->ecc.mode = NAND_ECC_HW_SYNDROME; nand->ecc.size = 512; nand->ecc.bytes = 6; diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 20f79fec73b5..e922b829c4be 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -52,28 +52,33 @@ #endif /* Define default oob placement schemes for large and small page devices */ -static struct nand_oobinfo nand_oob_8 = { - .useecc = MTD_NANDECC_AUTOPLACE, +static struct nand_ecclayout nand_oob_8 = { .eccbytes = 3, .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 = { - .useecc = MTD_NANDECC_AUTOPLACE, +static struct nand_ecclayout nand_oob_16 = { .eccbytes = 6, .eccpos = {0, 1, 2, 3, 6, 7}, - .oobfree = {{8, 8}} + .oobfree = { + {.offset = 8, + . length = 8}} }; -static struct nand_oobinfo nand_oob_64 = { - .useecc = MTD_NANDECC_AUTOPLACE, +static struct nand_ecclayout nand_oob_64 = { .eccbytes = 24, .eccpos = { 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 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 */ @@ -749,7 +754,7 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *p = buf; uint8_t *ecc_calc = chip->buffers.ecccalc; 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, chip->oob_poi, mtd->oobsize); @@ -795,7 +800,7 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *p = buf; uint8_t *ecc_calc = chip->buffers.ecccalc; 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) { 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, int eccsteps = chip->ecc.steps; uint8_t *ecc_calc = chip->buffers.ecccalc; const uint8_t *p = buf; - int *eccpos = chip->autooob->eccpos; + int *eccpos = chip->ecc.layout->eccpos; if (chip->ecc.mode != NAND_ECC_NONE) { /* Software ecc calculation */ @@ -1227,7 +1232,7 @@ static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, int eccsteps = chip->ecc.steps; uint8_t *ecc_calc = chip->buffers.ecccalc; 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) { chip->ecc.hwctl(mtd, NAND_ECC_WRITE); @@ -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 (!chip->autooob) { + if (!chip->ecc.layout) { switch (mtd->oobsize) { case 8: - chip->autooob = &nand_oob_8; + chip->ecc.layout = &nand_oob_8; break; case 16: - chip->autooob = &nand_oob_16; + chip->ecc.layout = &nand_oob_16; break; case 64: - chip->autooob = &nand_oob_64; + chip->ecc.layout = &nand_oob_64; break; default: printk(KERN_WARNING "No oob scheme defined for " @@ -2197,6 +2202,15 @@ int nand_scan(struct mtd_info *mtd, int maxchips) 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 * mode @@ -2236,8 +2250,8 @@ int nand_scan(struct mtd_info *mtd, int maxchips) mtd->block_isbad = nand_block_isbad; mtd->block_markbad = nand_block_markbad; - /* and make the autooob the default one */ - mtd->oobinfo = chip->autooob; + /* propagate ecc.layout to mtd_info */ + mtd->ecclayout = chip->ecc.layout; /* Check, if we should skip the bad block table scan */ if (chip->options & NAND_SKIP_BBTSCAN) diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index 5790d630faed..551702ddcacb 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -168,7 +168,7 @@ static void ndfc_chip_init(struct ndfc_nand_mtd *mtd) chip->ecc.mode = NAND_ECC_HW; chip->ecc.size = 256; chip->ecc.bytes = 3; - chip->autooob = mtd->pl_chip->oobinfo; + chip->ecclayout = mtd->pl_chip->ecclayout; mtd->mtd.priv = chip; mtd->mtd.owner = THIS_MODULE; } diff --git a/drivers/mtd/nand/rtc_from4.c b/drivers/mtd/nand/rtc_from4.c index de6de91fbad9..f8c49645324d 100644 --- a/drivers/mtd/nand/rtc_from4.c +++ b/drivers/mtd/nand/rtc_from4.c @@ -142,8 +142,7 @@ static struct rs_control *rs_decoder; /* * hardware specific Out Of Band information */ -static struct nand_oobinfo rtc_from4_nand_oobinfo = { - .useecc = MTD_NANDECC_AUTOPLACE, +static struct nand_ecclayout rtc_from4_nand_oobinfo = { .eccbytes = 32, .eccpos = { 0, 1, 2, 3, 4, 5, 6, 7, @@ -574,7 +573,7 @@ static int __init rtc_from4_init(void) /* return the status of extra status and ECC checks */ this->errstat = rtc_from4_errstat; /* 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.calculate = rtc_from4_calculate_ecc; this->ecc.correct = rtc_from4_correct_data; diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 215227d1a65c..8429793a6288 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -76,8 +76,7 @@ static int hardware_ecc = 0; /* new oob placement block for use with hardware ecc generation */ -static struct nand_oobinfo nand_hw_eccoob = { - .useecc = MTD_NANDECC_AUTOPLACE, +static struct nand_ecclayout nand_hw_eccoob = { .eccbytes = 3, .eccpos = {0, 1, 2}, .oobfree = {{8, 8}} @@ -502,7 +501,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, chip->ecc.mode = NAND_ECC_HW; chip->ecc.size = 512; chip->ecc.bytes = 3; - chip->autooob = &nand_hw_eccoob; + chip->ecc.layout = &nand_hw_eccoob; if (info->is_s3c2440) { chip->ecc.hwctl = s3c2440_nand_enable_hwecc; diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c index 45a1da724bff..21743658d150 100644 --- a/drivers/mtd/nand/sharpsl.c +++ b/drivers/mtd/nand/sharpsl.c @@ -115,8 +115,7 @@ static struct nand_bbt_descr sharpsl_akita_bbt = { .pattern = scan_ff_pattern }; -static struct nand_oobinfo akita_oobinfo = { - .useecc = MTD_NANDECC_AUTOPLACE, +static struct nand_ecclayout akita_oobinfo = { .eccbytes = 24, .eccpos = { 0x5, 0x1, 0x2, 0x3, 0x6, 0x7, 0x15, 0x11, @@ -202,7 +201,7 @@ static int __init sharpsl_nand_init(void) this->badblock_pattern = &sharpsl_bbt; if (machine_is_akita() || machine_is_borzoi()) { this->badblock_pattern = &sharpsl_akita_bbt; - this->autooob = &akita_oobinfo; + this->ecc.layout = &akita_oobinfo; } this->ecc.hwctl = sharpsl_nand_enable_hwecc; this->ecc.calculate = sharpsl_nand_calculate_ecc; diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index b24bfa6e202c..a0d3f011c0f2 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -23,8 +23,7 @@ /** * onenand_oob_64 - oob info for large (2KB) page */ -static struct nand_oobinfo onenand_oob_64 = { - .useecc = MTD_NANDECC_AUTOPLACE, +static struct nand_ecclayout onenand_oob_64 = { .eccbytes = 20, .eccpos = { 8, 9, 10, 11, 12, @@ -41,8 +40,7 @@ static struct nand_oobinfo onenand_oob_64 = { /** * onenand_oob_32 - oob info for middle (1KB) page */ -static struct nand_oobinfo onenand_oob_32 = { - .useecc = MTD_NANDECC_AUTOPLACE, +static struct nand_ecclayout onenand_oob_32 = { .eccbytes = 10, .eccpos = { 8, 9, 10, 11, 12, @@ -1747,22 +1745,22 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) switch (mtd->oobsize) { case 64: - this->autooob = &onenand_oob_64; + this->ecclayout = &onenand_oob_64; break; case 32: - this->autooob = &onenand_oob_32; + this->ecclayout = &onenand_oob_32; break; default: printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n", mtd->oobsize); /* To prevent kernel oops */ - this->autooob = &onenand_oob_32; + this->ecclayout = &onenand_oob_32; break; } - mtd->oobinfo = this->autooob; + mtd->ecclayout = this->ecclayout; /* Fill in remaining MTD driver data */ mtd->type = MTD_NANDFLASH; diff --git a/fs/jffs2/jffs2_fs_sb.h b/fs/jffs2/jffs2_fs_sb.h index 272fbea55192..506690cc9a78 100644 --- a/fs/jffs2/jffs2_fs_sb.h +++ b/fs/jffs2/jffs2_fs_sb.h @@ -107,7 +107,7 @@ struct jffs2_sb_info { struct rw_semaphore wbuf_sem; /* Protects the write buffer */ /* Information about out-of-band area usage... */ - struct nand_oobinfo *oobinfo; + struct nand_ecclayout *ecclayout; uint32_t badblock_pos; uint32_t fsdata_pos; uint32_t fsdata_len; diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c index dc275cedfe4a..c6a62e162963 100644 --- a/fs/jffs2/wbuf.c +++ b/fs/jffs2/wbuf.c @@ -1140,18 +1140,9 @@ int jffs2_write_nand_badblock(struct jffs2_sb_info *c, struct jffs2_eraseblock * 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) { - struct nand_oobinfo *oinfo = c->mtd->oobinfo; + struct nand_ecclayout *oinfo = c->mtd->ecclayout; /* Do this only, if we have an oob buffer */ if (!c->mtd->oobsize) @@ -1161,33 +1152,23 @@ static int jffs2_nand_set_oobinfo(struct jffs2_sb_info *c) c->cleanmarker_size = 0; /* Should we use autoplacement ? */ - if (oinfo && oinfo->useecc == MTD_NANDECC_AUTOPLACE) { - D1(printk(KERN_DEBUG "JFFS2 using autoplace on NAND\n")); - /* Get the position of the free bytes */ - if (!oinfo->oobfree[0][1]) { - printk (KERN_WARNING "jffs2_nand_set_oobinfo(): Eeep. Autoplacement selected and no empty space in oob\n"); - return -ENOSPC; - } - c->fsdata_pos = oinfo->oobfree[0][0]; - c->fsdata_len = oinfo->oobfree[0][1]; - if (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; + if (!oinfo) { + D1(printk(KERN_DEBUG "JFFS2 on NAND. No autoplacment info found\n")); + return -EINVAL; + } - default: - D1(printk(KERN_DEBUG "JFFS2 on NAND. No autoplacment info found\n")); - return -EINVAL; - } + D1(printk(KERN_DEBUG "JFFS2 using autoplace on NAND\n")); + /* Get the position of the free bytes */ + if (!oinfo->oobfree[0].length) { + printk (KERN_WARNING "jffs2_nand_set_oobinfo(): Eeep." + " Autoplacement selected and no empty space in oob\n"); + return -ENOSPC; } + c->fsdata_pos = oinfo->oobfree[0].offset; + c->fsdata_len = oinfo->oobfree[0].length; + if (c->fsdata_len > 8) + c->fsdata_len = 8; + return 0; } diff --git a/include/linux/mtd/inftl.h b/include/linux/mtd/inftl.h index d7eaa40e5ab0..6977780e548f 100644 --- a/include/linux/mtd/inftl.h +++ b/include/linux/mtd/inftl.h @@ -46,7 +46,7 @@ struct INFTLrecord { unsigned int nb_blocks; /* number of physical blocks */ unsigned int nb_boot_blocks; /* number of blocks used by the bios */ struct erase_info instr; - struct nand_oobinfo oobinfo; + struct nand_ecclayout oobinfo; }; int INFTL_mount(struct INFTLrecord *s); diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 8429da51bb09..48a9df21ab11 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -101,8 +101,8 @@ struct mtd_info { char *name; int index; - /* oobinfo structure pointer - read only ! */ - struct nand_oobinfo *oobinfo; + /* ecc layout structure pointer - read only ! */ + struct nand_ecclayout *ecclayout; /* Data for variable erase regions. If numeraseregions is zero, * it means that the whole device has erasesize as given above. diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index fd46bcf52281..dc2bf1bcf42b 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -244,6 +244,7 @@ struct nand_ecc_ctrl { int total; int prepad; int postpad; + struct nand_ecclayout *layout; void (*hwctl)(struct mtd_info *mtd, int mode); int (*calculate)(struct mtd_info *mtd, const uint8_t *dat, @@ -318,7 +319,7 @@ struct nand_buffers { * @chipsize: [INTERN] the size of one chip for multichip arrays * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1 * @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_td: [REPLACEABLE] bad block table descriptor for flash lookup * @bbt_md: [REPLACEABLE] bad block table mirror descriptor @@ -368,7 +369,7 @@ struct nand_chip { uint8_t *oob_poi; struct nand_hw_control *controller; - struct nand_oobinfo *autooob; + struct nand_ecclayout *ecclayout; struct nand_ecc_ctrl ecc; struct nand_buffers buffers; @@ -522,7 +523,7 @@ extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len, * @partitions: mtd partition list * @chip_delay: R/B delay value in us * @options: Option flags, e.g. 16bit buswidth - * @oobinfo: oob info structure (ecc placement) + * @ecclayout: ecc layout info structure * @priv: hardware controller specific settings */ struct platform_nand_chip { @@ -530,7 +531,7 @@ struct platform_nand_chip { int chip_offset; int nr_partitions; struct mtd_partition *partitions; - struct nand_oobinfo *oobinfo; + struct nand_ecclayout *ecclayout; int chip_delay; unsigned int options; void *priv; diff --git a/include/linux/mtd/nftl.h b/include/linux/mtd/nftl.h index d35d2c21ff3e..bcf2fb3fa4a7 100644 --- a/include/linux/mtd/nftl.h +++ b/include/linux/mtd/nftl.h @@ -37,7 +37,7 @@ struct NFTLrecord { unsigned int nb_blocks; /* number of physical blocks */ unsigned int nb_boot_blocks; /* number of blocks used by the bios */ struct erase_info instr; - struct nand_oobinfo oobinfo; + struct nand_ecclayout oobinfo; }; int NFTL_mount(struct NFTLrecord *s); diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h index 3f5919f2e9da..9ce9a48db444 100644 --- a/include/linux/mtd/onenand.h +++ b/include/linux/mtd/onenand.h @@ -77,7 +77,7 @@ struct onenand_bufferram { * @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 autooob [REPLACEABLE] the default (auto)placement scheme + * @param ecclayout [REPLACEABLE] the default ecc placement scheme * @param bbm [REPLACEABLE] pointer to Bad Block Management * @param priv [OPTIONAL] pointer to private chip date */ @@ -113,9 +113,9 @@ struct onenand_chip { onenand_state_t state; unsigned char *page_buf; - struct nand_oobinfo *autooob; + struct nand_ecclayout *ecclayout; - void *bbm; + void *bbm; void *priv; }; diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index b03f512d51b9..da6b3d6f12a7 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h @@ -41,7 +41,7 @@ struct mtd_partition { u_int32_t size; /* partition size */ u_int32_t offset; /* offset within the master MTD space */ 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 */ }; diff --git a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h index 1e09e4c8f485..54c673f9648d 100644 --- a/include/mtd/mtd-abi.h +++ b/include/mtd/mtd-abi.h @@ -82,12 +82,12 @@ struct otp_info { uint32_t locked; }; -#define MEMGETINFO _IOR('M', 1, struct mtd_info_user) -#define MEMERASE _IOW('M', 2, struct erase_info_user) -#define MEMWRITEOOB _IOWR('M', 3, struct mtd_oob_buf) -#define MEMREADOOB _IOWR('M', 4, struct mtd_oob_buf) -#define MEMLOCK _IOW('M', 5, struct erase_info_user) -#define MEMUNLOCK _IOW('M', 6, struct erase_info_user) +#define MEMGETINFO _IOR('M', 1, struct mtd_info_user) +#define MEMERASE _IOW('M', 2, struct erase_info_user) +#define MEMWRITEOOB _IOWR('M', 3, struct mtd_oob_buf) +#define MEMREADOOB _IOWR('M', 4, struct mtd_oob_buf) +#define MEMLOCK _IOW('M', 5, struct erase_info_user) +#define MEMUNLOCK _IOW('M', 6, struct erase_info_user) #define MEMGETREGIONCOUNT _IOR('M', 7, int) #define MEMGETREGIONINFO _IOWR('M', 8, struct region_info_user) #define MEMSETOOBSEL _IOW('M', 9, struct nand_oobinfo) @@ -97,8 +97,13 @@ struct otp_info { #define OTPSELECT _IOR('M', 13, int) #define OTPGETREGIONCOUNT _IOW('M', 14, int) #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 { uint32_t useecc; uint32_t eccbytes; @@ -106,4 +111,21 @@ struct nand_oobinfo { 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__ */ diff --git a/include/mtd/mtd-user.h b/include/mtd/mtd-user.h index 1c13fc7161fe..713f34d3e62e 100644 --- a/include/mtd/mtd-user.h +++ b/include/mtd/mtd-user.h @@ -16,5 +16,6 @@ typedef struct mtd_info_user mtd_info_t; typedef struct erase_info_user erase_info_t; typedef struct region_info_user region_info_t; typedef struct nand_oobinfo nand_oobinfo_t; +typedef struct nand_ecclayout nand_ecclayout_t; #endif /* __MTD_USER_H__ */ -- cgit v1.2.3-59-g8ed1b