ps3: R.I.P.
[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: