diff options
author | RogerCC Lin <rogercc.lin@mediatek.com> | 2016-09-18 22:53:25 -0400 |
---|---|---|
committer | Boris Brezillon <boris.brezillon@free-electrons.com> | 2016-09-19 05:56:33 -0400 |
commit | 7a353289925f01cb188ebc6fc4f4a33456b7de44 (patch) | |
tree | 9299f504fb4797d8c51e2778c0bb10d6e672f516 | |
parent | 3be7988674ab33565700a37b210f502563d932e6 (diff) |
mtd: nand: fix generating over-boundary ECC data when writing
When mtk_ecc_encode() is writing the ECC parity data to the OOB
region,because each register is 4 bytes in length,but the len's unit is
in bytes,the operation in the for loop will cross the ECC's boundary.
Signed-off-by: RogerCC Lin <rogercc.lin@mediatek.com>
Fixes: 1d6b1e464950 ("mtd: mediatek: driver for MTK Smart Device")
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
-rw-r--r-- | drivers/mtd/nand/mtk_ecc.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/mtd/nand/mtk_ecc.c b/drivers/mtd/nand/mtk_ecc.c index 25a4fbd4d24a..d54f666417e1 100644 --- a/drivers/mtd/nand/mtk_ecc.c +++ b/drivers/mtd/nand/mtk_ecc.c | |||
@@ -366,7 +366,8 @@ int mtk_ecc_encode(struct mtk_ecc *ecc, struct mtk_ecc_config *config, | |||
366 | u8 *data, u32 bytes) | 366 | u8 *data, u32 bytes) |
367 | { | 367 | { |
368 | dma_addr_t addr; | 368 | dma_addr_t addr; |
369 | u32 *p, len, i; | 369 | u8 *p; |
370 | u32 len, i, val; | ||
370 | int ret = 0; | 371 | int ret = 0; |
371 | 372 | ||
372 | addr = dma_map_single(ecc->dev, data, bytes, DMA_TO_DEVICE); | 373 | addr = dma_map_single(ecc->dev, data, bytes, DMA_TO_DEVICE); |
@@ -392,11 +393,14 @@ int mtk_ecc_encode(struct mtk_ecc *ecc, struct mtk_ecc_config *config, | |||
392 | 393 | ||
393 | /* Program ECC bytes to OOB: per sector oob = FDM + ECC + SPARE */ | 394 | /* Program ECC bytes to OOB: per sector oob = FDM + ECC + SPARE */ |
394 | len = (config->strength * ECC_PARITY_BITS + 7) >> 3; | 395 | len = (config->strength * ECC_PARITY_BITS + 7) >> 3; |
395 | p = (u32 *)(data + bytes); | 396 | p = data + bytes; |
396 | 397 | ||
397 | /* write the parity bytes generated by the ECC back to the OOB region */ | 398 | /* write the parity bytes generated by the ECC back to the OOB region */ |
398 | for (i = 0; i < len; i++) | 399 | for (i = 0; i < len; i++) { |
399 | p[i] = readl(ecc->regs + ECC_ENCPAR(i)); | 400 | if ((i % 4) == 0) |
401 | val = readl(ecc->regs + ECC_ENCPAR(i / 4)); | ||
402 | p[i] = (val >> ((i % 4) * 8)) & 0xff; | ||
403 | } | ||
400 | timeout: | 404 | timeout: |
401 | 405 | ||
402 | dma_unmap_single(ecc->dev, addr, bytes, DMA_TO_DEVICE); | 406 | dma_unmap_single(ecc->dev, addr, bytes, DMA_TO_DEVICE); |