]>
Commit | Line | Data |
---|---|---|
932394ac WD |
1 | /* |
2 | * drivers/mtd/nand.c | |
3 | * | |
4 | * Overview: | |
5 | * This is the generic MTD driver for NAND flash devices. It should be | |
6 | * capable of working with almost all NAND chips currently available. | |
ac7eb8a3 | 7 | * |
932394ac | 8 | * Additional technical information is available on |
c45912d8 | 9 | * http://www.linux-mtd.infradead.org/doc/nand.html |
ac7eb8a3 | 10 | * |
932394ac | 11 | * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) |
cfa460ad | 12 | * 2002-2006 Thomas Gleixner (tglx@linutronix.de) |
932394ac | 13 | * |
cfa460ad | 14 | * Credits: |
ac7eb8a3 WD |
15 | * David Woodhouse for adding multichip support |
16 | * | |
932394ac WD |
17 | * Aleph One Ltd. and Toby Churchill Ltd. for supporting the |
18 | * rework for 2K page size chips | |
19 | * | |
cfa460ad | 20 | * TODO: |
932394ac WD |
21 | * Enable cached programming for 2k page size chips |
22 | * Check, if mtd->ecctype should be set to MTD_ECC_HW | |
dfe64e2c | 23 | * if we have HW ECC support. |
c45912d8 | 24 | * BBT table is not serialized, has to be fixed |
932394ac | 25 | * |
932394ac WD |
26 | * This program is free software; you can redistribute it and/or modify |
27 | * it under the terms of the GNU General Public License version 2 as | |
28 | * published by the Free Software Foundation. | |
29 | * | |
30 | */ | |
31 | ||
ff94bc40 HS |
32 | #ifndef __UBOOT__ |
33 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
cfa460ad | 34 | |
ff94bc40 HS |
35 | #include <linux/module.h> |
36 | #include <linux/delay.h> | |
37 | #include <linux/errno.h> | |
38 | #include <linux/err.h> | |
39 | #include <linux/sched.h> | |
40 | #include <linux/slab.h> | |
41 | #include <linux/types.h> | |
42 | #include <linux/mtd/mtd.h> | |
43 | #include <linux/mtd/nand.h> | |
44 | #include <linux/mtd/nand_ecc.h> | |
45 | #include <linux/mtd/nand_bch.h> | |
46 | #include <linux/interrupt.h> | |
47 | #include <linux/bitops.h> | |
48 | #include <linux/leds.h> | |
49 | #include <linux/io.h> | |
50 | #include <linux/mtd/partitions.h> | |
51 | #else | |
52 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
53 | #include <common.h> | |
932394ac WD |
54 | #include <malloc.h> |
55 | #include <watchdog.h> | |
cfa460ad | 56 | #include <linux/err.h> |
7b15e2bb | 57 | #include <linux/compat.h> |
932394ac WD |
58 | #include <linux/mtd/mtd.h> |
59 | #include <linux/mtd/nand.h> | |
60 | #include <linux/mtd/nand_ecc.h> | |
4c6de856 | 61 | #include <linux/mtd/nand_bch.h> |
10bb62d8 SR |
62 | #ifdef CONFIG_MTD_PARTITIONS |
63 | #include <linux/mtd/partitions.h> | |
64 | #endif | |
932394ac WD |
65 | #include <asm/io.h> |
66 | #include <asm/errno.h> | |
67 | ||
8da60128 PT |
68 | /* |
69 | * CONFIG_SYS_NAND_RESET_CNT is used as a timeout mechanism when resetting | |
70 | * a flash. NAND flash is initialized prior to interrupts so standard timers | |
71 | * can't be used. CONFIG_SYS_NAND_RESET_CNT should be set to a value | |
72 | * which is greater than (max NAND reset time / NAND status read time). | |
73 | * A conservative default of 200000 (500 us / 25 ns) is used as a default. | |
74 | */ | |
75 | #ifndef CONFIG_SYS_NAND_RESET_CNT | |
76 | #define CONFIG_SYS_NAND_RESET_CNT 200000 | |
77 | #endif | |
78 | ||
ff94bc40 HS |
79 | static bool is_module_text_address(unsigned long addr) {return 0;} |
80 | #endif | |
81 | ||
932394ac | 82 | /* Define default oob placement schemes for large and small page devices */ |
cfa460ad | 83 | static struct nand_ecclayout nand_oob_8 = { |
932394ac WD |
84 | .eccbytes = 3, |
85 | .eccpos = {0, 1, 2}, | |
cfa460ad WJ |
86 | .oobfree = { |
87 | {.offset = 3, | |
88 | .length = 2}, | |
89 | {.offset = 6, | |
90e3f395 | 90 | .length = 2} } |
932394ac WD |
91 | }; |
92 | ||
cfa460ad | 93 | static struct nand_ecclayout nand_oob_16 = { |
932394ac WD |
94 | .eccbytes = 6, |
95 | .eccpos = {0, 1, 2, 3, 6, 7}, | |
cfa460ad WJ |
96 | .oobfree = { |
97 | {.offset = 8, | |
90e3f395 | 98 | . length = 8} } |
932394ac WD |
99 | }; |
100 | ||
cfa460ad | 101 | static struct nand_ecclayout nand_oob_64 = { |
932394ac WD |
102 | .eccbytes = 24, |
103 | .eccpos = { | |
cfa460ad WJ |
104 | 40, 41, 42, 43, 44, 45, 46, 47, |
105 | 48, 49, 50, 51, 52, 53, 54, 55, | |
106 | 56, 57, 58, 59, 60, 61, 62, 63}, | |
107 | .oobfree = { | |
108 | {.offset = 2, | |
90e3f395 | 109 | .length = 38} } |
932394ac WD |
110 | }; |
111 | ||
cfa460ad | 112 | static struct nand_ecclayout nand_oob_128 = { |
248ae5cf SP |
113 | .eccbytes = 48, |
114 | .eccpos = { | |
90e3f395 CH |
115 | 80, 81, 82, 83, 84, 85, 86, 87, |
116 | 88, 89, 90, 91, 92, 93, 94, 95, | |
117 | 96, 97, 98, 99, 100, 101, 102, 103, | |
cfa460ad WJ |
118 | 104, 105, 106, 107, 108, 109, 110, 111, |
119 | 112, 113, 114, 115, 116, 117, 118, 119, | |
120 | 120, 121, 122, 123, 124, 125, 126, 127}, | |
121 | .oobfree = { | |
122 | {.offset = 2, | |
90e3f395 | 123 | .length = 78} } |
932394ac WD |
124 | }; |
125 | ||
ff94bc40 | 126 | static int nand_get_device(struct mtd_info *mtd, int new_state); |
cfa460ad WJ |
127 | |
128 | static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, | |
129 | struct mtd_oob_ops *ops); | |
130 | ||
ff94bc40 HS |
131 | /* |
132 | * For devices which display every fart in the system on a separate LED. Is | |
133 | * compiled away when LED support is disabled. | |
134 | */ | |
135 | DEFINE_LED_TRIGGER(nand_led_trigger); | |
248ae5cf | 136 | |
2a8e0fc8 CH |
137 | static int check_offs_len(struct mtd_info *mtd, |
138 | loff_t ofs, uint64_t len) | |
139 | { | |
140 | struct nand_chip *chip = mtd->priv; | |
141 | int ret = 0; | |
142 | ||
143 | /* Start address must align on block boundary */ | |
ff94bc40 HS |
144 | if (ofs & ((1ULL << chip->phys_erase_shift) - 1)) { |
145 | pr_debug("%s: unaligned address\n", __func__); | |
2a8e0fc8 CH |
146 | ret = -EINVAL; |
147 | } | |
148 | ||
149 | /* Length must align on block boundary */ | |
ff94bc40 HS |
150 | if (len & ((1ULL << chip->phys_erase_shift) - 1)) { |
151 | pr_debug("%s: length not block aligned\n", __func__); | |
2a8e0fc8 CH |
152 | ret = -EINVAL; |
153 | } | |
154 | ||
2a8e0fc8 CH |
155 | return ret; |
156 | } | |
157 | ||
932394ac WD |
158 | /** |
159 | * nand_release_device - [GENERIC] release chip | |
dfe64e2c | 160 | * @mtd: MTD device structure |
ac7eb8a3 | 161 | * |
ff94bc40 | 162 | * Release chip lock and wake up anyone waiting on the device. |
932394ac | 163 | */ |
90e3f395 | 164 | static void nand_release_device(struct mtd_info *mtd) |
8e9655f8 | 165 | { |
2a8e0fc8 CH |
166 | struct nand_chip *chip = mtd->priv; |
167 | ||
ff94bc40 HS |
168 | #ifndef __UBOOT__ |
169 | /* Release the controller and the chip */ | |
170 | spin_lock(&chip->controller->lock); | |
171 | chip->controller->active = NULL; | |
172 | chip->state = FL_READY; | |
173 | wake_up(&chip->controller->wq); | |
174 | spin_unlock(&chip->controller->lock); | |
175 | #else | |
2a8e0fc8 CH |
176 | /* De-select the NAND device */ |
177 | chip->select_chip(mtd, -1); | |
ff94bc40 | 178 | #endif |
8e9655f8 | 179 | } |
932394ac WD |
180 | |
181 | /** | |
182 | * nand_read_byte - [DEFAULT] read one byte from the chip | |
dfe64e2c | 183 | * @mtd: MTD device structure |
932394ac | 184 | * |
ff94bc40 | 185 | * Default read function for 8bit buswidth |
932394ac | 186 | */ |
ff94bc40 HS |
187 | #ifndef __UBOOT__ |
188 | static uint8_t nand_read_byte(struct mtd_info *mtd) | |
189 | #else | |
82645f81 | 190 | uint8_t nand_read_byte(struct mtd_info *mtd) |
ff94bc40 | 191 | #endif |
932394ac | 192 | { |
cfa460ad WJ |
193 | struct nand_chip *chip = mtd->priv; |
194 | return readb(chip->IO_ADDR_R); | |
932394ac WD |
195 | } |
196 | ||
197 | /** | |
ff94bc40 | 198 | * nand_read_byte16 - [DEFAULT] read one byte endianness aware from the chip |
dfe64e2c SL |
199 | * nand_read_byte16 - [DEFAULT] read one byte endianness aware from the chip |
200 | * @mtd: MTD device structure | |
201 | * | |
202 | * Default read function for 16bit buswidth with endianness conversion. | |
932394ac | 203 | * |
932394ac | 204 | */ |
cfa460ad | 205 | static uint8_t nand_read_byte16(struct mtd_info *mtd) |
932394ac | 206 | { |
cfa460ad WJ |
207 | struct nand_chip *chip = mtd->priv; |
208 | return (uint8_t) cpu_to_le16(readw(chip->IO_ADDR_R)); | |
932394ac WD |
209 | } |
210 | ||
211 | /** | |
212 | * nand_read_word - [DEFAULT] read one word from the chip | |
dfe64e2c | 213 | * @mtd: MTD device structure |
932394ac | 214 | * |
dfe64e2c | 215 | * Default read function for 16bit buswidth without endianness conversion. |
932394ac WD |
216 | */ |
217 | static u16 nand_read_word(struct mtd_info *mtd) | |
218 | { | |
cfa460ad WJ |
219 | struct nand_chip *chip = mtd->priv; |
220 | return readw(chip->IO_ADDR_R); | |
932394ac WD |
221 | } |
222 | ||
223 | /** | |
224 | * nand_select_chip - [DEFAULT] control CE line | |
dfe64e2c SL |
225 | * @mtd: MTD device structure |
226 | * @chipnr: chipnumber to select, -1 for deselect | |
932394ac WD |
227 | * |
228 | * Default select function for 1 chip devices. | |
229 | */ | |
cfa460ad | 230 | static void nand_select_chip(struct mtd_info *mtd, int chipnr) |
932394ac | 231 | { |
cfa460ad WJ |
232 | struct nand_chip *chip = mtd->priv; |
233 | ||
234 | switch (chipnr) { | |
932394ac | 235 | case -1: |
cfa460ad | 236 | chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE); |
932394ac WD |
237 | break; |
238 | case 0: | |
932394ac WD |
239 | break; |
240 | ||
241 | default: | |
242 | BUG(); | |
243 | } | |
244 | } | |
245 | ||
ff94bc40 HS |
246 | /** |
247 | * nand_write_byte - [DEFAULT] write single byte to chip | |
248 | * @mtd: MTD device structure | |
249 | * @byte: value to write | |
250 | * | |
251 | * Default function to write a byte to I/O[7:0] | |
252 | */ | |
253 | static void nand_write_byte(struct mtd_info *mtd, uint8_t byte) | |
254 | { | |
255 | struct nand_chip *chip = mtd->priv; | |
256 | ||
257 | chip->write_buf(mtd, &byte, 1); | |
258 | } | |
259 | ||
260 | /** | |
261 | * nand_write_byte16 - [DEFAULT] write single byte to a chip with width 16 | |
262 | * @mtd: MTD device structure | |
263 | * @byte: value to write | |
264 | * | |
265 | * Default function to write a byte to I/O[7:0] on a 16-bit wide chip. | |
266 | */ | |
267 | static void nand_write_byte16(struct mtd_info *mtd, uint8_t byte) | |
268 | { | |
269 | struct nand_chip *chip = mtd->priv; | |
270 | uint16_t word = byte; | |
271 | ||
272 | /* | |
273 | * It's not entirely clear what should happen to I/O[15:8] when writing | |
274 | * a byte. The ONFi spec (Revision 3.1; 2012-09-19, Section 2.16) reads: | |
275 | * | |
276 | * When the host supports a 16-bit bus width, only data is | |
277 | * transferred at the 16-bit width. All address and command line | |
278 | * transfers shall use only the lower 8-bits of the data bus. During | |
279 | * command transfers, the host may place any value on the upper | |
280 | * 8-bits of the data bus. During address transfers, the host shall | |
281 | * set the upper 8-bits of the data bus to 00h. | |
282 | * | |
283 | * One user of the write_byte callback is nand_onfi_set_features. The | |
284 | * four parameters are specified to be written to I/O[7:0], but this is | |
285 | * neither an address nor a command transfer. Let's assume a 0 on the | |
286 | * upper I/O lines is OK. | |
287 | */ | |
288 | chip->write_buf(mtd, (uint8_t *)&word, 2); | |
289 | } | |
290 | ||
291 | #if defined(__UBOOT__) && !defined(CONFIG_BLACKFIN) | |
292 | static void iowrite8_rep(void *addr, const uint8_t *buf, int len) | |
293 | { | |
294 | int i; | |
295 | ||
296 | for (i = 0; i < len; i++) | |
297 | writeb(buf[i], addr); | |
298 | } | |
299 | static void ioread8_rep(void *addr, uint8_t *buf, int len) | |
300 | { | |
301 | int i; | |
302 | ||
303 | for (i = 0; i < len; i++) | |
304 | buf[i] = readb(addr); | |
305 | } | |
306 | ||
307 | static void ioread16_rep(void *addr, void *buf, int len) | |
308 | { | |
309 | int i; | |
310 | u16 *p = (u16 *) buf; | |
be16aba5 | 311 | |
ff94bc40 HS |
312 | for (i = 0; i < len; i++) |
313 | p[i] = readw(addr); | |
314 | } | |
315 | ||
316 | static void iowrite16_rep(void *addr, void *buf, int len) | |
317 | { | |
318 | int i; | |
319 | u16 *p = (u16 *) buf; | |
ff94bc40 HS |
320 | |
321 | for (i = 0; i < len; i++) | |
322 | writew(p[i], addr); | |
323 | } | |
324 | #endif | |
325 | ||
932394ac WD |
326 | /** |
327 | * nand_write_buf - [DEFAULT] write buffer to chip | |
dfe64e2c SL |
328 | * @mtd: MTD device structure |
329 | * @buf: data buffer | |
330 | * @len: number of bytes to write | |
932394ac | 331 | * |
dfe64e2c | 332 | * Default write function for 8bit buswidth. |
932394ac | 333 | */ |
ff94bc40 HS |
334 | #ifndef __UBOOT__ |
335 | static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | |
336 | #else | |
82645f81 | 337 | void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) |
ff94bc40 | 338 | #endif |
932394ac | 339 | { |
cfa460ad | 340 | struct nand_chip *chip = mtd->priv; |
932394ac | 341 | |
ff94bc40 | 342 | iowrite8_rep(chip->IO_ADDR_W, buf, len); |
932394ac WD |
343 | } |
344 | ||
345 | /** | |
ac7eb8a3 | 346 | * nand_read_buf - [DEFAULT] read chip data into buffer |
dfe64e2c SL |
347 | * @mtd: MTD device structure |
348 | * @buf: buffer to store date | |
349 | * @len: number of bytes to read | |
932394ac | 350 | * |
dfe64e2c | 351 | * Default read function for 8bit buswidth. |
932394ac | 352 | */ |
ff94bc40 HS |
353 | #ifndef __UBOOT__ |
354 | static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | |
355 | #else | |
12c2f1ee | 356 | void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) |
ff94bc40 | 357 | #endif |
932394ac | 358 | { |
cfa460ad | 359 | struct nand_chip *chip = mtd->priv; |
932394ac | 360 | |
ff94bc40 | 361 | ioread8_rep(chip->IO_ADDR_R, buf, len); |
932394ac WD |
362 | } |
363 | ||
ff94bc40 HS |
364 | #ifdef __UBOOT__ |
365 | #if defined(CONFIG_MTD_NAND_VERIFY_WRITE) | |
932394ac | 366 | /** |
ac7eb8a3 | 367 | * nand_verify_buf - [DEFAULT] Verify chip data against buffer |
dfe64e2c SL |
368 | * @mtd: MTD device structure |
369 | * @buf: buffer containing the data to compare | |
370 | * @len: number of bytes to compare | |
932394ac | 371 | * |
dfe64e2c | 372 | * Default verify function for 8bit buswidth. |
932394ac | 373 | */ |
cfa460ad | 374 | static int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len) |
932394ac WD |
375 | { |
376 | int i; | |
cfa460ad | 377 | struct nand_chip *chip = mtd->priv; |
932394ac | 378 | |
cfa460ad WJ |
379 | for (i = 0; i < len; i++) |
380 | if (buf[i] != readb(chip->IO_ADDR_R)) | |
932394ac | 381 | return -EFAULT; |
932394ac WD |
382 | return 0; |
383 | } | |
384 | ||
385 | /** | |
ff94bc40 | 386 | * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer |
dfe64e2c | 387 | * @mtd: MTD device structure |
ff94bc40 HS |
388 | * @buf: buffer containing the data to compare |
389 | * @len: number of bytes to compare | |
932394ac | 390 | * |
ff94bc40 | 391 | * Default verify function for 16bit buswidth. |
932394ac | 392 | */ |
ff94bc40 | 393 | static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) |
932394ac WD |
394 | { |
395 | int i; | |
cfa460ad | 396 | struct nand_chip *chip = mtd->priv; |
932394ac WD |
397 | u16 *p = (u16 *) buf; |
398 | len >>= 1; | |
ac7eb8a3 | 399 | |
cfa460ad | 400 | for (i = 0; i < len; i++) |
ff94bc40 HS |
401 | if (p[i] != readw(chip->IO_ADDR_R)) |
402 | return -EFAULT; | |
ac7eb8a3 | 403 | |
ff94bc40 | 404 | return 0; |
932394ac | 405 | } |
ff94bc40 HS |
406 | #endif |
407 | #endif | |
932394ac WD |
408 | |
409 | /** | |
ff94bc40 | 410 | * nand_write_buf16 - [DEFAULT] write buffer to chip |
dfe64e2c | 411 | * @mtd: MTD device structure |
ff94bc40 HS |
412 | * @buf: data buffer |
413 | * @len: number of bytes to write | |
932394ac | 414 | * |
ff94bc40 | 415 | * Default write function for 16bit buswidth. |
932394ac | 416 | */ |
ff94bc40 HS |
417 | #ifndef __UBOOT__ |
418 | static void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) | |
419 | #else | |
420 | void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) | |
421 | #endif | |
932394ac | 422 | { |
cfa460ad | 423 | struct nand_chip *chip = mtd->priv; |
932394ac | 424 | u16 *p = (u16 *) buf; |
932394ac | 425 | |
ff94bc40 | 426 | iowrite16_rep(chip->IO_ADDR_W, p, len >> 1); |
932394ac WD |
427 | } |
428 | ||
429 | /** | |
ff94bc40 | 430 | * nand_read_buf16 - [DEFAULT] read chip data into buffer |
dfe64e2c | 431 | * @mtd: MTD device structure |
ff94bc40 HS |
432 | * @buf: buffer to store date |
433 | * @len: number of bytes to read | |
932394ac | 434 | * |
ff94bc40 | 435 | * Default read function for 16bit buswidth. |
932394ac | 436 | */ |
ff94bc40 HS |
437 | #ifndef __UBOOT__ |
438 | static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len) | |
439 | #else | |
440 | void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len) | |
441 | #endif | |
932394ac | 442 | { |
cfa460ad | 443 | struct nand_chip *chip = mtd->priv; |
932394ac | 444 | u16 *p = (u16 *) buf; |
932394ac | 445 | |
ff94bc40 | 446 | ioread16_rep(chip->IO_ADDR_R, p, len >> 1); |
932394ac WD |
447 | } |
448 | ||
449 | /** | |
450 | * nand_block_bad - [DEFAULT] Read bad block marker from the chip | |
dfe64e2c SL |
451 | * @mtd: MTD device structure |
452 | * @ofs: offset from device start | |
453 | * @getchip: 0, if the chip is already selected | |
932394ac | 454 | * |
ac7eb8a3 | 455 | * Check, if the block is bad. |
932394ac WD |
456 | */ |
457 | static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) | |
458 | { | |
dfe64e2c | 459 | int page, chipnr, res = 0, i = 0; |
cfa460ad | 460 | struct nand_chip *chip = mtd->priv; |
932394ac WD |
461 | u16 bad; |
462 | ||
dfe64e2c | 463 | if (chip->bbt_options & NAND_BBT_SCANLASTPAGE) |
2a8e0fc8 CH |
464 | ofs += mtd->erasesize - mtd->writesize; |
465 | ||
cfa460ad | 466 | page = (int)(ofs >> chip->page_shift) & chip->pagemask; |
a7988659 | 467 | |
932394ac | 468 | if (getchip) { |
cfa460ad | 469 | chipnr = (int)(ofs >> chip->chip_shift); |
932394ac | 470 | |
ff94bc40 | 471 | nand_get_device(mtd, FL_READING); |
932394ac WD |
472 | |
473 | /* Select the NAND device */ | |
cfa460ad | 474 | chip->select_chip(mtd, chipnr); |
a7988659 | 475 | } |
932394ac | 476 | |
dfe64e2c SL |
477 | do { |
478 | if (chip->options & NAND_BUSWIDTH_16) { | |
479 | chip->cmdfunc(mtd, NAND_CMD_READOOB, | |
480 | chip->badblockpos & 0xFE, page); | |
481 | bad = cpu_to_le16(chip->read_word(mtd)); | |
482 | if (chip->badblockpos & 0x1) | |
483 | bad >>= 8; | |
484 | else | |
485 | bad &= 0xFF; | |
486 | } else { | |
487 | chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos, | |
488 | page); | |
489 | bad = chip->read_byte(mtd); | |
490 | } | |
ac7eb8a3 | 491 | |
dfe64e2c SL |
492 | if (likely(chip->badblockbits == 8)) |
493 | res = bad != 0xFF; | |
494 | else | |
495 | res = hweight8(bad) < chip->badblockbits; | |
496 | ofs += mtd->writesize; | |
497 | page = (int)(ofs >> chip->page_shift) & chip->pagemask; | |
498 | i++; | |
499 | } while (!res && i < 2 && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE)); | |
2a8e0fc8 | 500 | |
ff94bc40 HS |
501 | if (getchip) { |
502 | chip->select_chip(mtd, -1); | |
932394ac | 503 | nand_release_device(mtd); |
ff94bc40 | 504 | } |
ac7eb8a3 | 505 | |
932394ac WD |
506 | return res; |
507 | } | |
508 | ||
509 | /** | |
ff94bc40 | 510 | * nand_default_block_markbad - [DEFAULT] mark a block bad via bad block marker |
dfe64e2c SL |
511 | * @mtd: MTD device structure |
512 | * @ofs: offset from device start | |
932394ac | 513 | * |
dfe64e2c | 514 | * This is the default implementation, which can be overridden by a hardware |
ff94bc40 HS |
515 | * specific driver. It provides the details for writing a bad block marker to a |
516 | * block. | |
517 | */ | |
518 | static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) | |
519 | { | |
520 | struct nand_chip *chip = mtd->priv; | |
521 | struct mtd_oob_ops ops; | |
522 | uint8_t buf[2] = { 0, 0 }; | |
523 | int ret = 0, res, i = 0; | |
524 | ||
525 | ops.datbuf = NULL; | |
526 | ops.oobbuf = buf; | |
527 | ops.ooboffs = chip->badblockpos; | |
528 | if (chip->options & NAND_BUSWIDTH_16) { | |
529 | ops.ooboffs &= ~0x01; | |
530 | ops.len = ops.ooblen = 2; | |
531 | } else { | |
532 | ops.len = ops.ooblen = 1; | |
533 | } | |
534 | ops.mode = MTD_OPS_PLACE_OOB; | |
535 | ||
536 | /* Write to first/last page(s) if necessary */ | |
537 | if (chip->bbt_options & NAND_BBT_SCANLASTPAGE) | |
538 | ofs += mtd->erasesize - mtd->writesize; | |
539 | do { | |
540 | res = nand_do_write_oob(mtd, ofs, &ops); | |
541 | if (!ret) | |
542 | ret = res; | |
543 | ||
544 | i++; | |
545 | ofs += mtd->writesize; | |
546 | } while ((chip->bbt_options & NAND_BBT_SCAN2NDPAGE) && i < 2); | |
547 | ||
548 | return ret; | |
549 | } | |
550 | ||
551 | /** | |
552 | * nand_block_markbad_lowlevel - mark a block bad | |
553 | * @mtd: MTD device structure | |
554 | * @ofs: offset from device start | |
555 | * | |
556 | * This function performs the generic NAND bad block marking steps (i.e., bad | |
557 | * block table(s) and/or marker(s)). We only allow the hardware driver to | |
558 | * specify how to write bad block markers to OOB (chip->block_markbad). | |
559 | * | |
560 | * We try operations in the following order: | |
dfe64e2c | 561 | * (1) erase the affected block, to allow OOB marker to be written cleanly |
ff94bc40 HS |
562 | * (2) write bad block marker to OOB area of affected block (unless flag |
563 | * NAND_BBT_NO_OOB_BBM is present) | |
564 | * (3) update the BBT | |
565 | * Note that we retain the first error encountered in (2) or (3), finish the | |
dfe64e2c | 566 | * procedures, and dump the error in the end. |
932394ac | 567 | */ |
ff94bc40 | 568 | static int nand_block_markbad_lowlevel(struct mtd_info *mtd, loff_t ofs) |
932394ac | 569 | { |
cfa460ad | 570 | struct nand_chip *chip = mtd->priv; |
ff94bc40 | 571 | int res, ret = 0; |
2a8e0fc8 | 572 | |
ff94bc40 | 573 | if (!(chip->bbt_options & NAND_BBT_NO_OOB_BBM)) { |
dfe64e2c SL |
574 | struct erase_info einfo; |
575 | ||
576 | /* Attempt erase before marking OOB */ | |
577 | memset(&einfo, 0, sizeof(einfo)); | |
578 | einfo.mtd = mtd; | |
579 | einfo.addr = ofs; | |
ff94bc40 | 580 | einfo.len = 1ULL << chip->phys_erase_shift; |
dfe64e2c | 581 | nand_erase_nand(mtd, &einfo, 0); |
2a8e0fc8 | 582 | |
ff94bc40 HS |
583 | /* Write bad block marker to OOB */ |
584 | nand_get_device(mtd, FL_WRITING); | |
585 | ret = chip->block_markbad(mtd, ofs); | |
c45912d8 | 586 | nand_release_device(mtd); |
cfa460ad | 587 | } |
dfe64e2c | 588 | |
ff94bc40 HS |
589 | /* Mark block bad in BBT */ |
590 | if (chip->bbt) { | |
591 | res = nand_markbad_bbt(mtd, ofs); | |
dfe64e2c SL |
592 | if (!ret) |
593 | ret = res; | |
594 | } | |
595 | ||
cfa460ad WJ |
596 | if (!ret) |
597 | mtd->ecc_stats.badblocks++; | |
c45912d8 | 598 | |
cfa460ad | 599 | return ret; |
932394ac WD |
600 | } |
601 | ||
ac7eb8a3 | 602 | /** |
932394ac | 603 | * nand_check_wp - [GENERIC] check if the chip is write protected |
dfe64e2c | 604 | * @mtd: MTD device structure |
932394ac | 605 | * |
dfe64e2c SL |
606 | * Check, if the device is write protected. The function expects, that the |
607 | * device is already selected. | |
932394ac | 608 | */ |
cfa460ad | 609 | static int nand_check_wp(struct mtd_info *mtd) |
932394ac | 610 | { |
cfa460ad | 611 | struct nand_chip *chip = mtd->priv; |
2a8e0fc8 | 612 | |
dfe64e2c | 613 | /* Broken xD cards report WP despite being writable */ |
2a8e0fc8 CH |
614 | if (chip->options & NAND_BROKEN_XD) |
615 | return 0; | |
616 | ||
932394ac | 617 | /* Check the WP bit */ |
cfa460ad WJ |
618 | chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); |
619 | return (chip->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1; | |
932394ac | 620 | } |