]>
Commit | Line | Data |
---|---|---|
72fc6108 GKH |
1 | From foo@baz Mon Apr 9 10:16:32 CEST 2018 |
2 | From: Miquel Raynal <miquel.raynal@free-electrons.com> | |
3 | Date: Thu, 11 Jan 2018 21:39:20 +0100 | |
4 | Subject: mtd: mtd_oobtest: Handle bitflips during reads | |
5 | ||
6 | From: Miquel Raynal <miquel.raynal@free-electrons.com> | |
7 | ||
8 | ||
9 | [ Upstream commit 12663b442e5ac5aa3d6097cd3f287c71ba46d26e ] | |
10 | ||
11 | Reads from NAND devices usually trigger bitflips, this is an expected | |
12 | behavior. While bitflips are under a given threshold, the MTD core | |
13 | returns 0. However, when the number of corrected bitflips is above this | |
14 | same threshold, -EUCLEAN is returned to inform the upper layer that this | |
15 | block is slightly dying and soon the ECC engine will be overtaken so | |
16 | actions should be taken to move the data out of it. | |
17 | ||
18 | This particular condition should not be treated like an error and the | |
19 | test should continue. | |
20 | ||
21 | Signed-off-by: Miquel Raynal <miquel.raynal@free-electrons.com> | |
22 | Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> | |
23 | Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> | |
24 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
25 | --- | |
26 | drivers/mtd/tests/oobtest.c | 21 +++++++++++++++++++++ | |
27 | 1 file changed, 21 insertions(+) | |
28 | ||
29 | --- a/drivers/mtd/tests/oobtest.c | |
30 | +++ b/drivers/mtd/tests/oobtest.c | |
31 | @@ -193,6 +193,9 @@ static int verify_eraseblock(int ebnum) | |
32 | ops.datbuf = NULL; | |
33 | ops.oobbuf = readbuf; | |
34 | err = mtd_read_oob(mtd, addr, &ops); | |
35 | + if (mtd_is_bitflip(err)) | |
36 | + err = 0; | |
37 | + | |
38 | if (err || ops.oobretlen != use_len) { | |
39 | pr_err("error: readoob failed at %#llx\n", | |
40 | (long long)addr); | |
41 | @@ -227,6 +230,9 @@ static int verify_eraseblock(int ebnum) | |
42 | ops.datbuf = NULL; | |
43 | ops.oobbuf = readbuf; | |
44 | err = mtd_read_oob(mtd, addr, &ops); | |
45 | + if (mtd_is_bitflip(err)) | |
46 | + err = 0; | |
47 | + | |
48 | if (err || ops.oobretlen != mtd->oobavail) { | |
49 | pr_err("error: readoob failed at %#llx\n", | |
50 | (long long)addr); | |
51 | @@ -286,6 +292,9 @@ static int verify_eraseblock_in_one_go(i | |
52 | ||
53 | /* read entire block's OOB at one go */ | |
54 | err = mtd_read_oob(mtd, addr, &ops); | |
55 | + if (mtd_is_bitflip(err)) | |
56 | + err = 0; | |
57 | + | |
58 | if (err || ops.oobretlen != len) { | |
59 | pr_err("error: readoob failed at %#llx\n", | |
60 | (long long)addr); | |
61 | @@ -527,6 +536,9 @@ static int __init mtd_oobtest_init(void) | |
62 | pr_info("attempting to start read past end of OOB\n"); | |
63 | pr_info("an error is expected...\n"); | |
64 | err = mtd_read_oob(mtd, addr0, &ops); | |
65 | + if (mtd_is_bitflip(err)) | |
66 | + err = 0; | |
67 | + | |
68 | if (err) { | |
69 | pr_info("error occurred as expected\n"); | |
70 | err = 0; | |
71 | @@ -571,6 +583,9 @@ static int __init mtd_oobtest_init(void) | |
72 | pr_info("attempting to read past end of device\n"); | |
73 | pr_info("an error is expected...\n"); | |
74 | err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops); | |
75 | + if (mtd_is_bitflip(err)) | |
76 | + err = 0; | |
77 | + | |
78 | if (err) { | |
79 | pr_info("error occurred as expected\n"); | |
80 | err = 0; | |
81 | @@ -615,6 +630,9 @@ static int __init mtd_oobtest_init(void) | |
82 | pr_info("attempting to read past end of device\n"); | |
83 | pr_info("an error is expected...\n"); | |
84 | err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops); | |
85 | + if (mtd_is_bitflip(err)) | |
86 | + err = 0; | |
87 | + | |
88 | if (err) { | |
89 | pr_info("error occurred as expected\n"); | |
90 | err = 0; | |
91 | @@ -684,6 +702,9 @@ static int __init mtd_oobtest_init(void) | |
92 | ops.datbuf = NULL; | |
93 | ops.oobbuf = readbuf; | |
94 | err = mtd_read_oob(mtd, addr, &ops); | |
95 | + if (mtd_is_bitflip(err)) | |
96 | + err = 0; | |
97 | + | |
98 | if (err) | |
99 | goto out; | |
100 | if (memcmpshow(addr, readbuf, writebuf, |