From: Sean MacLennan <smaclennan@pikatech.com>
To: Stefan Roese <sr@denx.de>
Cc: u-boot@lists.denx.de, Feng Kan <fkan@amcc.com>,
linux-mtd@lists.infradead.org, linuxppc-dev@ozlabs.org
Subject: Re: [U-Boot] NAND ECC Error with wrong SMC ording bug
Date: Thu, 20 Aug 2009 15:36:44 -0400 [thread overview]
Message-ID: <20090820153644.631dbd7b@lappy.seanm.ca> (raw)
In-Reply-To: <200908200701.21076.sr@denx.de>
On Thu, 20 Aug 2009 07:01:21 +0200
Stefan Roese <sr@denx.de> wrote:
> On Thursday 20 August 2009 06:38:51 Sean MacLennan wrote:
> > > I see other boards using SMC as well, can someone comment on the
> > > change I am proposing.
> > > Should I change the correction algorithm or the calculate
> > > function? If the later is preferred
> > > it would mean the change must be pushed in both U-Boot and Linux.
> >
> > Odds are the calculate function is wrong. The correction algo is
> > used by many nand drivers, I *assume* it is correct. The calculate
> > function was set to agree with u-boot (1.3.0).
>
> Yes, it seems that you changed the order in the calculation function
> while reworking the NDFC driver for arch/powerpc. So we should
> probably change this order back to the original version. And change
> it in U-Boot as well.
>
> BTW: I didn't see any problems with ECC so far with the current code.
> Feng, how did you spot this problem?
Ok, I think I have reproduced the problem programmatically. Basically,
I force a one bit error with the following patch:
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 8c21b89..91dd5b4 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1628,11 +1628,22 @@ static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
uint8_t *ecc_calc = chip->buffers->ecccalc;
const uint8_t *p = buf;
uint32_t *eccpos = chip->ecc.layout->eccpos;
+ static int count;
for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
- chip->write_buf(mtd, p, eccsize);
- chip->ecc.calculate(mtd, p, &ecc_calc[i]);
+ if (count == 0) {
+ count = 1;
+ printk("Corrupt one bit: %08x => %08x\n",
+ *p, *p ^ 8);
+ *(uint8_t *)p ^= 8;
+ chip->write_buf(mtd, p, eccsize);
+ *(uint8_t *)p ^= 8;
+ nand_calculate_ecc(mtd, p, &ecc_calc[i]);
+ } else {
+ chip->write_buf(mtd, p, eccsize);
+ chip->ecc.calculate(mtd, p, &ecc_calc[i]);
+ }
}
for (i = 0; i < chip->ecc.total; i++)
Basically I write a one bit error to the NAND, but calculate with the
correct bit. This assumes nand_calculate_ecc is correct.
I then added debugs to the correction to make sure it corrected
properly:
diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c
index c0cb87d..57dcaa1 100644
--- a/drivers/mtd/nand/nand_ecc.c
+++ b/drivers/mtd/nand/nand_ecc.c
@@ -483,14 +483,20 @@ int nand_correct_data(struct mtd_info *mtd, unsigned char *buf,
byte_addr = (addressbits[b2 & 0x3] << 8) +
(addressbits[b1] << 4) + addressbits[b0];
bit_addr = addressbits[b2 >> 2];
+
+ printk("Single bit error: correct %08x => %08x\n",
+ buf[byte_addr], buf[byte_addr] ^ (1 << bit_addr));
+
/* flip the bit */
buf[byte_addr] ^= (1 << bit_addr);
return 1;
}
/* count nr of bits; use table lookup, faster than calculating it */
- if ((bitsperbyte[b0] + bitsperbyte[b1] + bitsperbyte[b2]) == 1)
+ if ((bitsperbyte[b0] + bitsperbyte[b1] + bitsperbyte[b2]) == 1) {
+ printk("ECC DATA BAD\n"); // SAM DBG
return 1; /* error in ecc data; no action needed */
+ }
printk(KERN_ERR "uncorrectable error : ");
return -1;
With the current ndfc code, the error correction gets the bits wrong.
Switching it back to the original way and the correction is correct.
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
index 89bf85a..497e175 100644
--- a/drivers/mtd/nand/ndfc.c
+++ b/drivers/mtd/nand/ndfc.c
@@ -101,9 +101,8 @@ static int ndfc_calculate_ecc(struct mtd_info *mtd,
wmb();
ecc = in_be32(ndfc->ndfcbase + NDFC_ECC);
- /* The NDFC uses Smart Media (SMC) bytes order */
- ecc_code[0] = p[2];
- ecc_code[1] = p[1];
+ ecc_code[0] = p[1];
+ ecc_code[1] = p[2];
ecc_code[2] = p[3];
return 0;
Does anybody see a problem with my method of reproducing the bug? This
bug is deadly for our customers. I don't want to make the change unless
it is absolutely necessary.
Cheers,
Sean
next prev parent reply other threads:[~2009-08-20 19:36 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-08-17 23:00 [PATCH 1/3 v3] powerpc/32: Always order writes to halves of 64-bit PTEs Paul Mackerras
2009-08-17 23:00 ` [PATCH 2/3 v3] powerpc: Allow perf_counters to access user memory at interrupt time Paul Mackerras
2009-08-18 4:24 ` Benjamin Herrenschmidt
2009-08-17 23:01 ` [PATCH 3/3 v3] perf_counter: powerpc: Add callchain support Paul Mackerras
2009-08-18 4:23 ` Benjamin Herrenschmidt
2009-08-18 0:00 ` [PATCH 1/3 v3] powerpc/32: Always order writes to halves of 64-bit PTEs Kumar Gala
2009-08-18 0:14 ` Paul Mackerras
2009-08-18 4:24 ` Benjamin Herrenschmidt
2009-08-19 23:16 ` NAND ECC Error with wrong SMC ording bug Feng Kan
2009-08-20 4:38 ` Sean MacLennan
2009-08-20 5:01 ` [U-Boot] " Stefan Roese
2009-08-20 19:36 ` Sean MacLennan [this message]
2009-08-20 22:56 ` Victor Gallardo
2009-08-21 5:17 ` vimal singh
2009-08-21 6:26 ` Sean MacLennan
2009-08-21 6:27 ` Stefan Roese
2009-08-21 6:30 ` Victor Gallardo
2009-08-20 23:42 ` Feng Kan
2009-08-21 7:59 ` Stefan Roese
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090820153644.631dbd7b@lappy.seanm.ca \
--to=smaclennan@pikatech.com \
--cc=fkan@amcc.com \
--cc=linux-mtd@lists.infradead.org \
--cc=linuxppc-dev@ozlabs.org \
--cc=sr@denx.de \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).