diff mbox

[REV3] mtd: nand: Prepare for Micron on-die ECC controller support.

Message ID 1396025800-18444-1-git-send-email-davidm@egauge.net
State Rejected
Headers show

Commit Message

David Mosberger-Tang March 28, 2014, 4:56 p.m. UTC
This patch adds NAND_ECC_HW_ON_DIE and all other changes to generic code.
On-die ECC detection now has moved into nand_onfi_detect_micron().

Signed-off-by: David Mosberger <davidm@egauge.net>
---
 drivers/mtd/nand/nand_base.c |   42 ++++++++++++++++++++++++++++++++++++------
 drivers/of/of_mtd.c          |    1 +
 include/linux/mtd/nand.h     |    7 +++++++
 3 files changed, 44 insertions(+), 6 deletions(-)

Comments

Gerhard Sittig March 29, 2014, 1:16 p.m. UTC | #1
a few general notes on your style of patch submission:

please check how subject lines usually are created, the above
"[REV3]" is wrong in multiple ways -- see if you can detect a
pattern in how other series are re-sent

please do provide a history of changes upon re-iteration, don't
expect others to dig up those details for you -- help those
people whom you expect to help you

it's hard to determine how this followup patch relates to the
former on-die-ECC introduction, please provide comments on how
things interact with or depend on each other when multiple sets
of patches are floating around -- is the on-die-ECC support patch
obsolete, do you want to re-start by creating infrastructure in
preparation, to add more support later?  if this is not an
iteration of the on-die-ECC support, why is it v3 then?  can you
provide this information for those of us who are not as much into
the details of your work as you are?


On Fri, 2014-03-28 at 10:56 -0600, David Mosberger wrote:
> 
> This patch adds NAND_ECC_HW_ON_DIE and all other changes to generic code.
> On-die ECC detection now has moved into nand_onfi_detect_micron().

I guess this was too quick a change with too little of
information, and should not get applied, see below

> @@ -3049,16 +3049,29 @@ static int nand_setup_read_retry_micron(struct mtd_info *mtd, int retry_mode)
>  /*
>   * Configure chip properties from Micron vendor-specific ONFI table
>   */
> -static void nand_onfi_detect_micron(struct nand_chip *chip,
> -		struct nand_onfi_params *p)
> +static void nand_onfi_detect_micron(struct mtd_info *mtd,
> +		struct nand_chip *chip, struct nand_onfi_params *p)
>  {
>  	struct nand_onfi_vendor_micron *micron = (void *)p->vendor;
> +	u8 features[ONFI_SUBFEATURE_PARAM_LEN];
>  
>  	if (le16_to_cpu(p->vendor_revision) < 1)
>  		return;
>  
>  	chip->read_retries = micron->read_retry_options;
>  	chip->setup_read_retry = nand_setup_read_retry_micron;
> +
> +	if (chip->onfi_get_features(mtd, chip, ONFI_FEATURE_ADDR_OP_MODE,
> +				    features) >= 0) {
> +		if (features[0] & ONFI_FEATURE_OP_MODE_ENABLE_ON_DIE_ECC) {
> +			/*
> +			 * If the chip has on-die ECC enabled, we kind
> +			 * of have to do the same...
> +			 */
> +			chip->ecc.mode = NAND_ECC_HW_ON_DIE;
> +			pr_info("Using on-die ECC\n");
> +		}
> +	}
>  }

ISTR that the test should not be done for a single bit, but for
the specific 0x08 data pattern, i.e. for equality of the byte

can you re-check the documentation?  this is how I read table 14

putting the new code into a separate routine and bailing out upon
unmet conditions might help to avoid a few levels of indentation

