diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2013-12-31 08:42:13 -0800 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2013-12-31 08:42:12 -0800 |
commit | 4bed7076009d4337e695b92f977668837f20111a (patch) | |
tree | 07cd449b895c262cec0e4ef3e1fd1fd497038434 /drivers/mtd | |
parent | 69556ccbbb622909b0edaddef68ad9c4e7c999c9 (diff) | |
parent | 555a56b89a9403091f6bcebbe9f6bd661dd49c59 (diff) |
Merge "mtd: msm_qpic_nand: Support for multi page read"
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/devices/msm_qpic_nand.c | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/drivers/mtd/devices/msm_qpic_nand.c b/drivers/mtd/devices/msm_qpic_nand.c index cca5c8cc5c1b..eb671295aba3 100644 --- a/drivers/mtd/devices/msm_qpic_nand.c +++ b/drivers/mtd/devices/msm_qpic_nand.c @@ -1828,19 +1828,46 @@ static int msm_nand_read(struct mtd_info *mtd, loff_t from, size_t len, struct mtd_oob_ops ops; ops.mode = MTD_OPS_AUTO_OOB; - ops.len = len; ops.retlen = 0; ops.ooblen = 0; - ops.datbuf = buf; ops.oobbuf = NULL; - if (!(from & (mtd->writesize - 1)) && !(len % mtd->writesize)) - /* read pages on page boundary */ - ret = msm_nand_read_oob(mtd, from, &ops); - else + if (!(from & (mtd->writesize - 1)) && !(len % mtd->writesize)) { + /* + * Handle reading of large size read buffer in vmalloc + * address space that does not fit in an MMU page. + */ + if (!virt_addr_valid(buf) && + ((unsigned long) buf & ~PAGE_MASK) + len > PAGE_SIZE) { + ops.len = mtd->writesize; + + for (;;) { + ops.datbuf = buf; + ret = msm_nand_read_oob(mtd, from, &ops); + if (ret < 0) + break; + + len -= mtd->writesize; + *retlen += mtd->writesize; + if (len == 0) + break; + + buf += mtd->writesize; + from += mtd->writesize; + } + } else { + ops.len = len; + ops.datbuf = buf; + ret = msm_nand_read_oob(mtd, from, &ops); + *retlen = ops.retlen; + } + } else { + ops.len = len; + ops.datbuf = buf; ret = msm_nand_read_partial_page(mtd, from, &ops); + *retlen = ops.retlen; + } - *retlen = ops.retlen; return ret; } |