diff options
Diffstat (limited to 'drivers/mtd/nand/nand_base.c')
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 3249 |
1 files changed, 1519 insertions, 1730 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 95e96fa1fceb..27083ed0a017 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -10,67 +10,31 @@ | |||
10 | * http://www.linux-mtd.infradead.org/tech/nand.html | 10 | * http://www.linux-mtd.infradead.org/tech/nand.html |
11 | * | 11 | * |
12 | * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) | 12 | * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) |
13 | * 2002 Thomas Gleixner (tglx@linutronix.de) | 13 | * 2002-2006 Thomas Gleixner (tglx@linutronix.de) |
14 | * | 14 | * |
15 | * 02-08-2004 tglx: support for strange chips, which cannot auto increment | 15 | * Credits: |
16 | * pages on read / read_oob | ||
17 | * | ||
18 | * 03-17-2004 tglx: Check ready before auto increment check. Simon Bayes | ||
19 | * pointed this out, as he marked an auto increment capable chip | ||
20 | * as NOAUTOINCR in the board driver. | ||
21 | * Make reads over block boundaries work too | ||
22 | * | ||
23 | * 04-14-2004 tglx: first working version for 2k page size chips | ||
24 | * | ||
25 | * 05-19-2004 tglx: Basic support for Renesas AG-AND chips | ||
26 | * | ||
27 | * 09-24-2004 tglx: add support for hardware controllers (e.g. ECC) shared | ||
28 | * among multiple independend devices. Suggestions and initial patch | ||
29 | * from Ben Dooks <ben-mtd@fluff.org> | ||
30 | * | ||
31 | * 12-05-2004 dmarlin: add workaround for Renesas AG-AND chips "disturb" issue. | ||
32 | * Basically, any block not rewritten may lose data when surrounding blocks | ||
33 | * are rewritten many times. JFFS2 ensures this doesn't happen for blocks | ||
34 | * it uses, but the Bad Block Table(s) may not be rewritten. To ensure they | ||
35 | * do not lose data, force them to be rewritten when some of the surrounding | ||
36 | * blocks are erased. Rather than tracking a specific nearby block (which | ||
37 | * could itself go bad), use a page address 'mask' to select several blocks | ||
38 | * in the same area, and rewrite the BBT when any of them are erased. | ||
39 | * | ||
40 | * 01-03-2005 dmarlin: added support for the device recovery command sequence for Renesas | ||
41 | * AG-AND chips. If there was a sudden loss of power during an erase operation, | ||
42 | * a "device recovery" operation must be performed when power is restored | ||
43 | * to ensure correct operation. | ||
44 | * | ||
45 | * 01-20-2005 dmarlin: added support for optional hardware specific callback routine to | ||
46 | * perform extra error status checks on erase and write failures. This required | ||
47 | * adding a wrapper function for nand_read_ecc. | ||
48 | * | ||
49 | * 08-20-2005 vwool: suspend/resume added | ||
50 | * | ||
51 | * Credits: | ||
52 | * David Woodhouse for adding multichip support | 16 | * David Woodhouse for adding multichip support |
53 | * | 17 | * |
54 | * Aleph One Ltd. and Toby Churchill Ltd. for supporting the | 18 | * Aleph One Ltd. and Toby Churchill Ltd. for supporting the |
55 | * rework for 2K page size chips | 19 | * rework for 2K page size chips |
56 | * | 20 | * |
57 | * TODO: | 21 | * TODO: |
58 | * Enable cached programming for 2k page size chips | 22 | * Enable cached programming for 2k page size chips |
59 | * Check, if mtd->ecctype should be set to MTD_ECC_HW | 23 | * Check, if mtd->ecctype should be set to MTD_ECC_HW |
60 | * if we have HW ecc support. | 24 | * if we have HW ecc support. |
61 | * The AG-AND chips have nice features for speed improvement, | 25 | * The AG-AND chips have nice features for speed improvement, |
62 | * which are not supported yet. Read / program 4 pages in one go. | 26 | * which are not supported yet. Read / program 4 pages in one go. |
63 | * | 27 | * |
64 | * $Id: nand_base.c,v 1.150 2005/09/15 13:58:48 vwool Exp $ | ||
65 | * | ||
66 | * This program is free software; you can redistribute it and/or modify | 28 | * This program is free software; you can redistribute it and/or modify |
67 | * it under the terms of the GNU General Public License version 2 as | 29 | * it under the terms of the GNU General Public License version 2 as |
68 | * published by the Free Software Foundation. | 30 | * published by the Free Software Foundation. |
69 | * | 31 | * |
70 | */ | 32 | */ |
71 | 33 | ||
34 | #include <linux/module.h> | ||
72 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
73 | #include <linux/errno.h> | 36 | #include <linux/errno.h> |
37 | #include <linux/err.h> | ||
74 | #include <linux/sched.h> | 38 | #include <linux/sched.h> |
75 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
76 | #include <linux/types.h> | 40 | #include <linux/types.h> |
@@ -88,75 +52,46 @@ | |||
88 | #endif | 52 | #endif |
89 | 53 | ||
90 | /* Define default oob placement schemes for large and small page devices */ | 54 | /* Define default oob placement schemes for large and small page devices */ |
91 | static struct nand_oobinfo nand_oob_8 = { | 55 | static struct nand_ecclayout nand_oob_8 = { |
92 | .useecc = MTD_NANDECC_AUTOPLACE, | ||
93 | .eccbytes = 3, | 56 | .eccbytes = 3, |
94 | .eccpos = {0, 1, 2}, | 57 | .eccpos = {0, 1, 2}, |
95 | .oobfree = { {3, 2}, {6, 2} } | 58 | .oobfree = { |
59 | {.offset = 3, | ||
60 | .length = 2}, | ||
61 | {.offset = 6, | ||
62 | .length = 2}} | ||
96 | }; | 63 | }; |
97 | 64 | ||
98 | static struct nand_oobinfo nand_oob_16 = { | 65 | static struct nand_ecclayout nand_oob_16 = { |
99 | .useecc = MTD_NANDECC_AUTOPLACE, | ||
100 | .eccbytes = 6, | 66 | .eccbytes = 6, |
101 | .eccpos = {0, 1, 2, 3, 6, 7}, | 67 | .eccpos = {0, 1, 2, 3, 6, 7}, |
102 | .oobfree = { {8, 8} } | 68 | .oobfree = { |
69 | {.offset = 8, | ||
70 | . length = 8}} | ||
103 | }; | 71 | }; |
104 | 72 | ||
105 | static struct nand_oobinfo nand_oob_64 = { | 73 | static struct nand_ecclayout nand_oob_64 = { |
106 | .useecc = MTD_NANDECC_AUTOPLACE, | ||
107 | .eccbytes = 24, | 74 | .eccbytes = 24, |
108 | .eccpos = { | 75 | .eccpos = { |
109 | 40, 41, 42, 43, 44, 45, 46, 47, | 76 | 40, 41, 42, 43, 44, 45, 46, 47, |
110 | 48, 49, 50, 51, 52, 53, 54, 55, | 77 | 48, 49, 50, 51, 52, 53, 54, 55, |
111 | 56, 57, 58, 59, 60, 61, 62, 63}, | 78 | 56, 57, 58, 59, 60, 61, 62, 63}, |
112 | .oobfree = { {2, 38} } | 79 | .oobfree = { |
80 | {.offset = 2, | ||
81 | .length = 38}} | ||
113 | }; | 82 | }; |
114 | 83 | ||
115 | /* This is used for padding purposes in nand_write_oob */ | 84 | static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, |
116 | static u_char ffchars[] = { | 85 | int new_state); |
117 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | 86 | |
118 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | 87 | static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, |
119 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | 88 | struct mtd_oob_ops *ops); |
120 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
121 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
122 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
123 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
124 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
125 | }; | ||
126 | 89 | ||
127 | /* | 90 | /* |
128 | * NAND low-level MTD interface functions | 91 | * For devices which display every fart in the system on a seperate LED. Is |
92 | * compiled away when LED support is disabled. | ||
129 | */ | 93 | */ |
130 | static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len); | 94 | DEFINE_LED_TRIGGER(nand_led_trigger); |
131 | static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len); | ||
132 | static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len); | ||
133 | |||
134 | static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf); | ||
135 | static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, | ||
136 | size_t * retlen, u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel); | ||
137 | static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf); | ||
138 | static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf); | ||
139 | static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, | ||
140 | size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel); | ||
141 | static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char *buf); | ||
142 | static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, | ||
143 | unsigned long count, loff_t to, size_t * retlen); | ||
144 | static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, | ||
145 | unsigned long count, loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel); | ||
146 | static int nand_erase (struct mtd_info *mtd, struct erase_info *instr); | ||
147 | static void nand_sync (struct mtd_info *mtd); | ||
148 | |||
149 | /* Some internal functions */ | ||
150 | static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf, | ||
151 | struct nand_oobinfo *oobsel, int mode); | ||
152 | #ifdef CONFIG_MTD_NAND_VERIFY_WRITE | ||
153 | static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages, | ||
154 | u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode); | ||
155 | #else | ||
156 | #define nand_verify_pages(...) (0) | ||
157 | #endif | ||
158 | |||
159 | static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state); | ||
160 | 95 | ||
161 | /** | 96 | /** |
162 | * nand_release_device - [GENERIC] release chip | 97 | * nand_release_device - [GENERIC] release chip |
@@ -164,27 +99,19 @@ static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int ne | |||
164 | * | 99 | * |
165 | * Deselect, release chip lock and wake up anyone waiting on the device | 100 | * Deselect, release chip lock and wake up anyone waiting on the device |
166 | */ | 101 | */ |
167 | static void nand_release_device (struct mtd_info *mtd) | 102 | static void nand_release_device(struct mtd_info *mtd) |
168 | { | 103 | { |
169 | struct nand_chip *this = mtd->priv; | 104 | struct nand_chip *chip = mtd->priv; |
170 | 105 | ||
171 | /* De-select the NAND device */ | 106 | /* De-select the NAND device */ |
172 | this->select_chip(mtd, -1); | 107 | chip->select_chip(mtd, -1); |
173 | 108 | ||
174 | if (this->controller) { | 109 | /* Release the controller and the chip */ |
175 | /* Release the controller and the chip */ | 110 | spin_lock(&chip->controller->lock); |
176 | spin_lock(&this->controller->lock); | 111 | chip->controller->active = NULL; |
177 | this->controller->active = NULL; | 112 | chip->state = FL_READY; |
178 | this->state = FL_READY; | 113 | wake_up(&chip->controller->wq); |
179 | wake_up(&this->controller->wq); | 114 | spin_unlock(&chip->controller->lock); |
180 | spin_unlock(&this->controller->lock); | ||
181 | } else { | ||
182 | /* Release the chip */ | ||
183 | spin_lock(&this->chip_lock); | ||
184 | this->state = FL_READY; | ||
185 | wake_up(&this->wq); | ||
186 | spin_unlock(&this->chip_lock); | ||
187 | } | ||
188 | } | 115 | } |
189 | 116 | ||
190 | /** | 117 | /** |
@@ -193,23 +120,10 @@ static void nand_release_device (struct mtd_info *mtd) | |||
193 | * | 120 | * |
194 | * Default read function for 8bit buswith | 121 | * Default read function for 8bit buswith |
195 | */ | 122 | */ |
196 | static u_char nand_read_byte(struct mtd_info *mtd) | 123 | static uint8_t nand_read_byte(struct mtd_info *mtd) |
197 | { | ||
198 | struct nand_chip *this = mtd->priv; | ||
199 | return readb(this->IO_ADDR_R); | ||
200 | } | ||
201 | |||
202 | /** | ||
203 | * nand_write_byte - [DEFAULT] write one byte to the chip | ||
204 | * @mtd: MTD device structure | ||
205 | * @byte: pointer to data byte to write | ||
206 | * | ||
207 | * Default write function for 8it buswith | ||
208 | */ | ||
209 | static void nand_write_byte(struct mtd_info *mtd, u_char byte) | ||
210 | { | 124 | { |
211 | struct nand_chip *this = mtd->priv; | 125 | struct nand_chip *chip = mtd->priv; |
212 | writeb(byte, this->IO_ADDR_W); | 126 | return readb(chip->IO_ADDR_R); |
213 | } | 127 | } |
214 | 128 | ||
215 | /** | 129 | /** |
@@ -219,24 +133,10 @@ static void nand_write_byte(struct mtd_info *mtd, u_char byte) | |||
219 | * Default read function for 16bit buswith with | 133 | * Default read function for 16bit buswith with |
220 | * endianess conversion | 134 | * endianess conversion |
221 | */ | 135 | */ |
222 | static u_char nand_read_byte16(struct mtd_info *mtd) | 136 | static uint8_t nand_read_byte16(struct mtd_info *mtd) |
223 | { | 137 | { |
224 | struct nand_chip *this = mtd->priv; | 138 | struct nand_chip *chip = mtd->priv; |
225 | return (u_char) cpu_to_le16(readw(this->IO_ADDR_R)); | 139 | return (uint8_t) cpu_to_le16(readw(chip->IO_ADDR_R)); |
226 | } | ||
227 | |||
228 | /** | ||
229 | * nand_write_byte16 - [DEFAULT] write one byte endianess aware to the chip | ||
230 | * @mtd: MTD device structure | ||
231 | * @byte: pointer to data byte to write | ||
232 | * | ||
233 | * Default write function for 16bit buswith with | ||
234 | * endianess conversion | ||
235 | */ | ||
236 | static void nand_write_byte16(struct mtd_info *mtd, u_char byte) | ||
237 | { | ||
238 | struct nand_chip *this = mtd->priv; | ||
239 | writew(le16_to_cpu((u16) byte), this->IO_ADDR_W); | ||
240 | } | 140 | } |
241 | 141 | ||
242 | /** | 142 | /** |
@@ -248,22 +148,8 @@ static void nand_write_byte16(struct mtd_info *mtd, u_char byte) | |||
248 | */ | 148 | */ |
249 | static u16 nand_read_word(struct mtd_info *mtd) | 149 | static u16 nand_read_word(struct mtd_info *mtd) |
250 | { | 150 | { |
251 | struct nand_chip *this = mtd->priv; | 151 | struct nand_chip *chip = mtd->priv; |
252 | return readw(this->IO_ADDR_R); | 152 | return readw(chip->IO_ADDR_R); |
253 | } | ||
254 | |||
255 | /** | ||
256 | * nand_write_word - [DEFAULT] write one word to the chip | ||
257 | * @mtd: MTD device structure | ||
258 | * @word: data word to write | ||
259 | * | ||
260 | * Default write function for 16bit buswith without | ||
261 | * endianess conversion | ||
262 | */ | ||
263 | static void nand_write_word(struct mtd_info *mtd, u16 word) | ||
264 | { | ||
265 | struct nand_chip *this = mtd->priv; | ||
266 | writew(word, this->IO_ADDR_W); | ||
267 | } | 153 | } |
268 | 154 | ||
269 | /** | 155 | /** |
@@ -273,15 +159,15 @@ static void nand_write_word(struct mtd_info *mtd, u16 word) | |||
273 | * | 159 | * |
274 | * Default select function for 1 chip devices. | 160 | * Default select function for 1 chip devices. |
275 | */ | 161 | */ |
276 | static void nand_select_chip(struct mtd_info *mtd, int chip) | 162 | static void nand_select_chip(struct mtd_info *mtd, int chipnr) |
277 | { | 163 | { |
278 | struct nand_chip *this = mtd->priv; | 164 | struct nand_chip *chip = mtd->priv; |
279 | switch(chip) { | 165 | |
166 | switch (chipnr) { | ||
280 | case -1: | 167 | case -1: |
281 | this->hwcontrol(mtd, NAND_CTL_CLRNCE); | 168 | chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE); |
282 | break; | 169 | break; |
283 | case 0: | 170 | case 0: |
284 | this->hwcontrol(mtd, NAND_CTL_SETNCE); | ||
285 | break; | 171 | break; |
286 | 172 | ||
287 | default: | 173 | default: |
@@ -297,13 +183,13 @@ static void nand_select_chip(struct mtd_info *mtd, int chip) | |||
297 | * | 183 | * |
298 | * Default write function for 8bit buswith | 184 | * Default write function for 8bit buswith |
299 | */ | 185 | */ |
300 | static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) | 186 | static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) |
301 | { | 187 | { |
302 | int i; | 188 | int i; |
303 | struct nand_chip *this = mtd->priv; | 189 | struct nand_chip *chip = mtd->priv; |
304 | 190 | ||
305 | for (i=0; i<len; i++) | 191 | for (i = 0; i < len; i++) |
306 | writeb(buf[i], this->IO_ADDR_W); | 192 | writeb(buf[i], chip->IO_ADDR_W); |
307 | } | 193 | } |
308 | 194 | ||
309 | /** | 195 | /** |
@@ -314,13 +200,13 @@ static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) | |||
314 | * | 200 | * |
315 | * Default read function for 8bit buswith | 201 | * Default read function for 8bit buswith |
316 | */ | 202 | */ |
317 | static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) | 203 | static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) |
318 | { | 204 | { |
319 | int i; | 205 | int i; |
320 | struct nand_chip *this = mtd->priv; | 206 | struct nand_chip *chip = mtd->priv; |
321 | 207 | ||
322 | for (i=0; i<len; i++) | 208 | for (i = 0; i < len; i++) |
323 | buf[i] = readb(this->IO_ADDR_R); | 209 | buf[i] = readb(chip->IO_ADDR_R); |
324 | } | 210 | } |
325 | 211 | ||
326 | /** | 212 | /** |
@@ -331,15 +217,14 @@ static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) | |||
331 | * | 217 | * |
332 | * Default verify function for 8bit buswith | 218 | * Default verify function for 8bit buswith |
333 | */ | 219 | */ |
334 | static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) | 220 | static int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len) |
335 | { | 221 | { |
336 | int i; | 222 | int i; |
337 | struct nand_chip *this = mtd->priv; | 223 | struct nand_chip *chip = mtd->priv; |
338 | 224 | ||
339 | for (i=0; i<len; i++) | 225 | for (i = 0; i < len; i++) |
340 | if (buf[i] != readb(this->IO_ADDR_R)) | 226 | if (buf[i] != readb(chip->IO_ADDR_R)) |
341 | return -EFAULT; | 227 | return -EFAULT; |
342 | |||
343 | return 0; | 228 | return 0; |
344 | } | 229 | } |
345 | 230 | ||
@@ -351,15 +236,15 @@ static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) | |||
351 | * | 236 | * |
352 | * Default write function for 16bit buswith | 237 | * Default write function for 16bit buswith |
353 | */ | 238 | */ |
354 | static void nand_write_buf16(struct mtd_info *mtd, const u_char *buf, int len) | 239 | static void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) |
355 | { | 240 | { |
356 | int i; | 241 | int i; |
357 | struct nand_chip *this = mtd->priv; | 242 | struct nand_chip *chip = mtd->priv; |
358 | u16 *p = (u16 *) buf; | 243 | u16 *p = (u16 *) buf; |
359 | len >>= 1; | 244 | len >>= 1; |
360 | 245 | ||
361 | for (i=0; i<len; i++) | 246 | for (i = 0; i < len; i++) |
362 | writew(p[i], this->IO_ADDR_W); | 247 | writew(p[i], chip->IO_ADDR_W); |
363 | 248 | ||
364 | } | 249 | } |
365 | 250 | ||
@@ -371,15 +256,15 @@ static void nand_write_buf16(struct mtd_info *mtd, const u_char *buf, int len) | |||
371 | * | 256 | * |
372 | * Default read function for 16bit buswith | 257 | * Default read function for 16bit buswith |
373 | */ | 258 | */ |
374 | static void nand_read_buf16(struct mtd_info *mtd, u_char *buf, int len) | 259 | static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len) |
375 | { | 260 | { |
376 | int i; | 261 | int i; |
377 | struct nand_chip *this = mtd->priv; | 262 | struct nand_chip *chip = mtd->priv; |
378 | u16 *p = (u16 *) buf; | 263 | u16 *p = (u16 *) buf; |
379 | len >>= 1; | 264 | len >>= 1; |
380 | 265 | ||
381 | for (i=0; i<len; i++) | 266 | for (i = 0; i < len; i++) |
382 | p[i] = readw(this->IO_ADDR_R); | 267 | p[i] = readw(chip->IO_ADDR_R); |
383 | } | 268 | } |
384 | 269 | ||
385 | /** | 270 | /** |
@@ -390,15 +275,15 @@ static void nand_read_buf16(struct mtd_info *mtd, u_char *buf, int len) | |||
390 | * | 275 | * |
391 | * Default verify function for 16bit buswith | 276 | * Default verify function for 16bit buswith |
392 | */ | 277 | */ |
393 | static int nand_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len) | 278 | static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) |
394 | { | 279 | { |
395 | int i; | 280 | int i; |
396 | struct nand_chip *this = mtd->priv; | 281 | struct nand_chip *chip = mtd->priv; |
397 | u16 *p = (u16 *) buf; | 282 | u16 *p = (u16 *) buf; |
398 | len >>= 1; | 283 | len >>= 1; |
399 | 284 | ||
400 | for (i=0; i<len; i++) | 285 | for (i = 0; i < len; i++) |
401 | if (p[i] != readw(this->IO_ADDR_R)) | 286 | if (p[i] != readw(chip->IO_ADDR_R)) |
402 | return -EFAULT; | 287 | return -EFAULT; |
403 | 288 | ||
404 | return 0; | 289 | return 0; |
@@ -415,38 +300,37 @@ static int nand_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len) | |||
415 | static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) | 300 | static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) |
416 | { | 301 | { |
417 | int page, chipnr, res = 0; | 302 | int page, chipnr, res = 0; |
418 | struct nand_chip *this = mtd->priv; | 303 | struct nand_chip *chip = mtd->priv; |
419 | u16 bad; | 304 | u16 bad; |
420 | 305 | ||
421 | if (getchip) { | 306 | if (getchip) { |
422 | page = (int)(ofs >> this->page_shift); | 307 | page = (int)(ofs >> chip->page_shift); |
423 | chipnr = (int)(ofs >> this->chip_shift); | 308 | chipnr = (int)(ofs >> chip->chip_shift); |
424 | 309 | ||
425 | /* Grab the lock and see if the device is available */ | 310 | nand_get_device(chip, mtd, FL_READING); |
426 | nand_get_device (this, mtd, FL_READING); | ||
427 | 311 | ||
428 | /* Select the NAND device */ | 312 | /* Select the NAND device */ |
429 | this->select_chip(mtd, chipnr); | 313 | chip->select_chip(mtd, chipnr); |
430 | } else | 314 | } else |
431 | page = (int) ofs; | 315 | page = (int)ofs; |
432 | 316 | ||
433 | if (this->options & NAND_BUSWIDTH_16) { | 317 | if (chip->options & NAND_BUSWIDTH_16) { |
434 | this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page & this->pagemask); | 318 | chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos & 0xFE, |
435 | bad = cpu_to_le16(this->read_word(mtd)); | 319 | page & chip->pagemask); |
436 | if (this->badblockpos & 0x1) | 320 | bad = cpu_to_le16(chip->read_word(mtd)); |
321 | if (chip->badblockpos & 0x1) | ||
437 | bad >>= 8; | 322 | bad >>= 8; |
438 | if ((bad & 0xFF) != 0xff) | 323 | if ((bad & 0xFF) != 0xff) |
439 | res = 1; | 324 | res = 1; |
440 | } else { | 325 | } else { |
441 | this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos, page & this->pagemask); | 326 | chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos, |
442 | if (this->read_byte(mtd) != 0xff) | 327 | page & chip->pagemask); |
328 | if (chip->read_byte(mtd) != 0xff) | ||
443 | res = 1; | 329 | res = 1; |
444 | } | 330 | } |
445 | 331 | ||
446 | if (getchip) { | 332 | if (getchip) |
447 | /* Deselect and wake up anyone waiting on the device */ | ||
448 | nand_release_device(mtd); | 333 | nand_release_device(mtd); |
449 | } | ||
450 | 334 | ||
451 | return res; | 335 | return res; |
452 | } | 336 | } |
@@ -461,23 +345,33 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) | |||
461 | */ | 345 | */ |
462 | static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) | 346 | static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) |
463 | { | 347 | { |
464 | struct nand_chip *this = mtd->priv; | 348 | struct nand_chip *chip = mtd->priv; |
465 | u_char buf[2] = {0, 0}; | 349 | uint8_t buf[2] = { 0, 0 }; |
466 | size_t retlen; | 350 | int block, ret; |
467 | int block; | ||
468 | 351 | ||
469 | /* Get block number */ | 352 | /* Get block number */ |
470 | block = ((int) ofs) >> this->bbt_erase_shift; | 353 | block = ((int)ofs) >> chip->bbt_erase_shift; |
471 | if (this->bbt) | 354 | if (chip->bbt) |
472 | this->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1); | 355 | chip->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1); |
473 | 356 | ||
474 | /* Do we have a flash based bad block table ? */ | 357 | /* Do we have a flash based bad block table ? */ |
475 | if (this->options & NAND_USE_FLASH_BBT) | 358 | if (chip->options & NAND_USE_FLASH_BBT) |
476 | return nand_update_bbt (mtd, ofs); | 359 | ret = nand_update_bbt(mtd, ofs); |
360 | else { | ||
361 | /* We write two bytes, so we dont have to mess with 16 bit | ||
362 | * access | ||
363 | */ | ||
364 | ofs += mtd->oobsize; | ||
365 | chip->ops.len = 2; | ||
366 | chip->ops.datbuf = NULL; | ||
367 | chip->ops.oobbuf = buf; | ||
368 | chip->ops.ooboffs = chip->badblockpos & ~0x01; | ||
477 | 369 | ||
478 | /* We write two bytes, so we dont have to mess with 16 bit access */ | 370 | ret = nand_do_write_oob(mtd, ofs, &chip->ops); |
479 | ofs += mtd->oobsize + (this->badblockpos & ~0x01); | 371 | } |
480 | return nand_write_oob (mtd, ofs , 2, &retlen, buf); | 372 | if (!ret) |
373 | mtd->ecc_stats.badblocks++; | ||
374 | return ret; | ||
481 | } | 375 | } |
482 | 376 | ||
483 | /** | 377 | /** |
@@ -487,12 +381,12 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) | |||
487 | * | 381 | * |
488 | * The function expects, that the device is already selected | 382 | * The function expects, that the device is already selected |
489 | */ | 383 | */ |
490 | static int nand_check_wp (struct mtd_info *mtd) | 384 | static int nand_check_wp(struct mtd_info *mtd) |
491 | { | 385 | { |
492 | struct nand_chip *this = mtd->priv; | 386 | struct nand_chip *chip = mtd->priv; |
493 | /* Check the WP bit */ | 387 | /* Check the WP bit */ |
494 | this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); | 388 | chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); |
495 | return (this->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1; | 389 | return (chip->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1; |
496 | } | 390 | } |
497 | 391 | ||
498 | /** | 392 | /** |
@@ -505,32 +399,31 @@ static int nand_check_wp (struct mtd_info *mtd) | |||
505 | * Check, if the block is bad. Either by reading the bad block table or | 399 | * Check, if the block is bad. Either by reading the bad block table or |
506 | * calling of the scan function. | 400 | * calling of the scan function. |
507 | */ | 401 | */ |
508 | static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt) | 402 | static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip, |
403 | int allowbbt) | ||
509 | { | 404 | { |
510 | struct nand_chip *this = mtd->priv; | 405 | struct nand_chip *chip = mtd->priv; |
511 | 406 | ||
512 | if (!this->bbt) | 407 | if (!chip->bbt) |
513 | return this->block_bad(mtd, ofs, getchip); | 408 | return chip->block_bad(mtd, ofs, getchip); |
514 | 409 | ||
515 | /* Return info from the table */ | 410 | /* Return info from the table */ |
516 | return nand_isbad_bbt (mtd, ofs, allowbbt); | 411 | return nand_isbad_bbt(mtd, ofs, allowbbt); |
517 | } | 412 | } |
518 | 413 | ||
519 | DEFINE_LED_TRIGGER(nand_led_trigger); | ||
520 | |||
521 | /* | 414 | /* |
522 | * Wait for the ready pin, after a command | 415 | * Wait for the ready pin, after a command |
523 | * The timeout is catched later. | 416 | * The timeout is catched later. |
524 | */ | 417 | */ |
525 | static void nand_wait_ready(struct mtd_info *mtd) | 418 | static void nand_wait_ready(struct mtd_info *mtd) |
526 | { | 419 | { |
527 | struct nand_chip *this = mtd->priv; | 420 | struct nand_chip *chip = mtd->priv; |
528 | unsigned long timeo = jiffies + 2; | 421 | unsigned long timeo = jiffies + 2; |
529 | 422 | ||
530 | led_trigger_event(nand_led_trigger, LED_FULL); | 423 | led_trigger_event(nand_led_trigger, LED_FULL); |
531 | /* wait until command is processed or timeout occures */ | 424 | /* wait until command is processed or timeout occures */ |
532 | do { | 425 | do { |
533 | if (this->dev_ready(mtd)) | 426 | if (chip->dev_ready(mtd)) |
534 | break; | 427 | break; |
535 | touch_softlockup_watchdog(); | 428 | touch_softlockup_watchdog(); |
536 | } while (time_before(jiffies, timeo)); | 429 | } while (time_before(jiffies, timeo)); |
@@ -547,21 +440,21 @@ static void nand_wait_ready(struct mtd_info *mtd) | |||
547 | * Send command to NAND device. This function is used for small page | 440 | * Send command to NAND device. This function is used for small page |
548 | * devices (256/512 Bytes per page) | 441 | * devices (256/512 Bytes per page) |
549 | */ | 442 | */ |
550 | static void nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr) | 443 | static void nand_command(struct mtd_info *mtd, unsigned int command, |
444 | int column, int page_addr) | ||
551 | { | 445 | { |
552 | register struct nand_chip *this = mtd->priv; | 446 | register struct nand_chip *chip = mtd->priv; |
447 | int ctrl = NAND_CTRL_CLE | NAND_CTRL_CHANGE; | ||
553 | 448 | ||
554 | /* Begin command latch cycle */ | ||
555 | this->hwcontrol(mtd, NAND_CTL_SETCLE); | ||
556 | /* | 449 | /* |
557 | * Write out the command to the device. | 450 | * Write out the command to the device. |
558 | */ | 451 | */ |
559 | if (command == NAND_CMD_SEQIN) { | 452 | if (command == NAND_CMD_SEQIN) { |
560 | int readcmd; | 453 | int readcmd; |
561 | 454 | ||
562 | if (column >= mtd->oobblock) { | 455 | if (column >= mtd->writesize) { |
563 | /* OOB area */ | 456 | /* OOB area */ |
564 | column -= mtd->oobblock; | 457 | column -= mtd->writesize; |
565 | readcmd = NAND_CMD_READOOB; | 458 | readcmd = NAND_CMD_READOOB; |
566 | } else if (column < 256) { | 459 | } else if (column < 256) { |
567 | /* First 256 bytes --> READ0 */ | 460 | /* First 256 bytes --> READ0 */ |
@@ -570,38 +463,37 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in | |||
570 | column -= 256; | 463 | column -= 256; |
571 | readcmd = NAND_CMD_READ1; | 464 | readcmd = NAND_CMD_READ1; |
572 | } | 465 | } |
573 | this->write_byte(mtd, readcmd); | 466 | chip->cmd_ctrl(mtd, readcmd, ctrl); |
467 | ctrl &= ~NAND_CTRL_CHANGE; | ||
574 | } | 468 | } |
575 | this->write_byte(mtd, command); | 469 | chip->cmd_ctrl(mtd, command, ctrl); |
576 | |||
577 | /* Set ALE and clear CLE to start address cycle */ | ||
578 | this->hwcontrol(mtd, NAND_CTL_CLRCLE); | ||
579 | 470 | ||
580 | if (column != -1 || page_addr != -1) { | 471 | /* |
581 | this->hwcontrol(mtd, NAND_CTL_SETALE); | 472 | * Address cycle, when necessary |
582 | 473 | */ | |
583 | /* Serially input address */ | 474 | ctrl = NAND_CTRL_ALE | NAND_CTRL_CHANGE; |
584 | if (column != -1) { | 475 | /* Serially input address */ |
585 | /* Adjust columns for 16 bit buswidth */ | 476 | if (column != -1) { |
586 | if (this->options & NAND_BUSWIDTH_16) | 477 | /* Adjust columns for 16 bit buswidth */ |
587 | column >>= 1; | 478 | if (chip->options & NAND_BUSWIDTH_16) |
588 | this->write_byte(mtd, column); | 479 | column >>= 1; |
589 | } | 480 | chip->cmd_ctrl(mtd, column, ctrl); |
590 | if (page_addr != -1) { | 481 | ctrl &= ~NAND_CTRL_CHANGE; |
591 | this->write_byte(mtd, (unsigned char) (page_addr & 0xff)); | 482 | } |
592 | this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff)); | 483 | if (page_addr != -1) { |
593 | /* One more address cycle for devices > 32MiB */ | 484 | chip->cmd_ctrl(mtd, page_addr, ctrl); |
594 | if (this->chipsize > (32 << 20)) | 485 | ctrl &= ~NAND_CTRL_CHANGE; |
595 | this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f)); | 486 | chip->cmd_ctrl(mtd, page_addr >> 8, ctrl); |
596 | } | 487 | /* One more address cycle for devices > 32MiB */ |
597 | /* Latch in address */ | 488 | if (chip->chipsize > (32 << 20)) |
598 | this->hwcontrol(mtd, NAND_CTL_CLRALE); | 489 | chip->cmd_ctrl(mtd, page_addr >> 16, ctrl); |
599 | } | 490 | } |
491 | chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); | ||
600 | 492 | ||
601 | /* | 493 | /* |
602 | * program and erase have their own busy handlers | 494 | * program and erase have their own busy handlers |
603 | * status and sequential in needs no delay | 495 | * status and sequential in needs no delay |
604 | */ | 496 | */ |
605 | switch (command) { | 497 | switch (command) { |
606 | 498 | ||
607 | case NAND_CMD_PAGEPROG: | 499 | case NAND_CMD_PAGEPROG: |
@@ -612,29 +504,30 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in | |||
612 | return; | 504 | return; |
613 | 505 | ||
614 | case NAND_CMD_RESET: | 506 | case NAND_CMD_RESET: |
615 | if (this->dev_ready) | 507 | if (chip->dev_ready) |
616 | break; | 508 | break; |
617 | udelay(this->chip_delay); | 509 | udelay(chip->chip_delay); |
618 | this->hwcontrol(mtd, NAND_CTL_SETCLE); | 510 | chip->cmd_ctrl(mtd, NAND_CMD_STATUS, |
619 | this->write_byte(mtd, NAND_CMD_STATUS); | 511 | NAND_CTRL_CLE | NAND_CTRL_CHANGE); |
620 | this->hwcontrol(mtd, NAND_CTL_CLRCLE); | 512 | chip->cmd_ctrl(mtd, |
621 | while ( !(this->read_byte(mtd) & NAND_STATUS_READY)); | 513 | NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); |
514 | while (!(chip->read_byte(mtd) & NAND_STATUS_READY)) ; | ||
622 | return; | 515 | return; |
623 | 516 | ||
624 | /* This applies to read commands */ | 517 | /* This applies to read commands */ |
625 | default: | 518 | default: |
626 | /* | 519 | /* |
627 | * If we don't have access to the busy pin, we apply the given | 520 | * If we don't have access to the busy pin, we apply the given |
628 | * command delay | 521 | * command delay |
629 | */ | 522 | */ |
630 | if (!this->dev_ready) { | 523 | if (!chip->dev_ready) { |
631 | udelay (this->chip_delay); | 524 | udelay(chip->chip_delay); |
632 | return; | 525 | return; |
633 | } | 526 | } |
634 | } | 527 | } |
635 | /* Apply this short delay always to ensure that we do wait tWB in | 528 | /* Apply this short delay always to ensure that we do wait tWB in |
636 | * any case on any machine. */ | 529 | * any case on any machine. */ |
637 | ndelay (100); | 530 | ndelay(100); |
638 | 531 | ||
639 | nand_wait_ready(mtd); | 532 | nand_wait_ready(mtd); |
640 | } | 533 | } |
@@ -646,50 +539,49 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in | |||
646 | * @column: the column address for this command, -1 if none | 539 | * @column: the column address for this command, -1 if none |
647 | * @page_addr: the page address for this command, -1 if none | 540 | * @page_addr: the page address for this command, -1 if none |
648 | * | 541 | * |
649 | * Send command to NAND device. This is the version for the new large page devices | 542 | * Send command to NAND device. This is the version for the new large page |
650 | * We dont have the seperate regions as we have in the small page devices. | 543 | * devices We dont have the separate regions as we have in the small page |
651 | * We must emulate NAND_CMD_READOOB to keep the code compatible. | 544 | * devices. We must emulate NAND_CMD_READOOB to keep the code compatible. |
652 | * | 545 | * |
653 | */ | 546 | */ |
654 | static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, int page_addr) | 547 | static void nand_command_lp(struct mtd_info *mtd, unsigned int command, |
548 | int column, int page_addr) | ||
655 | { | 549 | { |
656 | register struct nand_chip *this = mtd->priv; | 550 | register struct nand_chip *chip = mtd->priv; |
657 | 551 | ||
658 | /* Emulate NAND_CMD_READOOB */ | 552 | /* Emulate NAND_CMD_READOOB */ |
659 | if (command == NAND_CMD_READOOB) { | 553 | if (command == NAND_CMD_READOOB) { |
660 | column += mtd->oobblock; | 554 | column += mtd->writesize; |
661 | command = NAND_CMD_READ0; | 555 | command = NAND_CMD_READ0; |
662 | } | 556 | } |
663 | 557 | ||
664 | 558 | /* Command latch cycle */ | |
665 | /* Begin command latch cycle */ | 559 | chip->cmd_ctrl(mtd, command & 0xff, |
666 | this->hwcontrol(mtd, NAND_CTL_SETCLE); | 560 | NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE); |
667 | /* Write out the command to the device. */ | ||
668 | this->write_byte(mtd, (command & 0xff)); | ||
669 | /* End command latch cycle */ | ||
670 | this->hwcontrol(mtd, NAND_CTL_CLRCLE); | ||
671 | 561 | ||
672 | if (column != -1 || page_addr != -1) { | 562 | if (column != -1 || page_addr != -1) { |
673 | this->hwcontrol(mtd, NAND_CTL_SETALE); | 563 | int ctrl = NAND_CTRL_CHANGE | NAND_NCE | NAND_ALE; |
674 | 564 | ||
675 | /* Serially input address */ | 565 | /* Serially input address */ |
676 | if (column != -1) { | 566 | if (column != -1) { |
677 | /* Adjust columns for 16 bit buswidth */ | 567 | /* Adjust columns for 16 bit buswidth */ |
678 | if (this->options & NAND_BUSWIDTH_16) | 568 | if (chip->options & NAND_BUSWIDTH_16) |
679 | column >>= 1; | 569 | column >>= 1; |
680 | this->write_byte(mtd, column & 0xff); | 570 | chip->cmd_ctrl(mtd, column, ctrl); |
681 | this->write_byte(mtd, column >> 8); | 571 | ctrl &= ~NAND_CTRL_CHANGE; |
572 | chip->cmd_ctrl(mtd, column >> 8, ctrl); | ||
682 | } | 573 | } |
683 | if (page_addr != -1) { | 574 | if (page_addr != -1) { |
684 | this->write_byte(mtd, (unsigned char) (page_addr & 0xff)); | 575 | chip->cmd_ctrl(mtd, page_addr, ctrl); |
685 | this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff)); | 576 | chip->cmd_ctrl(mtd, page_addr >> 8, |
577 | NAND_NCE | NAND_ALE); | ||
686 | /* One more address cycle for devices > 128MiB */ | 578 | /* One more address cycle for devices > 128MiB */ |
687 | if (this->chipsize > (128 << 20)) | 579 | if (chip->chipsize > (128 << 20)) |
688 | this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0xff)); | 580 | chip->cmd_ctrl(mtd, page_addr >> 16, |
581 | NAND_NCE | NAND_ALE); | ||
689 | } | 582 | } |
690 | /* Latch in address */ | ||
691 | this->hwcontrol(mtd, NAND_CTL_CLRALE); | ||
692 | } | 583 | } |
584 | chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); | ||
693 | 585 | ||
694 | /* | 586 | /* |
695 | * program and erase have their own busy handlers | 587 | * program and erase have their own busy handlers |
@@ -702,55 +594,62 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, | |||
702 | case NAND_CMD_ERASE1: | 594 | case NAND_CMD_ERASE1: |
703 | case NAND_CMD_ERASE2: | 595 | case NAND_CMD_ERASE2: |
704 | case NAND_CMD_SEQIN: | 596 | case NAND_CMD_SEQIN: |
597 | case NAND_CMD_RNDIN: | ||
705 | case NAND_CMD_STATUS: | 598 | case NAND_CMD_STATUS: |
706 | case NAND_CMD_DEPLETE1: | 599 | case NAND_CMD_DEPLETE1: |
707 | return; | 600 | return; |
708 | 601 | ||
709 | /* | 602 | /* |
710 | * read error status commands require only a short delay | 603 | * read error status commands require only a short delay |
711 | */ | 604 | */ |
712 | case NAND_CMD_STATUS_ERROR: | 605 | case NAND_CMD_STATUS_ERROR: |
713 | case NAND_CMD_STATUS_ERROR0: | 606 | case NAND_CMD_STATUS_ERROR0: |
714 | case NAND_CMD_STATUS_ERROR1: | 607 | case NAND_CMD_STATUS_ERROR1: |
715 | case NAND_CMD_STATUS_ERROR2: | 608 | case NAND_CMD_STATUS_ERROR2: |
716 | case NAND_CMD_STATUS_ERROR3: | 609 | case NAND_CMD_STATUS_ERROR3: |
717 | udelay(this->chip_delay); | 610 | udelay(chip->chip_delay); |
718 | return; | 611 | return; |
719 | 612 | ||
720 | case NAND_CMD_RESET: | 613 | case NAND_CMD_RESET: |
721 | if (this->dev_ready) | 614 | if (chip->dev_ready) |
722 | break; | 615 | break; |
723 | udelay(this->chip_delay); | 616 | udelay(chip->chip_delay); |
724 | this->hwcontrol(mtd, NAND_CTL_SETCLE); | 617 | chip->cmd_ctrl(mtd, NAND_CMD_STATUS, |
725 | this->write_byte(mtd, NAND_CMD_STATUS); | 618 | NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE); |
726 | this->hwcontrol(mtd, NAND_CTL_CLRCLE); | 619 | chip->cmd_ctrl(mtd, NAND_CMD_NONE, |
727 | while ( !(this->read_byte(mtd) & NAND_STATUS_READY)); | 620 | NAND_NCE | NAND_CTRL_CHANGE); |
621 | while (!(chip->read_byte(mtd) & NAND_STATUS_READY)) ; | ||
622 | return; | ||
623 | |||
624 | case NAND_CMD_RNDOUT: | ||
625 | /* No ready / busy check necessary */ | ||
626 | chip->cmd_ctrl(mtd, NAND_CMD_RNDOUTSTART, | ||
627 | NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE); | ||
628 | chip->cmd_ctrl(mtd, NAND_CMD_NONE, | ||
629 | NAND_NCE | NAND_CTRL_CHANGE); | ||
728 | return; | 630 | return; |
729 | 631 | ||
730 | case NAND_CMD_READ0: | 632 | case NAND_CMD_READ0: |
731 | /* Begin command latch cycle */ | 633 | chip->cmd_ctrl(mtd, NAND_CMD_READSTART, |
732 | this->hwcontrol(mtd, NAND_CTL_SETCLE); | 634 | NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE); |
733 | /* Write out the start read command */ | 635 | chip->cmd_ctrl(mtd, NAND_CMD_NONE, |
734 | this->write_byte(mtd, NAND_CMD_READSTART); | 636 | NAND_NCE | NAND_CTRL_CHANGE); |
735 | /* End command latch cycle */ | 637 | |
736 | this->hwcontrol(mtd, NAND_CTL_CLRCLE); | 638 | /* This applies to read commands */ |
737 | /* Fall through into ready check */ | ||
738 | |||
739 | /* This applies to read commands */ | ||
740 | default: | 639 | default: |
741 | /* | 640 | /* |
742 | * If we don't have access to the busy pin, we apply the given | 641 | * If we don't have access to the busy pin, we apply the given |
743 | * command delay | 642 | * command delay |
744 | */ | 643 | */ |
745 | if (!this->dev_ready) { | 644 | if (!chip->dev_ready) { |
746 | udelay (this->chip_delay); | 645 | udelay(chip->chip_delay); |
747 | return; | 646 | return; |
748 | } | 647 | } |
749 | } | 648 | } |
750 | 649 | ||
751 | /* Apply this short delay always to ensure that we do wait tWB in | 650 | /* Apply this short delay always to ensure that we do wait tWB in |
752 | * any case on any machine. */ | 651 | * any case on any machine. */ |
753 | ndelay (100); | 652 | ndelay(100); |
754 | 653 | ||
755 | nand_wait_ready(mtd); | 654 | nand_wait_ready(mtd); |
756 | } | 655 | } |
@@ -763,34 +662,28 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, | |||
763 | * | 662 | * |
764 | * Get the device and lock it for exclusive access | 663 | * Get the device and lock it for exclusive access |
765 | */ | 664 | */ |
766 | static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state) | 665 | static int |
666 | nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state) | ||
767 | { | 667 | { |
768 | struct nand_chip *active; | 668 | spinlock_t *lock = &chip->controller->lock; |
769 | spinlock_t *lock; | 669 | wait_queue_head_t *wq = &chip->controller->wq; |
770 | wait_queue_head_t *wq; | 670 | DECLARE_WAITQUEUE(wait, current); |
771 | DECLARE_WAITQUEUE (wait, current); | 671 | retry: |
772 | |||
773 | lock = (this->controller) ? &this->controller->lock : &this->chip_lock; | ||
774 | wq = (this->controller) ? &this->controller->wq : &this->wq; | ||
775 | retry: | ||
776 | active = this; | ||
777 | spin_lock(lock); | 672 | spin_lock(lock); |
778 | 673 | ||
779 | /* Hardware controller shared among independend devices */ | 674 | /* Hardware controller shared among independend devices */ |
780 | if (this->controller) { | 675 | /* Hardware controller shared among independend devices */ |
781 | if (this->controller->active) | 676 | if (!chip->controller->active) |
782 | active = this->controller->active; | 677 | chip->controller->active = chip; |
783 | else | 678 | |
784 | this->controller->active = this; | 679 | if (chip->controller->active == chip && chip->state == FL_READY) { |
785 | } | 680 | chip->state = new_state; |
786 | if (active == this && this->state == FL_READY) { | ||
787 | this->state = new_state; | ||
788 | spin_unlock(lock); | 681 | spin_unlock(lock); |
789 | return 0; | 682 | return 0; |
790 | } | 683 | } |
791 | if (new_state == FL_PM_SUSPENDED) { | 684 | if (new_state == FL_PM_SUSPENDED) { |
792 | spin_unlock(lock); | 685 | spin_unlock(lock); |
793 | return (this->state == FL_PM_SUSPENDED) ? 0 : -EAGAIN; | 686 | return (chip->state == FL_PM_SUSPENDED) ? 0 : -EAGAIN; |
794 | } | 687 | } |
795 | set_current_state(TASK_UNINTERRUPTIBLE); | 688 | set_current_state(TASK_UNINTERRUPTIBLE); |
796 | add_wait_queue(wq, &wait); | 689 | add_wait_queue(wq, &wait); |
@@ -804,540 +697,339 @@ retry: | |||
804 | * nand_wait - [DEFAULT] wait until the command is done | 697 | * nand_wait - [DEFAULT] wait until the command is done |
805 | * @mtd: MTD device structure | 698 | * @mtd: MTD device structure |
806 | * @this: NAND chip structure | 699 | * @this: NAND chip structure |
807 | * @state: state to select the max. timeout value | ||
808 | * | 700 | * |
809 | * Wait for command done. This applies to erase and program only | 701 | * Wait for command done. This applies to erase and program only |
810 | * Erase can take up to 400ms and program up to 20ms according to | 702 | * Erase can take up to 400ms and program up to 20ms according to |
811 | * general NAND and SmartMedia specs | 703 | * general NAND and SmartMedia specs |
812 | * | 704 | * |
813 | */ | 705 | */ |
814 | static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) | 706 | static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip) |
815 | { | 707 | { |
816 | 708 | ||
817 | unsigned long timeo = jiffies; | 709 | unsigned long timeo = jiffies; |
818 | int status; | 710 | int status, state = chip->state; |
819 | 711 | ||
820 | if (state == FL_ERASING) | 712 | if (state == FL_ERASING) |
821 | timeo += (HZ * 400) / 1000; | 713 | timeo += (HZ * 400) / 1000; |
822 | else | 714 | else |
823 | timeo += (HZ * 20) / 1000; | 715 | timeo += (HZ * 20) / 1000; |
824 | 716 | ||
825 | led_trigger_event(nand_led_trigger, LED_FULL); | 717 | led_trigger_event(nand_led_trigger, LED_FULL); |
826 | 718 | ||
827 | /* Apply this short delay always to ensure that we do wait tWB in | 719 | /* Apply this short delay always to ensure that we do wait tWB in |
828 | * any case on any machine. */ | 720 | * any case on any machine. */ |
829 | ndelay (100); | 721 | ndelay(100); |
830 | 722 | ||
831 | if ((state == FL_ERASING) && (this->options & NAND_IS_AND)) | 723 | if ((state == FL_ERASING) && (chip->options & NAND_IS_AND)) |
832 | this->cmdfunc (mtd, NAND_CMD_STATUS_MULTI, -1, -1); | 724 | chip->cmdfunc(mtd, NAND_CMD_STATUS_MULTI, -1, -1); |
833 | else | 725 | else |
834 | this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); | 726 | chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); |
835 | 727 | ||
836 | while (time_before(jiffies, timeo)) { | 728 | while (time_before(jiffies, timeo)) { |
837 | /* Check, if we were interrupted */ | 729 | if (chip->dev_ready) { |
838 | if (this->state != state) | 730 | if (chip->dev_ready(mtd)) |
839 | return 0; | ||
840 | |||
841 | if (this->dev_ready) { | ||
842 | if (this->dev_ready(mtd)) | ||
843 | break; | 731 | break; |
844 | } else { | 732 | } else { |
845 | if (this->read_byte(mtd) & NAND_STATUS_READY) | 733 | if (chip->read_byte(mtd) & NAND_STATUS_READY) |
846 | break; | 734 | break; |
847 | } | 735 | } |
848 | cond_resched(); | 736 | cond_resched(); |
849 | } | 737 | } |
850 | led_trigger_event(nand_led_trigger, LED_OFF); | 738 | led_trigger_event(nand_led_trigger, LED_OFF); |
851 | 739 | ||
852 | status = (int) this->read_byte(mtd); | 740 | status = (int)chip->read_byte(mtd); |
853 | return status; | 741 | return status; |
854 | } | 742 | } |
855 | 743 | ||
856 | /** | 744 | /** |
857 | * nand_write_page - [GENERIC] write one page | 745 | * nand_read_page_raw - [Intern] read raw page data without ecc |
858 | * @mtd: MTD device structure | 746 | * @mtd: mtd info structure |
859 | * @this: NAND chip structure | 747 | * @chip: nand chip info structure |
860 | * @page: startpage inside the chip, must be called with (page & this->pagemask) | 748 | * @buf: buffer to store read data |
861 | * @oob_buf: out of band data buffer | ||
862 | * @oobsel: out of band selecttion structre | ||
863 | * @cached: 1 = enable cached programming if supported by chip | ||
864 | * | ||
865 | * Nand_page_program function is used for write and writev ! | ||
866 | * This function will always program a full page of data | ||
867 | * If you call it with a non page aligned buffer, you're lost :) | ||
868 | * | ||
869 | * Cached programming is not supported yet. | ||
870 | */ | 749 | */ |
871 | static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, | 750 | static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, |
872 | u_char *oob_buf, struct nand_oobinfo *oobsel, int cached) | 751 | uint8_t *buf) |
873 | { | 752 | { |
874 | int i, status; | 753 | chip->read_buf(mtd, buf, mtd->writesize); |
875 | u_char ecc_code[32]; | 754 | chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); |
876 | int eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE; | 755 | return 0; |
877 | int *oob_config = oobsel->eccpos; | 756 | } |
878 | int datidx = 0, eccidx = 0, eccsteps = this->eccsteps; | ||
879 | int eccbytes = 0; | ||
880 | |||
881 | /* FIXME: Enable cached programming */ | ||
882 | cached = 0; | ||
883 | 757 | ||
884 | /* Send command to begin auto page programming */ | 758 | /** |
885 | this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page); | 759 | * nand_read_page_swecc - {REPLACABLE] software ecc based page read function |
760 | * @mtd: mtd info structure | ||
761 | * @chip: nand chip info structure | ||
762 | * @buf: buffer to store read data | ||
763 | */ | ||
764 | static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, | ||
765 | uint8_t *buf) | ||
766 | { | ||
767 | int i, eccsize = chip->ecc.size; | ||
768 | int eccbytes = chip->ecc.bytes; | ||
769 | int eccsteps = chip->ecc.steps; | ||
770 | uint8_t *p = buf; | ||
771 | uint8_t *ecc_calc = chip->buffers.ecccalc; | ||
772 | uint8_t *ecc_code = chip->buffers.ecccode; | ||
773 | int *eccpos = chip->ecc.layout->eccpos; | ||
886 | 774 | ||
887 | /* Write out complete page of data, take care of eccmode */ | 775 | nand_read_page_raw(mtd, chip, buf); |
888 | switch (eccmode) { | ||
889 | /* No ecc, write all */ | ||
890 | case NAND_ECC_NONE: | ||
891 | printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n"); | ||
892 | this->write_buf(mtd, this->data_poi, mtd->oobblock); | ||
893 | break; | ||
894 | 776 | ||
895 | /* Software ecc 3/256, write all */ | 777 | for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) |
896 | case NAND_ECC_SOFT: | 778 | chip->ecc.calculate(mtd, p, &ecc_calc[i]); |
897 | for (; eccsteps; eccsteps--) { | ||
898 | this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code); | ||
899 | for (i = 0; i < 3; i++, eccidx++) | ||
900 | oob_buf[oob_config[eccidx]] = ecc_code[i]; | ||
901 | datidx += this->eccsize; | ||
902 | } | ||
903 | this->write_buf(mtd, this->data_poi, mtd->oobblock); | ||
904 | break; | ||
905 | default: | ||
906 | eccbytes = this->eccbytes; | ||
907 | for (; eccsteps; eccsteps--) { | ||
908 | /* enable hardware ecc logic for write */ | ||
909 | this->enable_hwecc(mtd, NAND_ECC_WRITE); | ||
910 | this->write_buf(mtd, &this->data_poi[datidx], this->eccsize); | ||
911 | this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code); | ||
912 | for (i = 0; i < eccbytes; i++, eccidx++) | ||
913 | oob_buf[oob_config[eccidx]] = ecc_code[i]; | ||
914 | /* If the hardware ecc provides syndromes then | ||
915 | * the ecc code must be written immidiately after | ||
916 | * the data bytes (words) */ | ||
917 | if (this->options & NAND_HWECC_SYNDROME) | ||
918 | this->write_buf(mtd, ecc_code, eccbytes); | ||
919 | datidx += this->eccsize; | ||
920 | } | ||
921 | break; | ||
922 | } | ||
923 | 779 | ||
924 | /* Write out OOB data */ | 780 | for (i = 0; i < chip->ecc.total; i++) |
925 | if (this->options & NAND_HWECC_SYNDROME) | 781 | ecc_code[i] = chip->oob_poi[eccpos[i]]; |
926 | this->write_buf(mtd, &oob_buf[oobsel->eccbytes], mtd->oobsize - oobsel->eccbytes); | ||
927 | else | ||
928 | this->write_buf(mtd, oob_buf, mtd->oobsize); | ||
929 | 782 | ||
930 | /* Send command to actually program the data */ | 783 | eccsteps = chip->ecc.steps; |
931 | this->cmdfunc (mtd, cached ? NAND_CMD_CACHEDPROG : NAND_CMD_PAGEPROG, -1, -1); | 784 | p = buf; |
932 | 785 | ||
933 | if (!cached) { | 786 | for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { |
934 | /* call wait ready function */ | 787 | int stat; |
935 | status = this->waitfunc (mtd, this, FL_WRITING); | ||
936 | 788 | ||
937 | /* See if operation failed and additional status checks are available */ | 789 | stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); |
938 | if ((status & NAND_STATUS_FAIL) && (this->errstat)) { | 790 | if (stat == -1) |
939 | status = this->errstat(mtd, this, FL_WRITING, status, page); | 791 | mtd->ecc_stats.failed++; |
940 | } | 792 | else |
941 | 793 | mtd->ecc_stats.corrected += stat; | |
942 | /* See if device thinks it succeeded */ | ||
943 | if (status & NAND_STATUS_FAIL) { | ||
944 | DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write, page 0x%08x, ", __FUNCTION__, page); | ||
945 | return -EIO; | ||
946 | } | ||
947 | } else { | ||
948 | /* FIXME: Implement cached programming ! */ | ||
949 | /* wait until cache is ready*/ | ||
950 | // status = this->waitfunc (mtd, this, FL_CACHEDRPG); | ||
951 | } | 794 | } |
952 | return 0; | 795 | return 0; |
953 | } | 796 | } |
954 | 797 | ||
955 | #ifdef CONFIG_MTD_NAND_VERIFY_WRITE | ||
956 | /** | 798 | /** |
957 | * nand_verify_pages - [GENERIC] verify the chip contents after a write | 799 | * nand_read_page_hwecc - {REPLACABLE] hardware ecc based page read function |
958 | * @mtd: MTD device structure | 800 | * @mtd: mtd info structure |
959 | * @this: NAND chip structure | 801 | * @chip: nand chip info structure |
960 | * @page: startpage inside the chip, must be called with (page & this->pagemask) | 802 | * @buf: buffer to store read data |
961 | * @numpages: number of pages to verify | ||
962 | * @oob_buf: out of band data buffer | ||
963 | * @oobsel: out of band selecttion structre | ||
964 | * @chipnr: number of the current chip | ||
965 | * @oobmode: 1 = full buffer verify, 0 = ecc only | ||
966 | * | 803 | * |
967 | * The NAND device assumes that it is always writing to a cleanly erased page. | 804 | * Not for syndrome calculating ecc controllers which need a special oob layout |
968 | * Hence, it performs its internal write verification only on bits that | ||
969 | * transitioned from 1 to 0. The device does NOT verify the whole page on a | ||
970 | * byte by byte basis. It is possible that the page was not completely erased | ||
971 | * or the page is becoming unusable due to wear. The read with ECC would catch | ||
972 | * the error later when the ECC page check fails, but we would rather catch | ||
973 | * it early in the page write stage. Better to write no data than invalid data. | ||
974 | */ | 805 | */ |
975 | static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages, | 806 | static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, |
976 | u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode) | 807 | uint8_t *buf) |
977 | { | 808 | { |
978 | int i, j, datidx = 0, oobofs = 0, res = -EIO; | 809 | int i, eccsize = chip->ecc.size; |
979 | int eccsteps = this->eccsteps; | 810 | int eccbytes = chip->ecc.bytes; |
980 | int hweccbytes; | 811 | int eccsteps = chip->ecc.steps; |
981 | u_char oobdata[64]; | 812 | uint8_t *p = buf; |
982 | 813 | uint8_t *ecc_calc = chip->buffers.ecccalc; | |
983 | hweccbytes = (this->options & NAND_HWECC_SYNDROME) ? (oobsel->eccbytes / eccsteps) : 0; | 814 | uint8_t *ecc_code = chip->buffers.ecccode; |
984 | 815 | int *eccpos = chip->ecc.layout->eccpos; | |
985 | /* Send command to read back the first page */ | 816 | |
986 | this->cmdfunc (mtd, NAND_CMD_READ0, 0, page); | 817 | for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { |
987 | 818 | chip->ecc.hwctl(mtd, NAND_ECC_READ); | |
988 | for(;;) { | 819 | chip->read_buf(mtd, p, eccsize); |
989 | for (j = 0; j < eccsteps; j++) { | 820 | chip->ecc.calculate(mtd, p, &ecc_calc[i]); |
990 | /* Loop through and verify the data */ | 821 | } |
991 | if (this->verify_buf(mtd, &this->data_poi[datidx], mtd->eccsize)) { | 822 | chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); |
992 | DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page); | ||
993 | goto out; | ||
994 | } | ||
995 | datidx += mtd->eccsize; | ||
996 | /* Have we a hw generator layout ? */ | ||
997 | if (!hweccbytes) | ||
998 | continue; | ||
999 | if (this->verify_buf(mtd, &this->oob_buf[oobofs], hweccbytes)) { | ||
1000 | DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page); | ||
1001 | goto out; | ||
1002 | } | ||
1003 | oobofs += hweccbytes; | ||
1004 | } | ||
1005 | 823 | ||
1006 | /* check, if we must compare all data or if we just have to | 824 | for (i = 0; i < chip->ecc.total; i++) |
1007 | * compare the ecc bytes | 825 | ecc_code[i] = chip->oob_poi[eccpos[i]]; |
1008 | */ | ||
1009 | if (oobmode) { | ||
1010 | if (this->verify_buf(mtd, &oob_buf[oobofs], mtd->oobsize - hweccbytes * eccsteps)) { | ||
1011 | DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page); | ||
1012 | goto out; | ||
1013 | } | ||
1014 | } else { | ||
1015 | /* Read always, else autoincrement fails */ | ||
1016 | this->read_buf(mtd, oobdata, mtd->oobsize - hweccbytes * eccsteps); | ||
1017 | |||
1018 | if (oobsel->useecc != MTD_NANDECC_OFF && !hweccbytes) { | ||
1019 | int ecccnt = oobsel->eccbytes; | ||
1020 | |||
1021 | for (i = 0; i < ecccnt; i++) { | ||
1022 | int idx = oobsel->eccpos[i]; | ||
1023 | if (oobdata[idx] != oob_buf[oobofs + idx] ) { | ||
1024 | DEBUG (MTD_DEBUG_LEVEL0, | ||
1025 | "%s: Failed ECC write " | ||
1026 | "verify, page 0x%08x, " "%6i bytes were succesful\n", __FUNCTION__, page, i); | ||
1027 | goto out; | ||
1028 | } | ||
1029 | } | ||
1030 | } | ||
1031 | } | ||
1032 | oobofs += mtd->oobsize - hweccbytes * eccsteps; | ||
1033 | page++; | ||
1034 | numpages--; | ||
1035 | |||
1036 | /* Apply delay or wait for ready/busy pin | ||
1037 | * Do this before the AUTOINCR check, so no problems | ||
1038 | * arise if a chip which does auto increment | ||
1039 | * is marked as NOAUTOINCR by the board driver. | ||
1040 | * Do this also before returning, so the chip is | ||
1041 | * ready for the next command. | ||
1042 | */ | ||
1043 | if (!this->dev_ready) | ||
1044 | udelay (this->chip_delay); | ||
1045 | else | ||
1046 | nand_wait_ready(mtd); | ||
1047 | 826 | ||
1048 | /* All done, return happy */ | 827 | eccsteps = chip->ecc.steps; |
1049 | if (!numpages) | 828 | p = buf; |
1050 | return 0; | ||
1051 | 829 | ||
830 | for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { | ||
831 | int stat; | ||
1052 | 832 | ||
1053 | /* Check, if the chip supports auto page increment */ | 833 | stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); |
1054 | if (!NAND_CANAUTOINCR(this)) | 834 | if (stat == -1) |
1055 | this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page); | 835 | mtd->ecc_stats.failed++; |
836 | else | ||
837 | mtd->ecc_stats.corrected += stat; | ||
1056 | } | 838 | } |
1057 | /* | 839 | return 0; |
1058 | * Terminate the read command. We come here in case of an error | ||
1059 | * So we must issue a reset command. | ||
1060 | */ | ||
1061 | out: | ||
1062 | this->cmdfunc (mtd, NAND_CMD_RESET, -1, -1); | ||
1063 | return res; | ||
1064 | } | 840 | } |
1065 | #endif | ||
1066 | 841 | ||
1067 | /** | 842 | /** |
1068 | * nand_read - [MTD Interface] MTD compability function for nand_do_read_ecc | 843 | * nand_read_page_syndrome - {REPLACABLE] hardware ecc syndrom based page read |
1069 | * @mtd: MTD device structure | 844 | * @mtd: mtd info structure |
1070 | * @from: offset to read from | 845 | * @chip: nand chip info structure |
1071 | * @len: number of bytes to read | 846 | * @buf: buffer to store read data |
1072 | * @retlen: pointer to variable to store the number of read bytes | ||
1073 | * @buf: the databuffer to put data | ||
1074 | * | 847 | * |
1075 | * This function simply calls nand_do_read_ecc with oob buffer and oobsel = NULL | 848 | * The hw generator calculates the error syndrome automatically. Therefor |
1076 | * and flags = 0xff | 849 | * we need a special oob layout and handling. |
1077 | */ | 850 | */ |
1078 | static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf) | 851 | static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip, |
852 | uint8_t *buf) | ||
1079 | { | 853 | { |
1080 | return nand_do_read_ecc (mtd, from, len, retlen, buf, NULL, &mtd->oobinfo, 0xff); | 854 | int i, eccsize = chip->ecc.size; |
1081 | } | 855 | int eccbytes = chip->ecc.bytes; |
856 | int eccsteps = chip->ecc.steps; | ||
857 | uint8_t *p = buf; | ||
858 | uint8_t *oob = chip->oob_poi; | ||
859 | |||
860 | for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { | ||
861 | int stat; | ||
862 | |||
863 | chip->ecc.hwctl(mtd, NAND_ECC_READ); | ||
864 | chip->read_buf(mtd, p, eccsize); | ||
865 | |||
866 | if (chip->ecc.prepad) { | ||
867 | chip->read_buf(mtd, oob, chip->ecc.prepad); | ||
868 | oob += chip->ecc.prepad; | ||
869 | } | ||
870 | |||
871 | chip->ecc.hwctl(mtd, NAND_ECC_READSYN); | ||
872 | chip->read_buf(mtd, oob, eccbytes); | ||
873 | stat = chip->ecc.correct(mtd, p, oob, NULL); | ||
874 | |||
875 | if (stat == -1) | ||
876 | mtd->ecc_stats.failed++; | ||
877 | else | ||
878 | mtd->ecc_stats.corrected += stat; | ||
879 | |||
880 | oob += eccbytes; | ||
881 | |||
882 | if (chip->ecc.postpad) { | ||
883 | chip->read_buf(mtd, oob, chip->ecc.postpad); | ||
884 | oob += chip->ecc.postpad; | ||
885 | } | ||
886 | } | ||
887 | |||
888 | /* Calculate remaining oob bytes */ | ||
889 | i = mtd->oobsize - (oob - chip->oob_poi); | ||
890 | if (i) | ||
891 | chip->read_buf(mtd, oob, i); | ||
1082 | 892 | ||
893 | return 0; | ||
894 | } | ||
1083 | 895 | ||
1084 | /** | 896 | /** |
1085 | * nand_read_ecc - [MTD Interface] MTD compability function for nand_do_read_ecc | 897 | * nand_transfer_oob - [Internal] Transfer oob to client buffer |
1086 | * @mtd: MTD device structure | 898 | * @chip: nand chip structure |
1087 | * @from: offset to read from | 899 | * @ops: oob ops structure |
1088 | * @len: number of bytes to read | ||
1089 | * @retlen: pointer to variable to store the number of read bytes | ||
1090 | * @buf: the databuffer to put data | ||
1091 | * @oob_buf: filesystem supplied oob data buffer | ||
1092 | * @oobsel: oob selection structure | ||
1093 | * | ||
1094 | * This function simply calls nand_do_read_ecc with flags = 0xff | ||
1095 | */ | 900 | */ |
1096 | static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, | 901 | static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob, |
1097 | size_t * retlen, u_char * buf, u_char * oob_buf, struct nand_oobinfo *oobsel) | 902 | struct mtd_oob_ops *ops) |
1098 | { | 903 | { |
1099 | /* use userspace supplied oobinfo, if zero */ | 904 | size_t len = ops->ooblen; |
1100 | if (oobsel == NULL) | 905 | |
1101 | oobsel = &mtd->oobinfo; | 906 | switch(ops->mode) { |
1102 | return nand_do_read_ecc(mtd, from, len, retlen, buf, oob_buf, oobsel, 0xff); | 907 | |
908 | case MTD_OOB_PLACE: | ||
909 | case MTD_OOB_RAW: | ||
910 | memcpy(oob, chip->oob_poi + ops->ooboffs, len); | ||
911 | return oob + len; | ||
912 | |||
913 | case MTD_OOB_AUTO: { | ||
914 | struct nand_oobfree *free = chip->ecc.layout->oobfree; | ||
915 | uint32_t boffs = 0, roffs = ops->ooboffs; | ||
916 | size_t bytes = 0; | ||
917 | |||
918 | for(; free->length && len; free++, len -= bytes) { | ||
919 | /* Read request not from offset 0 ? */ | ||
920 | if (unlikely(roffs)) { | ||
921 | if (roffs >= free->length) { | ||
922 | roffs -= free->length; | ||
923 | continue; | ||
924 | } | ||
925 | boffs = free->offset + roffs; | ||
926 | bytes = min_t(size_t, len, | ||
927 | (free->length - roffs)); | ||
928 | roffs = 0; | ||
929 | } else { | ||
930 | bytes = min_t(size_t, len, free->length); | ||
931 | boffs = free->offset; | ||
932 | } | ||
933 | memcpy(oob, chip->oob_poi + boffs, bytes); | ||
934 | oob += bytes; | ||
935 | } | ||
936 | return oob; | ||
937 | } | ||
938 | default: | ||
939 | BUG(); | ||
940 | } | ||
941 | return NULL; | ||
1103 | } | 942 | } |
1104 | 943 | ||
1105 | |||
1106 | /** | 944 | /** |
1107 | * nand_do_read_ecc - [MTD Interface] Read data with ECC | 945 | * nand_do_read_ops - [Internal] Read data with ECC |
946 | * | ||
1108 | * @mtd: MTD device structure | 947 | * @mtd: MTD device structure |
1109 | * @from: offset to read from | 948 | * @from: offset to read from |
1110 | * @len: number of bytes to read | ||
1111 | * @retlen: pointer to variable to store the number of read bytes | ||
1112 | * @buf: the databuffer to put data | ||
1113 | * @oob_buf: filesystem supplied oob data buffer (can be NULL) | ||
1114 | * @oobsel: oob selection structure | ||
1115 | * @flags: flag to indicate if nand_get_device/nand_release_device should be preformed | ||
1116 | * and how many corrected error bits are acceptable: | ||
1117 | * bits 0..7 - number of tolerable errors | ||
1118 | * bit 8 - 0 == do not get/release chip, 1 == get/release chip | ||
1119 | * | 949 | * |
1120 | * NAND read with ECC | 950 | * Internal function. Called with chip held. |
1121 | */ | 951 | */ |
1122 | int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, | 952 | static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, |
1123 | size_t * retlen, u_char * buf, u_char * oob_buf, | 953 | struct mtd_oob_ops *ops) |
1124 | struct nand_oobinfo *oobsel, int flags) | ||
1125 | { | 954 | { |
955 | int chipnr, page, realpage, col, bytes, aligned; | ||
956 | struct nand_chip *chip = mtd->priv; | ||
957 | struct mtd_ecc_stats stats; | ||
958 | int blkcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1; | ||
959 | int sndcmd = 1; | ||
960 | int ret = 0; | ||
961 | uint32_t readlen = ops->len; | ||
962 | uint8_t *bufpoi, *oob, *buf; | ||
1126 | 963 | ||
1127 | int i, j, col, realpage, page, end, ecc, chipnr, sndcmd = 1; | 964 | stats = mtd->ecc_stats; |
1128 | int read = 0, oob = 0, ecc_status = 0, ecc_failed = 0; | ||
1129 | struct nand_chip *this = mtd->priv; | ||
1130 | u_char *data_poi, *oob_data = oob_buf; | ||
1131 | u_char ecc_calc[32]; | ||
1132 | u_char ecc_code[32]; | ||
1133 | int eccmode, eccsteps; | ||
1134 | int *oob_config, datidx; | ||
1135 | int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1; | ||
1136 | int eccbytes; | ||
1137 | int compareecc = 1; | ||
1138 | int oobreadlen; | ||
1139 | |||
1140 | |||
1141 | DEBUG (MTD_DEBUG_LEVEL3, "nand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); | ||
1142 | |||
1143 | /* Do not allow reads past end of device */ | ||
1144 | if ((from + len) > mtd->size) { | ||
1145 | DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: Attempt read beyond end of device\n"); | ||
1146 | *retlen = 0; | ||
1147 | return -EINVAL; | ||
1148 | } | ||
1149 | |||
1150 | /* Grab the lock and see if the device is available */ | ||
1151 | if (flags & NAND_GET_DEVICE) | ||
1152 | nand_get_device (this, mtd, FL_READING); | ||
1153 | |||
1154 | /* Autoplace of oob data ? Use the default placement scheme */ | ||
1155 | if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) | ||
1156 | oobsel = this->autooob; | ||
1157 | |||
1158 | eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE; | ||
1159 | oob_config = oobsel->eccpos; | ||
1160 | |||
1161 | /* Select the NAND device */ | ||
1162 | chipnr = (int)(from >> this->chip_shift); | ||
1163 | this->select_chip(mtd, chipnr); | ||
1164 | |||
1165 | /* First we calculate the starting page */ | ||
1166 | realpage = (int) (from >> this->page_shift); | ||
1167 | page = realpage & this->pagemask; | ||
1168 | |||
1169 | /* Get raw starting column */ | ||
1170 | col = from & (mtd->oobblock - 1); | ||
1171 | |||
1172 | end = mtd->oobblock; | ||
1173 | ecc = this->eccsize; | ||
1174 | eccbytes = this->eccbytes; | ||
1175 | |||
1176 | if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME)) | ||
1177 | compareecc = 0; | ||
1178 | |||
1179 | oobreadlen = mtd->oobsize; | ||
1180 | if (this->options & NAND_HWECC_SYNDROME) | ||
1181 | oobreadlen -= oobsel->eccbytes; | ||
1182 | 965 | ||
1183 | /* Loop until all data read */ | 966 | chipnr = (int)(from >> chip->chip_shift); |
1184 | while (read < len) { | 967 | chip->select_chip(mtd, chipnr); |
1185 | 968 | ||
1186 | int aligned = (!col && (len - read) >= end); | 969 | realpage = (int)(from >> chip->page_shift); |
1187 | /* | 970 | page = realpage & chip->pagemask; |
1188 | * If the read is not page aligned, we have to read into data buffer | ||
1189 | * due to ecc, else we read into return buffer direct | ||
1190 | */ | ||
1191 | if (aligned) | ||
1192 | data_poi = &buf[read]; | ||
1193 | else | ||
1194 | data_poi = this->data_buf; | ||
1195 | 971 | ||
1196 | /* Check, if we have this page in the buffer | 972 | col = (int)(from & (mtd->writesize - 1)); |
1197 | * | 973 | chip->oob_poi = chip->buffers.oobrbuf; |
1198 | * FIXME: Make it work when we must provide oob data too, | ||
1199 | * check the usage of data_buf oob field | ||
1200 | */ | ||
1201 | if (realpage == this->pagebuf && !oob_buf) { | ||
1202 | /* aligned read ? */ | ||
1203 | if (aligned) | ||
1204 | memcpy (data_poi, this->data_buf, end); | ||
1205 | goto readdata; | ||
1206 | } | ||
1207 | 974 | ||
1208 | /* Check, if we must send the read command */ | 975 | buf = ops->datbuf; |
1209 | if (sndcmd) { | 976 | oob = ops->oobbuf; |
1210 | this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page); | ||
1211 | sndcmd = 0; | ||
1212 | } | ||
1213 | 977 | ||
1214 | /* get oob area, if we have no oob buffer from fs-driver */ | 978 | while(1) { |
1215 | if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE || | 979 | bytes = min(mtd->writesize - col, readlen); |
1216 | oobsel->useecc == MTD_NANDECC_AUTOPL_USR) | 980 | aligned = (bytes == mtd->writesize); |
1217 | oob_data = &this->data_buf[end]; | ||
1218 | 981 | ||
1219 | eccsteps = this->eccsteps; | 982 | /* Is the current page in the buffer ? */ |
983 | if (realpage != chip->pagebuf || oob) { | ||
984 | bufpoi = aligned ? buf : chip->buffers.databuf; | ||
1220 | 985 | ||
1221 | switch (eccmode) { | 986 | if (likely(sndcmd)) { |
1222 | case NAND_ECC_NONE: { /* No ECC, Read in a page */ | 987 | chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page); |
1223 | static unsigned long lastwhinge = 0; | 988 | sndcmd = 0; |
1224 | if ((lastwhinge / HZ) != (jiffies / HZ)) { | ||
1225 | printk (KERN_WARNING "Reading data from NAND FLASH without ECC is not recommended\n"); | ||
1226 | lastwhinge = jiffies; | ||
1227 | } | 989 | } |
1228 | this->read_buf(mtd, data_poi, end); | ||
1229 | break; | ||
1230 | } | ||
1231 | 990 | ||
1232 | case NAND_ECC_SOFT: /* Software ECC 3/256: Read in a page + oob data */ | 991 | /* Now read the page into the buffer */ |
1233 | this->read_buf(mtd, data_poi, end); | 992 | ret = chip->ecc.read_page(mtd, chip, bufpoi); |
1234 | for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc) | 993 | if (ret < 0) |
1235 | this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]); | 994 | break; |
1236 | break; | ||
1237 | 995 | ||
1238 | default: | 996 | /* Transfer not aligned data */ |
1239 | for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) { | 997 | if (!aligned) { |
1240 | this->enable_hwecc(mtd, NAND_ECC_READ); | 998 | chip->pagebuf = realpage; |
1241 | this->read_buf(mtd, &data_poi[datidx], ecc); | 999 | memcpy(buf, chip->buffers.databuf + col, bytes); |
1242 | |||
1243 | /* HW ecc with syndrome calculation must read the | ||
1244 | * syndrome from flash immidiately after the data */ | ||
1245 | if (!compareecc) { | ||
1246 | /* Some hw ecc generators need to know when the | ||
1247 | * syndrome is read from flash */ | ||
1248 | this->enable_hwecc(mtd, NAND_ECC_READSYN); | ||
1249 | this->read_buf(mtd, &oob_data[i], eccbytes); | ||
1250 | /* We calc error correction directly, it checks the hw | ||
1251 | * generator for an error, reads back the syndrome and | ||
1252 | * does the error correction on the fly */ | ||
1253 | ecc_status = this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]); | ||
1254 | if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) { | ||
1255 | DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " | ||
1256 | "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr); | ||
1257 | ecc_failed++; | ||
1258 | } | ||
1259 | } else { | ||
1260 | this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]); | ||
1261 | } | ||
1262 | } | 1000 | } |
1263 | break; | ||
1264 | } | ||
1265 | |||
1266 | /* read oobdata */ | ||
1267 | this->read_buf(mtd, &oob_data[mtd->oobsize - oobreadlen], oobreadlen); | ||
1268 | |||
1269 | /* Skip ECC check, if not requested (ECC_NONE or HW_ECC with syndromes) */ | ||
1270 | if (!compareecc) | ||
1271 | goto readoob; | ||
1272 | |||
1273 | /* Pick the ECC bytes out of the oob data */ | ||
1274 | for (j = 0; j < oobsel->eccbytes; j++) | ||
1275 | ecc_code[j] = oob_data[oob_config[j]]; | ||
1276 | 1001 | ||
1277 | /* correct data, if neccecary */ | 1002 | buf += bytes; |
1278 | for (i = 0, j = 0, datidx = 0; i < this->eccsteps; i++, datidx += ecc) { | ||
1279 | ecc_status = this->correct_data(mtd, &data_poi[datidx], &ecc_code[j], &ecc_calc[j]); | ||
1280 | 1003 | ||
1281 | /* Get next chunk of ecc bytes */ | 1004 | if (unlikely(oob)) { |
1282 | j += eccbytes; | 1005 | /* Raw mode does data:oob:data:oob */ |
1283 | 1006 | if (ops->mode != MTD_OOB_RAW) | |
1284 | /* Check, if we have a fs supplied oob-buffer, | 1007 | oob = nand_transfer_oob(chip, oob, ops); |
1285 | * This is the legacy mode. Used by YAFFS1 | 1008 | else |
1286 | * Should go away some day | 1009 | buf = nand_transfer_oob(chip, buf, ops); |
1287 | */ | ||
1288 | if (oob_buf && oobsel->useecc == MTD_NANDECC_PLACE) { | ||
1289 | int *p = (int *)(&oob_data[mtd->oobsize]); | ||
1290 | p[i] = ecc_status; | ||
1291 | } | 1010 | } |
1292 | 1011 | ||
1293 | if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) { | 1012 | if (!(chip->options & NAND_NO_READRDY)) { |
1294 | DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page); | 1013 | /* |
1295 | ecc_failed++; | 1014 | * Apply delay or wait for ready/busy pin. Do |
1015 | * this before the AUTOINCR check, so no | ||
1016 | * problems arise if a chip which does auto | ||
1017 | * increment is marked as NOAUTOINCR by the | ||
1018 | * board driver. | ||
1019 | */ | ||
1020 | if (!chip->dev_ready) | ||
1021 | udelay(chip->chip_delay); | ||
1022 | else | ||
1023 | nand_wait_ready(mtd); | ||
1296 | } | 1024 | } |
1025 | } else { | ||
1026 | memcpy(buf, chip->buffers.databuf + col, bytes); | ||
1027 | buf += bytes; | ||
1297 | } | 1028 | } |
1298 | 1029 | ||
1299 | readoob: | 1030 | readlen -= bytes; |
1300 | /* check, if we have a fs supplied oob-buffer */ | ||
1301 | if (oob_buf) { | ||
1302 | /* without autoplace. Legacy mode used by YAFFS1 */ | ||
1303 | switch(oobsel->useecc) { | ||
1304 | case MTD_NANDECC_AUTOPLACE: | ||
1305 | case MTD_NANDECC_AUTOPL_USR: | ||
1306 | /* Walk through the autoplace chunks */ | ||
1307 | for (i = 0; oobsel->oobfree[i][1]; i++) { | ||
1308 | int from = oobsel->oobfree[i][0]; | ||
1309 | int num = oobsel->oobfree[i][1]; | ||
1310 | memcpy(&oob_buf[oob], &oob_data[from], num); | ||
1311 | oob += num; | ||
1312 | } | ||
1313 | break; | ||
1314 | case MTD_NANDECC_PLACE: | ||
1315 | /* YAFFS1 legacy mode */ | ||
1316 | oob_data += this->eccsteps * sizeof (int); | ||
1317 | default: | ||
1318 | oob_data += mtd->oobsize; | ||
1319 | } | ||
1320 | } | ||
1321 | readdata: | ||
1322 | /* Partial page read, transfer data into fs buffer */ | ||
1323 | if (!aligned) { | ||
1324 | for (j = col; j < end && read < len; j++) | ||
1325 | buf[read++] = data_poi[j]; | ||
1326 | this->pagebuf = realpage; | ||
1327 | } else | ||
1328 | read += mtd->oobblock; | ||
1329 | |||
1330 | /* Apply delay or wait for ready/busy pin | ||
1331 | * Do this before the AUTOINCR check, so no problems | ||
1332 | * arise if a chip which does auto increment | ||
1333 | * is marked as NOAUTOINCR by the board driver. | ||
1334 | */ | ||
1335 | if (!this->dev_ready) | ||
1336 | udelay (this->chip_delay); | ||
1337 | else | ||
1338 | nand_wait_ready(mtd); | ||
1339 | 1031 | ||
1340 | if (read == len) | 1032 | if (!readlen) |
1341 | break; | 1033 | break; |
1342 | 1034 | ||
1343 | /* For subsequent reads align to page boundary. */ | 1035 | /* For subsequent reads align to page boundary. */ |
@@ -1345,701 +1037,775 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, | |||
1345 | /* Increment page address */ | 1037 | /* Increment page address */ |
1346 | realpage++; | 1038 | realpage++; |
1347 | 1039 | ||
1348 | page = realpage & this->pagemask; | 1040 | page = realpage & chip->pagemask; |
1349 | /* Check, if we cross a chip boundary */ | 1041 | /* Check, if we cross a chip boundary */ |
1350 | if (!page) { | 1042 | if (!page) { |
1351 | chipnr++; | 1043 | chipnr++; |
1352 | this->select_chip(mtd, -1); | 1044 | chip->select_chip(mtd, -1); |
1353 | this->select_chip(mtd, chipnr); | 1045 | chip->select_chip(mtd, chipnr); |
1354 | } | 1046 | } |
1047 | |||
1355 | /* Check, if the chip supports auto page increment | 1048 | /* Check, if the chip supports auto page increment |
1356 | * or if we have hit a block boundary. | 1049 | * or if we have hit a block boundary. |
1357 | */ | 1050 | */ |
1358 | if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) | 1051 | if (!NAND_CANAUTOINCR(chip) || !(page & blkcheck)) |
1359 | sndcmd = 1; | 1052 | sndcmd = 1; |
1360 | } | 1053 | } |
1361 | 1054 | ||
1362 | /* Deselect and wake up anyone waiting on the device */ | 1055 | ops->retlen = ops->len - (size_t) readlen; |
1363 | if (flags & NAND_GET_DEVICE) | ||
1364 | nand_release_device(mtd); | ||
1365 | 1056 | ||
1366 | /* | 1057 | if (ret) |
1367 | * Return success, if no ECC failures, else -EBADMSG | 1058 | return ret; |
1368 | * fs driver will take care of that, because | 1059 | |
1369 | * retlen == desired len and result == -EBADMSG | 1060 | if (mtd->ecc_stats.failed - stats.failed) |
1370 | */ | 1061 | return -EBADMSG; |
1371 | *retlen = read; | 1062 | |
1372 | return ecc_failed ? -EBADMSG : 0; | 1063 | return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0; |
1373 | } | 1064 | } |
1374 | 1065 | ||
1375 | /** | 1066 | /** |
1376 | * nand_read_oob - [MTD Interface] NAND read out-of-band | 1067 | * nand_read - [MTD Interface] MTD compability function for nand_do_read_ecc |
1377 | * @mtd: MTD device structure | 1068 | * @mtd: MTD device structure |
1378 | * @from: offset to read from | 1069 | * @from: offset to read from |
1379 | * @len: number of bytes to read | 1070 | * @len: number of bytes to read |
1380 | * @retlen: pointer to variable to store the number of read bytes | 1071 | * @retlen: pointer to variable to store the number of read bytes |
1381 | * @buf: the databuffer to put data | 1072 | * @buf: the databuffer to put data |
1382 | * | 1073 | * |
1383 | * NAND read out-of-band data from the spare area | 1074 | * Get hold of the chip and call nand_do_read |
1384 | */ | 1075 | */ |
1385 | static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf) | 1076 | static int nand_read(struct mtd_info *mtd, loff_t from, size_t len, |
1077 | size_t *retlen, uint8_t *buf) | ||
1386 | { | 1078 | { |
1387 | int i, col, page, chipnr; | 1079 | struct nand_chip *chip = mtd->priv; |
1388 | struct nand_chip *this = mtd->priv; | 1080 | int ret; |
1389 | int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1; | ||
1390 | 1081 | ||
1391 | DEBUG (MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); | 1082 | /* Do not allow reads past end of device */ |
1083 | if ((from + len) > mtd->size) | ||
1084 | return -EINVAL; | ||
1085 | if (!len) | ||
1086 | return 0; | ||
1392 | 1087 | ||
1393 | /* Shift to get page */ | 1088 | nand_get_device(chip, mtd, FL_READING); |
1394 | page = (int)(from >> this->page_shift); | ||
1395 | chipnr = (int)(from >> this->chip_shift); | ||
1396 | 1089 | ||
1397 | /* Mask to get column */ | 1090 | chip->ops.len = len; |
1398 | col = from & (mtd->oobsize - 1); | 1091 | chip->ops.datbuf = buf; |
1092 | chip->ops.oobbuf = NULL; | ||
1399 | 1093 | ||
1400 | /* Initialize return length value */ | 1094 | ret = nand_do_read_ops(mtd, from, &chip->ops); |
1401 | *retlen = 0; | ||
1402 | 1095 | ||
1403 | /* Do not allow reads past end of device */ | 1096 | nand_release_device(mtd); |
1404 | if ((from + len) > mtd->size) { | 1097 | |
1405 | DEBUG (MTD_DEBUG_LEVEL0, "nand_read_oob: Attempt read beyond end of device\n"); | 1098 | *retlen = chip->ops.retlen; |
1406 | *retlen = 0; | 1099 | return ret; |
1407 | return -EINVAL; | 1100 | } |
1101 | |||
1102 | /** | ||
1103 | * nand_read_oob_std - [REPLACABLE] the most common OOB data read function | ||
1104 | * @mtd: mtd info structure | ||
1105 | * @chip: nand chip info structure | ||
1106 | * @page: page number to read | ||
1107 | * @sndcmd: flag whether to issue read command or not | ||
1108 | */ | ||
1109 | static int nand_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip, | ||
1110 | int page, int sndcmd) | ||
1111 | { | ||
1112 | if (sndcmd) { | ||
1113 | chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page); | ||
1114 | sndcmd = 0; | ||
1408 | } | 1115 | } |
1116 | chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); | ||
1117 | return sndcmd; | ||
1118 | } | ||
1409 | 1119 | ||
1410 | /* Grab the lock and see if the device is available */ | 1120 | /** |
1411 | nand_get_device (this, mtd , FL_READING); | 1121 | * nand_read_oob_syndrome - [REPLACABLE] OOB data read function for HW ECC |
1122 | * with syndromes | ||
1123 | * @mtd: mtd info structure | ||
1124 | * @chip: nand chip info structure | ||
1125 | * @page: page number to read | ||
1126 | * @sndcmd: flag whether to issue read command or not | ||
1127 | */ | ||
1128 | static int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip, | ||
1129 | int page, int sndcmd) | ||
1130 | { | ||
1131 | uint8_t *buf = chip->oob_poi; | ||
1132 | int length = mtd->oobsize; | ||
1133 | int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad; | ||
1134 | int eccsize = chip->ecc.size; | ||
1135 | uint8_t *bufpoi = buf; | ||
1136 | int i, toread, sndrnd = 0, pos; | ||
1137 | |||
1138 | chip->cmdfunc(mtd, NAND_CMD_READ0, chip->ecc.size, page); | ||
1139 | for (i = 0; i < chip->ecc.steps; i++) { | ||
1140 | if (sndrnd) { | ||
1141 | pos = eccsize + i * (eccsize + chunk); | ||
1142 | if (mtd->writesize > 512) | ||
1143 | chip->cmdfunc(mtd, NAND_CMD_RNDOUT, pos, -1); | ||
1144 | else | ||
1145 | chip->cmdfunc(mtd, NAND_CMD_READ0, pos, page); | ||
1146 | } else | ||
1147 | sndrnd = 1; | ||
1148 | toread = min_t(int, length, chunk); | ||
1149 | chip->read_buf(mtd, bufpoi, toread); | ||
1150 | bufpoi += toread; | ||
1151 | length -= toread; | ||
1152 | } | ||
1153 | if (length > 0) | ||
1154 | chip->read_buf(mtd, bufpoi, length); | ||
1412 | 1155 | ||
1413 | /* Select the NAND device */ | 1156 | return 1; |
1414 | this->select_chip(mtd, chipnr); | 1157 | } |
1158 | |||
1159 | /** | ||
1160 | * nand_write_oob_std - [REPLACABLE] the most common OOB data write function | ||
1161 | * @mtd: mtd info structure | ||
1162 | * @chip: nand chip info structure | ||
1163 | * @page: page number to write | ||
1164 | */ | ||
1165 | static int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip, | ||
1166 | int page) | ||
1167 | { | ||
1168 | int status = 0; | ||
1169 | const uint8_t *buf = chip->oob_poi; | ||
1170 | int length = mtd->oobsize; | ||
1171 | |||
1172 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page); | ||
1173 | chip->write_buf(mtd, buf, length); | ||
1174 | /* Send command to program the OOB data */ | ||
1175 | chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); | ||
1176 | |||
1177 | status = chip->waitfunc(mtd, chip); | ||
1178 | |||
1179 | return status; | ||
1180 | } | ||
1181 | |||
1182 | /** | ||
1183 | * nand_write_oob_syndrome - [REPLACABLE] OOB data write function for HW ECC | ||
1184 | * with syndrome - only for large page flash ! | ||
1185 | * @mtd: mtd info structure | ||
1186 | * @chip: nand chip info structure | ||
1187 | * @page: page number to write | ||
1188 | */ | ||
1189 | static int nand_write_oob_syndrome(struct mtd_info *mtd, | ||
1190 | struct nand_chip *chip, int page) | ||
1191 | { | ||
1192 | int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad; | ||
1193 | int eccsize = chip->ecc.size, length = mtd->oobsize; | ||
1194 | int i, len, pos, status = 0, sndcmd = 0, steps = chip->ecc.steps; | ||
1195 | const uint8_t *bufpoi = chip->oob_poi; | ||
1415 | 1196 | ||
1416 | /* Send the read command */ | ||
1417 | this->cmdfunc (mtd, NAND_CMD_READOOB, col, page & this->pagemask); | ||
1418 | /* | 1197 | /* |
1419 | * Read the data, if we read more than one page | 1198 | * data-ecc-data-ecc ... ecc-oob |
1420 | * oob data, let the device transfer the data ! | 1199 | * or |
1200 | * data-pad-ecc-pad-data-pad .... ecc-pad-oob | ||
1421 | */ | 1201 | */ |
1422 | i = 0; | 1202 | if (!chip->ecc.prepad && !chip->ecc.postpad) { |
1423 | while (i < len) { | 1203 | pos = steps * (eccsize + chunk); |
1424 | int thislen = mtd->oobsize - col; | 1204 | steps = 0; |
1425 | thislen = min_t(int, thislen, len); | 1205 | } else |
1426 | this->read_buf(mtd, &buf[i], thislen); | 1206 | pos = eccsize + chunk; |
1427 | i += thislen; | ||
1428 | |||
1429 | /* Read more ? */ | ||
1430 | if (i < len) { | ||
1431 | page++; | ||
1432 | col = 0; | ||
1433 | |||
1434 | /* Check, if we cross a chip boundary */ | ||
1435 | if (!(page & this->pagemask)) { | ||
1436 | chipnr++; | ||
1437 | this->select_chip(mtd, -1); | ||
1438 | this->select_chip(mtd, chipnr); | ||
1439 | } | ||
1440 | |||
1441 | /* Apply delay or wait for ready/busy pin | ||
1442 | * Do this before the AUTOINCR check, so no problems | ||
1443 | * arise if a chip which does auto increment | ||
1444 | * is marked as NOAUTOINCR by the board driver. | ||
1445 | */ | ||
1446 | if (!this->dev_ready) | ||
1447 | udelay (this->chip_delay); | ||
1448 | else | ||
1449 | nand_wait_ready(mtd); | ||
1450 | 1207 | ||
1451 | /* Check, if the chip supports auto page increment | 1208 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, pos, page); |
1452 | * or if we have hit a block boundary. | 1209 | for (i = 0; i < steps; i++) { |
1453 | */ | 1210 | if (sndcmd) { |
1454 | if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) { | 1211 | if (mtd->writesize <= 512) { |
1455 | /* For subsequent page reads set offset to 0 */ | 1212 | uint32_t fill = 0xFFFFFFFF; |
1456 | this->cmdfunc (mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask); | 1213 | |
1214 | len = eccsize; | ||
1215 | while (len > 0) { | ||
1216 | int num = min_t(int, len, 4); | ||
1217 | chip->write_buf(mtd, (uint8_t *)&fill, | ||
1218 | num); | ||
1219 | len -= num; | ||
1220 | } | ||
1221 | } else { | ||
1222 | pos = eccsize + i * (eccsize + chunk); | ||
1223 | chip->cmdfunc(mtd, NAND_CMD_RNDIN, pos, -1); | ||
1457 | } | 1224 | } |
1458 | } | 1225 | } else |
1226 | sndcmd = 1; | ||
1227 | len = min_t(int, length, chunk); | ||
1228 | chip->write_buf(mtd, bufpoi, len); | ||
1229 | bufpoi += len; | ||
1230 | length -= len; | ||
1459 | } | 1231 | } |
1232 | if (length > 0) | ||
1233 | chip->write_buf(mtd, bufpoi, length); | ||
1460 | 1234 | ||
1461 | /* Deselect and wake up anyone waiting on the device */ | 1235 | chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); |
1462 | nand_release_device(mtd); | 1236 | status = chip->waitfunc(mtd, chip); |
1463 | 1237 | ||
1464 | /* Return happy */ | 1238 | return status & NAND_STATUS_FAIL ? -EIO : 0; |
1465 | *retlen = len; | ||
1466 | return 0; | ||
1467 | } | 1239 | } |
1468 | 1240 | ||
1469 | /** | 1241 | /** |
1470 | * nand_read_raw - [GENERIC] Read raw data including oob into buffer | 1242 | * nand_do_read_oob - [Intern] NAND read out-of-band |
1471 | * @mtd: MTD device structure | 1243 | * @mtd: MTD device structure |
1472 | * @buf: temporary buffer | ||
1473 | * @from: offset to read from | 1244 | * @from: offset to read from |
1474 | * @len: number of bytes to read | 1245 | * @ops: oob operations description structure |
1475 | * @ooblen: number of oob data bytes to read | ||
1476 | * | 1246 | * |
1477 | * Read raw data including oob into buffer | 1247 | * NAND read out-of-band data from the spare area |
1478 | */ | 1248 | */ |
1479 | int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen) | 1249 | static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, |
1250 | struct mtd_oob_ops *ops) | ||
1480 | { | 1251 | { |
1481 | struct nand_chip *this = mtd->priv; | 1252 | int page, realpage, chipnr, sndcmd = 1; |
1482 | int page = (int) (from >> this->page_shift); | 1253 | struct nand_chip *chip = mtd->priv; |
1483 | int chip = (int) (from >> this->chip_shift); | 1254 | int blkcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1; |
1484 | int sndcmd = 1; | 1255 | int readlen = ops->len; |
1485 | int cnt = 0; | 1256 | uint8_t *buf = ops->oobbuf; |
1486 | int pagesize = mtd->oobblock + mtd->oobsize; | ||
1487 | int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1; | ||
1488 | 1257 | ||
1489 | /* Do not allow reads past end of device */ | 1258 | DEBUG(MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08Lx, len = %i\n", |
1490 | if ((from + len) > mtd->size) { | 1259 | (unsigned long long)from, readlen); |
1491 | DEBUG (MTD_DEBUG_LEVEL0, "nand_read_raw: Attempt read beyond end of device\n"); | ||
1492 | return -EINVAL; | ||
1493 | } | ||
1494 | 1260 | ||
1495 | /* Grab the lock and see if the device is available */ | 1261 | chipnr = (int)(from >> chip->chip_shift); |
1496 | nand_get_device (this, mtd , FL_READING); | 1262 | chip->select_chip(mtd, chipnr); |
1497 | 1263 | ||
1498 | this->select_chip (mtd, chip); | 1264 | /* Shift to get page */ |
1265 | realpage = (int)(from >> chip->page_shift); | ||
1266 | page = realpage & chip->pagemask; | ||
1499 | 1267 | ||
1500 | /* Add requested oob length */ | 1268 | chip->oob_poi = chip->buffers.oobrbuf; |
1501 | len += ooblen; | ||
1502 | 1269 | ||
1503 | while (len) { | 1270 | while(1) { |
1504 | if (sndcmd) | 1271 | sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd); |
1505 | this->cmdfunc (mtd, NAND_CMD_READ0, 0, page & this->pagemask); | 1272 | buf = nand_transfer_oob(chip, buf, ops); |
1506 | sndcmd = 0; | ||
1507 | 1273 | ||
1508 | this->read_buf (mtd, &buf[cnt], pagesize); | 1274 | readlen -= ops->ooblen; |
1275 | if (!readlen) | ||
1276 | break; | ||
1509 | 1277 | ||
1510 | len -= pagesize; | 1278 | if (!(chip->options & NAND_NO_READRDY)) { |
1511 | cnt += pagesize; | 1279 | /* |
1512 | page++; | 1280 | * Apply delay or wait for ready/busy pin. Do this |
1281 | * before the AUTOINCR check, so no problems arise if a | ||
1282 | * chip which does auto increment is marked as | ||
1283 | * NOAUTOINCR by the board driver. | ||
1284 | */ | ||
1285 | if (!chip->dev_ready) | ||
1286 | udelay(chip->chip_delay); | ||
1287 | else | ||
1288 | nand_wait_ready(mtd); | ||
1289 | } | ||
1513 | 1290 | ||
1514 | if (!this->dev_ready) | 1291 | /* Increment page address */ |
1515 | udelay (this->chip_delay); | 1292 | realpage++; |
1516 | else | ||
1517 | nand_wait_ready(mtd); | ||
1518 | 1293 | ||
1519 | /* Check, if the chip supports auto page increment */ | 1294 | page = realpage & chip->pagemask; |
1520 | if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) | 1295 | /* Check, if we cross a chip boundary */ |
1296 | if (!page) { | ||
1297 | chipnr++; | ||
1298 | chip->select_chip(mtd, -1); | ||
1299 | chip->select_chip(mtd, chipnr); | ||
1300 | } | ||
1301 | |||
1302 | /* Check, if the chip supports auto page increment | ||
1303 | * or if we have hit a block boundary. | ||
1304 | */ | ||
1305 | if (!NAND_CANAUTOINCR(chip) || !(page & blkcheck)) | ||
1521 | sndcmd = 1; | 1306 | sndcmd = 1; |
1522 | } | 1307 | } |
1523 | 1308 | ||
1524 | /* Deselect and wake up anyone waiting on the device */ | 1309 | ops->retlen = ops->len; |
1525 | nand_release_device(mtd); | ||
1526 | return 0; | 1310 | return 0; |
1527 | } | 1311 | } |
1528 | 1312 | ||
1529 | |||
1530 | /** | 1313 | /** |
1531 | * nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer | 1314 | * nand_read_oob - [MTD Interface] NAND read data and/or out-of-band |
1532 | * @mtd: MTD device structure | 1315 | * @mtd: MTD device structure |
1533 | * @fsbuf: buffer given by fs driver | 1316 | * @from: offset to read from |
1534 | * @oobsel: out of band selection structre | 1317 | * @ops: oob operation description structure |
1535 | * @autoplace: 1 = place given buffer into the oob bytes | ||
1536 | * @numpages: number of pages to prepare | ||
1537 | * | ||
1538 | * Return: | ||
1539 | * 1. Filesystem buffer available and autoplacement is off, | ||
1540 | * return filesystem buffer | ||
1541 | * 2. No filesystem buffer or autoplace is off, return internal | ||
1542 | * buffer | ||
1543 | * 3. Filesystem buffer is given and autoplace selected | ||
1544 | * put data from fs buffer into internal buffer and | ||
1545 | * retrun internal buffer | ||
1546 | * | ||
1547 | * Note: The internal buffer is filled with 0xff. This must | ||
1548 | * be done only once, when no autoplacement happens | ||
1549 | * Autoplacement sets the buffer dirty flag, which | ||
1550 | * forces the 0xff fill before using the buffer again. | ||
1551 | * | 1318 | * |
1552 | */ | 1319 | * NAND read data and/or out-of-band data |
1553 | static u_char * nand_prepare_oobbuf (struct mtd_info *mtd, u_char *fsbuf, struct nand_oobinfo *oobsel, | 1320 | */ |
1554 | int autoplace, int numpages) | 1321 | static int nand_read_oob(struct mtd_info *mtd, loff_t from, |
1322 | struct mtd_oob_ops *ops) | ||
1555 | { | 1323 | { |
1556 | struct nand_chip *this = mtd->priv; | 1324 | int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip, |
1557 | int i, len, ofs; | 1325 | uint8_t *buf) = NULL; |
1558 | 1326 | struct nand_chip *chip = mtd->priv; | |
1559 | /* Zero copy fs supplied buffer */ | 1327 | int ret = -ENOTSUPP; |
1560 | if (fsbuf && !autoplace) | 1328 | |
1561 | return fsbuf; | 1329 | ops->retlen = 0; |
1562 | 1330 | ||
1563 | /* Check, if the buffer must be filled with ff again */ | 1331 | /* Do not allow reads past end of device */ |
1564 | if (this->oobdirty) { | 1332 | if ((from + ops->len) > mtd->size) { |
1565 | memset (this->oob_buf, 0xff, | 1333 | DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: " |
1566 | mtd->oobsize << (this->phys_erase_shift - this->page_shift)); | 1334 | "Attempt read beyond end of device\n"); |
1567 | this->oobdirty = 0; | 1335 | return -EINVAL; |
1568 | } | 1336 | } |
1569 | 1337 | ||
1570 | /* If we have no autoplacement or no fs buffer use the internal one */ | 1338 | nand_get_device(chip, mtd, FL_READING); |
1571 | if (!autoplace || !fsbuf) | 1339 | |
1572 | return this->oob_buf; | 1340 | switch(ops->mode) { |
1573 | 1341 | case MTD_OOB_PLACE: | |
1574 | /* Walk through the pages and place the data */ | 1342 | case MTD_OOB_AUTO: |
1575 | this->oobdirty = 1; | 1343 | break; |
1576 | ofs = 0; | 1344 | |
1577 | while (numpages--) { | 1345 | case MTD_OOB_RAW: |
1578 | for (i = 0, len = 0; len < mtd->oobavail; i++) { | 1346 | /* Replace the read_page algorithm temporary */ |
1579 | int to = ofs + oobsel->oobfree[i][0]; | 1347 | read_page = chip->ecc.read_page; |
1580 | int num = oobsel->oobfree[i][1]; | 1348 | chip->ecc.read_page = nand_read_page_raw; |
1581 | memcpy (&this->oob_buf[to], fsbuf, num); | 1349 | break; |
1582 | len += num; | 1350 | |
1583 | fsbuf += num; | 1351 | default: |
1584 | } | 1352 | goto out; |
1585 | ofs += mtd->oobavail; | ||
1586 | } | 1353 | } |
1587 | return this->oob_buf; | 1354 | |
1355 | if (!ops->datbuf) | ||
1356 | ret = nand_do_read_oob(mtd, from, ops); | ||
1357 | else | ||
1358 | ret = nand_do_read_ops(mtd, from, ops); | ||
1359 | |||
1360 | if (unlikely(ops->mode == MTD_OOB_RAW)) | ||
1361 | chip->ecc.read_page = read_page; | ||
1362 | out: | ||
1363 | nand_release_device(mtd); | ||
1364 | return ret; | ||
1588 | } | 1365 | } |
1589 | 1366 | ||
1590 | #define NOTALIGNED(x) (x & (mtd->oobblock-1)) != 0 | ||
1591 | 1367 | ||
1592 | /** | 1368 | /** |
1593 | * nand_write - [MTD Interface] compability function for nand_write_ecc | 1369 | * nand_write_page_raw - [Intern] raw page write function |
1594 | * @mtd: MTD device structure | 1370 | * @mtd: mtd info structure |
1595 | * @to: offset to write to | 1371 | * @chip: nand chip info structure |
1596 | * @len: number of bytes to write | 1372 | * @buf: data buffer |
1597 | * @retlen: pointer to variable to store the number of written bytes | 1373 | */ |
1598 | * @buf: the data to write | 1374 | static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, |
1599 | * | 1375 | const uint8_t *buf) |
1600 | * This function simply calls nand_write_ecc with oob buffer and oobsel = NULL | ||
1601 | * | ||
1602 | */ | ||
1603 | static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf) | ||
1604 | { | 1376 | { |
1605 | return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, NULL)); | 1377 | chip->write_buf(mtd, buf, mtd->writesize); |
1378 | chip->write_buf(mtd, chip->oob_poi, mtd->oobsize); | ||
1606 | } | 1379 | } |
1607 | 1380 | ||
1608 | /** | 1381 | /** |
1609 | * nand_write_ecc - [MTD Interface] NAND write with ECC | 1382 | * nand_write_page_swecc - {REPLACABLE] software ecc based page write function |
1610 | * @mtd: MTD device structure | 1383 | * @mtd: mtd info structure |
1611 | * @to: offset to write to | 1384 | * @chip: nand chip info structure |
1612 | * @len: number of bytes to write | 1385 | * @buf: data buffer |
1613 | * @retlen: pointer to variable to store the number of written bytes | ||
1614 | * @buf: the data to write | ||
1615 | * @eccbuf: filesystem supplied oob data buffer | ||
1616 | * @oobsel: oob selection structure | ||
1617 | * | ||
1618 | * NAND write with ECC | ||
1619 | */ | 1386 | */ |
1620 | static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, | 1387 | static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, |
1621 | size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel) | 1388 | const uint8_t *buf) |
1622 | { | 1389 | { |
1623 | int startpage, page, ret = -EIO, oob = 0, written = 0, chipnr; | 1390 | int i, eccsize = chip->ecc.size; |
1624 | int autoplace = 0, numpages, totalpages; | 1391 | int eccbytes = chip->ecc.bytes; |
1625 | struct nand_chip *this = mtd->priv; | 1392 | int eccsteps = chip->ecc.steps; |
1626 | u_char *oobbuf, *bufstart; | 1393 | uint8_t *ecc_calc = chip->buffers.ecccalc; |
1627 | int ppblock = (1 << (this->phys_erase_shift - this->page_shift)); | 1394 | const uint8_t *p = buf; |
1395 | int *eccpos = chip->ecc.layout->eccpos; | ||
1628 | 1396 | ||
1629 | DEBUG (MTD_DEBUG_LEVEL3, "nand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); | 1397 | /* Software ecc calculation */ |
1398 | for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) | ||
1399 | chip->ecc.calculate(mtd, p, &ecc_calc[i]); | ||
1630 | 1400 | ||
1631 | /* Initialize retlen, in case of early exit */ | 1401 | for (i = 0; i < chip->ecc.total; i++) |
1632 | *retlen = 0; | 1402 | chip->oob_poi[eccpos[i]] = ecc_calc[i]; |
1633 | 1403 | ||
1634 | /* Do not allow write past end of device */ | 1404 | nand_write_page_raw(mtd, chip, buf); |
1635 | if ((to + len) > mtd->size) { | 1405 | } |
1636 | DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: Attempt to write past end of page\n"); | ||
1637 | return -EINVAL; | ||
1638 | } | ||
1639 | 1406 | ||
1640 | /* reject writes, which are not page aligned */ | 1407 | /** |
1641 | if (NOTALIGNED (to) || NOTALIGNED(len)) { | 1408 | * nand_write_page_hwecc - {REPLACABLE] hardware ecc based page write function |
1642 | printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n"); | 1409 | * @mtd: mtd info structure |
1643 | return -EINVAL; | 1410 | * @chip: nand chip info structure |
1411 | * @buf: data buffer | ||
1412 | */ | ||
1413 | static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | ||
1414 | const uint8_t *buf) | ||
1415 | { | ||
1416 | int i, eccsize = chip->ecc.size; | ||
1417 | int eccbytes = chip->ecc.bytes; | ||
1418 | int eccsteps = chip->ecc.steps; | ||
1419 | uint8_t *ecc_calc = chip->buffers.ecccalc; | ||
1420 | const uint8_t *p = buf; | ||
1421 | int *eccpos = chip->ecc.layout->eccpos; | ||
1422 | |||
1423 | for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { | ||
1424 | chip->ecc.hwctl(mtd, NAND_ECC_WRITE); | ||
1425 | chip->write_buf(mtd, p, eccsize); | ||
1426 | chip->ecc.calculate(mtd, p, &ecc_calc[i]); | ||
1644 | } | 1427 | } |
1645 | 1428 | ||
1646 | /* Grab the lock and see if the device is available */ | 1429 | for (i = 0; i < chip->ecc.total; i++) |
1647 | nand_get_device (this, mtd, FL_WRITING); | 1430 | chip->oob_poi[eccpos[i]] = ecc_calc[i]; |
1648 | 1431 | ||
1649 | /* Calculate chipnr */ | 1432 | chip->write_buf(mtd, chip->oob_poi, mtd->oobsize); |
1650 | chipnr = (int)(to >> this->chip_shift); | 1433 | } |
1651 | /* Select the NAND device */ | ||
1652 | this->select_chip(mtd, chipnr); | ||
1653 | 1434 | ||
1654 | /* Check, if it is write protected */ | 1435 | /** |
1655 | if (nand_check_wp(mtd)) | 1436 | * nand_write_page_syndrome - {REPLACABLE] hardware ecc syndrom based page write |
1656 | goto out; | 1437 | * @mtd: mtd info structure |
1438 | * @chip: nand chip info structure | ||
1439 | * @buf: data buffer | ||
1440 | * | ||
1441 | * The hw generator calculates the error syndrome automatically. Therefor | ||
1442 | * we need a special oob layout and handling. | ||
1443 | */ | ||
1444 | static void nand_write_page_syndrome(struct mtd_info *mtd, | ||
1445 | struct nand_chip *chip, const uint8_t *buf) | ||
1446 | { | ||
1447 | int i, eccsize = chip->ecc.size; | ||
1448 | int eccbytes = chip->ecc.bytes; | ||
1449 | int eccsteps = chip->ecc.steps; | ||
1450 | const uint8_t *p = buf; | ||
1451 | uint8_t *oob = chip->oob_poi; | ||
1657 | 1452 | ||
1658 | /* if oobsel is NULL, use chip defaults */ | 1453 | for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { |
1659 | if (oobsel == NULL) | ||
1660 | oobsel = &mtd->oobinfo; | ||
1661 | 1454 | ||
1662 | /* Autoplace of oob data ? Use the default placement scheme */ | 1455 | chip->ecc.hwctl(mtd, NAND_ECC_WRITE); |
1663 | if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) { | 1456 | chip->write_buf(mtd, p, eccsize); |
1664 | oobsel = this->autooob; | ||
1665 | autoplace = 1; | ||
1666 | } | ||
1667 | if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR) | ||
1668 | autoplace = 1; | ||
1669 | 1457 | ||
1670 | /* Setup variables and oob buffer */ | 1458 | if (chip->ecc.prepad) { |
1671 | totalpages = len >> this->page_shift; | 1459 | chip->write_buf(mtd, oob, chip->ecc.prepad); |
1672 | page = (int) (to >> this->page_shift); | 1460 | oob += chip->ecc.prepad; |
1673 | /* Invalidate the page cache, if we write to the cached page */ | ||
1674 | if (page <= this->pagebuf && this->pagebuf < (page + totalpages)) | ||
1675 | this->pagebuf = -1; | ||
1676 | |||
1677 | /* Set it relative to chip */ | ||
1678 | page &= this->pagemask; | ||
1679 | startpage = page; | ||
1680 | /* Calc number of pages we can write in one go */ | ||
1681 | numpages = min (ppblock - (startpage & (ppblock - 1)), totalpages); | ||
1682 | oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel, autoplace, numpages); | ||
1683 | bufstart = (u_char *)buf; | ||
1684 | |||
1685 | /* Loop until all data is written */ | ||
1686 | while (written < len) { | ||
1687 | |||
1688 | this->data_poi = (u_char*) &buf[written]; | ||
1689 | /* Write one page. If this is the last page to write | ||
1690 | * or the last page in this block, then use the | ||
1691 | * real pageprogram command, else select cached programming | ||
1692 | * if supported by the chip. | ||
1693 | */ | ||
1694 | ret = nand_write_page (mtd, this, page, &oobbuf[oob], oobsel, (--numpages > 0)); | ||
1695 | if (ret) { | ||
1696 | DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: write_page failed %d\n", ret); | ||
1697 | goto out; | ||
1698 | } | 1461 | } |
1699 | /* Next oob page */ | ||
1700 | oob += mtd->oobsize; | ||
1701 | /* Update written bytes count */ | ||
1702 | written += mtd->oobblock; | ||
1703 | if (written == len) | ||
1704 | goto cmp; | ||
1705 | 1462 | ||
1706 | /* Increment page address */ | 1463 | chip->ecc.calculate(mtd, p, oob); |
1707 | page++; | 1464 | chip->write_buf(mtd, oob, eccbytes); |
1708 | 1465 | oob += eccbytes; | |
1709 | /* Have we hit a block boundary ? Then we have to verify and | 1466 | |
1710 | * if verify is ok, we have to setup the oob buffer for | 1467 | if (chip->ecc.postpad) { |
1711 | * the next pages. | 1468 | chip->write_buf(mtd, oob, chip->ecc.postpad); |
1712 | */ | 1469 | oob += chip->ecc.postpad; |
1713 | if (!(page & (ppblock - 1))){ | ||
1714 | int ofs; | ||
1715 | this->data_poi = bufstart; | ||
1716 | ret = nand_verify_pages (mtd, this, startpage, | ||
1717 | page - startpage, | ||
1718 | oobbuf, oobsel, chipnr, (eccbuf != NULL)); | ||
1719 | if (ret) { | ||
1720 | DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret); | ||
1721 | goto out; | ||
1722 | } | ||
1723 | *retlen = written; | ||
1724 | |||
1725 | ofs = autoplace ? mtd->oobavail : mtd->oobsize; | ||
1726 | if (eccbuf) | ||
1727 | eccbuf += (page - startpage) * ofs; | ||
1728 | totalpages -= page - startpage; | ||
1729 | numpages = min (totalpages, ppblock); | ||
1730 | page &= this->pagemask; | ||
1731 | startpage = page; | ||
1732 | oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel, | ||
1733 | autoplace, numpages); | ||
1734 | oob = 0; | ||
1735 | /* Check, if we cross a chip boundary */ | ||
1736 | if (!page) { | ||
1737 | chipnr++; | ||
1738 | this->select_chip(mtd, -1); | ||
1739 | this->select_chip(mtd, chipnr); | ||
1740 | } | ||
1741 | } | 1470 | } |
1742 | } | 1471 | } |
1743 | /* Verify the remaining pages */ | ||
1744 | cmp: | ||
1745 | this->data_poi = bufstart; | ||
1746 | ret = nand_verify_pages (mtd, this, startpage, totalpages, | ||
1747 | oobbuf, oobsel, chipnr, (eccbuf != NULL)); | ||
1748 | if (!ret) | ||
1749 | *retlen = written; | ||
1750 | else | ||
1751 | DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret); | ||
1752 | 1472 | ||
1753 | out: | 1473 | /* Calculate remaining oob bytes */ |
1754 | /* Deselect and wake up anyone waiting on the device */ | 1474 | i = mtd->oobsize - (oob - chip->oob_poi); |
1755 | nand_release_device(mtd); | 1475 | if (i) |
1756 | 1476 | chip->write_buf(mtd, oob, i); | |
1757 | return ret; | ||
1758 | } | 1477 | } |
1759 | 1478 | ||
1760 | |||
1761 | /** | 1479 | /** |
1762 | * nand_write_oob - [MTD Interface] NAND write out-of-band | 1480 | * nand_write_page - [INTERNAL] write one page |
1763 | * @mtd: MTD device structure | 1481 | * @mtd: MTD device structure |
1764 | * @to: offset to write to | 1482 | * @chip: NAND chip descriptor |
1765 | * @len: number of bytes to write | ||
1766 | * @retlen: pointer to variable to store the number of written bytes | ||
1767 | * @buf: the data to write | 1483 | * @buf: the data to write |
1768 | * | 1484 | * @page: page number to write |
1769 | * NAND write out-of-band | 1485 | * @cached: cached programming |
1770 | */ | 1486 | */ |
1771 | static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf) | 1487 | static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, |
1488 | const uint8_t *buf, int page, int cached) | ||
1772 | { | 1489 | { |
1773 | int column, page, status, ret = -EIO, chipnr; | 1490 | int status; |
1774 | struct nand_chip *this = mtd->priv; | ||
1775 | 1491 | ||
1776 | DEBUG (MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); | 1492 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); |
1777 | 1493 | ||
1778 | /* Shift to get page */ | 1494 | chip->ecc.write_page(mtd, chip, buf); |
1779 | page = (int) (to >> this->page_shift); | ||
1780 | chipnr = (int) (to >> this->chip_shift); | ||
1781 | 1495 | ||
1782 | /* Mask to get column */ | 1496 | /* |
1783 | column = to & (mtd->oobsize - 1); | 1497 | * Cached progamming disabled for now, Not sure if its worth the |
1498 | * trouble. The speed gain is not very impressive. (2.3->2.6Mib/s) | ||
1499 | */ | ||
1500 | cached = 0; | ||
1784 | 1501 | ||
1785 | /* Initialize return length value */ | 1502 | if (!cached || !(chip->options & NAND_CACHEPRG)) { |
1786 | *retlen = 0; | ||
1787 | 1503 | ||
1788 | /* Do not allow write past end of page */ | 1504 | chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); |
1789 | if ((column + len) > mtd->oobsize) { | 1505 | status = chip->waitfunc(mtd, chip); |
1790 | DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: Attempt to write past end of page\n"); | 1506 | /* |
1791 | return -EINVAL; | 1507 | * See if operation failed and additional status checks are |
1508 | * available | ||
1509 | */ | ||
1510 | if ((status & NAND_STATUS_FAIL) && (chip->errstat)) | ||
1511 | status = chip->errstat(mtd, chip, FL_WRITING, status, | ||
1512 | page); | ||
1513 | |||
1514 | if (status & NAND_STATUS_FAIL) | ||
1515 | return -EIO; | ||
1516 | } else { | ||
1517 | chip->cmdfunc(mtd, NAND_CMD_CACHEDPROG, -1, -1); | ||
1518 | status = chip->waitfunc(mtd, chip); | ||
1792 | } | 1519 | } |
1793 | 1520 | ||
1794 | /* Grab the lock and see if the device is available */ | 1521 | #ifdef CONFIG_MTD_NAND_VERIFY_WRITE |
1795 | nand_get_device (this, mtd, FL_WRITING); | 1522 | /* Send command to read back the data */ |
1523 | chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page); | ||
1796 | 1524 | ||
1797 | /* Select the NAND device */ | 1525 | if (chip->verify_buf(mtd, buf, mtd->writesize)) |
1798 | this->select_chip(mtd, chipnr); | 1526 | return -EIO; |
1527 | #endif | ||
1528 | return 0; | ||
1529 | } | ||
1530 | |||
1531 | /** | ||
1532 | * nand_fill_oob - [Internal] Transfer client buffer to oob | ||
1533 | * @chip: nand chip structure | ||
1534 | * @oob: oob data buffer | ||
1535 | * @ops: oob ops structure | ||
1536 | */ | ||
1537 | static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, | ||
1538 | struct mtd_oob_ops *ops) | ||
1539 | { | ||
1540 | size_t len = ops->ooblen; | ||
1541 | |||
1542 | switch(ops->mode) { | ||
1543 | |||
1544 | case MTD_OOB_PLACE: | ||
1545 | case MTD_OOB_RAW: | ||
1546 | memcpy(chip->oob_poi + ops->ooboffs, oob, len); | ||
1547 | return oob + len; | ||
1548 | |||
1549 | case MTD_OOB_AUTO: { | ||
1550 | struct nand_oobfree *free = chip->ecc.layout->oobfree; | ||
1551 | uint32_t boffs = 0, woffs = ops->ooboffs; | ||
1552 | size_t bytes = 0; | ||
1553 | |||
1554 | for(; free->length && len; free++, len -= bytes) { | ||
1555 | /* Write request not from offset 0 ? */ | ||
1556 | if (unlikely(woffs)) { | ||
1557 | if (woffs >= free->length) { | ||
1558 | woffs -= free->length; | ||
1559 | continue; | ||
1560 | } | ||
1561 | boffs = free->offset + woffs; | ||
1562 | bytes = min_t(size_t, len, | ||
1563 | (free->length - woffs)); | ||
1564 | woffs = 0; | ||
1565 | } else { | ||
1566 | bytes = min_t(size_t, len, free->length); | ||
1567 | boffs = free->offset; | ||
1568 | } | ||
1569 | memcpy(chip->oob_poi + woffs, oob, bytes); | ||
1570 | oob += bytes; | ||
1571 | } | ||
1572 | return oob; | ||
1573 | } | ||
1574 | default: | ||
1575 | BUG(); | ||
1576 | } | ||
1577 | return NULL; | ||
1578 | } | ||
1579 | |||
1580 | #define NOTALIGNED(x) (x & (mtd->writesize-1)) != 0 | ||
1581 | |||
1582 | /** | ||
1583 | * nand_do_write_ops - [Internal] NAND write with ECC | ||
1584 | * @mtd: MTD device structure | ||
1585 | * @to: offset to write to | ||
1586 | * @ops: oob operations description structure | ||
1587 | * | ||
1588 | * NAND write with ECC | ||
1589 | */ | ||
1590 | static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, | ||
1591 | struct mtd_oob_ops *ops) | ||
1592 | { | ||
1593 | int chipnr, realpage, page, blockmask; | ||
1594 | struct nand_chip *chip = mtd->priv; | ||
1595 | uint32_t writelen = ops->len; | ||
1596 | uint8_t *oob = ops->oobbuf; | ||
1597 | uint8_t *buf = ops->datbuf; | ||
1598 | int bytes = mtd->writesize; | ||
1599 | int ret; | ||
1799 | 1600 | ||
1800 | /* Reset the chip. Some chips (like the Toshiba TC5832DC found | 1601 | ops->retlen = 0; |
1801 | in one of my DiskOnChip 2000 test units) will clear the whole | 1602 | |
1802 | data page too if we don't do this. I have no clue why, but | 1603 | /* reject writes, which are not page aligned */ |
1803 | I seem to have 'fixed' it in the doc2000 driver in | 1604 | if (NOTALIGNED(to) || NOTALIGNED(ops->len)) { |
1804 | August 1999. dwmw2. */ | 1605 | printk(KERN_NOTICE "nand_write: " |
1805 | this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); | 1606 | "Attempt to write not page aligned data\n"); |
1607 | return -EINVAL; | ||
1608 | } | ||
1609 | |||
1610 | if (!writelen) | ||
1611 | return 0; | ||
1806 | 1612 | ||
1807 | /* Check, if it is write protected */ | 1613 | /* Check, if it is write protected */ |
1808 | if (nand_check_wp(mtd)) | 1614 | if (nand_check_wp(mtd)) |
1809 | goto out; | 1615 | return -EIO; |
1810 | 1616 | ||
1811 | /* Invalidate the page cache, if we write to the cached page */ | 1617 | chipnr = (int)(to >> chip->chip_shift); |
1812 | if (page == this->pagebuf) | 1618 | chip->select_chip(mtd, chipnr); |
1813 | this->pagebuf = -1; | ||
1814 | |||
1815 | if (NAND_MUST_PAD(this)) { | ||
1816 | /* Write out desired data */ | ||
1817 | this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock, page & this->pagemask); | ||
1818 | /* prepad 0xff for partial programming */ | ||
1819 | this->write_buf(mtd, ffchars, column); | ||
1820 | /* write data */ | ||
1821 | this->write_buf(mtd, buf, len); | ||
1822 | /* postpad 0xff for partial programming */ | ||
1823 | this->write_buf(mtd, ffchars, mtd->oobsize - (len+column)); | ||
1824 | } else { | ||
1825 | /* Write out desired data */ | ||
1826 | this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock + column, page & this->pagemask); | ||
1827 | /* write data */ | ||
1828 | this->write_buf(mtd, buf, len); | ||
1829 | } | ||
1830 | /* Send command to program the OOB data */ | ||
1831 | this->cmdfunc (mtd, NAND_CMD_PAGEPROG, -1, -1); | ||
1832 | 1619 | ||
1833 | status = this->waitfunc (mtd, this, FL_WRITING); | 1620 | realpage = (int)(to >> chip->page_shift); |
1621 | page = realpage & chip->pagemask; | ||
1622 | blockmask = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1; | ||
1834 | 1623 | ||
1835 | /* See if device thinks it succeeded */ | 1624 | /* Invalidate the page cache, when we write to the cached page */ |
1836 | if (status & NAND_STATUS_FAIL) { | 1625 | if (to <= (chip->pagebuf << chip->page_shift) && |
1837 | DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write, page 0x%08x\n", page); | 1626 | (chip->pagebuf << chip->page_shift) < (to + ops->len)) |
1838 | ret = -EIO; | 1627 | chip->pagebuf = -1; |
1839 | goto out; | ||
1840 | } | ||
1841 | /* Return happy */ | ||
1842 | *retlen = len; | ||
1843 | 1628 | ||
1844 | #ifdef CONFIG_MTD_NAND_VERIFY_WRITE | 1629 | chip->oob_poi = chip->buffers.oobwbuf; |
1845 | /* Send command to read back the data */ | ||
1846 | this->cmdfunc (mtd, NAND_CMD_READOOB, column, page & this->pagemask); | ||
1847 | 1630 | ||
1848 | if (this->verify_buf(mtd, buf, len)) { | 1631 | while(1) { |
1849 | DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write verify, page 0x%08x\n", page); | 1632 | int cached = writelen > bytes && page != blockmask; |
1850 | ret = -EIO; | 1633 | |
1851 | goto out; | 1634 | if (unlikely(oob)) |
1635 | oob = nand_fill_oob(chip, oob, ops); | ||
1636 | |||
1637 | ret = nand_write_page(mtd, chip, buf, page, cached); | ||
1638 | if (ret) | ||
1639 | break; | ||
1640 | |||
1641 | writelen -= bytes; | ||
1642 | if (!writelen) | ||
1643 | break; | ||
1644 | |||
1645 | buf += bytes; | ||
1646 | realpage++; | ||
1647 | |||
1648 | page = realpage & chip->pagemask; | ||
1649 | /* Check, if we cross a chip boundary */ | ||
1650 | if (!page) { | ||
1651 | chipnr++; | ||
1652 | chip->select_chip(mtd, -1); | ||
1653 | chip->select_chip(mtd, chipnr); | ||
1654 | } | ||
1852 | } | 1655 | } |
1853 | #endif | ||
1854 | ret = 0; | ||
1855 | out: | ||
1856 | /* Deselect and wake up anyone waiting on the device */ | ||
1857 | nand_release_device(mtd); | ||
1858 | 1656 | ||
1657 | if (unlikely(oob)) | ||
1658 | memset(chip->oob_poi, 0xff, mtd->oobsize); | ||
1659 | |||
1660 | ops->retlen = ops->len - writelen; | ||
1859 | return ret; | 1661 | return ret; |
1860 | } | 1662 | } |
1861 | 1663 | ||
1862 | |||
1863 | /** | 1664 | /** |
1864 | * nand_writev - [MTD Interface] compabilty function for nand_writev_ecc | 1665 | * nand_write - [MTD Interface] NAND write with ECC |
1865 | * @mtd: MTD device structure | 1666 | * @mtd: MTD device structure |
1866 | * @vecs: the iovectors to write | ||
1867 | * @count: number of vectors | ||
1868 | * @to: offset to write to | 1667 | * @to: offset to write to |
1668 | * @len: number of bytes to write | ||
1869 | * @retlen: pointer to variable to store the number of written bytes | 1669 | * @retlen: pointer to variable to store the number of written bytes |
1670 | * @buf: the data to write | ||
1870 | * | 1671 | * |
1871 | * NAND write with kvec. This just calls the ecc function | 1672 | * NAND write with ECC |
1872 | */ | 1673 | */ |
1873 | static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, | 1674 | static int nand_write(struct mtd_info *mtd, loff_t to, size_t len, |
1874 | loff_t to, size_t * retlen) | 1675 | size_t *retlen, const uint8_t *buf) |
1875 | { | 1676 | { |
1876 | return (nand_writev_ecc (mtd, vecs, count, to, retlen, NULL, NULL)); | 1677 | struct nand_chip *chip = mtd->priv; |
1678 | int ret; | ||
1679 | |||
1680 | /* Do not allow reads past end of device */ | ||
1681 | if ((to + len) > mtd->size) | ||
1682 | return -EINVAL; | ||
1683 | if (!len) | ||
1684 | return 0; | ||
1685 | |||
1686 | nand_get_device(chip, mtd, FL_WRITING); | ||
1687 | |||
1688 | chip->ops.len = len; | ||
1689 | chip->ops.datbuf = (uint8_t *)buf; | ||
1690 | chip->ops.oobbuf = NULL; | ||
1691 | |||
1692 | ret = nand_do_write_ops(mtd, to, &chip->ops); | ||
1693 | |||
1694 | nand_release_device(mtd); | ||
1695 | |||
1696 | *retlen = chip->ops.retlen; | ||
1697 | return ret; | ||
1877 | } | 1698 | } |
1878 | 1699 | ||
1879 | /** | 1700 | /** |
1880 | * nand_writev_ecc - [MTD Interface] write with iovec with ecc | 1701 | * nand_do_write_oob - [MTD Interface] NAND write out-of-band |
1881 | * @mtd: MTD device structure | 1702 | * @mtd: MTD device structure |
1882 | * @vecs: the iovectors to write | ||
1883 | * @count: number of vectors | ||
1884 | * @to: offset to write to | 1703 | * @to: offset to write to |
1885 | * @retlen: pointer to variable to store the number of written bytes | 1704 | * @ops: oob operation description structure |
1886 | * @eccbuf: filesystem supplied oob data buffer | ||
1887 | * @oobsel: oob selection structure | ||
1888 | * | 1705 | * |
1889 | * NAND write with iovec with ecc | 1706 | * NAND write out-of-band |
1890 | */ | 1707 | */ |
1891 | static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, | 1708 | static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, |
1892 | loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel) | 1709 | struct mtd_oob_ops *ops) |
1893 | { | 1710 | { |
1894 | int i, page, len, total_len, ret = -EIO, written = 0, chipnr; | 1711 | int chipnr, page, status; |
1895 | int oob, numpages, autoplace = 0, startpage; | 1712 | struct nand_chip *chip = mtd->priv; |
1896 | struct nand_chip *this = mtd->priv; | ||
1897 | int ppblock = (1 << (this->phys_erase_shift - this->page_shift)); | ||
1898 | u_char *oobbuf, *bufstart; | ||
1899 | |||
1900 | /* Preset written len for early exit */ | ||
1901 | *retlen = 0; | ||
1902 | |||
1903 | /* Calculate total length of data */ | ||
1904 | total_len = 0; | ||
1905 | for (i = 0; i < count; i++) | ||
1906 | total_len += (int) vecs[i].iov_len; | ||
1907 | 1713 | ||
1908 | DEBUG (MTD_DEBUG_LEVEL3, | 1714 | DEBUG(MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n", |
1909 | "nand_writev: to = 0x%08x, len = %i, count = %ld\n", (unsigned int) to, (unsigned int) total_len, count); | 1715 | (unsigned int)to, (int)ops->len); |
1910 | 1716 | ||
1911 | /* Do not allow write past end of page */ | 1717 | /* Do not allow write past end of page */ |
1912 | if ((to + total_len) > mtd->size) { | 1718 | if ((ops->ooboffs + ops->len) > mtd->oobsize) { |
1913 | DEBUG (MTD_DEBUG_LEVEL0, "nand_writev: Attempted write past end of device\n"); | 1719 | DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: " |
1720 | "Attempt to write past end of page\n"); | ||
1914 | return -EINVAL; | 1721 | return -EINVAL; |
1915 | } | 1722 | } |
1916 | 1723 | ||
1917 | /* reject writes, which are not page aligned */ | 1724 | chipnr = (int)(to >> chip->chip_shift); |
1918 | if (NOTALIGNED (to) || NOTALIGNED(total_len)) { | 1725 | chip->select_chip(mtd, chipnr); |
1919 | printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n"); | ||
1920 | return -EINVAL; | ||
1921 | } | ||
1922 | 1726 | ||
1923 | /* Grab the lock and see if the device is available */ | 1727 | /* Shift to get page */ |
1924 | nand_get_device (this, mtd, FL_WRITING); | 1728 | page = (int)(to >> chip->page_shift); |
1925 | 1729 | ||
1926 | /* Get the current chip-nr */ | 1730 | /* |
1927 | chipnr = (int) (to >> this->chip_shift); | 1731 | * Reset the chip. Some chips (like the Toshiba TC5832DC found in one |
1928 | /* Select the NAND device */ | 1732 | * of my DiskOnChip 2000 test units) will clear the whole data page too |
1929 | this->select_chip(mtd, chipnr); | 1733 | * if we don't do this. I have no clue why, but I seem to have 'fixed' |
1734 | * it in the doc2000 driver in August 1999. dwmw2. | ||
1735 | */ | ||
1736 | chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); | ||
1930 | 1737 | ||
1931 | /* Check, if it is write protected */ | 1738 | /* Check, if it is write protected */ |
1932 | if (nand_check_wp(mtd)) | 1739 | if (nand_check_wp(mtd)) |
1933 | goto out; | 1740 | return -EROFS; |
1934 | 1741 | ||
1935 | /* if oobsel is NULL, use chip defaults */ | 1742 | /* Invalidate the page cache, if we write to the cached page */ |
1936 | if (oobsel == NULL) | 1743 | if (page == chip->pagebuf) |
1937 | oobsel = &mtd->oobinfo; | 1744 | chip->pagebuf = -1; |
1938 | 1745 | ||
1939 | /* Autoplace of oob data ? Use the default placement scheme */ | 1746 | chip->oob_poi = chip->buffers.oobwbuf; |
1940 | if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) { | 1747 | memset(chip->oob_poi, 0xff, mtd->oobsize); |
1941 | oobsel = this->autooob; | 1748 | nand_fill_oob(chip, ops->oobbuf, ops); |
1942 | autoplace = 1; | 1749 | status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask); |
1943 | } | 1750 | memset(chip->oob_poi, 0xff, mtd->oobsize); |
1944 | if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR) | ||
1945 | autoplace = 1; | ||
1946 | 1751 | ||
1947 | /* Setup start page */ | 1752 | if (status) |
1948 | page = (int) (to >> this->page_shift); | 1753 | return status; |
1949 | /* Invalidate the page cache, if we write to the cached page */ | ||
1950 | if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift)) | ||
1951 | this->pagebuf = -1; | ||
1952 | 1754 | ||
1953 | startpage = page & this->pagemask; | 1755 | ops->retlen = ops->len; |
1954 | 1756 | ||
1955 | /* Loop until all kvec' data has been written */ | 1757 | return 0; |
1956 | len = 0; | 1758 | } |
1957 | while (count) { | ||
1958 | /* If the given tuple is >= pagesize then | ||
1959 | * write it out from the iov | ||
1960 | */ | ||
1961 | if ((vecs->iov_len - len) >= mtd->oobblock) { | ||
1962 | /* Calc number of pages we can write | ||
1963 | * out of this iov in one go */ | ||
1964 | numpages = (vecs->iov_len - len) >> this->page_shift; | ||
1965 | /* Do not cross block boundaries */ | ||
1966 | numpages = min (ppblock - (startpage & (ppblock - 1)), numpages); | ||
1967 | oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages); | ||
1968 | bufstart = (u_char *)vecs->iov_base; | ||
1969 | bufstart += len; | ||
1970 | this->data_poi = bufstart; | ||
1971 | oob = 0; | ||
1972 | for (i = 1; i <= numpages; i++) { | ||
1973 | /* Write one page. If this is the last page to write | ||
1974 | * then use the real pageprogram command, else select | ||
1975 | * cached programming if supported by the chip. | ||
1976 | */ | ||
1977 | ret = nand_write_page (mtd, this, page & this->pagemask, | ||
1978 | &oobbuf[oob], oobsel, i != numpages); | ||
1979 | if (ret) | ||
1980 | goto out; | ||
1981 | this->data_poi += mtd->oobblock; | ||
1982 | len += mtd->oobblock; | ||
1983 | oob += mtd->oobsize; | ||
1984 | page++; | ||
1985 | } | ||
1986 | /* Check, if we have to switch to the next tuple */ | ||
1987 | if (len >= (int) vecs->iov_len) { | ||
1988 | vecs++; | ||
1989 | len = 0; | ||
1990 | count--; | ||
1991 | } | ||
1992 | } else { | ||
1993 | /* We must use the internal buffer, read data out of each | ||
1994 | * tuple until we have a full page to write | ||
1995 | */ | ||
1996 | int cnt = 0; | ||
1997 | while (cnt < mtd->oobblock) { | ||
1998 | if (vecs->iov_base != NULL && vecs->iov_len) | ||
1999 | this->data_buf[cnt++] = ((u_char *) vecs->iov_base)[len++]; | ||
2000 | /* Check, if we have to switch to the next tuple */ | ||
2001 | if (len >= (int) vecs->iov_len) { | ||
2002 | vecs++; | ||
2003 | len = 0; | ||
2004 | count--; | ||
2005 | } | ||
2006 | } | ||
2007 | this->pagebuf = page; | ||
2008 | this->data_poi = this->data_buf; | ||
2009 | bufstart = this->data_poi; | ||
2010 | numpages = 1; | ||
2011 | oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages); | ||
2012 | ret = nand_write_page (mtd, this, page & this->pagemask, | ||
2013 | oobbuf, oobsel, 0); | ||
2014 | if (ret) | ||
2015 | goto out; | ||
2016 | page++; | ||
2017 | } | ||
2018 | 1759 | ||
2019 | this->data_poi = bufstart; | 1760 | /** |
2020 | ret = nand_verify_pages (mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0); | 1761 | * nand_write_oob - [MTD Interface] NAND write data and/or out-of-band |
2021 | if (ret) | 1762 | * @mtd: MTD device structure |
2022 | goto out; | 1763 | * @from: offset to read from |
1764 | * @ops: oob operation description structure | ||
1765 | */ | ||
1766 | static int nand_write_oob(struct mtd_info *mtd, loff_t to, | ||
1767 | struct mtd_oob_ops *ops) | ||
1768 | { | ||
1769 | void (*write_page)(struct mtd_info *mtd, struct nand_chip *chip, | ||
1770 | const uint8_t *buf) = NULL; | ||
1771 | struct nand_chip *chip = mtd->priv; | ||
1772 | int ret = -ENOTSUPP; | ||
2023 | 1773 | ||
2024 | written += mtd->oobblock * numpages; | 1774 | ops->retlen = 0; |
2025 | /* All done ? */ | ||
2026 | if (!count) | ||
2027 | break; | ||
2028 | 1775 | ||
2029 | startpage = page & this->pagemask; | 1776 | /* Do not allow writes past end of device */ |
2030 | /* Check, if we cross a chip boundary */ | 1777 | if ((to + ops->len) > mtd->size) { |
2031 | if (!startpage) { | 1778 | DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: " |
2032 | chipnr++; | 1779 | "Attempt read beyond end of device\n"); |
2033 | this->select_chip(mtd, -1); | 1780 | return -EINVAL; |
2034 | this->select_chip(mtd, chipnr); | ||
2035 | } | ||
2036 | } | 1781 | } |
2037 | ret = 0; | ||
2038 | out: | ||
2039 | /* Deselect and wake up anyone waiting on the device */ | ||
2040 | nand_release_device(mtd); | ||
2041 | 1782 | ||
2042 | *retlen = written; | 1783 | nand_get_device(chip, mtd, FL_WRITING); |
1784 | |||
1785 | switch(ops->mode) { | ||
1786 | case MTD_OOB_PLACE: | ||
1787 | case MTD_OOB_AUTO: | ||
1788 | break; | ||
1789 | |||
1790 | case MTD_OOB_RAW: | ||
1791 | /* Replace the write_page algorithm temporary */ | ||
1792 | write_page = chip->ecc.write_page; | ||
1793 | chip->ecc.write_page = nand_write_page_raw; | ||
1794 | break; | ||
1795 | |||
1796 | default: | ||
1797 | goto out; | ||
1798 | } | ||
1799 | |||
1800 | if (!ops->datbuf) | ||
1801 | ret = nand_do_write_oob(mtd, to, ops); | ||
1802 | else | ||
1803 | ret = nand_do_write_ops(mtd, to, ops); | ||
1804 | |||
1805 | if (unlikely(ops->mode == MTD_OOB_RAW)) | ||
1806 | chip->ecc.write_page = write_page; | ||
1807 | out: | ||
1808 | nand_release_device(mtd); | ||
2043 | return ret; | 1809 | return ret; |
2044 | } | 1810 | } |
2045 | 1811 | ||
@@ -2050,12 +1816,12 @@ out: | |||
2050 | * | 1816 | * |
2051 | * Standard erase command for NAND chips | 1817 | * Standard erase command for NAND chips |
2052 | */ | 1818 | */ |
2053 | static void single_erase_cmd (struct mtd_info *mtd, int page) | 1819 | static void single_erase_cmd(struct mtd_info *mtd, int page) |
2054 | { | 1820 | { |
2055 | struct nand_chip *this = mtd->priv; | 1821 | struct nand_chip *chip = mtd->priv; |
2056 | /* Send commands to erase a block */ | 1822 | /* Send commands to erase a block */ |
2057 | this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page); | 1823 | chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page); |
2058 | this->cmdfunc (mtd, NAND_CMD_ERASE2, -1, -1); | 1824 | chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1); |
2059 | } | 1825 | } |
2060 | 1826 | ||
2061 | /** | 1827 | /** |
@@ -2066,15 +1832,15 @@ static void single_erase_cmd (struct mtd_info *mtd, int page) | |||
2066 | * AND multi block erase command function | 1832 | * AND multi block erase command function |
2067 | * Erase 4 consecutive blocks | 1833 | * Erase 4 consecutive blocks |
2068 | */ | 1834 | */ |
2069 | static void multi_erase_cmd (struct mtd_info *mtd, int page) | 1835 | static void multi_erase_cmd(struct mtd_info *mtd, int page) |
2070 | { | 1836 | { |
2071 | struct nand_chip *this = mtd->priv; | 1837 | struct nand_chip *chip = mtd->priv; |
2072 | /* Send commands to erase a block */ | 1838 | /* Send commands to erase a block */ |
2073 | this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++); | 1839 | chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++); |
2074 | this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++); | 1840 | chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++); |
2075 | this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++); | 1841 | chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++); |
2076 | this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page); | 1842 | chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page); |
2077 | this->cmdfunc (mtd, NAND_CMD_ERASE2, -1, -1); | 1843 | chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1); |
2078 | } | 1844 | } |
2079 | 1845 | ||
2080 | /** | 1846 | /** |
@@ -2084,79 +1850,82 @@ static void multi_erase_cmd (struct mtd_info *mtd, int page) | |||
2084 | * | 1850 | * |
2085 | * Erase one ore more blocks | 1851 | * Erase one ore more blocks |
2086 | */ | 1852 | */ |
2087 | static int nand_erase (struct mtd_info *mtd, struct erase_info *instr) | 1853 | static int nand_erase(struct mtd_info *mtd, struct erase_info *instr) |
2088 | { | 1854 | { |
2089 | return nand_erase_nand (mtd, instr, 0); | 1855 | return nand_erase_nand(mtd, instr, 0); |
2090 | } | 1856 | } |
2091 | 1857 | ||
2092 | #define BBT_PAGE_MASK 0xffffff3f | 1858 | #define BBT_PAGE_MASK 0xffffff3f |
2093 | /** | 1859 | /** |
2094 | * nand_erase_intern - [NAND Interface] erase block(s) | 1860 | * nand_erase_nand - [Internal] erase block(s) |
2095 | * @mtd: MTD device structure | 1861 | * @mtd: MTD device structure |
2096 | * @instr: erase instruction | 1862 | * @instr: erase instruction |
2097 | * @allowbbt: allow erasing the bbt area | 1863 | * @allowbbt: allow erasing the bbt area |
2098 | * | 1864 | * |
2099 | * Erase one ore more blocks | 1865 | * Erase one ore more blocks |
2100 | */ | 1866 | */ |
2101 | int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbbt) | 1867 | int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, |
1868 | int allowbbt) | ||
2102 | { | 1869 | { |
2103 | int page, len, status, pages_per_block, ret, chipnr; | 1870 | int page, len, status, pages_per_block, ret, chipnr; |
2104 | struct nand_chip *this = mtd->priv; | 1871 | struct nand_chip *chip = mtd->priv; |
2105 | int rewrite_bbt[NAND_MAX_CHIPS]={0}; /* flags to indicate the page, if bbt needs to be rewritten. */ | 1872 | int rewrite_bbt[NAND_MAX_CHIPS]={0}; |
2106 | unsigned int bbt_masked_page; /* bbt mask to compare to page being erased. */ | 1873 | unsigned int bbt_masked_page = 0xffffffff; |
2107 | /* It is used to see if the current page is in the same */ | ||
2108 | /* 256 block group and the same bank as the bbt. */ | ||
2109 | 1874 | ||
2110 | DEBUG (MTD_DEBUG_LEVEL3, | 1875 | DEBUG(MTD_DEBUG_LEVEL3, "nand_erase: start = 0x%08x, len = %i\n", |
2111 | "nand_erase: start = 0x%08x, len = %i\n", (unsigned int) instr->addr, (unsigned int) instr->len); | 1876 | (unsigned int)instr->addr, (unsigned int)instr->len); |
2112 | 1877 | ||
2113 | /* Start address must align on block boundary */ | 1878 | /* Start address must align on block boundary */ |
2114 | if (instr->addr & ((1 << this->phys_erase_shift) - 1)) { | 1879 | if (instr->addr & ((1 << chip->phys_erase_shift) - 1)) { |
2115 | DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Unaligned address\n"); | 1880 | DEBUG(MTD_DEBUG_LEVEL0, "nand_erase: Unaligned address\n"); |
2116 | return -EINVAL; | 1881 | return -EINVAL; |
2117 | } | 1882 | } |
2118 | 1883 | ||
2119 | /* Length must align on block boundary */ | 1884 | /* Length must align on block boundary */ |
2120 | if (instr->len & ((1 << this->phys_erase_shift) - 1)) { | 1885 | if (instr->len & ((1 << chip->phys_erase_shift) - 1)) { |
2121 | DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Length not block aligned\n"); | 1886 | DEBUG(MTD_DEBUG_LEVEL0, "nand_erase: " |
1887 | "Length not block aligned\n"); | ||
2122 | return -EINVAL; | 1888 | return -EINVAL; |
2123 | } | 1889 | } |
2124 | 1890 | ||
2125 | /* Do not allow erase past end of device */ | 1891 | /* Do not allow erase past end of device */ |
2126 | if ((instr->len + instr->addr) > mtd->size) { | 1892 | if ((instr->len + instr->addr) > mtd->size) { |
2127 | DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Erase past end of device\n"); | 1893 | DEBUG(MTD_DEBUG_LEVEL0, "nand_erase: " |
1894 | "Erase past end of device\n"); | ||
2128 | return -EINVAL; | 1895 | return -EINVAL; |
2129 | } | 1896 | } |
2130 | 1897 | ||
2131 | instr->fail_addr = 0xffffffff; | 1898 | instr->fail_addr = 0xffffffff; |
2132 | 1899 | ||
2133 | /* Grab the lock and see if the device is available */ | 1900 | /* Grab the lock and see if the device is available */ |
2134 | nand_get_device (this, mtd, FL_ERASING); | 1901 | nand_get_device(chip, mtd, FL_ERASING); |
2135 | 1902 | ||
2136 | /* Shift to get first page */ | 1903 | /* Shift to get first page */ |
2137 | page = (int) (instr->addr >> this->page_shift); | 1904 | page = (int)(instr->addr >> chip->page_shift); |
2138 | chipnr = (int) (instr->addr >> this->chip_shift); | 1905 | chipnr = (int)(instr->addr >> chip->chip_shift); |
2139 | 1906 | ||
2140 | /* Calculate pages in each block */ | 1907 | /* Calculate pages in each block */ |
2141 | pages_per_block = 1 << (this->phys_erase_shift - this->page_shift); | 1908 | pages_per_block = 1 << (chip->phys_erase_shift - chip->page_shift); |
2142 | 1909 | ||
2143 | /* Select the NAND device */ | 1910 | /* Select the NAND device */ |
2144 | this->select_chip(mtd, chipnr); | 1911 | chip->select_chip(mtd, chipnr); |
2145 | 1912 | ||
2146 | /* Check the WP bit */ | ||
2147 | /* Check, if it is write protected */ | 1913 | /* Check, if it is write protected */ |
2148 | if (nand_check_wp(mtd)) { | 1914 | if (nand_check_wp(mtd)) { |
2149 | DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Device is write protected!!!\n"); | 1915 | DEBUG(MTD_DEBUG_LEVEL0, "nand_erase: " |
1916 | "Device is write protected!!!\n"); | ||
2150 | instr->state = MTD_ERASE_FAILED; | 1917 | instr->state = MTD_ERASE_FAILED; |
2151 | goto erase_exit; | 1918 | goto erase_exit; |
2152 | } | 1919 | } |
2153 | 1920 | ||
2154 | /* if BBT requires refresh, set the BBT page mask to see if the BBT should be rewritten */ | 1921 | /* |
2155 | if (this->options & BBT_AUTO_REFRESH) { | 1922 | * If BBT requires refresh, set the BBT page mask to see if the BBT |
2156 | bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK; | 1923 | * should be rewritten. Otherwise the mask is set to 0xffffffff which |
2157 | } else { | 1924 | * can not be matched. This is also done when the bbt is actually |
2158 | bbt_masked_page = 0xffffffff; /* should not match anything */ | 1925 | * erased to avoid recusrsive updates |
2159 | } | 1926 | */ |
1927 | if (chip->options & BBT_AUTO_REFRESH && !allowbbt) | ||
1928 | bbt_masked_page = chip->bbt_td->pages[chipnr] & BBT_PAGE_MASK; | ||
2160 | 1929 | ||
2161 | /* Loop through the pages */ | 1930 | /* Loop through the pages */ |
2162 | len = instr->len; | 1931 | len = instr->len; |
@@ -2164,64 +1933,77 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb | |||
2164 | instr->state = MTD_ERASING; | 1933 | instr->state = MTD_ERASING; |
2165 | 1934 | ||
2166 | while (len) { | 1935 | while (len) { |
2167 | /* Check if we have a bad block, we do not erase bad blocks ! */ | 1936 | /* |
2168 | if (nand_block_checkbad(mtd, ((loff_t) page) << this->page_shift, 0, allowbbt)) { | 1937 | * heck if we have a bad block, we do not erase bad blocks ! |
2169 | printk (KERN_WARNING "nand_erase: attempt to erase a bad block at page 0x%08x\n", page); | 1938 | */ |
1939 | if (nand_block_checkbad(mtd, ((loff_t) page) << | ||
1940 | chip->page_shift, 0, allowbbt)) { | ||
1941 | printk(KERN_WARNING "nand_erase: attempt to erase a " | ||
1942 | "bad block at page 0x%08x\n", page); | ||
2170 | instr->state = MTD_ERASE_FAILED; | 1943 | instr->state = MTD_ERASE_FAILED; |
2171 | goto erase_exit; | 1944 | goto erase_exit; |
2172 | } | 1945 | } |
2173 | 1946 | ||
2174 | /* Invalidate the page cache, if we erase the block which contains | 1947 | /* |
2175 | the current cached page */ | 1948 | * Invalidate the page cache, if we erase the block which |
2176 | if (page <= this->pagebuf && this->pagebuf < (page + pages_per_block)) | 1949 | * contains the current cached page |
2177 | this->pagebuf = -1; | 1950 | */ |
1951 | if (page <= chip->pagebuf && chip->pagebuf < | ||
1952 | (page + pages_per_block)) | ||
1953 | chip->pagebuf = -1; | ||
2178 | 1954 | ||
2179 | this->erase_cmd (mtd, page & this->pagemask); | 1955 | chip->erase_cmd(mtd, page & chip->pagemask); |
2180 | 1956 | ||
2181 | status = this->waitfunc (mtd, this, FL_ERASING); | 1957 | status = chip->waitfunc(mtd, chip); |
2182 | 1958 | ||
2183 | /* See if operation failed and additional status checks are available */ | 1959 | /* |
2184 | if ((status & NAND_STATUS_FAIL) && (this->errstat)) { | 1960 | * See if operation failed and additional status checks are |
2185 | status = this->errstat(mtd, this, FL_ERASING, status, page); | 1961 | * available |
2186 | } | 1962 | */ |
1963 | if ((status & NAND_STATUS_FAIL) && (chip->errstat)) | ||
1964 | status = chip->errstat(mtd, chip, FL_ERASING, | ||
1965 | status, page); | ||
2187 | 1966 | ||
2188 | /* See if block erase succeeded */ | 1967 | /* See if block erase succeeded */ |
2189 | if (status & NAND_STATUS_FAIL) { | 1968 | if (status & NAND_STATUS_FAIL) { |
2190 | DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: " "Failed erase, page 0x%08x\n", page); | 1969 | DEBUG(MTD_DEBUG_LEVEL0, "nand_erase: " |
1970 | "Failed erase, page 0x%08x\n", page); | ||
2191 | instr->state = MTD_ERASE_FAILED; | 1971 | instr->state = MTD_ERASE_FAILED; |
2192 | instr->fail_addr = (page << this->page_shift); | 1972 | instr->fail_addr = (page << chip->page_shift); |
2193 | goto erase_exit; | 1973 | goto erase_exit; |
2194 | } | 1974 | } |
2195 | 1975 | ||
2196 | /* if BBT requires refresh, set the BBT rewrite flag to the page being erased */ | 1976 | /* |
2197 | if (this->options & BBT_AUTO_REFRESH) { | 1977 | * If BBT requires refresh, set the BBT rewrite flag to the |
2198 | if (((page & BBT_PAGE_MASK) == bbt_masked_page) && | 1978 | * page being erased |
2199 | (page != this->bbt_td->pages[chipnr])) { | 1979 | */ |
2200 | rewrite_bbt[chipnr] = (page << this->page_shift); | 1980 | if (bbt_masked_page != 0xffffffff && |
2201 | } | 1981 | (page & BBT_PAGE_MASK) == bbt_masked_page) |
2202 | } | 1982 | rewrite_bbt[chipnr] = (page << chip->page_shift); |
2203 | 1983 | ||
2204 | /* Increment page address and decrement length */ | 1984 | /* Increment page address and decrement length */ |
2205 | len -= (1 << this->phys_erase_shift); | 1985 | len -= (1 << chip->phys_erase_shift); |
2206 | page += pages_per_block; | 1986 | page += pages_per_block; |
2207 | 1987 | ||
2208 | /* Check, if we cross a chip boundary */ | 1988 | /* Check, if we cross a chip boundary */ |
2209 | if (len && !(page & this->pagemask)) { | 1989 | if (len && !(page & chip->pagemask)) { |
2210 | chipnr++; | 1990 | chipnr++; |
2211 | this->select_chip(mtd, -1); | 1991 | chip->select_chip(mtd, -1); |
2212 | this->select_chip(mtd, chipnr); | 1992 | chip->select_chip(mtd, chipnr); |
2213 | |||
2214 | /* if BBT requires refresh and BBT-PERCHIP, | ||
2215 | * set the BBT page mask to see if this BBT should be rewritten */ | ||
2216 | if ((this->options & BBT_AUTO_REFRESH) && (this->bbt_td->options & NAND_BBT_PERCHIP)) { | ||
2217 | bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK; | ||
2218 | } | ||
2219 | 1993 | ||
1994 | /* | ||
1995 | * If BBT requires refresh and BBT-PERCHIP, set the BBT | ||
1996 | * page mask to see if this BBT should be rewritten | ||
1997 | */ | ||
1998 | if (bbt_masked_page != 0xffffffff && | ||
1999 | (chip->bbt_td->options & NAND_BBT_PERCHIP)) | ||
2000 | bbt_masked_page = chip->bbt_td->pages[chipnr] & | ||
2001 | BBT_PAGE_MASK; | ||
2220 | } | 2002 | } |
2221 | } | 2003 | } |
2222 | instr->state = MTD_ERASE_DONE; | 2004 | instr->state = MTD_ERASE_DONE; |
2223 | 2005 | ||
2224 | erase_exit: | 2006 | erase_exit: |
2225 | 2007 | ||
2226 | ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO; | 2008 | ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO; |
2227 | /* Do call back function */ | 2009 | /* Do call back function */ |
@@ -2231,16 +2013,21 @@ erase_exit: | |||
2231 | /* Deselect and wake up anyone waiting on the device */ | 2013 | /* Deselect and wake up anyone waiting on the device */ |
2232 | nand_release_device(mtd); | 2014 | nand_release_device(mtd); |
2233 | 2015 | ||
2234 | /* if BBT requires refresh and erase was successful, rewrite any selected bad block tables */ | 2016 | /* |
2235 | if ((this->options & BBT_AUTO_REFRESH) && (!ret)) { | 2017 | * If BBT requires refresh and erase was successful, rewrite any |
2236 | for (chipnr = 0; chipnr < this->numchips; chipnr++) { | 2018 | * selected bad block tables |
2237 | if (rewrite_bbt[chipnr]) { | 2019 | */ |
2238 | /* update the BBT for chip */ | 2020 | if (bbt_masked_page == 0xffffffff || ret) |
2239 | DEBUG (MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt (%d:0x%0x 0x%0x)\n", | 2021 | return ret; |
2240 | chipnr, rewrite_bbt[chipnr], this->bbt_td->pages[chipnr]); | 2022 | |
2241 | nand_update_bbt (mtd, rewrite_bbt[chipnr]); | 2023 | for (chipnr = 0; chipnr < chip->numchips; chipnr++) { |
2242 | } | 2024 | if (!rewrite_bbt[chipnr]) |
2243 | } | 2025 | continue; |
2026 | /* update the BBT for chip */ | ||
2027 | DEBUG(MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt " | ||
2028 | "(%d:0x%0x 0x%0x)\n", chipnr, rewrite_bbt[chipnr], | ||
2029 | chip->bbt_td->pages[chipnr]); | ||
2030 | nand_update_bbt(mtd, rewrite_bbt[chipnr]); | ||
2244 | } | 2031 | } |
2245 | 2032 | ||
2246 | /* Return more or less happy */ | 2033 | /* Return more or less happy */ |
@@ -2253,51 +2040,50 @@ erase_exit: | |||
2253 | * | 2040 | * |
2254 | * Sync is actually a wait for chip ready function | 2041 | * Sync is actually a wait for chip ready function |
2255 | */ | 2042 | */ |
2256 | static void nand_sync (struct mtd_info *mtd) | 2043 | static void nand_sync(struct mtd_info *mtd) |
2257 | { | 2044 | { |
2258 | struct nand_chip *this = mtd->priv; | 2045 | struct nand_chip *chip = mtd->priv; |
2259 | 2046 | ||
2260 | DEBUG (MTD_DEBUG_LEVEL3, "nand_sync: called\n"); | 2047 | DEBUG(MTD_DEBUG_LEVEL3, "nand_sync: called\n"); |
2261 | 2048 | ||
2262 | /* Grab the lock and see if the device is available */ | 2049 | /* Grab the lock and see if the device is available */ |
2263 | nand_get_device (this, mtd, FL_SYNCING); | 2050 | nand_get_device(chip, mtd, FL_SYNCING); |
2264 | /* Release it and go back */ | 2051 | /* Release it and go back */ |
2265 | nand_release_device (mtd); | 2052 | nand_release_device(mtd); |
2266 | } | 2053 | } |
2267 | 2054 | ||
2268 | |||
2269 | /** | 2055 | /** |
2270 | * nand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad | 2056 | * nand_block_isbad - [MTD Interface] Check if block at offset is bad |
2271 | * @mtd: MTD device structure | 2057 | * @mtd: MTD device structure |
2272 | * @ofs: offset relative to mtd start | 2058 | * @ofs: offset relative to mtd start |
2273 | */ | 2059 | */ |
2274 | static int nand_block_isbad (struct mtd_info *mtd, loff_t ofs) | 2060 | static int nand_block_isbad(struct mtd_info *mtd, loff_t offs) |
2275 | { | 2061 | { |
2276 | /* Check for invalid offset */ | 2062 | /* Check for invalid offset */ |
2277 | if (ofs > mtd->size) | 2063 | if (offs > mtd->size) |
2278 | return -EINVAL; | 2064 | return -EINVAL; |
2279 | 2065 | ||
2280 | return nand_block_checkbad (mtd, ofs, 1, 0); | 2066 | return nand_block_checkbad(mtd, offs, 1, 0); |
2281 | } | 2067 | } |
2282 | 2068 | ||
2283 | /** | 2069 | /** |
2284 | * nand_block_markbad - [MTD Interface] Mark the block at the given offset as bad | 2070 | * nand_block_markbad - [MTD Interface] Mark block at the given offset as bad |
2285 | * @mtd: MTD device structure | 2071 | * @mtd: MTD device structure |
2286 | * @ofs: offset relative to mtd start | 2072 | * @ofs: offset relative to mtd start |
2287 | */ | 2073 | */ |
2288 | static int nand_block_markbad (struct mtd_info *mtd, loff_t ofs) | 2074 | static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs) |
2289 | { | 2075 | { |
2290 | struct nand_chip *this = mtd->priv; | 2076 | struct nand_chip *chip = mtd->priv; |
2291 | int ret; | 2077 | int ret; |
2292 | 2078 | ||
2293 | if ((ret = nand_block_isbad(mtd, ofs))) { | 2079 | if ((ret = nand_block_isbad(mtd, ofs))) { |
2294 | /* If it was bad already, return success and do nothing. */ | 2080 | /* If it was bad already, return success and do nothing. */ |
2295 | if (ret > 0) | 2081 | if (ret > 0) |
2296 | return 0; | 2082 | return 0; |
2297 | return ret; | 2083 | return ret; |
2298 | } | 2084 | } |
2299 | 2085 | ||
2300 | return this->block_markbad(mtd, ofs); | 2086 | return chip->block_markbad(mtd, ofs); |
2301 | } | 2087 | } |
2302 | 2088 | ||
2303 | /** | 2089 | /** |
@@ -2306,9 +2092,9 @@ static int nand_block_markbad (struct mtd_info *mtd, loff_t ofs) | |||
2306 | */ | 2092 | */ |
2307 | static int nand_suspend(struct mtd_info *mtd) | 2093 | static int nand_suspend(struct mtd_info *mtd) |
2308 | { | 2094 | { |
2309 | struct nand_chip *this = mtd->priv; | 2095 | struct nand_chip *chip = mtd->priv; |
2310 | 2096 | ||
2311 | return nand_get_device (this, mtd, FL_PM_SUSPENDED); | 2097 | return nand_get_device(chip, mtd, FL_PM_SUSPENDED); |
2312 | } | 2098 | } |
2313 | 2099 | ||
2314 | /** | 2100 | /** |
@@ -2317,373 +2103,385 @@ static int nand_suspend(struct mtd_info *mtd) | |||
2317 | */ | 2103 | */ |
2318 | static void nand_resume(struct mtd_info *mtd) | 2104 | static void nand_resume(struct mtd_info *mtd) |
2319 | { | 2105 | { |
2320 | struct nand_chip *this = mtd->priv; | 2106 | struct nand_chip *chip = mtd->priv; |
2321 | 2107 | ||
2322 | if (this->state == FL_PM_SUSPENDED) | 2108 | if (chip->state == FL_PM_SUSPENDED) |
2323 | nand_release_device(mtd); | 2109 | nand_release_device(mtd); |
2324 | else | 2110 | else |
2325 | printk(KERN_ERR "resume() called for the chip which is not " | 2111 | printk(KERN_ERR "nand_resume() called for a chip which is not " |
2326 | "in suspended state\n"); | 2112 | "in suspended state\n"); |
2327 | |||
2328 | } | 2113 | } |
2329 | 2114 | ||
2330 | 2115 | /* | |
2331 | /** | 2116 | * Set default functions |
2332 | * nand_scan - [NAND Interface] Scan for the NAND device | ||
2333 | * @mtd: MTD device structure | ||
2334 | * @maxchips: Number of chips to scan for | ||
2335 | * | ||
2336 | * This fills out all the not initialized function pointers | ||
2337 | * with the defaults. | ||
2338 | * The flash ID is read and the mtd/chip structures are | ||
2339 | * filled with the appropriate values. Buffers are allocated if | ||
2340 | * they are not provided by the board driver | ||
2341 | * | ||
2342 | */ | 2117 | */ |
2343 | int nand_scan (struct mtd_info *mtd, int maxchips) | 2118 | static void nand_set_defaults(struct nand_chip *chip, int busw) |
2344 | { | 2119 | { |
2345 | int i, nand_maf_id, nand_dev_id, busw, maf_id; | ||
2346 | struct nand_chip *this = mtd->priv; | ||
2347 | |||
2348 | /* Get buswidth to select the correct functions*/ | ||
2349 | busw = this->options & NAND_BUSWIDTH_16; | ||
2350 | |||
2351 | /* check for proper chip_delay setup, set 20us if not */ | 2120 | /* check for proper chip_delay setup, set 20us if not */ |
2352 | if (!this->chip_delay) | 2121 | if (!chip->chip_delay) |
2353 | this->chip_delay = 20; | 2122 | chip->chip_delay = 20; |
2354 | 2123 | ||
2355 | /* check, if a user supplied command function given */ | 2124 | /* check, if a user supplied command function given */ |
2356 | if (this->cmdfunc == NULL) | 2125 | if (chip->cmdfunc == NULL) |
2357 | this->cmdfunc = nand_command; | 2126 | chip->cmdfunc = nand_command; |
2358 | 2127 | ||
2359 | /* check, if a user supplied wait function given */ | 2128 | /* check, if a user supplied wait function given */ |
2360 | if (this->waitfunc == NULL) | 2129 | if (chip->waitfunc == NULL) |
2361 | this->waitfunc = nand_wait; | 2130 | chip->waitfunc = nand_wait; |
2362 | 2131 | ||
2363 | if (!this->select_chip) | 2132 | if (!chip->select_chip) |
2364 | this->select_chip = nand_select_chip; | 2133 | chip->select_chip = nand_select_chip; |
2365 | if (!this->write_byte) | 2134 | if (!chip->read_byte) |
2366 | this->write_byte = busw ? nand_write_byte16 : nand_write_byte; | 2135 | chip->read_byte = busw ? nand_read_byte16 : nand_read_byte; |
2367 | if (!this->read_byte) | 2136 | if (!chip->read_word) |
2368 | this->read_byte = busw ? nand_read_byte16 : nand_read_byte; | 2137 | chip->read_word = nand_read_word; |
2369 | if (!this->write_word) | 2138 | if (!chip->block_bad) |
2370 | this->write_word = nand_write_word; | 2139 | chip->block_bad = nand_block_bad; |
2371 | if (!this->read_word) | 2140 | if (!chip->block_markbad) |
2372 | this->read_word = nand_read_word; | 2141 | chip->block_markbad = nand_default_block_markbad; |
2373 | if (!this->block_bad) | 2142 | if (!chip->write_buf) |
2374 | this->block_bad = nand_block_bad; | 2143 | chip->write_buf = busw ? nand_write_buf16 : nand_write_buf; |
2375 | if (!this->block_markbad) | 2144 | if (!chip->read_buf) |
2376 | this->block_markbad = nand_default_block_markbad; | 2145 | chip->read_buf = busw ? nand_read_buf16 : nand_read_buf; |
2377 | if (!this->write_buf) | 2146 | if (!chip->verify_buf) |
2378 | this->write_buf = busw ? nand_write_buf16 : nand_write_buf; | 2147 | chip->verify_buf = busw ? nand_verify_buf16 : nand_verify_buf; |
2379 | if (!this->read_buf) | 2148 | if (!chip->scan_bbt) |
2380 | this->read_buf = busw ? nand_read_buf16 : nand_read_buf; | 2149 | chip->scan_bbt = nand_default_bbt; |
2381 | if (!this->verify_buf) | 2150 | |
2382 | this->verify_buf = busw ? nand_verify_buf16 : nand_verify_buf; | 2151 | if (!chip->controller) { |
2383 | if (!this->scan_bbt) | 2152 | chip->controller = &chip->hwcontrol; |
2384 | this->scan_bbt = nand_default_bbt; | 2153 | spin_lock_init(&chip->controller->lock); |
2154 | init_waitqueue_head(&chip->controller->wq); | ||
2155 | } | ||
2156 | |||
2157 | } | ||
2158 | |||
2159 | /* | ||
2160 | * Get the flash and manufacturer id and lookup if the type is supported | ||
2161 | */ | ||
2162 | static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | ||
2163 | struct nand_chip *chip, | ||
2164 | int busw, int *maf_id) | ||
2165 | { | ||
2166 | struct nand_flash_dev *type = NULL; | ||
2167 | int i, dev_id, maf_idx; | ||
2385 | 2168 | ||
2386 | /* Select the device */ | 2169 | /* Select the device */ |
2387 | this->select_chip(mtd, 0); | 2170 | chip->select_chip(mtd, 0); |
2388 | 2171 | ||
2389 | /* Send the command for reading device ID */ | 2172 | /* Send the command for reading device ID */ |
2390 | this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1); | 2173 | chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); |
2391 | 2174 | ||
2392 | /* Read manufacturer and device IDs */ | 2175 | /* Read manufacturer and device IDs */ |
2393 | nand_maf_id = this->read_byte(mtd); | 2176 | *maf_id = chip->read_byte(mtd); |
2394 | nand_dev_id = this->read_byte(mtd); | 2177 | dev_id = chip->read_byte(mtd); |
2395 | 2178 | ||
2396 | /* Print and store flash device information */ | 2179 | /* Lookup the flash id */ |
2397 | for (i = 0; nand_flash_ids[i].name != NULL; i++) { | 2180 | for (i = 0; nand_flash_ids[i].name != NULL; i++) { |
2181 | if (dev_id == nand_flash_ids[i].id) { | ||
2182 | type = &nand_flash_ids[i]; | ||
2183 | break; | ||
2184 | } | ||
2185 | } | ||
2398 | 2186 | ||
2399 | if (nand_dev_id != nand_flash_ids[i].id) | 2187 | if (!type) |
2400 | continue; | 2188 | return ERR_PTR(-ENODEV); |
2189 | |||
2190 | if (!mtd->name) | ||
2191 | mtd->name = type->name; | ||
2192 | |||
2193 | chip->chipsize = type->chipsize << 20; | ||
2194 | |||
2195 | /* Newer devices have all the information in additional id bytes */ | ||
2196 | if (!type->pagesize) { | ||
2197 | int extid; | ||
2198 | /* The 3rd id byte contains non relevant data ATM */ | ||
2199 | extid = chip->read_byte(mtd); | ||
2200 | /* The 4th id byte is the important one */ | ||
2201 | extid = chip->read_byte(mtd); | ||
2202 | /* Calc pagesize */ | ||
2203 | mtd->writesize = 1024 << (extid & 0x3); | ||
2204 | extid >>= 2; | ||
2205 | /* Calc oobsize */ | ||
2206 | mtd->oobsize = (8 << (extid & 0x01)) * (mtd->writesize >> 9); | ||
2207 | extid >>= 2; | ||
2208 | /* Calc blocksize. Blocksize is multiples of 64KiB */ | ||
2209 | mtd->erasesize = (64 * 1024) << (extid & 0x03); | ||
2210 | extid >>= 2; | ||
2211 | /* Get buswidth information */ | ||
2212 | busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0; | ||
2401 | 2213 | ||
2402 | if (!mtd->name) mtd->name = nand_flash_ids[i].name; | 2214 | } else { |
2403 | this->chipsize = nand_flash_ids[i].chipsize << 20; | 2215 | /* |
2404 | 2216 | * Old devices have chip data hardcoded in the device id table | |
2405 | /* New devices have all the information in additional id bytes */ | 2217 | */ |
2406 | if (!nand_flash_ids[i].pagesize) { | 2218 | mtd->erasesize = type->erasesize; |
2407 | int extid; | 2219 | mtd->writesize = type->pagesize; |
2408 | /* The 3rd id byte contains non relevant data ATM */ | 2220 | mtd->oobsize = mtd->writesize / 32; |
2409 | extid = this->read_byte(mtd); | 2221 | busw = type->options & NAND_BUSWIDTH_16; |
2410 | /* The 4th id byte is the important one */ | 2222 | } |
2411 | extid = this->read_byte(mtd); | ||
2412 | /* Calc pagesize */ | ||
2413 | mtd->oobblock = 1024 << (extid & 0x3); | ||
2414 | extid >>= 2; | ||
2415 | /* Calc oobsize */ | ||
2416 | mtd->oobsize = (8 << (extid & 0x01)) * (mtd->oobblock >> 9); | ||
2417 | extid >>= 2; | ||
2418 | /* Calc blocksize. Blocksize is multiples of 64KiB */ | ||
2419 | mtd->erasesize = (64 * 1024) << (extid & 0x03); | ||
2420 | extid >>= 2; | ||
2421 | /* Get buswidth information */ | ||
2422 | busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0; | ||
2423 | 2223 | ||
2424 | } else { | 2224 | /* Try to identify manufacturer */ |
2425 | /* Old devices have this data hardcoded in the | 2225 | for (maf_idx = 0; nand_manuf_ids[maf_idx].id != 0x0; maf_id++) { |
2426 | * device id table */ | 2226 | if (nand_manuf_ids[maf_idx].id == *maf_id) |
2427 | mtd->erasesize = nand_flash_ids[i].erasesize; | 2227 | break; |
2428 | mtd->oobblock = nand_flash_ids[i].pagesize; | 2228 | } |
2429 | mtd->oobsize = mtd->oobblock / 32; | ||
2430 | busw = nand_flash_ids[i].options & NAND_BUSWIDTH_16; | ||
2431 | } | ||
2432 | 2229 | ||
2433 | /* Try to identify manufacturer */ | 2230 | /* |
2434 | for (maf_id = 0; nand_manuf_ids[maf_id].id != 0x0; maf_id++) { | 2231 | * Check, if buswidth is correct. Hardware drivers should set |
2435 | if (nand_manuf_ids[maf_id].id == nand_maf_id) | 2232 | * chip correct ! |
2436 | break; | 2233 | */ |
2437 | } | 2234 | if (busw != (chip->options & NAND_BUSWIDTH_16)) { |
2235 | printk(KERN_INFO "NAND device: Manufacturer ID:" | ||
2236 | " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, | ||
2237 | dev_id, nand_manuf_ids[maf_idx].name, mtd->name); | ||
2238 | printk(KERN_WARNING "NAND bus width %d instead %d bit\n", | ||
2239 | (chip->options & NAND_BUSWIDTH_16) ? 16 : 8, | ||
2240 | busw ? 16 : 8); | ||
2241 | return ERR_PTR(-EINVAL); | ||
2242 | } | ||
2438 | 2243 | ||
2439 | /* Check, if buswidth is correct. Hardware drivers should set | 2244 | /* Calculate the address shift from the page size */ |
2440 | * this correct ! */ | 2245 | chip->page_shift = ffs(mtd->writesize) - 1; |
2441 | if (busw != (this->options & NAND_BUSWIDTH_16)) { | 2246 | /* Convert chipsize to number of pages per chip -1. */ |
2442 | printk (KERN_INFO "NAND device: Manufacturer ID:" | 2247 | chip->pagemask = (chip->chipsize >> chip->page_shift) - 1; |
2443 | " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, | ||
2444 | nand_manuf_ids[maf_id].name , mtd->name); | ||
2445 | printk (KERN_WARNING | ||
2446 | "NAND bus width %d instead %d bit\n", | ||
2447 | (this->options & NAND_BUSWIDTH_16) ? 16 : 8, | ||
2448 | busw ? 16 : 8); | ||
2449 | this->select_chip(mtd, -1); | ||
2450 | return 1; | ||
2451 | } | ||
2452 | 2248 | ||
2453 | /* Calculate the address shift from the page size */ | 2249 | chip->bbt_erase_shift = chip->phys_erase_shift = |
2454 | this->page_shift = ffs(mtd->oobblock) - 1; | 2250 | ffs(mtd->erasesize) - 1; |
2455 | this->bbt_erase_shift = this->phys_erase_shift = ffs(mtd->erasesize) - 1; | 2251 | chip->chip_shift = ffs(chip->chipsize) - 1; |
2456 | this->chip_shift = ffs(this->chipsize) - 1; | ||
2457 | |||
2458 | /* Set the bad block position */ | ||
2459 | this->badblockpos = mtd->oobblock > 512 ? | ||
2460 | NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS; | ||
2461 | |||
2462 | /* Get chip options, preserve non chip based options */ | ||
2463 | this->options &= ~NAND_CHIPOPTIONS_MSK; | ||
2464 | this->options |= nand_flash_ids[i].options & NAND_CHIPOPTIONS_MSK; | ||
2465 | /* Set this as a default. Board drivers can override it, if neccecary */ | ||
2466 | this->options |= NAND_NO_AUTOINCR; | ||
2467 | /* Check if this is a not a samsung device. Do not clear the options | ||
2468 | * for chips which are not having an extended id. | ||
2469 | */ | ||
2470 | if (nand_maf_id != NAND_MFR_SAMSUNG && !nand_flash_ids[i].pagesize) | ||
2471 | this->options &= ~NAND_SAMSUNG_LP_OPTIONS; | ||
2472 | 2252 | ||
2473 | /* Check for AND chips with 4 page planes */ | 2253 | /* Set the bad block position */ |
2474 | if (this->options & NAND_4PAGE_ARRAY) | 2254 | chip->badblockpos = mtd->writesize > 512 ? |
2475 | this->erase_cmd = multi_erase_cmd; | 2255 | NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS; |
2476 | else | ||
2477 | this->erase_cmd = single_erase_cmd; | ||
2478 | 2256 | ||
2479 | /* Do not replace user supplied command function ! */ | 2257 | /* Get chip options, preserve non chip based options */ |
2480 | if (mtd->oobblock > 512 && this->cmdfunc == nand_command) | 2258 | chip->options &= ~NAND_CHIPOPTIONS_MSK; |
2481 | this->cmdfunc = nand_command_lp; | 2259 | chip->options |= type->options & NAND_CHIPOPTIONS_MSK; |
2482 | 2260 | ||
2483 | printk (KERN_INFO "NAND device: Manufacturer ID:" | 2261 | /* |
2484 | " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, | 2262 | * Set chip as a default. Board drivers can override it, if necessary |
2485 | nand_manuf_ids[maf_id].name , nand_flash_ids[i].name); | 2263 | */ |
2486 | break; | 2264 | chip->options |= NAND_NO_AUTOINCR; |
2487 | } | 2265 | |
2266 | /* Check if chip is a not a samsung device. Do not clear the | ||
2267 | * options for chips which are not having an extended id. | ||
2268 | */ | ||
2269 | if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize) | ||
2270 | chip->options &= ~NAND_SAMSUNG_LP_OPTIONS; | ||
2271 | |||
2272 | /* Check for AND chips with 4 page planes */ | ||
2273 | if (chip->options & NAND_4PAGE_ARRAY) | ||
2274 | chip->erase_cmd = multi_erase_cmd; | ||
2275 | else | ||
2276 | chip->erase_cmd = single_erase_cmd; | ||
2277 | |||
2278 | /* Do not replace user supplied command function ! */ | ||
2279 | if (mtd->writesize > 512 && chip->cmdfunc == nand_command) | ||
2280 | chip->cmdfunc = nand_command_lp; | ||
2281 | |||
2282 | printk(KERN_INFO "NAND device: Manufacturer ID:" | ||
2283 | " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, dev_id, | ||
2284 | nand_manuf_ids[maf_idx].name, type->name); | ||
2285 | |||
2286 | return type; | ||
2287 | } | ||
2288 | |||
2289 | /* module_text_address() isn't exported, and it's mostly a pointless | ||
2290 | test if this is a module _anyway_ -- they'd have to try _really_ hard | ||
2291 | to call us from in-kernel code if the core NAND support is modular. */ | ||
2292 | #ifdef MODULE | ||
2293 | #define caller_is_module() (1) | ||
2294 | #else | ||
2295 | #define caller_is_module() \ | ||
2296 | module_text_address((unsigned long)__builtin_return_address(0)) | ||
2297 | #endif | ||
2488 | 2298 | ||
2489 | if (!nand_flash_ids[i].name) { | 2299 | /** |
2490 | printk (KERN_WARNING "No NAND device found!!!\n"); | 2300 | * nand_scan - [NAND Interface] Scan for the NAND device |
2491 | this->select_chip(mtd, -1); | 2301 | * @mtd: MTD device structure |
2492 | return 1; | 2302 | * @maxchips: Number of chips to scan for |
2303 | * | ||
2304 | * This fills out all the uninitialized function pointers | ||
2305 | * with the defaults. | ||
2306 | * The flash ID is read and the mtd/chip structures are | ||
2307 | * filled with the appropriate values. | ||
2308 | * The mtd->owner field must be set to the module of the caller | ||
2309 | * | ||
2310 | */ | ||
2311 | int nand_scan(struct mtd_info *mtd, int maxchips) | ||
2312 | { | ||
2313 | int i, busw, nand_maf_id; | ||
2314 | struct nand_chip *chip = mtd->priv; | ||
2315 | struct nand_flash_dev *type; | ||
2316 | |||
2317 | /* Many callers got this wrong, so check for it for a while... */ | ||
2318 | if (!mtd->owner && caller_is_module()) { | ||
2319 | printk(KERN_CRIT "nand_scan() called with NULL mtd->owner!\n"); | ||
2320 | BUG(); | ||
2493 | } | 2321 | } |
2494 | 2322 | ||
2495 | for (i=1; i < maxchips; i++) { | 2323 | /* Get buswidth to select the correct functions */ |
2496 | this->select_chip(mtd, i); | 2324 | busw = chip->options & NAND_BUSWIDTH_16; |
2325 | /* Set the default functions */ | ||
2326 | nand_set_defaults(chip, busw); | ||
2497 | 2327 | ||
2498 | /* Send the command for reading device ID */ | 2328 | /* Read the flash type */ |
2499 | this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1); | 2329 | type = nand_get_flash_type(mtd, chip, busw, &nand_maf_id); |
2330 | |||
2331 | if (IS_ERR(type)) { | ||
2332 | printk(KERN_WARNING "No NAND device found!!!\n"); | ||
2333 | chip->select_chip(mtd, -1); | ||
2334 | return PTR_ERR(type); | ||
2335 | } | ||
2500 | 2336 | ||
2337 | /* Check for a chip array */ | ||
2338 | for (i = 1; i < maxchips; i++) { | ||
2339 | chip->select_chip(mtd, i); | ||
2340 | /* Send the command for reading device ID */ | ||
2341 | chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); | ||
2501 | /* Read manufacturer and device IDs */ | 2342 | /* Read manufacturer and device IDs */ |
2502 | if (nand_maf_id != this->read_byte(mtd) || | 2343 | if (nand_maf_id != chip->read_byte(mtd) || |
2503 | nand_dev_id != this->read_byte(mtd)) | 2344 | type->id != chip->read_byte(mtd)) |
2504 | break; | 2345 | break; |
2505 | } | 2346 | } |
2506 | if (i > 1) | 2347 | if (i > 1) |
2507 | printk(KERN_INFO "%d NAND chips detected\n", i); | 2348 | printk(KERN_INFO "%d NAND chips detected\n", i); |
2508 | 2349 | ||
2509 | /* Allocate buffers, if neccecary */ | 2350 | /* Store the number of chips and calc total size for mtd */ |
2510 | if (!this->oob_buf) { | 2351 | chip->numchips = i; |
2511 | size_t len; | 2352 | mtd->size = i * chip->chipsize; |
2512 | len = mtd->oobsize << (this->phys_erase_shift - this->page_shift); | ||
2513 | this->oob_buf = kmalloc (len, GFP_KERNEL); | ||
2514 | if (!this->oob_buf) { | ||
2515 | printk (KERN_ERR "nand_scan(): Cannot allocate oob_buf\n"); | ||
2516 | return -ENOMEM; | ||
2517 | } | ||
2518 | this->options |= NAND_OOBBUF_ALLOC; | ||
2519 | } | ||
2520 | 2353 | ||
2521 | if (!this->data_buf) { | 2354 | /* Preset the internal oob write buffer */ |
2522 | size_t len; | 2355 | memset(chip->buffers.oobwbuf, 0xff, mtd->oobsize); |
2523 | len = mtd->oobblock + mtd->oobsize; | ||
2524 | this->data_buf = kmalloc (len, GFP_KERNEL); | ||
2525 | if (!this->data_buf) { | ||
2526 | if (this->options & NAND_OOBBUF_ALLOC) | ||
2527 | kfree (this->oob_buf); | ||
2528 | printk (KERN_ERR "nand_scan(): Cannot allocate data_buf\n"); | ||
2529 | return -ENOMEM; | ||
2530 | } | ||
2531 | this->options |= NAND_DATABUF_ALLOC; | ||
2532 | } | ||
2533 | 2356 | ||
2534 | /* Store the number of chips and calc total size for mtd */ | 2357 | /* |
2535 | this->numchips = i; | 2358 | * If no default placement scheme is given, select an appropriate one |
2536 | mtd->size = i * this->chipsize; | 2359 | */ |
2537 | /* Convert chipsize to number of pages per chip -1. */ | 2360 | if (!chip->ecc.layout) { |
2538 | this->pagemask = (this->chipsize >> this->page_shift) - 1; | ||
2539 | /* Preset the internal oob buffer */ | ||
2540 | memset(this->oob_buf, 0xff, mtd->oobsize << (this->phys_erase_shift - this->page_shift)); | ||
2541 | |||
2542 | /* If no default placement scheme is given, select an | ||
2543 | * appropriate one */ | ||
2544 | if (!this->autooob) { | ||
2545 | /* Select the appropriate default oob placement scheme for | ||
2546 | * placement agnostic filesystems */ | ||
2547 | switch (mtd->oobsize) { | 2361 | switch (mtd->oobsize) { |
2548 | case 8: | 2362 | case 8: |
2549 | this->autooob = &nand_oob_8; | 2363 | chip->ecc.layout = &nand_oob_8; |
2550 | break; | 2364 | break; |
2551 | case 16: | 2365 | case 16: |
2552 | this->autooob = &nand_oob_16; | 2366 | chip->ecc.layout = &nand_oob_16; |
2553 | break; | 2367 | break; |
2554 | case 64: | 2368 | case 64: |
2555 | this->autooob = &nand_oob_64; | 2369 | chip->ecc.layout = &nand_oob_64; |
2556 | break; | 2370 | break; |
2557 | default: | 2371 | default: |
2558 | printk (KERN_WARNING "No oob scheme defined for oobsize %d\n", | 2372 | printk(KERN_WARNING "No oob scheme defined for " |
2559 | mtd->oobsize); | 2373 | "oobsize %d\n", mtd->oobsize); |
2560 | BUG(); | 2374 | BUG(); |
2561 | } | 2375 | } |
2562 | } | 2376 | } |
2563 | 2377 | ||
2564 | /* The number of bytes available for the filesystem to place fs dependend | ||
2565 | * oob data */ | ||
2566 | mtd->oobavail = 0; | ||
2567 | for (i = 0; this->autooob->oobfree[i][1]; i++) | ||
2568 | mtd->oobavail += this->autooob->oobfree[i][1]; | ||
2569 | |||
2570 | /* | 2378 | /* |
2571 | * check ECC mode, default to software | 2379 | * check ECC mode, default to software if 3byte/512byte hardware ECC is |
2572 | * if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize | 2380 | * selected and we have 256 byte pagesize fallback to software ECC |
2573 | * fallback to software ECC | 2381 | */ |
2574 | */ | 2382 | switch (chip->ecc.mode) { |
2575 | this->eccsize = 256; /* set default eccsize */ | 2383 | case NAND_ECC_HW: |
2576 | this->eccbytes = 3; | 2384 | /* Use standard hwecc read page function ? */ |
2577 | 2385 | if (!chip->ecc.read_page) | |
2578 | switch (this->eccmode) { | 2386 | chip->ecc.read_page = nand_read_page_hwecc; |
2579 | case NAND_ECC_HW12_2048: | 2387 | if (!chip->ecc.write_page) |
2580 | if (mtd->oobblock < 2048) { | 2388 | chip->ecc.write_page = nand_write_page_hwecc; |
2581 | printk(KERN_WARNING "2048 byte HW ECC not possible on %d byte page size, fallback to SW ECC\n", | 2389 | if (!chip->ecc.read_oob) |
2582 | mtd->oobblock); | 2390 | chip->ecc.read_oob = nand_read_oob_std; |
2583 | this->eccmode = NAND_ECC_SOFT; | 2391 | if (!chip->ecc.write_oob) |
2584 | this->calculate_ecc = nand_calculate_ecc; | 2392 | chip->ecc.write_oob = nand_write_oob_std; |
2585 | this->correct_data = nand_correct_data; | 2393 | |
2586 | } else | 2394 | case NAND_ECC_HW_SYNDROME: |
2587 | this->eccsize = 2048; | 2395 | if (!chip->ecc.calculate || !chip->ecc.correct || |
2588 | break; | 2396 | !chip->ecc.hwctl) { |
2589 | 2397 | printk(KERN_WARNING "No ECC functions supplied, " | |
2590 | case NAND_ECC_HW3_512: | 2398 | "Hardware ECC not possible\n"); |
2591 | case NAND_ECC_HW6_512: | 2399 | BUG(); |
2592 | case NAND_ECC_HW8_512: | 2400 | } |
2593 | if (mtd->oobblock == 256) { | 2401 | /* Use standard syndrome read/write page function ? */ |
2594 | printk (KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n"); | 2402 | if (!chip->ecc.read_page) |
2595 | this->eccmode = NAND_ECC_SOFT; | 2403 | chip->ecc.read_page = nand_read_page_syndrome; |
2596 | this->calculate_ecc = nand_calculate_ecc; | 2404 | if (!chip->ecc.write_page) |
2597 | this->correct_data = nand_correct_data; | 2405 | chip->ecc.write_page = nand_write_page_syndrome; |
2598 | } else | 2406 | if (!chip->ecc.read_oob) |
2599 | this->eccsize = 512; /* set eccsize to 512 */ | 2407 | chip->ecc.read_oob = nand_read_oob_syndrome; |
2600 | break; | 2408 | if (!chip->ecc.write_oob) |
2409 | chip->ecc.write_oob = nand_write_oob_syndrome; | ||
2410 | |||
2411 | if (mtd->writesize >= chip->ecc.size) | ||
2412 | break; | ||
2413 | printk(KERN_WARNING "%d byte HW ECC not possible on " | ||
2414 | "%d byte page size, fallback to SW ECC\n", | ||
2415 | chip->ecc.size, mtd->writesize); | ||
2416 | chip->ecc.mode = NAND_ECC_SOFT; | ||
2601 | 2417 | ||
2602 | case NAND_ECC_HW3_256: | 2418 | case NAND_ECC_SOFT: |
2419 | chip->ecc.calculate = nand_calculate_ecc; | ||
2420 | chip->ecc.correct = nand_correct_data; | ||
2421 | chip->ecc.read_page = nand_read_page_swecc; | ||
2422 | chip->ecc.write_page = nand_write_page_swecc; | ||
2423 | chip->ecc.read_oob = nand_read_oob_std; | ||
2424 | chip->ecc.write_oob = nand_write_oob_std; | ||
2425 | chip->ecc.size = 256; | ||
2426 | chip->ecc.bytes = 3; | ||
2603 | break; | 2427 | break; |
2604 | 2428 | ||
2605 | case NAND_ECC_NONE: | 2429 | case NAND_ECC_NONE: |
2606 | printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n"); | 2430 | printk(KERN_WARNING "NAND_ECC_NONE selected by board driver. " |
2607 | this->eccmode = NAND_ECC_NONE; | 2431 | "This is not recommended !!\n"); |
2432 | chip->ecc.read_page = nand_read_page_raw; | ||
2433 | chip->ecc.write_page = nand_write_page_raw; | ||
2434 | chip->ecc.read_oob = nand_read_oob_std; | ||
2435 | chip->ecc.write_oob = nand_write_oob_std; | ||
2436 | chip->ecc.size = mtd->writesize; | ||
2437 | chip->ecc.bytes = 0; | ||
2608 | break; | 2438 | break; |
2609 | |||
2610 | case NAND_ECC_SOFT: | ||
2611 | this->calculate_ecc = nand_calculate_ecc; | ||
2612 | this->correct_data = nand_correct_data; | ||
2613 | break; | ||
2614 | |||
2615 | default: | 2439 | default: |
2616 | printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode); | 2440 | printk(KERN_WARNING "Invalid NAND_ECC_MODE %d\n", |
2617 | BUG(); | 2441 | chip->ecc.mode); |
2618 | } | ||
2619 | |||
2620 | /* Check hardware ecc function availability and adjust number of ecc bytes per | ||
2621 | * calculation step | ||
2622 | */ | ||
2623 | switch (this->eccmode) { | ||
2624 | case NAND_ECC_HW12_2048: | ||
2625 | this->eccbytes += 4; | ||
2626 | case NAND_ECC_HW8_512: | ||
2627 | this->eccbytes += 2; | ||
2628 | case NAND_ECC_HW6_512: | ||
2629 | this->eccbytes += 3; | ||
2630 | case NAND_ECC_HW3_512: | ||
2631 | case NAND_ECC_HW3_256: | ||
2632 | if (this->calculate_ecc && this->correct_data && this->enable_hwecc) | ||
2633 | break; | ||
2634 | printk (KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n"); | ||
2635 | BUG(); | 2442 | BUG(); |
2636 | } | 2443 | } |
2637 | 2444 | ||
2638 | mtd->eccsize = this->eccsize; | 2445 | /* |
2639 | 2446 | * The number of bytes available for a client to place data into | |
2640 | /* Set the number of read / write steps for one page to ensure ECC generation */ | 2447 | * the out of band area |
2641 | switch (this->eccmode) { | 2448 | */ |
2642 | case NAND_ECC_HW12_2048: | 2449 | chip->ecc.layout->oobavail = 0; |
2643 | this->eccsteps = mtd->oobblock / 2048; | 2450 | for (i = 0; chip->ecc.layout->oobfree[i].length; i++) |
2644 | break; | 2451 | chip->ecc.layout->oobavail += |
2645 | case NAND_ECC_HW3_512: | 2452 | chip->ecc.layout->oobfree[i].length; |
2646 | case NAND_ECC_HW6_512: | ||
2647 | case NAND_ECC_HW8_512: | ||
2648 | this->eccsteps = mtd->oobblock / 512; | ||
2649 | break; | ||
2650 | case NAND_ECC_HW3_256: | ||
2651 | case NAND_ECC_SOFT: | ||
2652 | this->eccsteps = mtd->oobblock / 256; | ||
2653 | break; | ||
2654 | 2453 | ||
2655 | case NAND_ECC_NONE: | 2454 | /* |
2656 | this->eccsteps = 1; | 2455 | * Set the number of read / write steps for one page depending on ECC |
2657 | break; | 2456 | * mode |
2457 | */ | ||
2458 | chip->ecc.steps = mtd->writesize / chip->ecc.size; | ||
2459 | if(chip->ecc.steps * chip->ecc.size != mtd->writesize) { | ||
2460 | printk(KERN_WARNING "Invalid ecc parameters\n"); | ||
2461 | BUG(); | ||
2658 | } | 2462 | } |
2463 | chip->ecc.total = chip->ecc.steps * chip->ecc.bytes; | ||
2659 | 2464 | ||
2660 | /* Initialize state, waitqueue and spinlock */ | 2465 | /* Initialize state */ |
2661 | this->state = FL_READY; | 2466 | chip->state = FL_READY; |
2662 | init_waitqueue_head (&this->wq); | ||
2663 | spin_lock_init (&this->chip_lock); | ||
2664 | 2467 | ||
2665 | /* De-select the device */ | 2468 | /* De-select the device */ |
2666 | this->select_chip(mtd, -1); | 2469 | chip->select_chip(mtd, -1); |
2667 | 2470 | ||
2668 | /* Invalidate the pagebuffer reference */ | 2471 | /* Invalidate the pagebuffer reference */ |
2669 | this->pagebuf = -1; | 2472 | chip->pagebuf = -1; |
2670 | 2473 | ||
2671 | /* Fill in remaining MTD driver data */ | 2474 | /* Fill in remaining MTD driver data */ |
2672 | mtd->type = MTD_NANDFLASH; | 2475 | mtd->type = MTD_NANDFLASH; |
2673 | mtd->flags = MTD_CAP_NANDFLASH | MTD_ECC; | 2476 | mtd->flags = MTD_CAP_NANDFLASH; |
2674 | mtd->ecctype = MTD_ECC_SW; | 2477 | mtd->ecctype = MTD_ECC_SW; |
2675 | mtd->erase = nand_erase; | 2478 | mtd->erase = nand_erase; |
2676 | mtd->point = NULL; | 2479 | mtd->point = NULL; |
2677 | mtd->unpoint = NULL; | 2480 | mtd->unpoint = NULL; |
2678 | mtd->read = nand_read; | 2481 | mtd->read = nand_read; |
2679 | mtd->write = nand_write; | 2482 | mtd->write = nand_write; |
2680 | mtd->read_ecc = nand_read_ecc; | ||
2681 | mtd->write_ecc = nand_write_ecc; | ||
2682 | mtd->read_oob = nand_read_oob; | 2483 | mtd->read_oob = nand_read_oob; |
2683 | mtd->write_oob = nand_write_oob; | 2484 | mtd->write_oob = nand_write_oob; |
2684 | mtd->readv = NULL; | ||
2685 | mtd->writev = nand_writev; | ||
2686 | mtd->writev_ecc = nand_writev_ecc; | ||
2687 | mtd->sync = nand_sync; | 2485 | mtd->sync = nand_sync; |
2688 | mtd->lock = NULL; | 2486 | mtd->lock = NULL; |
2689 | mtd->unlock = NULL; | 2487 | mtd->unlock = NULL; |
@@ -2692,47 +2490,38 @@ int nand_scan (struct mtd_info *mtd, int maxchips) | |||
2692 | mtd->block_isbad = nand_block_isbad; | 2490 | mtd->block_isbad = nand_block_isbad; |
2693 | mtd->block_markbad = nand_block_markbad; | 2491 | mtd->block_markbad = nand_block_markbad; |
2694 | 2492 | ||
2695 | /* and make the autooob the default one */ | 2493 | /* propagate ecc.layout to mtd_info */ |
2696 | memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo)); | 2494 | mtd->ecclayout = chip->ecc.layout; |
2697 | |||
2698 | mtd->owner = THIS_MODULE; | ||
2699 | 2495 | ||
2700 | /* Check, if we should skip the bad block table scan */ | 2496 | /* Check, if we should skip the bad block table scan */ |
2701 | if (this->options & NAND_SKIP_BBTSCAN) | 2497 | if (chip->options & NAND_SKIP_BBTSCAN) |
2702 | return 0; | 2498 | return 0; |
2703 | 2499 | ||
2704 | /* Build bad block table */ | 2500 | /* Build bad block table */ |
2705 | return this->scan_bbt (mtd); | 2501 | return chip->scan_bbt(mtd); |
2706 | } | 2502 | } |
2707 | 2503 | ||
2708 | /** | 2504 | /** |
2709 | * nand_release - [NAND Interface] Free resources held by the NAND device | 2505 | * nand_release - [NAND Interface] Free resources held by the NAND device |
2710 | * @mtd: MTD device structure | 2506 | * @mtd: MTD device structure |
2711 | */ | 2507 | */ |
2712 | void nand_release (struct mtd_info *mtd) | 2508 | void nand_release(struct mtd_info *mtd) |
2713 | { | 2509 | { |
2714 | struct nand_chip *this = mtd->priv; | 2510 | struct nand_chip *chip = mtd->priv; |
2715 | 2511 | ||
2716 | #ifdef CONFIG_MTD_PARTITIONS | 2512 | #ifdef CONFIG_MTD_PARTITIONS |
2717 | /* Deregister partitions */ | 2513 | /* Deregister partitions */ |
2718 | del_mtd_partitions (mtd); | 2514 | del_mtd_partitions(mtd); |
2719 | #endif | 2515 | #endif |
2720 | /* Deregister the device */ | 2516 | /* Deregister the device */ |
2721 | del_mtd_device (mtd); | 2517 | del_mtd_device(mtd); |
2722 | 2518 | ||
2723 | /* Free bad block table memory */ | 2519 | /* Free bad block table memory */ |
2724 | kfree (this->bbt); | 2520 | kfree(chip->bbt); |
2725 | /* Buffer allocated by nand_scan ? */ | ||
2726 | if (this->options & NAND_OOBBUF_ALLOC) | ||
2727 | kfree (this->oob_buf); | ||
2728 | /* Buffer allocated by nand_scan ? */ | ||
2729 | if (this->options & NAND_DATABUF_ALLOC) | ||
2730 | kfree (this->data_buf); | ||
2731 | } | 2521 | } |
2732 | 2522 | ||
2733 | EXPORT_SYMBOL_GPL (nand_scan); | 2523 | EXPORT_SYMBOL_GPL(nand_scan); |
2734 | EXPORT_SYMBOL_GPL (nand_release); | 2524 | EXPORT_SYMBOL_GPL(nand_release); |
2735 | |||
2736 | 2525 | ||
2737 | static int __init nand_base_init(void) | 2526 | static int __init nand_base_init(void) |
2738 | { | 2527 | { |
@@ -2748,6 +2537,6 @@ static void __exit nand_base_exit(void) | |||
2748 | module_init(nand_base_init); | 2537 | module_init(nand_base_init); |
2749 | module_exit(nand_base_exit); | 2538 | module_exit(nand_base_exit); |
2750 | 2539 | ||
2751 | MODULE_LICENSE ("GPL"); | 2540 | MODULE_LICENSE("GPL"); |
2752 | MODULE_AUTHOR ("Steven J. Hill <sjhill@realitydiluted.com>, Thomas Gleixner <tglx@linutronix.de>"); | 2541 | MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com>, Thomas Gleixner <tglx@linutronix.de>"); |
2753 | MODULE_DESCRIPTION ("Generic NAND flash driver code"); | 2542 | MODULE_DESCRIPTION("Generic NAND flash driver code"); |