> @@ -3792,13 +3805,24 @@ int nand_scan_tail(struct mtd_info *mtd)
>  			!(chip->bbt_options & NAND_BBT_USE_FLASH));
>  
>  	if (!(chip->options & NAND_OWN_BUFFERS)) {
> +		size_t on_die_bufsz = 0;
> +
> +		if (chip->ecc.mode == NAND_ECC_HW_ON_DIE)
> +			on_die_bufsz = 2*(mtd->writesize + mtd->oobsize);
> +
>  		nbuf = kzalloc(sizeof(*nbuf) + mtd->writesize
> -				+ mtd->oobsize * 3, GFP_KERNEL);
> +				+ mtd->oobsize * 3 + on_die_bufsz, GFP_KERNEL);
>  		if (!nbuf)
>  			return -ENOMEM;
>  		nbuf->ecccalc = (uint8_t *)(nbuf + 1);
>  		nbuf->ecccode = nbuf->ecccalc + mtd->oobsize;
>  		nbuf->databuf = nbuf->ecccode + mtd->oobsize;
> +		if (chip->ecc.mode == NAND_ECC_HW_ON_DIE) {
> +			nbuf->chkbuf = (nbuf->databuf + mtd->writesize
> +					+ mtd->oobsize);
> +			nbuf->rawbuf = (nbuf->chkbuf + mtd->writesize
> +					+ mtd->oobsize);
> +		}
>  
>  		chip->buffers = nbuf;
>  	} else {

so the additional buffers only get allocated when upon
identification the on-die-ECC feature already is enabled?  not
when it's supported, and might get enabled at any later point in
time?

this might be OK if there is no intention to enable the
on-die-ECC feature at runtime, but only to use it when enabled by
other entities earlier in the boot progress -- though I guess the
comments and the commit message should reflect such a limitation
that applies by design

> @@ -214,6 +215,10 @@ struct nand_chip;
>  /* Vendor-specific feature address (Micron) */
>  #define ONFI_FEATURE_ADDR_READ_RETRY	0x89
>  
> +/* Vendor-specific array operation mode (Micron) */
> +#define ONFI_FEATURE_ADDR_OP_MODE	0x90
> +#define ONFI_FEATURE_OP_MODE_ENABLE_ON_DIE_ECC		0x08
> +
>  /* ONFI subfeature parameters length */
>  #define ONFI_SUBFEATURE_PARAM_LEN	4
>  

is something like "array op mode" more appropriate, in case other
things might have their individual mode of operation in the future?


virtually yours
Gerhard Sittig
David Mosberger-Tang March 31, 2014, 6:33 p.m. UTC | #2
On Sat, Mar 29, 2014 at 7:16 AM, Gerhard Sittig <gsi@denx.de> wrote:

> ISTR that the test should not be done for a single bit, but for
> the specific 0x08 data pattern, i.e. for equality of the byte
>
> can you re-check the documentation?  this is how I read table 14

Yes, the data sheet certainly makes it look that way.
However, Micron's own sample code checks individual bits.
Also, I don't know why the other array-op features (OTP) would
be exclusive with internal ECC, so I'm leaning towards believing
the sample code (see function test_on_die_ecc() on page 8 & 9):

 http://www.micron.com/~/media/Documents/Products/Technical%20Note/NAND%20Flash/tn2956_ondie_ecc_omap3_linux.pdf


>>       if (!(chip->options & NAND_OWN_BUFFERS)) {
>> +             size_t on_die_bufsz = 0;
>> +
>> +             if (chip->ecc.mode == NAND_ECC_HW_ON_DIE)
>> +                     on_die_bufsz = 2*(mtd->writesize + mtd->oobsize);
>> +
>>               nbuf = kzalloc(sizeof(*nbuf) + mtd->writesize
>> -                             + mtd->oobsize * 3, GFP_KERNEL);
>> +                             + mtd->oobsize * 3 + on_die_bufsz, GFP_KERNEL);
>>               if (!nbuf)
>>                       return -ENOMEM;
>>               nbuf->ecccalc = (uint8_t *)(nbuf + 1);
>>               nbuf->ecccode = nbuf->ecccalc + mtd->oobsize;
>>               nbuf->databuf = nbuf->ecccode + mtd->oobsize;
>> +             if (chip->ecc.mode == NAND_ECC_HW_ON_DIE) {
>> +                     nbuf->chkbuf = (nbuf->databuf + mtd->writesize
>> +                                     + mtd->oobsize);
>> +                     nbuf->rawbuf = (nbuf->chkbuf + mtd->writesize
>> +                                     + mtd->oobsize);
>> +             }
>>
>>               chip->buffers = nbuf;
>>       } else {
>
> so the additional buffers only get allocated when upon
> identification the on-die-ECC feature already is enabled?

Yes.

> not
> when it's supported, and might get enabled at any later point in
> time?

There is no way to switch ECC mode later on, is there?

>>  /* Vendor-specific feature address (Micron) */
>>  #define ONFI_FEATURE_ADDR_READ_RETRY 0x89
>>
>> +/* Vendor-specific array operation mode (Micron) */
>> +#define ONFI_FEATURE_ADDR_OP_MODE    0x90
>> +#define ONFI_FEATURE_OP_MODE_ENABLE_ON_DIE_ECC               0x08
>> +
>>  /* ONFI subfeature parameters length */
>>  #define ONFI_SUBFEATURE_PARAM_LEN    4
>>
>
> is something like "array op mode" more appropriate, in case other
> things might have their individual mode of operation in the future?

Either way is fine with me.  ARRAY_OP_MODE is more accurate, but
it tends to get long and there is no other op-mode at this point in time.

  --david
Gerhard Sittig March 31, 2014, 7:45 p.m. UTC | #3
On Mon, 2014-03-31 at 12:33 -0600, David Mosberger wrote:
> 
> On Sat, Mar 29, 2014 at 7:16 AM, Gerhard Sittig <gsi@denx.de> wrote:
> 
> > so the additional buffers only get allocated when upon
> > identification the on-die-ECC feature already is enabled?
> 
> Yes.
> 
> > not
> > when it's supported, and might get enabled at any later point in
> > time?
> 
> There is no way to switch ECC mode later on, is there?

Isn't there the ONFI SETFEATURE request?  And don't you use this
very request to disable and enable chip internal ECC support, to
get the raw (uncorrected) bits after bitflips were detected?  So
I understand that there is support to enable this mode at will,
and we already have (or will have) code to do so.

If we consider disabling on-die-ECC support when we find it
enabled and know it's not what the user wants to run, then the
next logical step might be to support enabling this feature if
the user wants it and the chip doesn't have it enabled at this
point in time.

So I guess the buffers should get allocated as soon as the chip
supports on-die-ECC.  (While the allocation should only get
introduced in the phase where the raw-read and bitflip count gets
added.)


virtually yours
Gerhard Sittig
David Mosberger-Tang March 31, 2014, 8:58 p.m. UTC | #4
Gerhard,

On Mon, Mar 31, 2014 at 1:45 PM, Gerhard Sittig <gsi@denx.de> wrote:

> Isn't there the ONFI SETFEATURE request?  And don't you use this
> very request to disable and enable chip internal ECC support, to
> get the raw (uncorrected) bits after bitflips were detected?  So
> I understand that there is support to enable this mode at will,
> and we already have (or will have) code to do so.
>
> If we consider disabling on-die-ECC support when we find it
> enabled and know it's not what the user wants to run, then the
> next logical step might be to support enabling this feature if
> the user wants it and the chip doesn't have it enabled at this
> point in time.
>
> So I guess the buffers should get allocated as soon as the chip
> supports on-die-ECC.  (While the allocation should only get
> introduced in the phase where the raw-read and bitflip count gets
> added.)

The ECC-mode of the driver never changes.
Sure, what you describe could be implemented as an additional feature
in the future (I don't have any plans to do so since it makes little sense to
me, as no other ECC-mode uses the layout of the on-die-controller).

To be honest, I'm a bit confused: on the one hand, you're asking me to
simplify the patches into smaller pieces, on the other you seem to ask
for new features.

  --david
pekon gupta April 1, 2014, 5:29 a.m. UTC | #5
Hi David,

>From: David Mosberger [mailto:davidm@egauge.net]
>>On Mon, Mar 31, 2014 at 1:45 PM, Gerhard Sittig <gsi@denx.de> wrote:
>
>> Isn't there the ONFI SETFEATURE request?  And don't you use this
>> very request to disable and enable chip internal ECC support, to
>> get the raw (uncorrected) bits after bitflips were detected?  So
>> I understand that there is support to enable this mode at will,
>> and we already have (or will have) code to do so.
>>
>> If we consider disabling on-die-ECC support when we find it
>> enabled and know it's not what the user wants to run, then the
>> next logical step might be to support enabling this feature if
>> the user wants it and the chip doesn't have it enabled at this
>> point in time.
>>
>> So I guess the buffers should get allocated as soon as the chip
>> supports on-die-ECC.  (While the allocation should only get
>> introduced in the phase where the raw-read and bitflip count gets
>> added.)
>
>The ECC-mode of the driver never changes.
>Sure, what you describe could be implemented as an additional feature
>in the future (I don't have any plans to do so since it makes little sense to
>me, as no other ECC-mode uses the layout of the on-die-controller).
>
>To be honest, I'm a bit confused: on the one hand, you're asking me to
>simplify the patches into smaller pieces, on the other you seem to ask
>for new features.
>
I too would like to see ECC-mode selection based on user's choice.
So there should be mechanism to enable/disable this feature based on
DT or platform-data. And onfi_set_feature() is the correct thing to use.
This would make your patches more simple, without disturbing the generic
frame-work. If you patch causes any regression, or abruptly changes
behavior of any working driver, then it's less likely to get accepted.
So, instead of re-sending patches it's important to discuss the changes.


with regards, pekon
Brian Norris April 1, 2014, 9:19 a.m. UTC | #6
On Mon, Mar 31, 2014 at 02:58:12PM -0600, David Mosberger wrote:
> On Mon, Mar 31, 2014 at 1:45 PM, Gerhard Sittig <gsi@denx.de> wrote:
> > Isn't there the ONFI SETFEATURE request?  And don't you use this
> > very request to disable and enable chip internal ECC support, to
> > get the raw (uncorrected) bits after bitflips were detected?  So
> > I understand that there is support to enable this mode at will,
> > and we already have (or will have) code to do so.
> >
> > If we consider disabling on-die-ECC support when we find it
> > enabled and know it's not what the user wants to run, then the
> > next logical step might be to support enabling this feature if
> > the user wants it and the chip doesn't have it enabled at this
> > point in time.
> >
> > So I guess the buffers should get allocated as soon as the chip
> > supports on-die-ECC.  (While the allocation should only get
> > introduced in the phase where the raw-read and bitflip count gets
> > added.)
> 
> The ECC-mode of the driver never changes.
> Sure, what you describe could be implemented as an additional feature
> in the future (I don't have any plans to do so since it makes little sense to
> me, as no other ECC-mode uses the layout of the on-die-controller).

I don't think we should expect changes at runtime. I'd go with your
assessment and implementation (although I don't really like 2 extra
buffers...).

Brian
Brian Norris April 1, 2014, 9:33 a.m. UTC | #7
On Tue, Apr 01, 2014 at 05:29:54AM +0000, Pekon Gupta wrote:
> >From: David Mosberger [mailto:davidm@egauge.net]
> >The ECC-mode of the driver never changes.
> >Sure, what you describe could be implemented as an additional feature
> >in the future (I don't have any plans to do so since it makes little sense to
> >me, as no other ECC-mode uses the layout of the on-die-controller).
> >
> >To be honest, I'm a bit confused: on the one hand, you're asking me to
> >simplify the patches into smaller pieces, on the other you seem to ask
> >for new features.
> >
> I too would like to see ECC-mode selection based on user's choice.

I think what Gerhard was asking and what Pekon is asking for are
different. I don't think Gerhard's suggestion is realistic (that users
would change ECC modes mid-use). But Pekon's following concern (which I
share) sounds more reasonable, I think, for init-time configuration.

