summaryrefslogtreecommitdiffstats
path: root/target/linux/goldfish/patches-2.6.30/1000-nand_driver_fixes.patch
blob: 0cd366ce90000317d57d6546dc9859dfb47c5219 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
--- 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: