aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/nand/nand_base.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 1525cd01dacd..408e1d0abfd1 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2088,14 +2088,22 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
2088 2088
2089/** 2089/**
2090 * nand_fill_oob - [Internal] Transfer client buffer to oob 2090 * nand_fill_oob - [Internal] Transfer client buffer to oob
2091 * @chip: nand chip structure 2091 * @mtd: MTD device structure
2092 * @oob: oob data buffer 2092 * @oob: oob data buffer
2093 * @len: oob data write length 2093 * @len: oob data write length
2094 * @ops: oob ops structure 2094 * @ops: oob ops structure
2095 */ 2095 */
2096static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, size_t len, 2096static uint8_t *nand_fill_oob(struct mtd_info *mtd, uint8_t *oob, size_t len,
2097 struct mtd_oob_ops *ops) 2097 struct mtd_oob_ops *ops)
2098{ 2098{
2099 struct nand_chip *chip = mtd->priv;
2100
2101 /*
2102 * Initialise to all 0xFF, to avoid the possibility of left over OOB
2103 * data from a previous OOB read.
2104 */
2105 memset(chip->oob_poi, 0xff, mtd->oobsize);
2106
2099 switch (ops->mode) { 2107 switch (ops->mode) {
2100 2108
2101 case MTD_OOB_PLACE: 2109 case MTD_OOB_PLACE:
@@ -2192,10 +2200,6 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
2192 (chip->pagebuf << chip->page_shift) < (to + ops->len)) 2200 (chip->pagebuf << chip->page_shift) < (to + ops->len))
2193 chip->pagebuf = -1; 2201 chip->pagebuf = -1;
2194 2202
2195 /* If we're not given explicit OOB data, let it be 0xFF */
2196 if (likely(!oob))
2197 memset(chip->oob_poi, 0xff, mtd->oobsize);
2198
2199 /* Don't allow multipage oob writes with offset */ 2203 /* Don't allow multipage oob writes with offset */
2200 if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen)) 2204 if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen))
2201 return -EINVAL; 2205 return -EINVAL;
@@ -2217,8 +2221,11 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
2217 2221
2218 if (unlikely(oob)) { 2222 if (unlikely(oob)) {
2219 size_t len = min(oobwritelen, oobmaxlen); 2223 size_t len = min(oobwritelen, oobmaxlen);
2220 oob = nand_fill_oob(chip, oob, len, ops); 2224 oob = nand_fill_oob(mtd, oob, len, ops);
2221 oobwritelen -= len; 2225 oobwritelen -= len;
2226 } else {
2227 /* We still need to erase leftover OOB data */
2228 memset(chip->oob_poi, 0xff, mtd->oobsize);
2222 } 2229 }
2223 2230
2224 ret = chip->write_page(mtd, chip, wbuf, page, cached, 2231 ret = chip->write_page(mtd, chip, wbuf, page, cached,
@@ -2392,10 +2399,8 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
2392 if (page == chip->pagebuf) 2399 if (page == chip->pagebuf)
2393 chip->pagebuf = -1; 2400 chip->pagebuf = -1;
2394 2401
2395 memset(chip->oob_poi, 0xff, mtd->oobsize); 2402 nand_fill_oob(mtd, ops->oobbuf, ops->ooblen, ops);
2396 nand_fill_oob(chip, ops->oobbuf, ops->ooblen, ops);
2397 status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask); 2403 status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask);
2398 memset(chip->oob_poi, 0xff, mtd->oobsize);
2399 2404
2400 if (status) 2405 if (status)
2401 return status; 2406 return status;