mtd: nand: sunxi: retrieve corrected OOB bytes
The ECC engine is protecting a few OOB bytes. Retrieve them from the USER_DATA register instead of reading them in raw mode (ie without the ECC protection). Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> Signed-off-by: Brian Norris <computersforpeace@gmail.com>
This commit is contained in:
parent
35d0e24f09
commit
f363e0faa8
|
@ -567,6 +567,14 @@ static void sunxi_nfc_hw_ecc_disable(struct mtd_info *mtd)
|
||||||
nfc->regs + NFC_REG_ECC_CTL);
|
nfc->regs + NFC_REG_ECC_CTL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void sunxi_nfc_user_data_to_buf(u32 user_data, u8 *buf)
|
||||||
|
{
|
||||||
|
buf[0] = user_data;
|
||||||
|
buf[1] = user_data >> 8;
|
||||||
|
buf[2] = user_data >> 16;
|
||||||
|
buf[3] = user_data >> 24;
|
||||||
|
}
|
||||||
|
|
||||||
static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd,
|
static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd,
|
||||||
u8 *data, int data_off,
|
u8 *data, int data_off,
|
||||||
u8 *oob, int oob_off,
|
u8 *oob, int oob_off,
|
||||||
|
@ -606,8 +614,16 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd,
|
||||||
nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
|
nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
|
||||||
sunxi_nfc_read_buf(mtd, oob, ecc->bytes + 4);
|
sunxi_nfc_read_buf(mtd, oob, ecc->bytes + 4);
|
||||||
|
|
||||||
if (status & NFC_ECC_ERR(0))
|
if (status & NFC_ECC_ERR(0)) {
|
||||||
ret = -EIO;
|
ret = -EIO;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* The engine protects 4 bytes of OOB data per chunk.
|
||||||
|
* Retrieve the corrected OOB bytes.
|
||||||
|
*/
|
||||||
|
sunxi_nfc_user_data_to_buf(readl(nfc->regs + NFC_REG_USER_DATA(0)),
|
||||||
|
oob);
|
||||||
|
}
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
mtd->ecc_stats.failed++;
|
mtd->ecc_stats.failed++;
|
||||||
|
|
Loading…
Reference in New Issue