> So there should be mechanism to enable/disable this feature based on
> DT or platform-data. And onfi_set_feature() is the correct thing to use.
> This would make your patches more simple, without disturbing the generic
> frame-work. If you patch causes any regression, or abruptly changes
> behavior of any working driver, then it's less likely to get accepted.

I actually don't think his patches would abruptly change any working
driver, since it only utilizes on-die ECC if the chip already had it
enabled (and existing drivers would thus not function properly). But I
don't think it's the best design, since it assumes that the flash's
initial state is the expected mode of operation.

> So, instead of re-sending patches it's important to discuss the changes.

Yes, please.

Brian
Gerhard Sittig April 1, 2014, 2:06 p.m. UTC | #8
On Mon, 2014-03-31 at 14:58 -0600, David Mosberger wrote:
> 
> Gerhard,
> 
> On Mon, Mar 31, 2014 at 1:45 PM, Gerhard Sittig <gsi@denx.de> wrote:
> 
> > Isn't there the ONFI SETFEATURE request?  And don't you use this
> > very request to disable and enable chip internal ECC support, to
> > get the raw (uncorrected) bits after bitflips were detected?  So
> > I understand that there is support to enable this mode at will,
> > and we already have (or will have) code to do so.
> >
> > If we consider disabling on-die-ECC support when we find it
> > enabled and know it's not what the user wants to run, then the
> > next logical step might be to support enabling this feature if
> > the user wants it and the chip doesn't have it enabled at this
> > point in time.
> >
> > So I guess the buffers should get allocated as soon as the chip
> > supports on-die-ECC.  (While the allocation should only get
> > introduced in the phase where the raw-read and bitflip count gets
> > added.)
> 
> The ECC-mode of the driver never changes.
> Sure, what you describe could be implemented as an additional feature
> in the future (I don't have any plans to do so since it makes little sense to
> me, as no other ECC-mode uses the layout of the on-die-controller).

