diff options
author | Dmitry Torokhov <dtor@insightbb.com> | 2007-05-01 00:24:54 -0400 |
---|---|---|
committer | Dmitry Torokhov <dtor@insightbb.com> | 2007-05-01 00:24:54 -0400 |
commit | bc95f3669f5e6f63cf0b84fe4922c3c6dd4aa775 (patch) | |
tree | 427fcf2a7287c16d4b5aa6cbf494d59579a6a8b1 /drivers/mtd/nand/nand_base.c | |
parent | 3d29cdff999c37b3876082278a8134a0642a02cd (diff) | |
parent | dc87c3985e9b442c60994308a96f887579addc39 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
drivers/usb/input/Makefile
drivers/usb/input/gtco.c
Diffstat (limited to 'drivers/mtd/nand/nand_base.c')
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 56 |
1 files changed, 46 insertions, 10 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index dfe56e03e48b..04de315e4937 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -312,7 +312,7 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) /* Select the NAND device */ chip->select_chip(mtd, chipnr); } else - page = (int)ofs; + page = (int)(ofs >> chip->page_shift); if (chip->options & NAND_BUSWIDTH_16) { chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos & 0xFE, @@ -350,7 +350,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) int block, ret; /* Get block number */ - block = ((int)ofs) >> chip->bbt_erase_shift; + block = (int)(ofs >> chip->bbt_erase_shift); if (chip->bbt) chip->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1); @@ -771,7 +771,7 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *ecc_code = chip->buffers->ecccode; int *eccpos = chip->ecc.layout->eccpos; - nand_read_page_raw(mtd, chip, buf); + chip->ecc.read_page_raw(mtd, chip, buf); for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) chip->ecc.calculate(mtd, p, &ecc_calc[i]); @@ -1272,10 +1272,25 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, DEBUG(MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08Lx, len = %i\n", (unsigned long long)from, readlen); - if (ops->mode == MTD_OOB_RAW) - len = mtd->oobsize; - else + if (ops->mode == MTD_OOB_AUTO) len = chip->ecc.layout->oobavail; + else + len = mtd->oobsize; + + if (unlikely(ops->ooboffs >= len)) { + DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: " + "Attempt to start read outside oob\n"); + return -EINVAL; + } + + /* Do not allow reads past end of device */ + if (unlikely(from >= mtd->size || + ops->ooboffs + readlen > ((mtd->size >> chip->page_shift) - + (from >> chip->page_shift)) * len)) { + DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: " + "Attempt read beyond end of device\n"); + return -EINVAL; + } chipnr = (int)(from >> chip->chip_shift); chip->select_chip(mtd, chipnr); @@ -1411,7 +1426,7 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, for (i = 0; i < chip->ecc.total; i++) chip->oob_poi[eccpos[i]] = ecc_calc[i]; - nand_write_page_raw(mtd, chip, buf); + chip->ecc.write_page_raw(mtd, chip, buf); } /** @@ -1742,19 +1757,40 @@ static int nand_write(struct mtd_info *mtd, loff_t to, size_t len, static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops) { - int chipnr, page, status; + int chipnr, page, status, len; struct nand_chip *chip = mtd->priv; DEBUG(MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n", (unsigned int)to, (int)ops->ooblen); + if (ops->mode == MTD_OOB_AUTO) + len = chip->ecc.layout->oobavail; + else + len = mtd->oobsize; + /* Do not allow write past end of page */ - if ((ops->ooboffs + ops->ooblen) > mtd->oobsize) { + if ((ops->ooboffs + ops->ooblen) > len) { DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: " "Attempt to write past end of page\n"); return -EINVAL; } + if (unlikely(ops->ooboffs >= len)) { + DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: " + "Attempt to start write outside oob\n"); + return -EINVAL; + } + + /* Do not allow reads past end of device */ + if (unlikely(to >= mtd->size || + ops->ooboffs + ops->ooblen > + ((mtd->size >> chip->page_shift) - + (to >> chip->page_shift)) * len)) { + DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: " + "Attempt write beyond end of device\n"); + return -EINVAL; + } + chipnr = (int)(to >> chip->chip_shift); chip->select_chip(mtd, chipnr); @@ -2488,6 +2524,7 @@ int nand_scan_tail(struct mtd_info *mtd) for (i = 0; chip->ecc.layout->oobfree[i].length; i++) chip->ecc.layout->oobavail += chip->ecc.layout->oobfree[i].length; + mtd->oobavail = chip->ecc.layout->oobavail; /* * Set the number of read / write steps for one page depending on ECC @@ -2530,7 +2567,6 @@ int nand_scan_tail(struct mtd_info *mtd) /* Fill in remaining MTD driver data */ mtd->type = MTD_NANDFLASH; mtd->flags = MTD_CAP_NANDFLASH; - mtd->ecctype = MTD_ECC_SW; mtd->erase = nand_erase; mtd->point = NULL; mtd->unpoint = NULL; |