aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/nand_base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/nand/nand_base.c')
-rw-r--r--drivers/mtd/nand/nand_base.c47
1 files changed, 41 insertions, 6 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index dfe56e03e48b..acaf97bc80d1 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1272,10 +1272,25 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
1272 DEBUG(MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08Lx, len = %i\n", 1272 DEBUG(MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08Lx, len = %i\n",
1273 (unsigned long long)from, readlen); 1273 (unsigned long long)from, readlen);
1274 1274
1275 if (ops->mode == MTD_OOB_RAW) 1275 if (ops->mode == MTD_OOB_AUTO)
1276 len = mtd->oobsize;
1277 else
1278 len = chip->ecc.layout->oobavail; 1276 len = chip->ecc.layout->oobavail;
1277 else
1278 len = mtd->oobsize;
1279
1280 if (unlikely(ops->ooboffs >= len)) {
1281 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
1282 "Attempt to start read outside oob\n");
1283 return -EINVAL;
1284 }
1285
1286 /* Do not allow reads past end of device */
1287 if (unlikely(from >= mtd->size ||
1288 ops->ooboffs + readlen > ((mtd->size >> chip->page_shift) -
1289 (from >> chip->page_shift)) * len)) {
1290 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
1291 "Attempt read beyond end of device\n");
1292 return -EINVAL;
1293 }
1279 1294
1280 chipnr = (int)(from >> chip->chip_shift); 1295 chipnr = (int)(from >> chip->chip_shift);
1281 chip->select_chip(mtd, chipnr); 1296 chip->select_chip(mtd, chipnr);
@@ -1742,19 +1757,40 @@ static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
1742static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, 1757static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
1743 struct mtd_oob_ops *ops) 1758 struct mtd_oob_ops *ops)
1744{ 1759{
1745 int chipnr, page, status; 1760 int chipnr, page, status, len;
1746 struct nand_chip *chip = mtd->priv; 1761 struct nand_chip *chip = mtd->priv;
1747 1762
1748 DEBUG(MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n", 1763 DEBUG(MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n",
1749 (unsigned int)to, (int)ops->ooblen); 1764 (unsigned int)to, (int)ops->ooblen);
1750 1765
1766 if (ops->mode == MTD_OOB_AUTO)
1767 len = chip->ecc.layout->oobavail;
1768 else
1769 len = mtd->oobsize;
1770
1751 /* Do not allow write past end of page */ 1771 /* Do not allow write past end of page */
1752 if ((ops->ooboffs + ops->ooblen) > mtd->oobsize) { 1772 if ((ops->ooboffs + ops->ooblen) > len) {
1753 DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: " 1773 DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: "
1754 "Attempt to write past end of page\n"); 1774 "Attempt to write past end of page\n");
1755 return -EINVAL; 1775 return -EINVAL;
1756 } 1776 }
1757 1777
1778 if (unlikely(ops->ooboffs >= len)) {
1779 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
1780 "Attempt to start write outside oob\n");
1781 return -EINVAL;
1782 }
1783
1784 /* Do not allow reads past end of device */
1785 if (unlikely(to >= mtd->size ||
1786 ops->ooboffs + ops->ooblen >
1787 ((mtd->size >> chip->page_shift) -
1788 (to >> chip->page_shift)) * len)) {
1789 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
1790 "Attempt write beyond end of device\n");
1791 return -EINVAL;
1792 }
1793
1758 chipnr = (int)(to >> chip->chip_shift); 1794 chipnr = (int)(to >> chip->chip_shift);
1759 chip->select_chip(mtd, chipnr); 1795 chip->select_chip(mtd, chipnr);
1760 1796
@@ -2530,7 +2566,6 @@ int nand_scan_tail(struct mtd_info *mtd)
2530 /* Fill in remaining MTD driver data */ 2566 /* Fill in remaining MTD driver data */
2531 mtd->type = MTD_NANDFLASH; 2567 mtd->type = MTD_NANDFLASH;
2532 mtd->flags = MTD_CAP_NANDFLASH; 2568 mtd->flags = MTD_CAP_NANDFLASH;
2533 mtd->ecctype = MTD_ECC_SW;
2534 mtd->erase = nand_erase; 2569 mtd->erase = nand_erase;
2535 mtd->point = NULL; 2570 mtd->point = NULL;
2536 mtd->unpoint = NULL; 2571 mtd->unpoint = NULL;