I'm sorry, it appears that I was unspecific or sloppy there.

The situation is that there are several phases in the setup:
There is the identification of the chip and its capabilities, an
optional adjustment of pre-set values according to the
information that was gathered, and then the "final" setup after
everything was evaluated.  This (in my mind) maps to the sequence
of nand_scan_ident(), nand_scan_tail(), and what might glue them
together.

So yes, after the ECC scheme was determined, it won't change for
the remainder of the driver's runtime.  Yet there is the code in
your submission that a pre-set software ECC would "turn into"
on-die-ECC if the chip was found in a specific state.  There has
been discussion that we might not blindly follow the chip's
current state, but involve a user's request and potentially
adjust what was found if it's different.

So please drop my thought of chaning ECC mode at runtime, after
the initial determination of which mode to use.  This really does
not apply.  The only change that might occur would be to
enable/disable the chip's feature if it differs from the user's
request, and this would happen before resource allocation in
nand_scan_tail().  At the very point of resource allocation, the
situation is stable.  Having determined the use of on-die-ECC
here at this point in time has involved all of the "supported",
"enabled", and "wanted" conditions.

I'm sorry for the confusion that I may have caused.


> To be honest, I'm a bit confused: on the one hand, you're asking me to
> simplify the patches into smaller pieces, on the other you seem to ask
> for new features.

