lkml.org 
[lkml]   [2010]   [Feb]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 2/7] MTD: nand: cleanup nand_do_write_ops
    Date
    nand_do_write_ops have broken in regard to writing several pages each with its own oob
    Although nand_do_write_ops intends to allow such mode, it fails do do so
    Probably this was never tested.
    Also add missing checks for attemts to write at illegal offsets

    Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
    ---
    drivers/mtd/nand/nand_base.c | 24 +++++++++++++++++-------
    1 files changed, 17 insertions(+), 7 deletions(-)

    diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
    index 405c538..64b0f10 100644
    --- a/drivers/mtd/nand/nand_base.c
    +++ b/drivers/mtd/nand/nand_base.c
    @@ -1884,11 +1884,9 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
    * @oob: oob data buffer
    * @ops: oob ops structure
    */
    -static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob,
    - struct mtd_oob_ops *ops)
    +static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, size_t len,
    + struct mtd_oob_ops *ops)
    {
    - size_t len = ops->ooblen;
    -
    switch(ops->mode) {

    case MTD_OOB_PLACE:
    @@ -1943,6 +1941,11 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
    int chipnr, realpage, page, blockmask, column;
    struct nand_chip *chip = mtd->priv;
    uint32_t writelen = ops->len;
    +
    + uint32_t oobwritelen = ops->ooblen;
    + uint32_t oobmaxlen = ops->mode == MTD_OOB_AUTO ?
    + mtd->oobavail : mtd->oobsize;
    +
    uint8_t *oob = ops->oobbuf;
    uint8_t *buf = ops->datbuf;
    int ret, subpage;
    @@ -1984,6 +1987,10 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
    if (likely(!oob))
    memset(chip->oob_poi, 0xff, mtd->oobsize);

    + /* Don't allow multipage oob writes with offset */
    + if (ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen))
    + return -EINVAL;
    +
    while(1) {
    int bytes = mtd->writesize;
    int cached = writelen > bytes && page != blockmask;
    @@ -1999,8 +2006,11 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
    wbuf = chip->buffers->databuf;
    }

    - if (unlikely(oob))
    - oob = nand_fill_oob(chip, oob, ops);
    + if (unlikely(oob)) {
    + size_t len = min(oobwritelen, oobmaxlen);
    + oob = nand_fill_oob(chip, oob, len, ops);
    + oobwritelen -= len;
    + }

    ret = chip->write_page(mtd, chip, wbuf, page, cached,
    (ops->mode == MTD_OOB_RAW));
    @@ -2174,7 +2184,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
    chip->pagebuf = -1;

    memset(chip->oob_poi, 0xff, mtd->oobsize);
    - nand_fill_oob(chip, ops->oobbuf, ops);
    + nand_fill_oob(chip, ops->oobbuf, ops->ooblen, ops);
    status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask);
    memset(chip->oob_poi, 0xff, mtd->oobsize);

    --
    1.6.3.3


    \
     
     \ /
      Last update: 2010-02-06 00:21    [W:0.025 / U:0.832 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site