diff options
author | Alexander Couzens <lynxis@fe80.eu> | 2017-05-02 06:19:00 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-05-25 09:44:48 -0400 |
commit | 5956b2815f90e0749d98ea0baedc49b1792f598b (patch) | |
tree | 99a25b587bf888b8e9f33d60e5b773b0b7528e4d | |
parent | 6639b27f5a4c5425a46b2f1039d390dd1ad7b94f (diff) |
mtd: nand: add ooblayout for old hamming layout
commit 6a623e07694437ad09f382a13f76cffc32239a7f upstream.
The old 1-bit hamming layout requires ECC data to be placed at a
fixed offset, and not necessarily at the end of the OOB area.
Add this old layout back in order to fix legacy setups.
Fixes: 41b207a70d3a ("mtd: nand: implement the default mtd_ooblayout_ops")
Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 70 |
1 files changed, 69 insertions, 1 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 3bde96a3f7bf..f222f8a7ba52 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -138,6 +138,74 @@ const struct mtd_ooblayout_ops nand_ooblayout_lp_ops = { | |||
138 | }; | 138 | }; |
139 | EXPORT_SYMBOL_GPL(nand_ooblayout_lp_ops); | 139 | EXPORT_SYMBOL_GPL(nand_ooblayout_lp_ops); |
140 | 140 | ||
141 | /* | ||
142 | * Support the old "large page" layout used for 1-bit Hamming ECC where ECC | ||
143 | * are placed at a fixed offset. | ||
144 | */ | ||
145 | static int nand_ooblayout_ecc_lp_hamming(struct mtd_info *mtd, int section, | ||
146 | struct mtd_oob_region *oobregion) | ||
147 | { | ||
148 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
149 | struct nand_ecc_ctrl *ecc = &chip->ecc; | ||
150 | |||
151 | if (section) | ||
152 | return -ERANGE; | ||
153 | |||
154 | switch (mtd->oobsize) { | ||
155 | case 64: | ||
156 | oobregion->offset = 40; | ||
157 | break; | ||
158 | case 128: | ||
159 | oobregion->offset = 80; | ||
160 | break; | ||
161 | default: | ||
162 | return -EINVAL; | ||
163 | } | ||
164 | |||
165 | oobregion->length = ecc->total; | ||
166 | if (oobregion->offset + oobregion->length > mtd->oobsize) | ||
167 | return -ERANGE; | ||
168 | |||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | static int nand_ooblayout_free_lp_hamming(struct mtd_info *mtd, int section, | ||
173 | struct mtd_oob_region *oobregion) | ||
174 | { | ||
175 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
176 | struct nand_ecc_ctrl *ecc = &chip->ecc; | ||
177 | int ecc_offset = 0; | ||
178 | |||
179 | if (section < 0 || section > 1) | ||
180 | return -ERANGE; | ||
181 | |||
182 | switch (mtd->oobsize) { | ||
183 | case 64: | ||
184 | ecc_offset = 40; | ||
185 | break; | ||
186 | case 128: | ||
187 | ecc_offset = 80; | ||
188 | break; | ||
189 | default: | ||
190 | return -EINVAL; | ||
191 | } | ||
192 | |||
193 | if (section == 0) { | ||
194 | oobregion->offset = 2; | ||
195 | oobregion->length = ecc_offset - 2; | ||
196 | } else { | ||
197 | oobregion->offset = ecc_offset + ecc->total; | ||
198 | oobregion->length = mtd->oobsize - oobregion->offset; | ||
199 | } | ||
200 | |||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | const struct mtd_ooblayout_ops nand_ooblayout_lp_hamming_ops = { | ||
205 | .ecc = nand_ooblayout_ecc_lp_hamming, | ||
206 | .free = nand_ooblayout_free_lp_hamming, | ||
207 | }; | ||
208 | |||
141 | static int check_offs_len(struct mtd_info *mtd, | 209 | static int check_offs_len(struct mtd_info *mtd, |
142 | loff_t ofs, uint64_t len) | 210 | loff_t ofs, uint64_t len) |
143 | { | 211 | { |
@@ -4565,7 +4633,7 @@ int nand_scan_tail(struct mtd_info *mtd) | |||
4565 | break; | 4633 | break; |
4566 | case 64: | 4634 | case 64: |
4567 | case 128: | 4635 | case 128: |
4568 | mtd_set_ooblayout(mtd, &nand_ooblayout_lp_ops); | 4636 | mtd_set_ooblayout(mtd, &nand_ooblayout_lp_hamming_ops); |
4569 | break; | 4637 | break; |
4570 | default: | 4638 | default: |
4571 | WARN(1, "No oob scheme defined for oobsize %d\n", | 4639 | WARN(1, "No oob scheme defined for oobsize %d\n", |