lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Tue, 25 Mar 2014 08:19:57 +0000 From: Lee Jones <lee.jones@...aro.org> To: linux-arm-kernel@...ts.infradead.org, linux-kernel@...r.kernel.org Cc: lee.jones@...aro.org, kernel@...inux.com, computersforpeace@...il.com, linux-mtd@...ts.infradead.org, dwmw2@...radead.org, angus.clark@...com, pekon@...com Subject: [RFC 40/47] mtd: nand: stm_nand_bch: MTD erase (BCH) Carry out the normal checks, then attempt to erase a given block. Signed-off-by: Lee Jones <lee.jones@...aro.org> --- drivers/mtd/nand/stm_nand_bch.c | 85 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/drivers/mtd/nand/stm_nand_bch.c b/drivers/mtd/nand/stm_nand_bch.c index 75c5c9b..55f4a4c 100644 --- a/drivers/mtd/nand/stm_nand_bch.c +++ b/drivers/mtd/nand/stm_nand_bch.c @@ -1218,6 +1218,89 @@ static int flex_do_write_ops(struct nandi_controller *nandi, return 0; } +static int bch_mtd_erase(struct mtd_info *mtd, struct erase_info *instr) +{ + struct nand_chip *chip = mtd->priv; + struct nandi_controller *nandi = chip->priv; + uint64_t block_mask = mtd->erasesize - 1; + uint64_t offs_cached; + loff_t offs = instr->addr; + size_t len = instr->len; + uint8_t status; + int ret; + + dev_dbg(nandi->dev, "%s: 0x%012llx @ 0x%012llx\n", __func__, + (unsigned long long)len, offs); + + if (offs & block_mask) { + dev_err(nandi->dev, + "attempt to erase from non-block-aligned offset\n"); + return -EINVAL; + } + + if (len & block_mask) { + dev_err(nandi->dev, + "attempt to erase non-block-aligned length\n"); + return -EINVAL; + } + + if ((offs + len) > mtd->size) { + dev_err(nandi->dev, "attempt to erase past end of device\n"); + return -EINVAL; + } + + nand_get_device(mtd, FL_ERASING); + instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN; + + if (flex_check_wp(nandi)) { + dev_dbg(nandi->dev, "device is write-protected\n"); + instr->state = MTD_ERASE_FAILED; + goto erase_exit; + } + + /* Offset of block containing cached page */ + offs_cached = ((uint64_t)nandi->cached_page << nandi->page_shift) & + ~block_mask; + + instr->state = MTD_ERASING; + while (len) { + if (mtd_block_isbad(mtd, offs)) { + dev_err(nandi->dev, + "attempt to erase a bad block at 0x%012llx\n", + offs); + instr->state = MTD_ERASE_FAILED; + instr->fail_addr = offs; + goto erase_exit; + } + + if (offs == offs_cached) + nandi->cached_page = -1; + + status = bch_erase_block(nandi, offs); + + if (status & NAND_STATUS_FAIL) { + dev_err(nandi->dev, + "failed to erase block at 0x%012llx\n", offs); + instr->state = MTD_ERASE_FAILED; + instr->fail_addr = offs; + goto erase_exit; + } + + len -= mtd->erasesize; + offs += mtd->erasesize; + } + instr->state = MTD_ERASE_DONE; + + erase_exit: + nand_release_device(mtd); + + ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO; + if (ret == 0) + mtd_erase_callback(instr); + + return ret; +} + static void nandi_dump_bad_blocks(struct nandi_controller *nandi) { int bad_count = 0; @@ -1321,6 +1404,8 @@ static void nandi_set_mtd_defaults(struct nandi_controller *nandi, mtd->oobavail = 0; mtd->subpage_sft = 0; + mtd->_erase = bch_mtd_erase; + mtd->_point = NULL; mtd->_unpoint = NULL; mtd->_lock = NULL; -- 1.8.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists