summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2013-11-15 23:48:51 +0000
committerian <ian@FreeBSD.org>2013-11-15 23:48:51 +0000
commitef361f73c1648dd7337c2ee0019bf6b0d4aba44d (patch)
tree18705b2edd3568513bc4eda1573bc5c82b4a59b9
parent97c1344519cc2c161a24aa04d9a22746086f8957 (diff)
downloadFreeBSD-src-ef361f73c1648dd7337c2ee0019bf6b0d4aba44d.zip
FreeBSD-src-ef361f73c1648dd7337c2ee0019bf6b0d4aba44d.tar.gz
Rework the routine that returns a pointer to the table of software ECC
byte positions within the OOB area to support chips with unusual OOB sizes such as 218 or 224 bytes. The table for 128 byte OOB works for these but it assumes 3 bytes of ECC per 256 byte block, and in the case of an ONFI chip the params page may ask for something different. In other words, this is better but not yet perfect.
-rw-r--r--sys/dev/nand/nand.c33
1 files changed, 16 insertions, 17 deletions
diff --git a/sys/dev/nand/nand.c b/sys/dev/nand/nand.c
index 902ff79..fb83e67 100644
--- a/sys/dev/nand/nand.c
+++ b/sys/dev/nand/nand.c
@@ -309,23 +309,22 @@ nand_get_chip_param(struct nand_chip *chip, struct chip_param_io *param)
static uint16_t *
default_software_ecc_positions(struct nand_chip *chip)
{
- struct nand_ecc_data *eccd;
-
- eccd = &chip->nand->ecc;
-
- if (eccd->eccpositions)
- return (eccd->eccpositions);
-
- switch (chip->chip_geom.oob_size) {
- case 16:
- return ((uint16_t *)&default_software_ecc_positions_16);
- case 64:
- return ((uint16_t *)&default_software_ecc_positions_64);
- case 128:
- return ((uint16_t *)&default_software_ecc_positions_128);
- default:
- return (NULL); /* No ecc bytes positions defs available */
- }
+ /* If positions have been set already, use them. */
+ if (chip->nand->ecc.eccpositions)
+ return (chip->nand->ecc.eccpositions);
+
+ /*
+ * XXX Note that the following logic isn't really sufficient, especially
+ * in the ONFI case where the number of ECC bytes can be dictated by
+ * values in the parameters page, and that could lead to needing more
+ * byte positions than exist within the tables of software-ecc defaults.
+ */
+ if (chip->chip_geom.oob_size >= 128)
+ return (default_software_ecc_positions_128);
+ if (chip->chip_geom.oob_size >= 64)
+ return (default_software_ecc_positions_64);
+ else if (chip->chip_geom.oob_size >= 16)
+ return (default_software_ecc_positions_16);
return (NULL);
}
OpenPOWER on IntegriCloud