|
@@ -139,6 +139,74 @@ const struct mtd_ooblayout_ops nand_ooblayout_lp_ops = {
|
|
|
};
|
|
|
EXPORT_SYMBOL_GPL(nand_ooblayout_lp_ops);
|
|
|
|
|
|
+/*
|
|
|
+ * Support the old "large page" layout used for 1-bit Hamming ECC where ECC
|
|
|
+ * are placed at a fixed offset.
|
|
|
+ */
|
|
|
+static int nand_ooblayout_ecc_lp_hamming(struct mtd_info *mtd, int section,
|
|
|
+ struct mtd_oob_region *oobregion)
|
|
|
+{
|
|
|
+ struct nand_chip *chip = mtd_to_nand(mtd);
|
|
|
+ struct nand_ecc_ctrl *ecc = &chip->ecc;
|
|
|
+
|
|
|
+ if (section)
|
|
|
+ return -ERANGE;
|
|
|
+
|
|
|
+ switch (mtd->oobsize) {
|
|
|
+ case 64:
|
|
|
+ oobregion->offset = 40;
|
|
|
+ break;
|
|
|
+ case 128:
|
|
|
+ oobregion->offset = 80;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ oobregion->length = ecc->total;
|
|
|
+ if (oobregion->offset + oobregion->length > mtd->oobsize)
|
|
|
+ return -ERANGE;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int nand_ooblayout_free_lp_hamming(struct mtd_info *mtd, int section,
|
|
|
+ struct mtd_oob_region *oobregion)
|
|
|
+{
|
|
|
+ struct nand_chip *chip = mtd_to_nand(mtd);
|
|
|
+ struct nand_ecc_ctrl *ecc = &chip->ecc;
|
|
|
+ int ecc_offset = 0;
|
|
|
+
|
|
|
+ if (section < 0 || section > 1)
|
|
|
+ return -ERANGE;
|
|
|
+
|
|
|
+ switch (mtd->oobsize) {
|
|
|
+ case 64:
|
|
|
+ ecc_offset = 40;
|
|
|
+ break;
|
|
|
+ case 128:
|
|
|
+ ecc_offset = 80;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (section == 0) {
|
|
|
+ oobregion->offset = 2;
|
|
|
+ oobregion->length = ecc_offset - 2;
|
|
|
+ } else {
|
|
|
+ oobregion->offset = ecc_offset + ecc->total;
|
|
|
+ oobregion->length = mtd->oobsize - oobregion->offset;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+const struct mtd_ooblayout_ops nand_ooblayout_lp_hamming_ops = {
|
|
|
+ .ecc = nand_ooblayout_ecc_lp_hamming,
|
|
|
+ .free = nand_ooblayout_free_lp_hamming,
|
|
|
+};
|
|
|
+
|
|
|
static int check_offs_len(struct mtd_info *mtd,
|
|
|
loff_t ofs, uint64_t len)
|
|
|
{
|
|
@@ -4559,7 +4627,7 @@ int nand_scan_tail(struct mtd_info *mtd)
|
|
|
break;
|
|
|
case 64:
|
|
|
case 128:
|
|
|
- mtd_set_ooblayout(mtd, &nand_ooblayout_lp_ops);
|
|
|
+ mtd_set_ooblayout(mtd, &nand_ooblayout_lp_hamming_ops);
|
|
|
break;
|
|
|
default:
|
|
|
WARN(1, "No oob scheme defined for oobsize %d\n",
|