mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH] mtd: nand_omap_gpmc: fix BCH error correction
@ 2017-04-14 18:29 Matt Reimer
  0 siblings, 0 replies; 4+ messages in thread
From: Matt Reimer @ 2017-04-14 18:29 UTC (permalink / raw)
  To: barebox; +Cc: Matt Reimer

BCH error detection and correction was only looking at the first
of four syndrome polynomials, which meant it was failing to detect
and correct bitflips in the last 3/4 of the data. In effect, only
the first 512 bytes of a 2048 byte page were being protected by ECC.

The syndrome polynomials (BCH error codes) are stored in the NAND's
OOB, each of which protects 512 bytes of data. The driver used
eccsteps = 1 which effectively made it only use the first polynomial,
and therefore was only protecting the first 512 bytes of the page.

The fix is to pull over a bit of code from the kernel's
omap_correct_data() that sets eccsteps = 4 when the page size is 2048
bytes and hardware ECC is being used.

Signed-off-by: Matt Reimer <mreimer@sdgsystems.com>
---
 drivers/mtd/nand/nand_omap_gpmc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/nand_omap_gpmc.c b/drivers/mtd/nand/nand_omap_gpmc.c
index 9d9d27e..2fe6a10 100644
--- a/drivers/mtd/nand/nand_omap_gpmc.c
+++ b/drivers/mtd/nand/nand_omap_gpmc.c
@@ -302,7 +302,8 @@ static int omap_correct_bch(struct mtd_info *mtd, uint8_t *dat,
 	unsigned int err_loc[8];
 	int select_4_8;
 
-	int eccsteps = oinfo->nand.ecc.steps;
+        int eccsteps = (nand->ecc.mode == NAND_ECC_HW) &&
+                (nand->ecc.size == 2048) ? 4 : 1;
 	int eccsize = oinfo->nand.ecc.bytes;
 
 	switch (oinfo->ecc_mode) {
-- 
2.10.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] mtd: nand_omap_gpmc: fix BCH error correction
  2017-04-14 18:32 Matt Reimer
  2017-04-19  8:10 ` Sascha Hauer
@ 2017-05-26 12:28 ` Daniel Schultz
  1 sibling, 0 replies; 4+ messages in thread
From: Daniel Schultz @ 2017-05-26 12:28 UTC (permalink / raw)
  To: barebox, mreimer

Hi Matt,

could you give me some more informations about how you figured out this 
problem and how you tested it?

The Linux kernel and Barebox differs a lot in this driver. Your 
conditional assignment of eccsteps is from the omap_correct_data 
function, which will only be called if Hamming error correction is used, 
but BCH uses either omap_elm_correct_data or nand_bch_correct_data. 
These two function use the old way of getting eccsteps.

After I applied your patch, only the first 512 Bytes of a page was 
corrected (I made omap_correct_bch more verbose), before that the whole 
page was corrected. BCH in Barebox (which is default by the DTS) can 
only use the ROMCODE one, which has a default ECC size of 512 Bytes. So, 
eccsteps would always be 1, instead of 4.

Since hamming is using the omap_correct_hamming function, maybe this 
patch isn't needed?

-- 
Mit freundlichen Grüßen,
With best regards,
   Daniel Schultz

Am 14.04.2017 um 20:32 schrieb Matt Reimer:
> BCH error detection and correction was only looking at the first
> of four syndrome polynomials, which meant it was failing to detect
> and correct bitflips in the last 3/4 of the data. In effect, only
> the first 512 bytes of a 2048 byte page were being protected by ECC.
> 
> The syndrome polynomials (BCH error codes) are stored in the NAND's
> OOB, each of which protects 512 bytes of data. The driver used
> eccsteps = 1 which effectively made it only use the first polynomial,
> and therefore was only protecting the first 512 bytes of the page.
> 
> The fix is to pull over a bit of code from the kernel's
> omap_correct_data() that sets eccsteps = 4 when the page size is 2048
> bytes and hardware ECC is being used.
> 
> Signed-off-by: Matt Reimer <mreimer@sdgsystems.com>
> ---
>   drivers/mtd/nand/nand_omap_gpmc.c | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/nand_omap_gpmc.c b/drivers/mtd/nand/nand_omap_gpmc.c
> index 9d9d27e..2fe6a10 100644
> --- a/drivers/mtd/nand/nand_omap_gpmc.c
> +++ b/drivers/mtd/nand/nand_omap_gpmc.c
> @@ -302,7 +302,8 @@ static int omap_correct_bch(struct mtd_info *mtd, uint8_t *dat,
>   	unsigned int err_loc[8];
>   	int select_4_8;
>   
> -	int eccsteps = oinfo->nand.ecc.steps;
> +        int eccsteps = (nand->ecc.mode == NAND_ECC_HW) &&
> +                (nand->ecc.size == 2048) ? 4 : 1;
>   	int eccsize = oinfo->nand.ecc.bytes;
>   
>   	switch (oinfo->ecc_mode) {
> 



_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] mtd: nand_omap_gpmc: fix BCH error correction
  2017-04-14 18:32 Matt Reimer
@ 2017-04-19  8:10 ` Sascha Hauer
  2017-05-26 12:28 ` Daniel Schultz
  1 sibling, 0 replies; 4+ messages in thread
From: Sascha Hauer @ 2017-04-19  8:10 UTC (permalink / raw)
  To: Matt Reimer; +Cc: barebox

Hi Matt,

On Fri, Apr 14, 2017 at 11:32:05AM -0700, Matt Reimer wrote:
> BCH error detection and correction was only looking at the first
> of four syndrome polynomials, which meant it was failing to detect
> and correct bitflips in the last 3/4 of the data. In effect, only
> the first 512 bytes of a 2048 byte page were being protected by ECC.
> 
> The syndrome polynomials (BCH error codes) are stored in the NAND's
> OOB, each of which protects 512 bytes of data. The driver used
> eccsteps = 1 which effectively made it only use the first polynomial,
> and therefore was only protecting the first 512 bytes of the page.
> 
> The fix is to pull over a bit of code from the kernel's
> omap_correct_data() that sets eccsteps = 4 when the page size is 2048
> bytes and hardware ECC is being used.
> 
> Signed-off-by: Matt Reimer <mreimer@sdgsystems.com>
> ---
>  drivers/mtd/nand/nand_omap_gpmc.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/nand_omap_gpmc.c b/drivers/mtd/nand/nand_omap_gpmc.c
> index 9d9d27e..2fe6a10 100644
> --- a/drivers/mtd/nand/nand_omap_gpmc.c
> +++ b/drivers/mtd/nand/nand_omap_gpmc.c
> @@ -302,7 +302,8 @@ static int omap_correct_bch(struct mtd_info *mtd, uint8_t *dat,
>  	unsigned int err_loc[8];
>  	int select_4_8;
>  
> -	int eccsteps = oinfo->nand.ecc.steps;
> +        int eccsteps = (nand->ecc.mode == NAND_ECC_HW) &&
> +                (nand->ecc.size == 2048) ? 4 : 1;

Fixed up indention and applied, thanks

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH] mtd: nand_omap_gpmc: fix BCH error correction
@ 2017-04-14 18:32 Matt Reimer
  2017-04-19  8:10 ` Sascha Hauer
  2017-05-26 12:28 ` Daniel Schultz
  0 siblings, 2 replies; 4+ messages in thread
From: Matt Reimer @ 2017-04-14 18:32 UTC (permalink / raw)
  To: barebox; +Cc: Matt Reimer

BCH error detection and correction was only looking at the first
of four syndrome polynomials, which meant it was failing to detect
and correct bitflips in the last 3/4 of the data. In effect, only
the first 512 bytes of a 2048 byte page were being protected by ECC.

The syndrome polynomials (BCH error codes) are stored in the NAND's
OOB, each of which protects 512 bytes of data. The driver used
eccsteps = 1 which effectively made it only use the first polynomial,
and therefore was only protecting the first 512 bytes of the page.

The fix is to pull over a bit of code from the kernel's
omap_correct_data() that sets eccsteps = 4 when the page size is 2048
bytes and hardware ECC is being used.

Signed-off-by: Matt Reimer <mreimer@sdgsystems.com>
---
 drivers/mtd/nand/nand_omap_gpmc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/nand_omap_gpmc.c b/drivers/mtd/nand/nand_omap_gpmc.c
index 9d9d27e..2fe6a10 100644
--- a/drivers/mtd/nand/nand_omap_gpmc.c
+++ b/drivers/mtd/nand/nand_omap_gpmc.c
@@ -302,7 +302,8 @@ static int omap_correct_bch(struct mtd_info *mtd, uint8_t *dat,
 	unsigned int err_loc[8];
 	int select_4_8;
 
-	int eccsteps = oinfo->nand.ecc.steps;
+        int eccsteps = (nand->ecc.mode == NAND_ECC_HW) &&
+                (nand->ecc.size == 2048) ? 4 : 1;
 	int eccsize = oinfo->nand.ecc.bytes;
 
 	switch (oinfo->ecc_mode) {
-- 
2.10.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2017-05-26 12:28 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-14 18:29 [PATCH] mtd: nand_omap_gpmc: fix BCH error correction Matt Reimer
2017-04-14 18:32 Matt Reimer
2017-04-19  8:10 ` Sascha Hauer
2017-05-26 12:28 ` Daniel Schultz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox