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:
parent
74e2b75857
commit
3e1ddb3de9
@ -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);
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
Loading…
Reference in New Issue
Block a user