Patchwork mtd: nand: fix off-by-one read retry mode counting

login
register
mail settings
Submitter Brian Norris
Date Feb. 13, 2014, 12:46 a.m.
Message ID <1392252394-32512-1-git-send-email-computersforpeace@gmail.com>
Download mbox | patch
Permalink /patch/319851/
State New
Headers show

Comments

Brian Norris - Feb. 13, 2014, 12:46 a.m.
A flash may support N read retry voltage threshold modes, numbered 1
through N (where mode 0 represents the initial state). However,
nand_setup_read_retry() prematurely quits with an error when mode == N.

This off-by-one error shows up, for instance, when using nanddump, and
we have cycled through available modes:

    nand: setting READ RETRY mode 0
    nand: setting READ RETRY mode 1
    nand: setting READ RETRY mode 2
    nand: setting READ RETRY mode 3
    nand: setting READ RETRY mode 4
    nand: setting READ RETRY mode 5
    nand: setting READ RETRY mode 6
    nand: setting READ RETRY mode 7
    nand: setting READ RETRY mode 8
    libmtd: error!: cannot read 8192 bytes from mtd0 (eraseblock 20, offset 0)
            error 22 (Invalid argument)
    nanddump: error!: mtd_read

Tested on Micron MT29F64G08CBCBBH1, with 8 retry modes.

Signed-off-by: Brian Norris <computersforpeace@gmail.com>
---
 drivers/mtd/nand/nand_base.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Brian Norris - Feb. 13, 2014, 12:58 a.m.
On Wed, Feb 12, 2014 at 04:46:34PM -0800, Brian Norris wrote:
> A flash may support N read retry voltage threshold modes, numbered 1
> through N (where mode 0 represents the initial state). However,
> nand_setup_read_retry() prematurely quits with an error when mode == N.

Scratch that; apparently N retry modes means we can use feature address
0 through N-1. So the off-by-one error is actually in
nand_do_read_ops(). I'll send a v2 shortly.

Brian

Patch

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 9be7842f300e..76535a61b87a 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1471,7 +1471,7 @@  static int nand_setup_read_retry(struct mtd_info *mtd, int retry_mode)
 
 	pr_debug("setting READ RETRY mode %d\n", retry_mode);
 
-	if (retry_mode >= chip->read_retries)
+	if (retry_mode > chip->read_retries)
 		return -EINVAL;
 
 	if (!chip->setup_read_retry)