mtd/nand: Return -EUCLEAN when the bit error happen but fixed by ecc

follow how Linux report the correction information from ecc:
http://www.infradead.org/pipermail/linux-mtd/2012-March/040305.html
since this information is very useful to file system(e.g. yaffs, ubi/buifs)
which is specially designed for nand flash.

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
Xiang Xiao 2023-05-01 03:25:33 +08:00 committed by Petro Karashchenko
parent 74e2b75857
commit 3e1ddb3de9
2 changed files with 16 additions and 6 deletions

View File

@ -549,6 +549,7 @@ static ssize_t nand_bread(FAR struct mtd_dev_s *dev, off_t startpage,
FAR struct nand_dev_s *nand = (FAR struct nand_dev_s *)dev; FAR struct nand_dev_s *nand = (FAR struct nand_dev_s *)dev;
FAR struct nand_raw_s *raw; FAR struct nand_raw_s *raw;
FAR struct nand_model_s *model; FAR struct nand_model_s *model;
bool fixedecc = false;
unsigned int pagesperblock; unsigned int pagesperblock;
unsigned int page; unsigned int page;
uint16_t pagesize; uint16_t pagesize;
@ -600,7 +601,11 @@ static ssize_t nand_bread(FAR struct mtd_dev_s *dev, off_t startpage,
/* Read the next page from NAND */ /* Read the next page from NAND */
ret = nand_readpage(nand, block, page, buffer); ret = nand_readpage(nand, block, page, buffer);
if (ret < 0) if (ret == -EUCLEAN)
{
fixedecc = true;
}
else if (ret < 0)
{ {
ferr("ERROR: nand_readpage failed block=%ld page=%d: %d\n", ferr("ERROR: nand_readpage failed block=%ld page=%d: %d\n",
(long)block, page, ret); (long)block, page, ret);
@ -624,7 +629,7 @@ static ssize_t nand_bread(FAR struct mtd_dev_s *dev, off_t startpage,
} }
nxmutex_unlock(&nand->lock); nxmutex_unlock(&nand->lock);
return npages; return fixedecc ? -EUCLEAN : npages;
errout_with_lock: errout_with_lock:
nxmutex_unlock(&nand->lock); nxmutex_unlock(&nand->lock);

View File

@ -138,14 +138,19 @@ int nandecc_readpage(FAR struct nand_dev_s *nand, off_t block,
/* Use the ECC data to verify the page */ /* Use the ECC data to verify the page */
ret = hamming_verify256x(data, pagesize, raw->ecc); ret = hamming_verify256x(data, pagesize, raw->ecc);
if (ret && (ret != HAMMING_ERROR_SINGLEBIT)) switch (ret)
{ {
case HAMMING_SUCCESS:
return OK;
case HAMMING_ERROR_SINGLEBIT:
return -EUCLEAN;
default:
ferr("ERROR: Block=%d page=%d Unrecoverable error: %d\n", ferr("ERROR: Block=%d page=%d Unrecoverable error: %d\n",
block, page, ret); block, page, ret);
return -EIO; return -EBADMSG;
} }
return OK;
} }
/**************************************************************************** /****************************************************************************