mtd: nand: ecc-hamming: Rename the exported functions
Prefix by ecc_sw_hamming_ the functions which should be internal only but are exported for "raw" operations. Prefix by nand_ecc_sw_hamming_ the other functions which will be used in the context of the declaration of an Hamming proper ECC engine object. Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Link: https://lore.kernel.org/linux-mtd/20200929230124.31491-16-miquel.raynal@bootlin.com
This commit is contained in:
parent
b551fa3059
commit
90ccf0a019
13 changed files with 115 additions and 99 deletions
|
@ -75,7 +75,7 @@ static const char bitsperbyte[256] = {
|
||||||
* addressbits is a lookup table to filter out the bits from the xor-ed
|
* addressbits is a lookup table to filter out the bits from the xor-ed
|
||||||
* ECC data that identify the faulty location.
|
* ECC data that identify the faulty location.
|
||||||
* this is only used for repairing parity
|
* this is only used for repairing parity
|
||||||
* see the comments in nand_correct_data for more details
|
* see the comments in nand_ecc_sw_hamming_correct for more details
|
||||||
*/
|
*/
|
||||||
static const char addressbits[256] = {
|
static const char addressbits[256] = {
|
||||||
0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
|
0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
|
||||||
|
@ -112,11 +112,11 @@ static const char addressbits[256] = {
|
||||||
0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f
|
0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f
|
||||||
};
|
};
|
||||||
|
|
||||||
void __nand_calculate_ecc(const unsigned char *buf, unsigned int eccsize,
|
int ecc_sw_hamming_calculate(const unsigned char *buf, unsigned int step_size,
|
||||||
unsigned char *code, bool sm_order)
|
unsigned char *code, bool sm_order)
|
||||||
{
|
{
|
||||||
const u32 *bp = (uint32_t *)buf;
|
const u32 *bp = (uint32_t *)buf;
|
||||||
const u32 eccsize_mult = eccsize >> 8;
|
const u32 eccsize_mult = step_size >> 8;
|
||||||
/* current value in buffer */
|
/* current value in buffer */
|
||||||
u32 cur;
|
u32 cur;
|
||||||
/* rp0..rp17 are the various accumulated parities (per byte) */
|
/* rp0..rp17 are the various accumulated parities (per byte) */
|
||||||
|
@ -347,31 +347,32 @@ void __nand_calculate_ecc(const unsigned char *buf, unsigned int eccsize,
|
||||||
(invparity[par & 0x55] << 2) |
|
(invparity[par & 0x55] << 2) |
|
||||||
(invparity[rp17] << 1) |
|
(invparity[rp17] << 1) |
|
||||||
(invparity[rp16] << 0);
|
(invparity[rp16] << 0);
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(__nand_calculate_ecc);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* nand_calculate_ecc - Calculate 3-byte ECC for 256/512-byte block
|
|
||||||
* @chip: NAND chip object
|
|
||||||
* @buf: Input buffer with raw data
|
|
||||||
* @code: Output buffer with ECC
|
|
||||||
*/
|
|
||||||
int nand_calculate_ecc(struct nand_chip *chip, const unsigned char *buf,
|
|
||||||
unsigned char *code)
|
|
||||||
{
|
|
||||||
bool sm_order = chip->ecc.options & NAND_ECC_SOFT_HAMMING_SM_ORDER;
|
|
||||||
|
|
||||||
__nand_calculate_ecc(buf, chip->ecc.size, code, sm_order);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(nand_calculate_ecc);
|
EXPORT_SYMBOL(ecc_sw_hamming_calculate);
|
||||||
|
|
||||||
int __nand_correct_data(unsigned char *buf,
|
/**
|
||||||
unsigned char *read_ecc, unsigned char *calc_ecc,
|
* nand_ecc_sw_hamming_calculate - Calculate 3-byte ECC for 256/512-byte block
|
||||||
unsigned int eccsize, bool sm_order)
|
* @nand: NAND device
|
||||||
|
* @buf: Input buffer with raw data
|
||||||
|
* @code: Output buffer with ECC
|
||||||
|
*/
|
||||||
|
int nand_ecc_sw_hamming_calculate(struct nand_device *nand,
|
||||||
|
const unsigned char *buf, unsigned char *code)
|
||||||
{
|
{
|
||||||
const u32 eccsize_mult = eccsize >> 8;
|
struct nand_chip *chip = mtd_to_nand(nanddev_to_mtd(nand));
|
||||||
|
bool sm_order = chip->ecc.options & NAND_ECC_SOFT_HAMMING_SM_ORDER;
|
||||||
|
|
||||||
|
return ecc_sw_hamming_calculate(buf, chip->ecc.size, code, sm_order);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(nand_ecc_sw_hamming_calculate);
|
||||||
|
|
||||||
|
int ecc_sw_hamming_correct(unsigned char *buf, unsigned char *read_ecc,
|
||||||
|
unsigned char *calc_ecc, unsigned int step_size,
|
||||||
|
bool sm_order)
|
||||||
|
{
|
||||||
|
const u32 eccsize_mult = step_size >> 8;
|
||||||
unsigned char b0, b1, b2, bit_addr;
|
unsigned char b0, b1, b2, bit_addr;
|
||||||
unsigned int byte_addr;
|
unsigned int byte_addr;
|
||||||
|
|
||||||
|
@ -437,26 +438,28 @@ int __nand_correct_data(unsigned char *buf,
|
||||||
pr_err("%s: uncorrectable ECC error\n", __func__);
|
pr_err("%s: uncorrectable ECC error\n", __func__);
|
||||||
return -EBADMSG;
|
return -EBADMSG;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(__nand_correct_data);
|
EXPORT_SYMBOL(ecc_sw_hamming_correct);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nand_correct_data - Detect and correct bit error(s)
|
* nand_ecc_sw_hamming_correct - Detect and correct bit error(s)
|
||||||
* @chip: NAND chip object
|
* @nand: NAND device
|
||||||
* @buf: Raw data read from the chip
|
* @buf: Raw data read from the chip
|
||||||
* @read_ecc: ECC bytes read from the chip
|
* @read_ecc: ECC bytes read from the chip
|
||||||
* @calc_ecc: ECC calculated from the raw data
|
* @calc_ecc: ECC calculated from the raw data
|
||||||
*
|
*
|
||||||
* Detect and correct up to 1 bit error per 256/512-byte block.
|
* Detect and correct up to 1 bit error per 256/512-byte block.
|
||||||
*/
|
*/
|
||||||
int nand_correct_data(struct nand_chip *chip, unsigned char *buf,
|
int nand_ecc_sw_hamming_correct(struct nand_device *nand, unsigned char *buf,
|
||||||
unsigned char *read_ecc, unsigned char *calc_ecc)
|
unsigned char *read_ecc,
|
||||||
|
unsigned char *calc_ecc)
|
||||||
{
|
{
|
||||||
|
struct nand_chip *chip = mtd_to_nand(nanddev_to_mtd(nand));
|
||||||
bool sm_order = chip->ecc.options & NAND_ECC_SOFT_HAMMING_SM_ORDER;
|
bool sm_order = chip->ecc.options & NAND_ECC_SOFT_HAMMING_SM_ORDER;
|
||||||
|
|
||||||
return __nand_correct_data(buf, read_ecc, calc_ecc, chip->ecc.size,
|
return ecc_sw_hamming_correct(buf, read_ecc, calc_ecc, chip->ecc.size,
|
||||||
sm_order);
|
sm_order);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(nand_correct_data);
|
EXPORT_SYMBOL(nand_ecc_sw_hamming_correct);
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_AUTHOR("Frans Meulenbroeks <fransmeulenbroeks@gmail.com>");
|
MODULE_AUTHOR("Frans Meulenbroeks <fransmeulenbroeks@gmail.com>");
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/mtd/mtd.h>
|
#include <linux/mtd/mtd.h>
|
||||||
#include <linux/mtd/rawnand.h>
|
#include <linux/mtd/rawnand.h>
|
||||||
#include <linux/mtd/nand-ecc-sw-hamming.h>
|
|
||||||
#include <linux/mtd/partitions.h>
|
#include <linux/mtd/partitions.h>
|
||||||
#include <linux/iopoll.h>
|
#include <linux/iopoll.h>
|
||||||
|
|
||||||
|
@ -252,7 +251,7 @@ static int cs553x_attach_chip(struct nand_chip *chip)
|
||||||
chip->ecc.bytes = 3;
|
chip->ecc.bytes = 3;
|
||||||
chip->ecc.hwctl = cs_enable_hwecc;
|
chip->ecc.hwctl = cs_enable_hwecc;
|
||||||
chip->ecc.calculate = cs_calculate_ecc;
|
chip->ecc.calculate = cs_calculate_ecc;
|
||||||
chip->ecc.correct = nand_correct_data;
|
chip->ecc.correct = rawnand_sw_hamming_correct;
|
||||||
chip->ecc.strength = 1;
|
chip->ecc.strength = 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -918,7 +918,7 @@ static int fsmc_nand_attach_chip(struct nand_chip *nand)
|
||||||
case NAND_ECC_ENGINE_TYPE_ON_HOST:
|
case NAND_ECC_ENGINE_TYPE_ON_HOST:
|
||||||
dev_info(host->dev, "Using 1-bit HW ECC scheme\n");
|
dev_info(host->dev, "Using 1-bit HW ECC scheme\n");
|
||||||
nand->ecc.calculate = fsmc_read_hwecc_ecc1;
|
nand->ecc.calculate = fsmc_read_hwecc_ecc1;
|
||||||
nand->ecc.correct = nand_correct_data;
|
nand->ecc.correct = rawnand_sw_hamming_correct;
|
||||||
nand->ecc.hwctl = fsmc_enable_hwecc;
|
nand->ecc.hwctl = fsmc_enable_hwecc;
|
||||||
nand->ecc.bytes = 3;
|
nand->ecc.bytes = 3;
|
||||||
nand->ecc.strength = 1;
|
nand->ecc.strength = 1;
|
||||||
|
|
|
@ -803,7 +803,7 @@ static int lpc32xx_nand_attach_chip(struct nand_chip *chip)
|
||||||
chip->ecc.write_oob = lpc32xx_nand_write_oob_syndrome;
|
chip->ecc.write_oob = lpc32xx_nand_write_oob_syndrome;
|
||||||
chip->ecc.read_oob = lpc32xx_nand_read_oob_syndrome;
|
chip->ecc.read_oob = lpc32xx_nand_read_oob_syndrome;
|
||||||
chip->ecc.calculate = lpc32xx_nand_ecc_calculate;
|
chip->ecc.calculate = lpc32xx_nand_ecc_calculate;
|
||||||
chip->ecc.correct = nand_correct_data;
|
chip->ecc.correct = rawnand_sw_hamming_correct;
|
||||||
chip->ecc.hwctl = lpc32xx_nand_ecc_enable;
|
chip->ecc.hwctl = lpc32xx_nand_ecc_enable;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -5139,6 +5139,27 @@ static void nand_scan_ident_cleanup(struct nand_chip *chip)
|
||||||
kfree(chip->parameters.onfi);
|
kfree(chip->parameters.onfi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rawnand_sw_hamming_calculate(struct nand_chip *chip,
|
||||||
|
const unsigned char *buf,
|
||||||
|
unsigned char *code)
|
||||||
|
{
|
||||||
|
struct nand_device *base = &chip->base;
|
||||||
|
|
||||||
|
return nand_ecc_sw_hamming_calculate(base, buf, code);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(rawnand_sw_hamming_calculate);
|
||||||
|
|
||||||
|
int rawnand_sw_hamming_correct(struct nand_chip *chip,
|
||||||
|
unsigned char *buf,
|
||||||
|
unsigned char *read_ecc,
|
||||||
|
unsigned char *calc_ecc)
|
||||||
|
{
|
||||||
|
struct nand_device *base = &chip->base;
|
||||||
|
|
||||||
|
return nand_ecc_sw_hamming_correct(base, buf, read_ecc, calc_ecc);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(rawnand_sw_hamming_correct);
|
||||||
|
|
||||||
int rawnand_sw_bch_init(struct nand_chip *chip)
|
int rawnand_sw_bch_init(struct nand_chip *chip)
|
||||||
{
|
{
|
||||||
struct nand_device *base = &chip->base;
|
struct nand_device *base = &chip->base;
|
||||||
|
@ -5263,8 +5284,8 @@ static int nand_set_ecc_soft_ops(struct nand_chip *chip)
|
||||||
|
|
||||||
switch (ecc->algo) {
|
switch (ecc->algo) {
|
||||||
case NAND_ECC_ALGO_HAMMING:
|
case NAND_ECC_ALGO_HAMMING:
|
||||||
ecc->calculate = nand_calculate_ecc;
|
ecc->calculate = rawnand_sw_hamming_calculate;
|
||||||
ecc->correct = nand_correct_data;
|
ecc->correct = rawnand_sw_hamming_correct;
|
||||||
ecc->read_page = nand_read_page_swecc;
|
ecc->read_page = nand_read_page_swecc;
|
||||||
ecc->read_subpage = nand_read_subpage;
|
ecc->read_subpage = nand_read_subpage;
|
||||||
ecc->write_page = nand_write_page_swecc;
|
ecc->write_page = nand_write_page_swecc;
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
*/
|
*/
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/mtd/rawnand.h>
|
#include <linux/mtd/rawnand.h>
|
||||||
#include <linux/mtd/nand-ecc-sw-hamming.h>
|
|
||||||
#include <linux/mtd/partitions.h>
|
#include <linux/mtd/partitions.h>
|
||||||
#include <linux/mtd/ndfc.h>
|
#include <linux/mtd/ndfc.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
@ -146,7 +145,7 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc,
|
||||||
chip->controller = &ndfc->ndfc_control;
|
chip->controller = &ndfc->ndfc_control;
|
||||||
chip->legacy.read_buf = ndfc_read_buf;
|
chip->legacy.read_buf = ndfc_read_buf;
|
||||||
chip->legacy.write_buf = ndfc_write_buf;
|
chip->legacy.write_buf = ndfc_write_buf;
|
||||||
chip->ecc.correct = nand_correct_data;
|
chip->ecc.correct = rawnand_sw_hamming_correct;
|
||||||
chip->ecc.hwctl = ndfc_enable_hwecc;
|
chip->ecc.hwctl = ndfc_enable_hwecc;
|
||||||
chip->ecc.calculate = ndfc_calculate_ecc;
|
chip->ecc.calculate = ndfc_calculate_ecc;
|
||||||
chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
|
chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
|
||||||
|
|
|
@ -107,7 +107,7 @@ static int sharpsl_attach_chip(struct nand_chip *chip)
|
||||||
chip->ecc.strength = 1;
|
chip->ecc.strength = 1;
|
||||||
chip->ecc.hwctl = sharpsl_nand_enable_hwecc;
|
chip->ecc.hwctl = sharpsl_nand_enable_hwecc;
|
||||||
chip->ecc.calculate = sharpsl_nand_calculate_ecc;
|
chip->ecc.calculate = sharpsl_nand_calculate_ecc;
|
||||||
chip->ecc.correct = nand_correct_data;
|
chip->ecc.correct = rawnand_sw_hamming_correct;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -293,11 +293,11 @@ static int tmio_nand_correct_data(struct nand_chip *chip, unsigned char *buf,
|
||||||
int r0, r1;
|
int r0, r1;
|
||||||
|
|
||||||
/* assume ecc.size = 512 and ecc.bytes = 6 */
|
/* assume ecc.size = 512 and ecc.bytes = 6 */
|
||||||
r0 = __nand_correct_data(buf, read_ecc, calc_ecc, 256, false);
|
r0 = rawnand_sw_hamming_correct(chip, buf, read_ecc, calc_ecc);
|
||||||
if (r0 < 0)
|
if (r0 < 0)
|
||||||
return r0;
|
return r0;
|
||||||
r1 = __nand_correct_data(buf + 256, read_ecc + 3, calc_ecc + 3, 256,
|
r1 = rawnand_sw_hamming_correct(chip, buf + 256, read_ecc + 3,
|
||||||
false);
|
calc_ecc + 3);
|
||||||
if (r1 < 0)
|
if (r1 < 0)
|
||||||
return r1;
|
return r1;
|
||||||
return r0 + r1;
|
return r0 + r1;
|
||||||
|
|
|
@ -194,8 +194,8 @@ static int txx9ndfmc_correct_data(struct nand_chip *chip, unsigned char *buf,
|
||||||
int stat;
|
int stat;
|
||||||
|
|
||||||
for (eccsize = chip->ecc.size; eccsize > 0; eccsize -= 256) {
|
for (eccsize = chip->ecc.size; eccsize > 0; eccsize -= 256) {
|
||||||
stat = __nand_correct_data(buf, read_ecc, calc_ecc, 256,
|
stat = rawnand_sw_hamming_correct(chip, buf, read_ecc,
|
||||||
false);
|
calc_ecc);
|
||||||
if (stat < 0)
|
if (stat < 0)
|
||||||
return stat;
|
return stat;
|
||||||
corrected += stat;
|
corrected += stat;
|
||||||
|
|
|
@ -216,20 +216,19 @@ static void sm_break_offset(struct sm_ftl *ftl, loff_t loffset,
|
||||||
|
|
||||||
static int sm_correct_sector(uint8_t *buffer, struct sm_oob *oob)
|
static int sm_correct_sector(uint8_t *buffer, struct sm_oob *oob)
|
||||||
{
|
{
|
||||||
|
bool sm_order = IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC);
|
||||||
uint8_t ecc[3];
|
uint8_t ecc[3];
|
||||||
|
|
||||||
__nand_calculate_ecc(buffer, SM_SMALL_PAGE, ecc,
|
ecc_sw_hamming_calculate(buffer, SM_SMALL_PAGE, ecc, sm_order);
|
||||||
IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC));
|
if (ecc_sw_hamming_correct(buffer, ecc, oob->ecc1, SM_SMALL_PAGE,
|
||||||
if (__nand_correct_data(buffer, ecc, oob->ecc1, SM_SMALL_PAGE,
|
sm_order) < 0)
|
||||||
IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC)) < 0)
|
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
buffer += SM_SMALL_PAGE;
|
buffer += SM_SMALL_PAGE;
|
||||||
|
|
||||||
__nand_calculate_ecc(buffer, SM_SMALL_PAGE, ecc,
|
ecc_sw_hamming_calculate(buffer, SM_SMALL_PAGE, ecc, sm_order);
|
||||||
IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC));
|
if (ecc_sw_hamming_correct(buffer, ecc, oob->ecc2, SM_SMALL_PAGE,
|
||||||
if (__nand_correct_data(buffer, ecc, oob->ecc2, SM_SMALL_PAGE,
|
sm_order) < 0)
|
||||||
IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC)) < 0)
|
|
||||||
return -EIO;
|
return -EIO;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -369,6 +368,7 @@ static int sm_write_block(struct sm_ftl *ftl, uint8_t *buf,
|
||||||
int zone, int block, int lba,
|
int zone, int block, int lba,
|
||||||
unsigned long invalid_bitmap)
|
unsigned long invalid_bitmap)
|
||||||
{
|
{
|
||||||
|
bool sm_order = IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC);
|
||||||
struct sm_oob oob;
|
struct sm_oob oob;
|
||||||
int boffset;
|
int boffset;
|
||||||
int retry = 0;
|
int retry = 0;
|
||||||
|
@ -395,13 +395,13 @@ restart:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ftl->smallpagenand) {
|
if (ftl->smallpagenand) {
|
||||||
__nand_calculate_ecc(buf + boffset, SM_SMALL_PAGE,
|
ecc_sw_hamming_calculate(buf + boffset,
|
||||||
oob.ecc1,
|
SM_SMALL_PAGE, oob.ecc1,
|
||||||
IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC));
|
sm_order);
|
||||||
|
|
||||||
__nand_calculate_ecc(buf + boffset + SM_SMALL_PAGE,
|
ecc_sw_hamming_calculate(buf + boffset + SM_SMALL_PAGE,
|
||||||
SM_SMALL_PAGE, oob.ecc2,
|
SM_SMALL_PAGE, oob.ecc2,
|
||||||
IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC));
|
sm_order);
|
||||||
}
|
}
|
||||||
if (!sm_write_sector(ftl, zone, block, boffset,
|
if (!sm_write_sector(ftl, zone, block, boffset,
|
||||||
buf + boffset, &oob))
|
buf + boffset, &oob))
|
||||||
|
|
|
@ -119,13 +119,13 @@ static void no_bit_error(void *error_data, void *error_ecc,
|
||||||
static int no_bit_error_verify(void *error_data, void *error_ecc,
|
static int no_bit_error_verify(void *error_data, void *error_ecc,
|
||||||
void *correct_data, const size_t size)
|
void *correct_data, const size_t size)
|
||||||
{
|
{
|
||||||
|
bool sm_order = IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC);
|
||||||
unsigned char calc_ecc[3];
|
unsigned char calc_ecc[3];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
__nand_calculate_ecc(error_data, size, calc_ecc,
|
ecc_sw_hamming_calculate(error_data, size, calc_ecc, sm_order);
|
||||||
IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC));
|
ret = ecc_sw_hamming_correct(error_data, error_ecc, calc_ecc, size,
|
||||||
ret = __nand_correct_data(error_data, error_ecc, calc_ecc, size,
|
sm_order);
|
||||||
IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC));
|
|
||||||
if (ret == 0 && !memcmp(correct_data, error_data, size))
|
if (ret == 0 && !memcmp(correct_data, error_data, size))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -149,13 +149,13 @@ static void single_bit_error_in_ecc(void *error_data, void *error_ecc,
|
||||||
static int single_bit_error_correct(void *error_data, void *error_ecc,
|
static int single_bit_error_correct(void *error_data, void *error_ecc,
|
||||||
void *correct_data, const size_t size)
|
void *correct_data, const size_t size)
|
||||||
{
|
{
|
||||||
|
bool sm_order = IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC);
|
||||||
unsigned char calc_ecc[3];
|
unsigned char calc_ecc[3];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
__nand_calculate_ecc(error_data, size, calc_ecc,
|
ecc_sw_hamming_calculate(error_data, size, calc_ecc, sm_order);
|
||||||
IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC));
|
ret = ecc_sw_hamming_correct(error_data, error_ecc, calc_ecc, size,
|
||||||
ret = __nand_correct_data(error_data, error_ecc, calc_ecc, size,
|
sm_order);
|
||||||
IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC));
|
|
||||||
if (ret == 1 && !memcmp(correct_data, error_data, size))
|
if (ret == 1 && !memcmp(correct_data, error_data, size))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -186,13 +186,13 @@ static void double_bit_error_in_ecc(void *error_data, void *error_ecc,
|
||||||
static int double_bit_error_detect(void *error_data, void *error_ecc,
|
static int double_bit_error_detect(void *error_data, void *error_ecc,
|
||||||
void *correct_data, const size_t size)
|
void *correct_data, const size_t size)
|
||||||
{
|
{
|
||||||
|
bool sm_order = IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC);
|
||||||
unsigned char calc_ecc[3];
|
unsigned char calc_ecc[3];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
__nand_calculate_ecc(error_data, size, calc_ecc,
|
ecc_sw_hamming_calculate(error_data, size, calc_ecc, sm_order);
|
||||||
IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC));
|
ret = ecc_sw_hamming_correct(error_data, error_ecc, calc_ecc, size,
|
||||||
ret = __nand_correct_data(error_data, error_ecc, calc_ecc, size,
|
sm_order);
|
||||||
IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC));
|
|
||||||
|
|
||||||
return (ret == -EBADMSG) ? 0 : -EINVAL;
|
return (ret == -EBADMSG) ? 0 : -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -248,6 +248,7 @@ static void dump_data_ecc(void *error_data, void *error_ecc, void *correct_data,
|
||||||
|
|
||||||
static int nand_ecc_test_run(const size_t size)
|
static int nand_ecc_test_run(const size_t size)
|
||||||
{
|
{
|
||||||
|
bool sm_order = IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC);
|
||||||
int i;
|
int i;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
void *error_data;
|
void *error_data;
|
||||||
|
@ -266,9 +267,7 @@ static int nand_ecc_test_run(const size_t size)
|
||||||
}
|
}
|
||||||
|
|
||||||
prandom_bytes(correct_data, size);
|
prandom_bytes(correct_data, size);
|
||||||
__nand_calculate_ecc(correct_data, size, correct_ecc,
|
ecc_sw_hamming_calculate(correct_data, size, correct_ecc, sm_order);
|
||||||
IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC));
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(nand_ecc_test); i++) {
|
for (i = 0; i < ARRAY_SIZE(nand_ecc_test); i++) {
|
||||||
nand_ecc_test[i].prepare(error_data, error_ecc,
|
nand_ecc_test[i].prepare(error_data, error_ecc,
|
||||||
correct_data, correct_ecc, size);
|
correct_data, correct_ecc, size);
|
||||||
|
|
|
@ -10,30 +10,18 @@
|
||||||
#ifndef __MTD_NAND_ECC_SW_HAMMING_H__
|
#ifndef __MTD_NAND_ECC_SW_HAMMING_H__
|
||||||
#define __MTD_NAND_ECC_SW_HAMMING_H__
|
#define __MTD_NAND_ECC_SW_HAMMING_H__
|
||||||
|
|
||||||
struct nand_chip;
|
#include <linux/mtd/nand.h>
|
||||||
|
|
||||||
/*
|
int ecc_sw_hamming_calculate(const unsigned char *buf, unsigned int step_size,
|
||||||
* Calculate 3 byte ECC code for eccsize byte block
|
unsigned char *code, bool sm_order);
|
||||||
*/
|
int nand_ecc_sw_hamming_calculate(struct nand_device *nand,
|
||||||
void __nand_calculate_ecc(const u_char *dat, unsigned int eccsize,
|
const unsigned char *buf,
|
||||||
u_char *ecc_code, bool sm_order);
|
unsigned char *code);
|
||||||
|
int ecc_sw_hamming_correct(unsigned char *buf, unsigned char *read_ecc,
|
||||||
/*
|
unsigned char *calc_ecc, unsigned int step_size,
|
||||||
* Calculate 3 byte ECC code for 256/512 byte block
|
bool sm_order);
|
||||||
*/
|
int nand_ecc_sw_hamming_correct(struct nand_device *nand, unsigned char *buf,
|
||||||
int nand_calculate_ecc(struct nand_chip *chip, const u_char *dat,
|
unsigned char *read_ecc,
|
||||||
u_char *ecc_code);
|
unsigned char *calc_ecc);
|
||||||
|
|
||||||
/*
|
|
||||||
* Detect and correct a 1 bit error for eccsize byte block
|
|
||||||
*/
|
|
||||||
int __nand_correct_data(u_char *dat, u_char *read_ecc, u_char *calc_ecc,
|
|
||||||
unsigned int eccsize, bool sm_order);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Detect and correct a 1 bit error for 256/512 byte block
|
|
||||||
*/
|
|
||||||
int nand_correct_data(struct nand_chip *chip, u_char *dat, u_char *read_ecc,
|
|
||||||
u_char *calc_ecc);
|
|
||||||
|
|
||||||
#endif /* __MTD_NAND_ECC_SW_HAMMING_H__ */
|
#endif /* __MTD_NAND_ECC_SW_HAMMING_H__ */
|
||||||
|
|
|
@ -1301,6 +1301,13 @@ static inline int nand_opcode_8bits(unsigned int command)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rawnand_sw_hamming_calculate(struct nand_chip *chip,
|
||||||
|
const unsigned char *buf,
|
||||||
|
unsigned char *code);
|
||||||
|
int rawnand_sw_hamming_correct(struct nand_chip *chip,
|
||||||
|
unsigned char *buf,
|
||||||
|
unsigned char *read_ecc,
|
||||||
|
unsigned char *calc_ecc);
|
||||||
int rawnand_sw_bch_init(struct nand_chip *chip);
|
int rawnand_sw_bch_init(struct nand_chip *chip);
|
||||||
int rawnand_sw_bch_correct(struct nand_chip *chip, unsigned char *buf,
|
int rawnand_sw_bch_correct(struct nand_chip *chip, unsigned char *buf,
|
||||||
unsigned char *read_ecc, unsigned char *calc_ecc);
|
unsigned char *read_ecc, unsigned char *calc_ecc);
|
||||||
|
|
Loading…
Add table
Reference in a new issue