diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2013-11-18 11:42:17 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2013-11-18 11:42:17 -0600 |
commit | 89b31345a9ba8e5621dfd1ddb9e9dffa7f9b8d0d (patch) | |
tree | a1447a538249044c92ae7de101b10cd9f40710cf | |
parent | 48f1dbe806ac71235d6be98f13c60354a1f623e6 (diff) | |
download | px4-nuttx-89b31345a9ba8e5621dfd1ddb9e9dffa7f9b8d0d.tar.gz px4-nuttx-89b31345a9ba8e5621dfd1ddb9e9dffa7f9b8d0d.tar.bz2 px4-nuttx-89b31345a9ba8e5621dfd1ddb9e9dffa7f9b8d0d.zip |
Finishes up NAND software ECC logic
-rw-r--r-- | nuttx/arch/arm/src/sama5/Kconfig | 88 | ||||
-rw-r--r-- | nuttx/arch/arm/src/sama5/sam_nand.c | 227 | ||||
-rw-r--r-- | nuttx/drivers/mtd/Kconfig | 14 | ||||
-rw-r--r-- | nuttx/drivers/mtd/hamming.c | 2 | ||||
-rwxr-xr-x | nuttx/drivers/mtd/mtd_nand.c | 4 | ||||
-rw-r--r-- | nuttx/drivers/mtd/mtd_nandecc.c | 125 | ||||
-rw-r--r-- | nuttx/include/nuttx/mtd/hamming.h | 40 | ||||
-rw-r--r-- | nuttx/include/nuttx/mtd/nand.h | 2 | ||||
-rw-r--r-- | nuttx/include/nuttx/mtd/nand_raw.h | 24 |
9 files changed, 500 insertions, 26 deletions
diff --git a/nuttx/arch/arm/src/sama5/Kconfig b/nuttx/arch/arm/src/sama5/Kconfig index 412586baf..d8f8c2d1b 100644 --- a/nuttx/arch/arm/src/sama5/Kconfig +++ b/nuttx/arch/arm/src/sama5/Kconfig @@ -3041,6 +3041,28 @@ config SAMA5_EBICS0_NAND select MTD_NAND endchoice # CS0 Memory Type + +if SAMA5_EBICS0_NAND && MTD_NAND_BLOCKCHECK && MTD_NAND_HWECC + config SAMA5_EBICS0_HWECC + bool "NAND H/W ECC support" + default n + ---help--- + Enable hardware assisted support for ECC calculations + +if SAMA5_EBICS0_HWECC +choice + prompt "H/W ECC method" + default SAMA5_EBICS0_PMECC + +config SAMA5_EBICS0_PMECC + bool "PMECC" + +config SAMA5_EBICS0_HSIAO + bool "HSIAO ECC" + +endchoice # H/W ECC method +endif # SAMA5_EBICS0_HWECC +endif # SAMA5_EBICS0_NAND && MTD_NAND_BLOCKCHECK && MTD_NAND_HWECC endif # SAMA5_EBICS0 config SAMA5_EBICS1 @@ -3092,6 +3114,28 @@ config SAMA5_EBICS1_NAND select MTD_NAND endchoice # CS1 Memory Type + +if SAMA5_EBICS1_NAND && MTD_NAND_BLOCKCHECK && MTD_NAND_HWECC + config SAMA5_EBICS1_HWECC + bool "NAND H/W ECC support" + default n + ---help--- + Enable hardware assisted support for ECC calculations + +if SAMA5_EBICS1_HWECC +choice + prompt "H/W ECC method" + default SAMA5_EBICS1_PMECC + +config SAMA5_EBICS1_PMECC + bool "PMECC" + +config SAMA5_EBICS1_HSIAO + bool "HSIAO ECC" + +endchoice # H/W ECC method +endif # SAMA5_EBICS1_HWECC +endif # SAMA5_EBICS1_NAND && MTD_NAND_BLOCKCHECK && MTD_NAND_HWECC endif # SAMA5_EBICS1 config SAMA5_EBICS2 @@ -3143,6 +3187,28 @@ config SAMA5_EBICS2_NAND select MTD_NAND endchoice # CS2 Memory Type + +if SAMA5_EBICS2_NAND && MTD_NAND_BLOCKCHECK && MTD_NAND_HWECC + config SAMA5_EBICS2_HWECC + bool "NAND H/W ECC support" + default n + ---help--- + Enable hardware assisted support for ECC calculations + +if SAMA5_EBICS2_HWECC +choice + prompt "H/W ECC method" + default SAMA5_EBICS2_PMECC + +config SAMA5_EBICS2_PMECC + bool "PMECC" + +config SAMA5_EBICS2_HSIAO + bool "HSIAO ECC" + +endchoice # H/W ECC method +endif # SAMA5_EBICS2_HWECC +endif # SAMA5_EBICS2_NAND && MTD_NAND_BLOCKCHECK && MTD_NAND_HWECC endif # SAMA5_EBICS2 config SAMA5_EBICS3 @@ -3194,6 +3260,28 @@ config SAMA5_EBICS3_NAND select MTD_NAND endchoice # CS3 Memory Type + +if SAMA5_EBICS3_NAND && MTD_NAND_BLOCKCHECK && MTD_NAND_HWECC + config SAMA5_EBICS3_HWECC + bool "NAND H/W ECC support" + default n + ---help--- + Enable hardware assisted support for ECC calculations + +if SAMA5_EBICS3_HWECC +choice + prompt "H/W ECC method" + default SAMA5_EBICS3_PMECC + +config SAMA5_EBICS3_PMECC + bool "PMECC" + +config SAMA5_EBICS3_HSIAO + bool "HSIAO ECC" + +endchoice # H/W ECC method +endif # SAMA5_EBICS3_HWECC +endif # SAMA5_EBICS3_NAND && MTD_NAND_BLOCKCHECK && MTD_NAND_HWECC endif # SAMA5_EBICS3 if SAMA5_EBICS0_NAND || SAMA5_EBICS1_NAND || SAMA5_EBICS2_NAND || SAMA5_EBICS3_NAND diff --git a/nuttx/arch/arm/src/sama5/sam_nand.c b/nuttx/arch/arm/src/sama5/sam_nand.c index 00e61767b..77c7c1cb8 100644 --- a/nuttx/arch/arm/src/sama5/sam_nand.c +++ b/nuttx/arch/arm/src/sama5/sam_nand.c @@ -88,6 +88,24 @@ struct sam_rawnand_s /**************************************************************************** * Private Function Prototypes ****************************************************************************/ +/* NAND Helpers */ + +static int nand_readpage_noecc(struct sam_rawnand_s *priv, off_t block, + unsigned int page, void *data, void *spare); +#ifdef CONFIG_MTD_NAND_BLOCKCHECK +static int nand_readpage_hwecc(struct sam_rawnand_s *priv, off_t block, + unsigned int page, void *data, void *spare); +static int nand_readpage_pmecc(struct sam_rawnand_s *priv, off_t block, + unsigned int page, void *data, void *spare); +#endif +static int nand_writepage_noecc(struct sam_rawnand_s *priv, off_t block, + unsigned int page, const void *data, const void *spare); +#ifdef CONFIG_MTD_NAND_BLOCKCHECK +static int nand_writepage_hwecc(struct sam_rawnand_s *priv, off_t block, + unsigned int page, const void *data, const void *spare); +static int nand_writepage_pmecc(struct sam_rawnand_s *priv, off_t block, + unsigned int page, const void *data, const void *spare); +#endif /* MTD driver methods */ @@ -122,6 +140,171 @@ static struct sam_rawnand_s g_cs3nand; ****************************************************************************/ /**************************************************************************** + * Name: nand_readpage_noecc + * + * Description: + * Reads the data and/or the spare areas of a page of a NAND FLASH into the + * provided buffers. The raw NAND contents are returned with no ECC + * corrections. + * + * Input parameters: + * priv - Lower-half, private NAND FLASH device state + * block - Number of the block where the page to read resides. + * page - Number of the page to read inside the given block. + * data - Buffer where the data area will be stored. + * spare - Buffer where the spare area will be stored. + * + * Returned value. + * OK is returned in succes; a negated errno value is returned on failure. + * + ****************************************************************************/ + +static int nand_readpage_noecc(struct sam_rawnand_s *priv, off_t block, + unsigned int page, void *data, void *spare) +{ +#warning Missing logic + return -ENOSYS; +} + +/**************************************************************************** + * Name: nand_readpage_hwecc + * + * Description: + * Reads the data and/or the spare areas of a page of a NAND FLASH into the + * provided buffers. HSIAO ECC is used + * + * Input parameters: + * priv - Lower-half, private NAND FLASH device state + * block - Number of the block where the page to read resides. + * page - Number of the page to read inside the given block. + * data - Buffer where the data area will be stored. + * spare - Buffer where the spare area will be stored. + * + * Returned value. + * OK is returned in succes; a negated errno value is returned on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_MTD_NAND_BLOCKCHECK +static int nand_readpage_hwecc(struct sam_rawnand_s *priv, off_t block, + unsigned int page, void *data, void *spare) +{ +#warning Missing logic + return -ENOSYS; +} +#endif /* CONFIG_MTD_NAND_BLOCKCHECK */ + +/**************************************************************************** + * Name: nand_readpage_pmecc + * + * Description: + * Reads the data and/or the spare areas of a page of a NAND FLASH into the + * provided buffers. PMECC is used + * + * Input parameters: + * priv - Lower-half, private NAND FLASH device state + * block - Number of the block where the page to read resides. + * page - Number of the page to read inside the given block. + * data - Buffer where the data area will be stored. + * spare - Buffer where the spare area will be stored. + * + * Returned value. + * OK is returned in succes; a negated errno value is returned on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_MTD_NAND_BLOCKCHECK +static int nand_readpage_pmecc(struct sam_rawnand_s *priv, off_t block, + unsigned int page, void *data, void *spare) +{ +#warning Missing logic + return -ENOSYS; +} +#endif /* CONFIG_MTD_NAND_BLOCKCHECK */ + +/**************************************************************************** + * Name: nand_writepage_noecc + * + * Description: + * Writes the data and/or the spare area of a page on a NAND FLASH chip. + * No ECC calculations are performed. + * + * Input parameters: + * priv - Lower-half, private NAND FLASH device state + * block - Number of the block where the page to write resides. + * page - Number of the page to write inside the given block. + * data - Buffer containing the data to be writting + * spare - Buffer conatining the spare data to be written. + * + * Returned value. + * OK is returned in succes; a negated errno value is returned on failure. + * + ****************************************************************************/ + +static int nand_writepage_noecc(struct sam_rawnand_s *priv, off_t block, + unsigned int page, const void *data, const void *spare) +{ +#warning Missing logic + return -ENOSYS; +} + +/**************************************************************************** + * Name: nand_writepage_noecc + * + * Description: + * Writes the data and/or the spare area of a page on a NAND FLASH chip. + * HSIAO ECC calculations are performed. + * + * Input parameters: + * priv - Lower-half, private NAND FLASH device state + * block - Number of the block where the page to write resides. + * page - Number of the page to write inside the given block. + * data - Buffer containing the data to be writting + * spare - Buffer conatining the spare data to be written. + * + * Returned value. + * OK is returned in succes; a negated errno value is returned on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_MTD_NAND_BLOCKCHECK +static int nand_writepage_hwecc(struct sam_rawnand_s *priv, off_t block, + unsigned int page, const void *data, const void *spare) +{ +#warning Missing logic + return -ENOSYS; +} +#endif /* CONFIG_MTD_NAND_BLOCKCHECK */ + +/**************************************************************************** + * Name: nand_writepage_noecc + * + * Description: + * Writes the data and/or the spare area of a page on a NAND FLASH chip. + * PMECC calculations are performed. + * + * Input parameters: + * priv - Lower-half, private NAND FLASH device state + * block - Number of the block where the page to write resides. + * page - Number of the page to write inside the given block. + * data - Buffer containing the data to be writting + * spare - Buffer conatining the spare data to be written. + * + * Returned value. + * OK is returned in succes; a negated errno value is returned on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_MTD_NAND_BLOCKCHECK +static int nand_writepage_pmecc(struct sam_rawnand_s *priv, off_t block, + unsigned int page, const void *data, const void *spare) +{ +#warning Missing logic + return -ENOSYS; +} +#endif /* CONFIG_MTD_NAND_BLOCKCHECK */ + +/**************************************************************************** * Name: nand_eraseblock * * Description: @@ -168,8 +351,25 @@ static int nand_readpage(struct nand_raw_s *raw, off_t block, { struct sam_rawnand_s *priv = (struct sam_rawnand_s *)raw; DEBUGASSERT(raw); -#warning Missing logic - return -ENOSYS; + +#ifndef CONFIG_MTD_NAND_BLOCKCHECK + return nand_readpage_noecc(priv, block, page, data, spare); +#else + DEBUGASSERT(raw->ecctype != NANDECC_SWECC); + switch (raw->ecctype) + { + case NANDECC_NONE: + return nand_readpage_noecc(priv, block, page, data, spare); + case NANDECC_HWECC: + return nand_readpage_hwecc(priv, block, page, data, spare); + case NANDECC_PMECC: + return nand_readpage_pmecc(priv, block, page, data, spare); + + case NANDECC_SWECC: + default: + return -EINVAL; + } +#endif } /**************************************************************************** @@ -196,8 +396,25 @@ static int nand_writepage(struct nand_raw_s *raw, off_t block, { struct sam_rawnand_s *priv = (struct sam_rawnand_s *)raw; DEBUGASSERT(raw); -#warning Missing logic - return -ENOSYS; + +#ifndef CONFIG_MTD_NAND_BLOCKCHECK + return nand_writepage_noecc(priv, block, page, data, spare); +#else + DEBUGASSERT(raw->ecctype != NANDECC_SWECC); + switch (raw->ecctype) + { + case NANDECC_NONE: + return nand_writepage_noecc(priv, block, page, data, spare); + case NANDECC_HWECC: + return nand_writepage_hwecc(priv, block, page, data, spare); + case NANDECC_PMECC: + return nand_writepage_pmecc(priv, block, page, data, spare); + + case NANDECC_SWECC: + default: + return -EINVAL; + } +#endif } /**************************************************************************** @@ -226,7 +443,7 @@ static int nand_writepage(struct nand_raw_s *raw, off_t block, struct mtd_dev_s *sam_nand_initialize(int cs) { struct sam_rawnand_s *priv; - struct mtd_s *mtd; + struct mtd_dev_s *mtd; uintptr_t cmdaddr; uintptr_t addraddr; uintptr_t dataaddr; diff --git a/nuttx/drivers/mtd/Kconfig b/nuttx/drivers/mtd/Kconfig index adcb204fc..62d147cb3 100644 --- a/nuttx/drivers/mtd/Kconfig +++ b/nuttx/drivers/mtd/Kconfig @@ -139,12 +139,6 @@ config MTD_NAND_HWECC ---help--- Build in logic to support hardware calculation of ECC. -config MTD_NAND_MAXSPAREEXTRABYTES - int "Max extra free bytes" - default 206 - ---help--- - Maximum number of extra free bytes inside the spare area of a page. - config MTD_NAND_MAX_HWECCSIZE int "Max H/W ECC size" default 200 @@ -152,6 +146,14 @@ config MTD_NAND_MAX_HWECCSIZE ---help--- Maximum HW ECC size +config MTD_NAND_MAXSPAREEXTRABYTES + int "Max extra free bytes" + default 206 + ---help--- + Maximum number of extra free bytes inside the spare area of a page. + +endif # MTD_NAND_BLOCKCHECK + config MTD_NAND_EMBEDDEDECC bool "Support devices with Embedded ECC" default n diff --git a/nuttx/drivers/mtd/hamming.c b/nuttx/drivers/mtd/hamming.c index 31bd8a3e5..49e6a2626 100644 --- a/nuttx/drivers/mtd/hamming.c +++ b/nuttx/drivers/mtd/hamming.c @@ -407,7 +407,7 @@ void hamming_compute256x(FAR const uint8_t *data, size_t size, uint8_t *code) * ****************************************************************************/ -int hamming_verify256x(uint8_t *data, size_t size, const uint8_t *code) +int hamming_verify256x(FAR uint8_t *data, size_t size, FAR const uint8_t *code) { ssize_t remaining = (ssize_t)size; int result = HAMMING_SUCCESS; diff --git a/nuttx/drivers/mtd/mtd_nand.c b/nuttx/drivers/mtd/mtd_nand.c index 9f5e06ec5..97fcbf894 100755 --- a/nuttx/drivers/mtd/mtd_nand.c +++ b/nuttx/drivers/mtd/mtd_nand.c @@ -432,7 +432,7 @@ static int nand_readpage(FAR struct nand_dev_s *nand, off_t block, /* nandecc_readpage will handle the software ECC case */ DEBUGASSERT(nand && nand->raw); - if (nand->raw->ecc == NANDECC_SWECC) + if (nand->raw->ecctype == NANDECC_SWECC) { /* Read data with software ECC verification */ @@ -485,7 +485,7 @@ static int nand_writepage(FAR struct nand_dev_s *nand, off_t block, /* nandecc_writepage will handle the software ECC case */ DEBUGASSERT(nand && nand->raw); - if (nand->raw->ecc == NANDECC_SWECC) + if (nand->raw->ecctype == NANDECC_SWECC) { /* Write data with software ECC calculation */ diff --git a/nuttx/drivers/mtd/mtd_nandecc.c b/nuttx/drivers/mtd/mtd_nandecc.c index 324723903..d1796b0ee 100644 --- a/nuttx/drivers/mtd/mtd_nandecc.c +++ b/nuttx/drivers/mtd/mtd_nandecc.c @@ -48,10 +48,14 @@ #include <sys/types.h> #include <stdint.h> +#include <string.h> #include <errno.h> +#include <assert.h> #include <debug.h> #include <nuttx/mtd/nand.h> +#include <nuttx/mtd/hamming.h> +#include <nuttx/mtd/nand_scheme.h> #include <nuttx/mtd/nand_ecc.h> /**************************************************************************** @@ -86,8 +90,68 @@ int nandecc_readpage(FAR struct nand_dev_s *nand, off_t block, unsigned int page, FAR void *data, FAR void *spare) { -#warning Missing logic - return -ENOSYS; + FAR struct nand_raw_s *raw; + FAR struct nand_model_s *model; + FAR const struct nand_scheme_s *scheme; + unsigned int pagesize; + unsigned int sparesize; + int ret; + + /* Get convenience pointers */ + + DEBUGASSERT(nand && nand->raw); + raw = nand->raw; + model = &raw->model; + + /* Get size parameters */ + + pagesize = nandmodel_getpagesize(model); + sparesize = nandmodel_getsparesize(model); + + /* Store code in spare buffer, either the buffer provided by the caller or + * the scatch buffer in the raw NAND structure. + */ + + if (!spare) + { + spare = raw->spare; + memset(spare, 0xff, sparesize); + } + + /* Start by reading the spare data */ + + ret = NAND_READPAGE(raw, block, page, 0, spare); + if (ret < 0) + { + fdbg("ERROR: Failed to read page:d\n", ret); + return ret; + } + + /* Then reading the data */ + + ret = NAND_READPAGE(nand->raw, block, page, data, 0); + if (ret < 0) + { + fdbg("ERROR: Failed to read page:d\n", ret); + return ret; + } + + /* Retrieve ECC information from page */ + + scheme = nandmodel_getscheme(model); + nandscheme_readecc(scheme, spare, raw->ecc); + + /* Use the ECC data to verify the page */ + + ret = hamming_verify256x(data, pagesize, raw->ecc); + if (ret && (ret != HAMMING_ERROR_SINGLEBIT)) + { + fdbg("ERROR: Blockd paged Unrecoverable error:d\n", + block, page, ret); + return -EIO; + } + + return OK; } /**************************************************************************** @@ -116,6 +180,59 @@ int nandecc_writepage(FAR struct nand_dev_s *nand, off_t block, unsigned int page, FAR const void *data, FAR void *spare) { -#warning Missing logic - return -ENOSYS; + FAR struct nand_raw_s *raw; + FAR struct nand_model_s *model; + FAR const struct nand_scheme_s *scheme; + unsigned int pagesize; + unsigned int sparesize; + int ret; + + /* Get convenience pointers */ + + DEBUGASSERT(nand && nand->raw); + raw = nand->raw; + model = &raw->model; + + /* Get size parameters */ + + pagesize = nandmodel_getpagesize(model); + sparesize = nandmodel_getsparesize(model); + + /* Set hamming code set to 0xffff.. to keep existing bytes */ + + memset(raw->ecc, 0xff, CONFIG_MTD_NAND_MAXSPAREECCBYTES); + + /* Compute ECC on the new data, if provided */ + + if (data) + { + /* Compute hamming code on data */ + + hamming_compute256x(data, pagesize, raw->ecc); + } + + /* Store code in spare buffer, either the buffer provided by the caller or + * the scatch buffer in the raw NAND structure. + */ + + if (!spare) + { + spare = raw->spare; + memset(spare, 0xff, sparesize); + } + + /* Write the ECC */ + + scheme = nandmodel_getscheme(model); + nandscheme_writeecc(scheme, spare, raw->ecc); + + /* Perform page write operation */ + + ret = NAND_WRITEPAGE(nand->raw, block, page, data, spare); + if (ret < 0) + { + fdbg("ERROR: Failed to write page:d\n", ret); + } + + return ret; } diff --git a/nuttx/include/nuttx/mtd/hamming.h b/nuttx/include/nuttx/mtd/hamming.h index b7b25033a..17184c356 100644 --- a/nuttx/include/nuttx/mtd/hamming.h +++ b/nuttx/include/nuttx/mtd/hamming.h @@ -96,6 +96,46 @@ extern "C" * Public Function Prototypes ****************************************************************************/ +/**************************************************************************** + * Name: hamming_compute256x + * + * Description: + * Computes 3-bytes hamming codes for a data block whose size is multiple + * of 256 bytes. Each 256 bytes block gets its own code. + * + * Input Parameters: + * data - Data to compute code for + * size - Data size in bytes + * code - Codes buffer + * + * Returned Values: + * None + * + ****************************************************************************/ + +void hamming_compute256x(FAR const uint8_t *data, size_t size, uint8_t *code); + +/**************************************************************************** + * Name: hamming_verify256x + * + * Description: + * Verifies 3-bytes hamming codes for a data block whose size is multiple + * of 256 bytes. Each 256-bytes block is verified with its own code. + * + * Input Parameters: + * data - Data buffer to verify + * size - Size of the data in bytes + * code - Original codes + * + * Returned Values: + * Return 0 if the data is correct, HAMMING_ERROR_SINGLEBIT if one or more + * block(s) have had a single bit corrected, or either HAMMING_ERROR_ECC + * or HAMMING_ERROR_MULTIPLEBITS. + * + ****************************************************************************/ + +int hamming_verify256x(FAR uint8_t *data, size_t size, FAR const uint8_t *code); + #undef EXTERN #ifdef __cplusplus } diff --git a/nuttx/include/nuttx/mtd/nand.h b/nuttx/include/nuttx/mtd/nand.h index 0854b34bb..21cd73f88 100644 --- a/nuttx/include/nuttx/mtd/nand.h +++ b/nuttx/include/nuttx/mtd/nand.h @@ -72,7 +72,7 @@ struct nand_dev_s { struct mtd_dev_s mtd; /* Externally visible part of the driver */ FAR struct nand_raw_s *raw; /* Retained reference to the lower half */ - sem_t exclsem; /* For exclusive access to the NAND flas */ + sem_t exclsem; /* For exclusive access to the NAND FLASH */ }; /**************************************************************************** diff --git a/nuttx/include/nuttx/mtd/nand_raw.h b/nuttx/include/nuttx/mtd/nand_raw.h index c30a99e1f..0c828dc77 100644 --- a/nuttx/include/nuttx/mtd/nand_raw.h +++ b/nuttx/include/nuttx/mtd/nand_raw.h @@ -47,6 +47,7 @@ ****************************************************************************/ #include <nuttx/config.h> +#include <nuttx/mtd/nand_config.h> #include <stdint.h> #include <stdbool.h> @@ -81,13 +82,19 @@ #define COMMAND_READ_A 0x00 #define COMMAND_READ_C 0x50 -/* Type of ECC to be performed (must be enabled in the configuration) +/* Type of ECC to be performed (may also need to be enabled in the + * configuration) + * * NANDECC_NONE No ECC, only raw NAND FLASH accesses * NANDECC_SWECC Software ECC. Handled by the common MTD logic. * NANDECC_HWECC Values >= 2 are various hardware ECC implementations * all handled by the lower-half, raw NAND FLASH driver. * These hardware ECC types may be extended beginning * with the value NANDECC_HWECC. + * + * Software ECC is performed by common, upper-half MTD logic; All + * hardware assisted ECC operations are handled by the platform-specific, + * lower-half driver. */ #define NANDECC_NONE 0 @@ -191,12 +198,6 @@ struct nand_raw_s uintptr_t addraddr; /* NAND address address base */ uintptr_t dataaddr; /* NAND data address */ -#ifdef CONFIG_MTD_NAND_BLOCKCHECK - /* ECC */ - - uint8_t ecc; /* See enum nand_ecc_e */ -#endif - /* NAND operations */ CODE int (*eraseblock)(FAR struct nand_raw_s *raw, off_t block); @@ -205,6 +206,15 @@ struct nand_raw_s CODE int (*writepage)(FAR struct nand_raw_s *raw, off_t block, unsigned int page, FAR const void *data, FAR const void *spare); + +#ifdef CONFIG_MTD_NAND_BLOCKCHECK + /* ECC */ + + uint8_t ecctype; /* See enum nand_ecc_e */ + uint8_t spare[CONFIG_MTD_NAND_MAXPAGESPARESIZE]; + uint8_t ecc[CONFIG_MTD_NAND_MAXSPAREECCBYTES]; + +#endif }; /**************************************************************************** |