--- zzzz-none-000/linux-4.4.60/drivers/mtd/nand/nand_base.c 2017-04-08 07:53:53.000000000 +0000 +++ scorpion-7490-727/linux-4.4.60/drivers/mtd/nand/nand_base.c 2021-02-04 17:41:59.000000000 +0000 @@ -92,6 +92,26 @@ .length = 78} } }; +static struct nand_ecclayout nand_oob_256 = { + .eccbytes = 96, + .eccpos = { + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255}, + .oobfree = { + {.offset = 2, + .length = 158} } +}; + static int nand_get_device(struct mtd_info *mtd, int new_state); static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, @@ -134,6 +154,13 @@ { struct nand_chip *chip = mtd->priv; + /* AVM */ +#ifdef CONFIG_TFFS_PANIC_LOG + /* We never release device in panic. */ + if (chip->ecc.get_tffs_panic_state && + unlikely(chip->ecc.get_tffs_panic_state(mtd))) + return; +#endif /* Release the controller and the chip */ spin_lock(&chip->controller->lock); chip->controller->active = NULL; @@ -317,9 +344,9 @@ * * Check, if the block is bad. */ -static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) +static int nand_block_bad(struct mtd_info *mtd, loff_t ofs) { - int page, chipnr, res = 0, i = 0; + int page, res = 0, i = 0; struct nand_chip *chip = mtd->priv; u16 bad; @@ -328,15 +355,6 @@ page = (int)(ofs >> chip->page_shift) & chip->pagemask; - if (getchip) { - chipnr = (int)(ofs >> chip->chip_shift); - - nand_get_device(mtd, FL_READING); - - /* Select the NAND device */ - chip->select_chip(mtd, chipnr); - } - do { if (chip->options & NAND_BUSWIDTH_16) { chip->cmdfunc(mtd, NAND_CMD_READOOB, @@ -361,11 +379,6 @@ i++; } while (!res && i < 2 && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE)); - if (getchip) { - chip->select_chip(mtd, -1); - nand_release_device(mtd); - } - return res; } @@ -394,7 +407,11 @@ } else { ops.len = ops.ooblen = 1; } - ops.mode = MTD_OPS_PLACE_OOB; + + if (unlikely(chip->bbt_options & NAND_BBT_ACCESS_BBM_RAW)) + ops.mode = MTD_OPS_RAW; + else + ops.mode = MTD_OPS_PLACE_OOB; /* Write to first/last page(s) if necessary */ if (chip->bbt_options & NAND_BBT_SCANLASTPAGE) @@ -503,19 +520,17 @@ * nand_block_checkbad - [GENERIC] Check if a block is marked bad * @mtd: MTD device structure * @ofs: offset from device start - * @getchip: 0, if the chip is already selected * @allowbbt: 1, if its allowed to access the bbt area * * Check, if the block is bad. Either by reading the bad block table or * calling of the scan function. */ -static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip, - int allowbbt) +static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int allowbbt) { struct nand_chip *chip = mtd->priv; if (!chip->bbt) - return chip->block_bad(mtd, ofs, getchip); + return chip->block_bad(mtd, ofs); /* Return info from the table */ return nand_isbad_bbt(mtd, ofs, allowbbt); @@ -836,6 +851,19 @@ spinlock_t *lock = &chip->controller->lock; wait_queue_head_t *wq = &chip->controller->wq; DECLARE_WAITQUEUE(wait, current); + + /* AVM */ +#if IS_ENABLED(CONFIG_TFFS_PANIC_LOG) && IS_ENABLED(CONFIG_TFFS_DEV_MTDNAND) + WARN_ONCE(!chip->ecc.get_tffs_panic_state, + "NAND: get_tffs_panic_state not set!\n"); + + /* Either now or never. */ + if (chip->ecc.get_tffs_panic_state && + unlikely(chip->ecc.get_tffs_panic_state(mtd))) { + panic_nand_get_device(chip, mtd, new_state); + return 0; + } +#endif retry: spin_lock(lock); @@ -912,7 +940,16 @@ chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); + + /* AVM */ +#ifdef CONFIG_TFFS_PANIC_LOG + if (in_interrupt() || oops_in_progress || ( + chip->ecc.get_tffs_panic_state && + unlikely(chip->ecc.get_tffs_panic_state(mtd)) + )) +#else if (in_interrupt() || oops_in_progress) +#endif panic_nand_wait(mtd, chip, timeo); else { timeo = jiffies + msecs_to_jiffies(timeo); @@ -2023,6 +2060,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) { + unsigned int max_bitflips = 0; int page, realpage, chipnr; struct nand_chip *chip = mtd->priv; struct mtd_ecc_stats stats; @@ -2083,6 +2121,8 @@ nand_wait_ready(mtd); } + max_bitflips = max_t(unsigned int, max_bitflips, ret); + readlen -= len; if (!readlen) break; @@ -2108,7 +2148,7 @@ if (mtd->ecc_stats.failed - stats.failed) return -EBADMSG; - return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0; + return max_bitflips; } /** @@ -2918,7 +2958,7 @@ while (len) { /* Check if we have a bad block, we do not erase bad blocks! */ if (nand_block_checkbad(mtd, ((loff_t) page) << - chip->page_shift, 0, allowbbt)) { + chip->page_shift, allowbbt)) { pr_warn("%s: attempt to erase a bad block at page 0x%08x\n", __func__, page); instr->state = MTD_ERASE_FAILED; @@ -3005,7 +3045,20 @@ */ static int nand_block_isbad(struct mtd_info *mtd, loff_t offs) { - return nand_block_checkbad(mtd, offs, 1, 0); + struct nand_chip *chip = mtd_to_nand(mtd); + int chipnr = (int)(offs >> chip->chip_shift); + int ret; + + /* Select the NAND device */ + nand_get_device(mtd, FL_READING); + chip->select_chip(mtd, chipnr); + + ret = nand_block_checkbad(mtd, offs, 0); + + chip->select_chip(mtd, -1); + nand_release_device(mtd); + + return ret; } /** @@ -3741,7 +3794,13 @@ maf_id == NAND_MFR_AMD || maf_id == NAND_MFR_MACRONIX)) || (mtd->writesize == 2048 && - maf_id == NAND_MFR_MICRON)) + maf_id == NAND_MFR_MICRON) || + (mtd->writesize == 2048 && + maf_id == NAND_MFR_GIGA) || + (mtd->writesize == 2048 && + maf_id == NAND_MFR_MACRONIX) || + (mtd->writesize == 2048 && + maf_id == NAND_MFR_WINBOND)) chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; } @@ -4127,6 +4186,9 @@ case 128: ecc->layout = &nand_oob_128; break; + case 256: + ecc->layout = &nand_oob_256; + break; default: pr_warn("No oob scheme defined for oobsize %d\n", mtd->oobsize);