This might look like a conflict only at first glance.  But I feel
that you can construct larger things with higher confidence if
you can inspect and verify individual pieces which you then snug
together.  If you know that the foundation is solid, you can put
more stuff on it with less worry.  Nothing in the kernel started
out at the complexity that's present now.  So no, splitting a
large patch into a series does not conflict with growing more
features within the resulting series.


virtually yours
Gerhard Sittig
diff mbox

Patch

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 5826da3..1f4a9d8 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3049,16 +3049,29 @@  static int nand_setup_read_retry_micron(struct mtd_info *mtd, int retry_mode)
 /*
  * Configure chip properties from Micron vendor-specific ONFI table
  */
-static void nand_onfi_detect_micron(struct nand_chip *chip,
-		struct nand_onfi_params *p)
+static void nand_onfi_detect_micron(struct mtd_info *mtd,
+		struct nand_chip *chip, struct nand_onfi_params *p)
 {
 	struct nand_onfi_vendor_micron *micron = (void *)p->vendor;
+	u8 features[ONFI_SUBFEATURE_PARAM_LEN];
 
 	if (le16_to_cpu(p->vendor_revision) < 1)
 		return;
 
 	chip->read_retries = micron->read_retry_options;
 	chip->setup_read_retry = nand_setup_read_retry_micron;
+
+	if (chip->onfi_get_features(mtd, chip, ONFI_FEATURE_ADDR_OP_MODE,
+				    features) >= 0) {
+		if (features[0] & ONFI_FEATURE_OP_MODE_ENABLE_ON_DIE_ECC) {
+			/*
+			 * If the chip has on-die ECC enabled, we kind
+			 * of have to do the same...
+			 */
+			chip->ecc.mode = NAND_ECC_HW_ON_DIE;
+			pr_info("Using on-die ECC\n");
+		}
+	}
 }
 
 /*
@@ -3160,7 +3173,7 @@  static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
 	}
 
 	if (p->jedec_id == NAND_MFR_MICRON)
-		nand_onfi_detect_micron(chip, p);
+		nand_onfi_detect_micron(mtd, chip, p);
 
 	return 1;
 }
@@ -3792,13 +3805,24 @@  int nand_scan_tail(struct mtd_info *mtd)
 			!(chip->bbt_options & NAND_BBT_USE_FLASH));
 
 	if (!(chip->options & NAND_OWN_BUFFERS)) {
+		size_t on_die_bufsz = 0;
+
+		if (chip->ecc.mode == NAND_ECC_HW_ON_DIE)
+			on_die_bufsz = 2*(mtd->writesize + mtd->oobsize);
+
 		nbuf = kzalloc(sizeof(*nbuf) + mtd->writesize
-				+ mtd->oobsize * 3, GFP_KERNEL);
+				+ mtd->oobsize * 3 + on_die_bufsz, GFP_KERNEL);
 		if (!nbuf)
 			return -ENOMEM;
 		nbuf->ecccalc = (uint8_t *)(nbuf + 1);
 		nbuf->ecccode = nbuf->ecccalc + mtd->oobsize;
 		nbuf->databuf = nbuf->ecccode + mtd->oobsize;
+		if (chip->ecc.mode == NAND_ECC_HW_ON_DIE) {
+			nbuf->chkbuf = (nbuf->databuf + mtd->writesize
+					+ mtd->oobsize);
+			nbuf->rawbuf = (nbuf->chkbuf + mtd->writesize
+					+ mtd->oobsize);
+		}
 
 		chip->buffers = nbuf;
 	} else {
@@ -3956,6 +3980,7 @@  int nand_scan_tail(struct mtd_info *mtd)
 		ecc->strength = ecc->bytes * 8 / fls(8 * ecc->size);
 		break;
 
+	case NAND_ECC_HW_ON_DIE:
 	case NAND_ECC_NONE:
 		pr_warn("NAND_ECC_NONE selected by board driver. "
 			   "This is not recommended!\n");
@@ -4023,8 +4048,13 @@  int nand_scan_tail(struct mtd_info *mtd)
 	/* Invalidate the pagebuffer reference */
 	chip->pagebuf = -1;
 
-	/* Large page NAND with SOFT_ECC should support subpage reads */
-	if ((ecc->mode == NAND_ECC_SOFT) && (chip->page_shift > 9))
+	/*
+	 * Large page NAND with SOFT_ECC or on-die ECC should support
+	 * subpage reads.
+	 */
+	if (((ecc->mode == NAND_ECC_SOFT)
+	     || (chip->ecc.mode == NAND_ECC_HW_ON_DIE))
+	    && (chip->page_shift > 9))
 		chip->options |= NAND_SUBPAGE_READ;
 
 	/* Fill in remaining MTD driver data */
diff --git a/drivers/of/of_mtd.c b/drivers/of/of_mtd.c
index b7361ed..c844c84 100644
--- a/drivers/of/of_mtd.c
+++ b/drivers/of/of_mtd.c
@@ -23,6 +23,7 @@  static const char *nand_ecc_modes[] = {
 	[NAND_ECC_HW_SYNDROME]	= "hw_syndrome",
 	[NAND_ECC_HW_OOB_FIRST]	= "hw_oob_first",
 	[NAND_ECC_SOFT_BCH]	= "soft_bch",
+	[NAND_ECC_HW_ON_DIE]	= "hw_on_die",
 };
 
 /**
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 450d61e..a1cc980 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -115,6 +115,7 @@  typedef enum {
 	NAND_ECC_HW_SYNDROME,
 	NAND_ECC_HW_OOB_FIRST,
 	NAND_ECC_SOFT_BCH,
+	NAND_ECC_HW_ON_DIE,
 } nand_ecc_modes_t;
 
 /*
@@ -214,6 +215,10 @@  struct nand_chip;
 /* Vendor-specific feature address (Micron) */
 #define ONFI_FEATURE_ADDR_READ_RETRY	0x89
 
+/* Vendor-specific array operation mode (Micron) */
+#define ONFI_FEATURE_ADDR_OP_MODE	0x90
+#define ONFI_FEATURE_OP_MODE_ENABLE_ON_DIE_ECC		0x08
+
 /* ONFI subfeature parameters length */
 #define ONFI_SUBFEATURE_PARAM_LEN	4
 
@@ -516,6 +521,8 @@  struct nand_buffers {
 	uint8_t	*ecccalc;
 	uint8_t	*ecccode;
 	uint8_t *databuf;
+	uint8_t *chkbuf;
+	uint8_t *rawbuf;
 };
 
 /**