diff options
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 27 |
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 | */ |
2096 | static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, size_t len, | 2096 | static 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; |