add the 'goldfish' target, useful for experimenting with virtual phone hardware ...
[openwrt/openwrt.git] / target / linux / goldfish / patches-2.6.30 / 1000-nand_driver_fixes.patch
1 --- a/drivers/mtd/devices/goldfish_nand.c
2 +++ b/drivers/mtd/devices/goldfish_nand.c
3 @@ -65,7 +65,7 @@ static int goldfish_nand_erase(struct mt
4 if(rem)
5 goto invalid_arg;
6 ofs *= (mtd->writesize + mtd->oobsize);
7 -
8 +
9 if(len % mtd->writesize)
10 goto invalid_arg;
11 len = len / mtd->writesize * (mtd->writesize + mtd->oobsize);
12 @@ -94,15 +94,12 @@ static int goldfish_nand_read_oob(struct
13
14 if(ofs + ops->len > mtd->size)
15 goto invalid_arg;
16 - if(ops->datbuf && ops->len && ops->len != mtd->writesize)
17 - goto invalid_arg;
18 if(ops->ooblen + ops->ooboffs > mtd->oobsize)
19 goto invalid_arg;
20
21 rem = do_div(ofs, mtd->writesize);
22 - if(rem)
23 - goto invalid_arg;
24 ofs *= (mtd->writesize + mtd->oobsize);
25 + ofs += rem;
26
27 if(ops->datbuf)
28 ops->retlen = goldfish_nand_cmd(mtd, NAND_CMD_READ, ofs,
29 @@ -131,7 +128,7 @@ static int goldfish_nand_write_oob(struc
30 goto invalid_arg;
31 if(ops->ooblen + ops->ooboffs > mtd->oobsize)
32 goto invalid_arg;
33 -
34 +
35 rem = do_div(ofs, mtd->writesize);
36 if(rem)
37 goto invalid_arg;
38 @@ -160,15 +157,24 @@ static int goldfish_nand_read(struct mtd
39
40 if(from + len > mtd->size)
41 goto invalid_arg;
42 - if(len != mtd->writesize)
43 - goto invalid_arg;
44 +
45 + *retlen = 0;
46
47 rem = do_div(from, mtd->writesize);
48 - if(rem)
49 - goto invalid_arg;
50 from *= (mtd->writesize + mtd->oobsize);
51 + from += rem;
52
53 - *retlen = goldfish_nand_cmd(mtd, NAND_CMD_READ, from, len, buf);
54 + do {
55 + *retlen += goldfish_nand_cmd(mtd, NAND_CMD_READ, from, min(len, mtd->writesize - rem), buf);
56 + if (len > mtd->writesize - rem) {
57 + len -= mtd->writesize - rem;
58 + buf += mtd->writesize - rem;
59 + from += mtd->writesize + mtd->oobsize - rem;
60 + rem = 0;
61 + } else {
62 + len = 0;
63 + }
64 + } while (len);
65 return 0;
66
67 invalid_arg:
68 @@ -184,15 +190,23 @@ static int goldfish_nand_write(struct mt
69
70 if(to + len > mtd->size)
71 goto invalid_arg;
72 - if(len != mtd->writesize)
73 - goto invalid_arg;
74
75 rem = do_div(to, mtd->writesize);
76 if(rem)
77 goto invalid_arg;
78 to *= (mtd->writesize + mtd->oobsize);
79
80 - *retlen = goldfish_nand_cmd(mtd, NAND_CMD_WRITE, to, len, (void *)buf);
81 + *retlen = 0;
82 + do {
83 + *retlen += goldfish_nand_cmd(mtd, NAND_CMD_WRITE, to, min(len, mtd->writesize), (void *)buf);
84 + if (len > mtd->writesize) {
85 + len -= mtd->writesize;
86 + buf += mtd->writesize;
87 + to += mtd->writesize + mtd->oobsize;
88 + } else {
89 + len = 0;
90 + }
91 + } while (len);
92 return 0;
93
94 invalid_arg: