You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openwrt/target/linux/goldfish/patches-2.6.30/1000-nand_driver_fixes.patch

95 lines
2.4 KiB
Diff

--- a/drivers/mtd/devices/goldfish_nand.c
+++ b/drivers/mtd/devices/goldfish_nand.c
@@ -65,7 +65,7 @@ static int goldfish_nand_erase(struct mt
if(rem)
goto invalid_arg;
ofs *= (mtd->writesize + mtd->oobsize);
-
+
if(len % mtd->writesize)
goto invalid_arg;
len = len / mtd->writesize * (mtd->writesize + mtd->oobsize);
@@ -94,15 +94,12 @@ static int goldfish_nand_read_oob(struct
if(ofs + ops->len > mtd->size)
goto invalid_arg;
- if(ops->datbuf && ops->len && ops->len != mtd->writesize)
- goto invalid_arg;
if(ops->ooblen + ops->ooboffs > mtd->oobsize)
goto invalid_arg;
rem = do_div(ofs, mtd->writesize);
- if(rem)
- goto invalid_arg;
ofs *= (mtd->writesize + mtd->oobsize);
+ ofs += rem;
if(ops->datbuf)
ops->retlen = goldfish_nand_cmd(mtd, NAND_CMD_READ, ofs,
@@ -131,7 +128,7 @@ static int goldfish_nand_write_oob(struc
goto invalid_arg;
if(ops->ooblen + ops->ooboffs > mtd->oobsize)
goto invalid_arg;
-
+
rem = do_div(ofs, mtd->writesize);
if(rem)
goto invalid_arg;
@@ -160,15 +157,24 @@ static int goldfish_nand_read(struct mtd
if(from + len > mtd->size)
goto invalid_arg;
- if(len != mtd->writesize)
- goto invalid_arg;
+
+ *retlen = 0;
rem = do_div(from, mtd->writesize);
- if(rem)
- goto invalid_arg;
from *= (mtd->writesize + mtd->oobsize);
+ from += rem;
- *retlen = goldfish_nand_cmd(mtd, NAND_CMD_READ, from, len, buf);
+ do {
+ *retlen += goldfish_nand_cmd(mtd, NAND_CMD_READ, from, min(len, mtd->writesize - rem), buf);
+ if (len > mtd->writesize - rem) {
+ len -= mtd->writesize - rem;
+ buf += mtd->writesize - rem;
+ from += mtd->writesize + mtd->oobsize - rem;
+ rem = 0;
+ } else {
+ len = 0;
+ }
+ } while (len);
return 0;
invalid_arg:
@@ -184,15 +190,23 @@ static int goldfish_nand_write(struct mt
if(to + len > mtd->size)
goto invalid_arg;
- if(len != mtd->writesize)
- goto invalid_arg;
rem = do_div(to, mtd->writesize);
if(rem)
goto invalid_arg;
to *= (mtd->writesize + mtd->oobsize);
- *retlen = goldfish_nand_cmd(mtd, NAND_CMD_WRITE, to, len, (void *)buf);
+ *retlen = 0;
+ do {
+ *retlen += goldfish_nand_cmd(mtd, NAND_CMD_WRITE, to, min(len, mtd->writesize), (void *)buf);
+ if (len > mtd->writesize) {
+ len -= mtd->writesize;
+ buf += mtd->writesize;
+ to += mtd->writesize + mtd->oobsize;
+ } else {
+ len = 0;
+ }
+ } while (len);
return 0;
invalid_arg: