[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 <tglx@linutronix.de>
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index 82262a4a..463e12c 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -1058,8 +1058,7 @@
  * 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 @@
 	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 20f79fe..e922b82 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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	/*
 	 * 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 "
@@ -2198,6 +2203,15 @@
 	}
 
 	/*
+	 * 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 @@
 	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 5790d63..551702d 100644
--- a/drivers/mtd/nand/ndfc.c
+++ b/drivers/mtd/nand/ndfc.c
@@ -168,7 +168,7 @@
 	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 de6de91..f8c4964 100644
--- a/drivers/mtd/nand/rtc_from4.c
+++ b/drivers/mtd/nand/rtc_from4.c
@@ -142,8 +142,7 @@
 /*
  *      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 @@
 	/* 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 215227d..8429793 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -76,8 +76,7 @@
 /* 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 @@
 		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 45a1da7..2174365 100644
--- a/drivers/mtd/nand/sharpsl.c
+++ b/drivers/mtd/nand/sharpsl.c
@@ -115,8 +115,7 @@
 	.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 @@
 	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;