diff options
author | Alexander Couzens <lynxis@fe80.eu> | 2017-05-02 06:19:00 -0400 |
---|---|---|
committer | Brian Norris <computersforpeace@gmail.com> | 2017-05-02 21:56:39 -0400 |
commit | 6a623e07694437ad09f382a13f76cffc32239a7f (patch) | |
tree | b189b4914fdc96540f99082f04ba9e94c3689e40 /drivers/mtd/nand | |
parent | b98e1995e4fa9030474a61ed0dbc033464fe5ea0 (diff) |
mtd: nand: add ooblayout for old hamming layout
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")
Cc: <stable@vger.kernel.org>
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>
Diffstat (limited to 'drivers/mtd/nand')
-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 ed49a1d634b0..d474378ed810 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -139,6 +139,74 @@ const struct mtd_ooblayout_ops nand_ooblayout_lp_ops = { | |||
139 | }; | 139 | }; |
140 | EXPORT_SYMBOL_GPL(nand_ooblayout_lp_ops); | 140 | EXPORT_SYMBOL_GPL(nand_ooblayout_lp_ops); |
141 | 141 | ||
142 | /* | ||
143 | * Support the old "large page" layout used for 1-bit Hamming ECC where ECC | ||
144 | * are placed at a fixed offset. | ||
145 | */ | ||
146 | static int nand_ooblayout_ecc_lp_hamming(struct mtd_info *mtd, int section, | ||
147 | struct mtd_oob_region *oobregion) | ||
148 | { | ||
149 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
150 | struct nand_ecc_ctrl *ecc = &chip->ecc; | ||
151 | |||
152 | if (section) | ||
153 | return -ERANGE; | ||
154 | |||
155 | switch (mtd->oobsize) { | ||
156 | case 64: | ||
157 | oobregion->offset = 40; | ||
158 | break; | ||
159 | case 128: | ||
160 | oobregion->offset = 80; | ||
161 | break; | ||
162 | default: | ||
163 | return -EINVAL; | ||
164 | } | ||
165 | |||
166 | oobregion->length = ecc->total; | ||
167 | if (oobregion->offset + oobregion->length > mtd->oobsize) | ||
168 | return -ERANGE; | ||
169 | |||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | static int nand_ooblayout_free_lp_hamming(struct mtd_info *mtd, int section, | ||
174 | struct mtd_oob_region *oobregion) | ||
175 | { | ||
176 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
177 | struct nand_ecc_ctrl *ecc = &chip->ecc; | ||
178 | int ecc_offset = 0; | ||
179 | |||
180 | if (section < 0 || section > 1) | ||
181 | return -ERANGE; | ||
182 | |||
183 | switch (mtd->oobsize) { | ||
184 | case 64: | ||
185 | ecc_offset = 40; | ||
186 | break; | ||
187 | case 128: | ||
188 | ecc_offset = 80; | ||
189 | break; | ||
190 | default: | ||
191 | return -EINVAL; | ||
192 | } | ||
193 | |||
194 | if (section == 0) { | ||
195 | oobregion->offset = 2; | ||
196 | oobregion->length = ecc_offset - 2; | ||
197 | } else { | ||
198 | oobregion->offset = ecc_offset + ecc->total; | ||
199 | oobregion->length = mtd->oobsize - oobregion->offset; | ||
200 | } | ||
201 | |||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | const struct mtd_ooblayout_ops nand_ooblayout_lp_hamming_ops = { | ||
206 | .ecc = nand_ooblayout_ecc_lp_hamming, | ||
207 | .free = nand_ooblayout_free_lp_hamming, | ||
208 | }; | ||
209 | |||
142 | static int check_offs_len(struct mtd_info *mtd, | 210 | static int check_offs_len(struct mtd_info *mtd, |
143 | loff_t ofs, uint64_t len) | 211 | loff_t ofs, uint64_t len) |
144 | { | 212 | { |
@@ -4559,7 +4627,7 @@ int nand_scan_tail(struct mtd_info *mtd) | |||
4559 | break; | 4627 | break; |
4560 | case 64: | 4628 | case 64: |
4561 | case 128: | 4629 | case 128: |
4562 | mtd_set_ooblayout(mtd, &nand_ooblayout_lp_ops); | 4630 | mtd_set_ooblayout(mtd, &nand_ooblayout_lp_hamming_ops); |
4563 | break; | 4631 | break; |
4564 | default: | 4632 | default: |
4565 | WARN(1, "No oob scheme defined for oobsize %d\n", | 4633 | WARN(1, "No oob scheme defined for oobsize %d\n", |