diff options
-rw-r--r-- | drivers/mtd/nand/Kconfig | 10 | ||||
-rw-r--r-- | drivers/mtd/nand/au1550nd.c | 58 | ||||
-rw-r--r-- | drivers/mtd/nand/autcpu12.c | 22 | ||||
-rw-r--r-- | drivers/mtd/nand/diskonchip.c | 100 | ||||
-rw-r--r-- | drivers/mtd/nand/edb7312.c | 48 | ||||
-rw-r--r-- | drivers/mtd/nand/h1910.c | 48 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 478 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_bbt.c | 248 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_ecc.c | 44 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_ids.c | 30 | ||||
-rw-r--r-- | drivers/mtd/nand/nandsim.c | 162 | ||||
-rw-r--r-- | drivers/mtd/nand/ppchameleonevb.c | 6 | ||||
-rw-r--r-- | drivers/mtd/nand/rtc_from4.c | 58 | ||||
-rw-r--r-- | drivers/mtd/nand/s3c2410.c | 30 | ||||
-rw-r--r-- | drivers/mtd/nand/sharpsl.c | 22 | ||||
-rw-r--r-- | drivers/mtd/nand/spia.c | 6 | ||||
-rw-r--r-- | drivers/mtd/nand/toto.c | 20 |
17 files changed, 695 insertions, 695 deletions
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index f6f5ac808957..1fc4c134d939 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig | |||
@@ -1,5 +1,5 @@ | |||
1 | # drivers/mtd/nand/Kconfig | 1 | # drivers/mtd/nand/Kconfig |
2 | # $Id: Kconfig,v 1.34 2005/09/23 01:44:55 ppopov Exp $ | 2 | # $Id: Kconfig,v 1.35 2005/11/07 11:14:30 gleixner Exp $ |
3 | 3 | ||
4 | menu "NAND Flash Device Drivers" | 4 | menu "NAND Flash Device Drivers" |
5 | depends on MTD!=n | 5 | depends on MTD!=n |
@@ -27,14 +27,14 @@ config MTD_NAND_AUTCPU12 | |||
27 | tristate "SmartMediaCard on autronix autcpu12 board" | 27 | tristate "SmartMediaCard on autronix autcpu12 board" |
28 | depends on MTD_NAND && ARCH_AUTCPU12 | 28 | depends on MTD_NAND && ARCH_AUTCPU12 |
29 | help | 29 | help |
30 | This enables the driver for the autronix autcpu12 board to | 30 | This enables the driver for the autronix autcpu12 board to |
31 | access the SmartMediaCard. | 31 | access the SmartMediaCard. |
32 | 32 | ||
33 | config MTD_NAND_EDB7312 | 33 | config MTD_NAND_EDB7312 |
34 | tristate "Support for Cirrus Logic EBD7312 evaluation board" | 34 | tristate "Support for Cirrus Logic EBD7312 evaluation board" |
35 | depends on MTD_NAND && ARCH_EDB7312 | 35 | depends on MTD_NAND && ARCH_EDB7312 |
36 | help | 36 | help |
37 | This enables the driver for the Cirrus Logic EBD7312 evaluation | 37 | This enables the driver for the Cirrus Logic EBD7312 evaluation |
38 | board to access the onboard NAND Flash. | 38 | board to access the onboard NAND Flash. |
39 | 39 | ||
40 | config MTD_NAND_H1900 | 40 | config MTD_NAND_H1900 |
@@ -71,7 +71,7 @@ config MTD_NAND_RTC_FROM4 | |||
71 | select REED_SOLOMON | 71 | select REED_SOLOMON |
72 | select REED_SOLOMON_DEC8 | 72 | select REED_SOLOMON_DEC8 |
73 | help | 73 | help |
74 | This enables the driver for the Renesas Technology AG-AND | 74 | This enables the driver for the Renesas Technology AG-AND |
75 | flash interface board (FROM_BOARD4) | 75 | flash interface board (FROM_BOARD4) |
76 | 76 | ||
77 | config MTD_NAND_PPCHAMELEONEVB | 77 | config MTD_NAND_PPCHAMELEONEVB |
@@ -88,7 +88,7 @@ config MTD_NAND_S3C2410 | |||
88 | SoCs | 88 | SoCs |
89 | 89 | ||
90 | No board specfic support is done by this driver, each board | 90 | No board specfic support is done by this driver, each board |
91 | must advertise a platform_device for the driver to attach. | 91 | must advertise a platform_device for the driver to attach. |
92 | 92 | ||
93 | config MTD_NAND_S3C2410_DEBUG | 93 | config MTD_NAND_S3C2410_DEBUG |
94 | bool "S3C2410 NAND driver debug" | 94 | bool "S3C2410 NAND driver debug" |
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c index 953daf379b9b..3cafcdf28aed 100644 --- a/drivers/mtd/nand/au1550nd.c +++ b/drivers/mtd/nand/au1550nd.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2004 Embedded Edge, LLC | 4 | * Copyright (C) 2004 Embedded Edge, LLC |
5 | * | 5 | * |
6 | * $Id: au1550nd.c,v 1.12 2005/09/23 01:44:55 ppopov Exp $ | 6 | * $Id: au1550nd.c,v 1.13 2005/11/07 11:14:30 gleixner Exp $ |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
@@ -25,10 +25,10 @@ | |||
25 | #else | 25 | #else |
26 | #include <asm/au1000.h> | 26 | #include <asm/au1000.h> |
27 | #ifdef CONFIG_MIPS_PB1550 | 27 | #ifdef CONFIG_MIPS_PB1550 |
28 | #include <asm/pb1550.h> | 28 | #include <asm/pb1550.h> |
29 | #endif | 29 | #endif |
30 | #ifdef CONFIG_MIPS_DB1550 | 30 | #ifdef CONFIG_MIPS_DB1550 |
31 | #include <asm/db1x00.h> | 31 | #include <asm/db1x00.h> |
32 | #endif | 32 | #endif |
33 | #endif | 33 | #endif |
34 | 34 | ||
@@ -43,12 +43,12 @@ static int nand_width = 1; /* default x8*/ | |||
43 | * Define partitions for flash device | 43 | * Define partitions for flash device |
44 | */ | 44 | */ |
45 | const static struct mtd_partition partition_info[] = { | 45 | const static struct mtd_partition partition_info[] = { |
46 | { | 46 | { |
47 | .name = "NAND FS 0", | 47 | .name = "NAND FS 0", |
48 | .offset = 0, | 48 | .offset = 0, |
49 | .size = 8*1024*1024 | 49 | .size = 8*1024*1024 |
50 | }, | 50 | }, |
51 | { | 51 | { |
52 | .name = "NAND FS 1", | 52 | .name = "NAND FS 1", |
53 | .offset = MTDPART_OFS_APPEND, | 53 | .offset = MTDPART_OFS_APPEND, |
54 | .size = MTDPART_SIZ_FULL | 54 | .size = MTDPART_SIZ_FULL |
@@ -89,7 +89,7 @@ static void au_write_byte(struct mtd_info *mtd, u_char byte) | |||
89 | * au_read_byte16 - read one byte endianess aware from the chip | 89 | * au_read_byte16 - read one byte endianess aware from the chip |
90 | * @mtd: MTD device structure | 90 | * @mtd: MTD device structure |
91 | * | 91 | * |
92 | * read function for 16bit buswith with | 92 | * read function for 16bit buswith with |
93 | * endianess conversion | 93 | * endianess conversion |
94 | */ | 94 | */ |
95 | static u_char au_read_byte16(struct mtd_info *mtd) | 95 | static u_char au_read_byte16(struct mtd_info *mtd) |
@@ -119,7 +119,7 @@ static void au_write_byte16(struct mtd_info *mtd, u_char byte) | |||
119 | * au_read_word - read one word from the chip | 119 | * au_read_word - read one word from the chip |
120 | * @mtd: MTD device structure | 120 | * @mtd: MTD device structure |
121 | * | 121 | * |
122 | * read function for 16bit buswith without | 122 | * read function for 16bit buswith without |
123 | * endianess conversion | 123 | * endianess conversion |
124 | */ | 124 | */ |
125 | static u16 au_read_word(struct mtd_info *mtd) | 125 | static u16 au_read_word(struct mtd_info *mtd) |
@@ -135,7 +135,7 @@ static u16 au_read_word(struct mtd_info *mtd) | |||
135 | * @mtd: MTD device structure | 135 | * @mtd: MTD device structure |
136 | * @word: data word to write | 136 | * @word: data word to write |
137 | * | 137 | * |
138 | * write function for 16bit buswith without | 138 | * write function for 16bit buswith without |
139 | * endianess conversion | 139 | * endianess conversion |
140 | */ | 140 | */ |
141 | static void au_write_word(struct mtd_info *mtd, u16 word) | 141 | static void au_write_word(struct mtd_info *mtd, u16 word) |
@@ -165,7 +165,7 @@ static void au_write_buf(struct mtd_info *mtd, const u_char *buf, int len) | |||
165 | } | 165 | } |
166 | 166 | ||
167 | /** | 167 | /** |
168 | * au_read_buf - read chip data into buffer | 168 | * au_read_buf - read chip data into buffer |
169 | * @mtd: MTD device structure | 169 | * @mtd: MTD device structure |
170 | * @buf: buffer to store date | 170 | * @buf: buffer to store date |
171 | * @len: number of bytes to read | 171 | * @len: number of bytes to read |
@@ -179,12 +179,12 @@ static void au_read_buf(struct mtd_info *mtd, u_char *buf, int len) | |||
179 | 179 | ||
180 | for (i=0; i<len; i++) { | 180 | for (i=0; i<len; i++) { |
181 | buf[i] = readb(this->IO_ADDR_R); | 181 | buf[i] = readb(this->IO_ADDR_R); |
182 | au_sync(); | 182 | au_sync(); |
183 | } | 183 | } |
184 | } | 184 | } |
185 | 185 | ||
186 | /** | 186 | /** |
187 | * au_verify_buf - Verify chip data against buffer | 187 | * au_verify_buf - Verify chip data against buffer |
188 | * @mtd: MTD device structure | 188 | * @mtd: MTD device structure |
189 | * @buf: buffer containing the data to compare | 189 | * @buf: buffer containing the data to compare |
190 | * @len: number of bytes to compare | 190 | * @len: number of bytes to compare |
@@ -219,16 +219,16 @@ static void au_write_buf16(struct mtd_info *mtd, const u_char *buf, int len) | |||
219 | struct nand_chip *this = mtd->priv; | 219 | struct nand_chip *this = mtd->priv; |
220 | u16 *p = (u16 *) buf; | 220 | u16 *p = (u16 *) buf; |
221 | len >>= 1; | 221 | len >>= 1; |
222 | 222 | ||
223 | for (i=0; i<len; i++) { | 223 | for (i=0; i<len; i++) { |
224 | writew(p[i], this->IO_ADDR_W); | 224 | writew(p[i], this->IO_ADDR_W); |
225 | au_sync(); | 225 | au_sync(); |
226 | } | 226 | } |
227 | 227 | ||
228 | } | 228 | } |
229 | 229 | ||
230 | /** | 230 | /** |
231 | * au_read_buf16 - read chip data into buffer | 231 | * au_read_buf16 - read chip data into buffer |
232 | * @mtd: MTD device structure | 232 | * @mtd: MTD device structure |
233 | * @buf: buffer to store date | 233 | * @buf: buffer to store date |
234 | * @len: number of bytes to read | 234 | * @len: number of bytes to read |
@@ -249,7 +249,7 @@ static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len) | |||
249 | } | 249 | } |
250 | 250 | ||
251 | /** | 251 | /** |
252 | * au_verify_buf16 - Verify chip data against buffer | 252 | * au_verify_buf16 - Verify chip data against buffer |
253 | * @mtd: MTD device structure | 253 | * @mtd: MTD device structure |
254 | * @buf: buffer containing the data to compare | 254 | * @buf: buffer containing the data to compare |
255 | * @len: number of bytes to compare | 255 | * @len: number of bytes to compare |
@@ -282,26 +282,26 @@ static void au1550_hwcontrol(struct mtd_info *mtd, int cmd) | |||
282 | case NAND_CTL_CLRCLE: this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; break; | 282 | case NAND_CTL_CLRCLE: this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; break; |
283 | 283 | ||
284 | case NAND_CTL_SETALE: this->IO_ADDR_W = p_nand + MEM_STNAND_ADDR; break; | 284 | case NAND_CTL_SETALE: this->IO_ADDR_W = p_nand + MEM_STNAND_ADDR; break; |
285 | case NAND_CTL_CLRALE: | 285 | case NAND_CTL_CLRALE: |
286 | this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; | 286 | this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; |
287 | /* FIXME: Nobody knows why this is neccecary, | 287 | /* FIXME: Nobody knows why this is neccecary, |
288 | * but it works only that way */ | 288 | * but it works only that way */ |
289 | udelay(1); | 289 | udelay(1); |
290 | break; | 290 | break; |
291 | 291 | ||
292 | case NAND_CTL_SETNCE: | 292 | case NAND_CTL_SETNCE: |
293 | /* assert (force assert) chip enable */ | 293 | /* assert (force assert) chip enable */ |
294 | au_writel((1<<(4+NAND_CS)) , MEM_STNDCTL); break; | 294 | au_writel((1<<(4+NAND_CS)) , MEM_STNDCTL); break; |
295 | break; | 295 | break; |
296 | 296 | ||
297 | case NAND_CTL_CLRNCE: | 297 | case NAND_CTL_CLRNCE: |
298 | /* deassert chip enable */ | 298 | /* deassert chip enable */ |
299 | au_writel(0, MEM_STNDCTL); break; | 299 | au_writel(0, MEM_STNDCTL); break; |
300 | break; | 300 | break; |
301 | } | 301 | } |
302 | 302 | ||
303 | this->IO_ADDR_R = this->IO_ADDR_W; | 303 | this->IO_ADDR_R = this->IO_ADDR_W; |
304 | 304 | ||
305 | /* Drain the writebuffer */ | 305 | /* Drain the writebuffer */ |
306 | au_sync(); | 306 | au_sync(); |
307 | } | 307 | } |
@@ -325,7 +325,7 @@ int __init au1xxx_nand_init (void) | |||
325 | u32 nand_phys; | 325 | u32 nand_phys; |
326 | 326 | ||
327 | /* Allocate memory for MTD device structure and private data */ | 327 | /* Allocate memory for MTD device structure and private data */ |
328 | au1550_mtd = kmalloc (sizeof(struct mtd_info) + | 328 | au1550_mtd = kmalloc (sizeof(struct mtd_info) + |
329 | sizeof (struct nand_chip), GFP_KERNEL); | 329 | sizeof (struct nand_chip), GFP_KERNEL); |
330 | if (!au1550_mtd) { | 330 | if (!au1550_mtd) { |
331 | printk ("Unable to allocate NAND MTD dev structure.\n"); | 331 | printk ("Unable to allocate NAND MTD dev structure.\n"); |
@@ -345,7 +345,7 @@ int __init au1xxx_nand_init (void) | |||
345 | 345 | ||
346 | /* disable interrupts */ | 346 | /* disable interrupts */ |
347 | au_writel(au_readl(MEM_STNDCTL) & ~(1<<8), MEM_STNDCTL); | 347 | au_writel(au_readl(MEM_STNDCTL) & ~(1<<8), MEM_STNDCTL); |
348 | 348 | ||
349 | /* disable NAND boot */ | 349 | /* disable NAND boot */ |
350 | au_writel(au_readl(MEM_STNDCTL) & ~(1<<0), MEM_STNDCTL); | 350 | au_writel(au_readl(MEM_STNDCTL) & ~(1<<0), MEM_STNDCTL); |
351 | 351 | ||
@@ -353,7 +353,7 @@ int __init au1xxx_nand_init (void) | |||
353 | /* set gpio206 high */ | 353 | /* set gpio206 high */ |
354 | au_writel(au_readl(GPIO2_DIR) & ~(1<<6), GPIO2_DIR); | 354 | au_writel(au_readl(GPIO2_DIR) & ~(1<<6), GPIO2_DIR); |
355 | 355 | ||
356 | boot_swapboot = (au_readl(MEM_STSTAT) & (0x7<<1)) | | 356 | boot_swapboot = (au_readl(MEM_STSTAT) & (0x7<<1)) | |
357 | ((bcsr->status >> 6) & 0x1); | 357 | ((bcsr->status >> 6) & 0x1); |
358 | switch (boot_swapboot) { | 358 | switch (boot_swapboot) { |
359 | case 0: | 359 | case 0: |
@@ -402,7 +402,7 @@ int __init au1xxx_nand_init (void) | |||
402 | au_writel(NAND_STADDR, MEM_STADDR3); | 402 | au_writel(NAND_STADDR, MEM_STADDR3); |
403 | } | 403 | } |
404 | #endif | 404 | #endif |
405 | 405 | ||
406 | /* Locate NAND chip-select in order to determine NAND phys address */ | 406 | /* Locate NAND chip-select in order to determine NAND phys address */ |
407 | mem_staddr = 0x00000000; | 407 | mem_staddr = 0x00000000; |
408 | if (((au_readl(MEM_STCFG0) & 0x7) == 0x5) && (NAND_CS == 0)) | 408 | if (((au_readl(MEM_STCFG0) & 0x7) == 0x5) && (NAND_CS == 0)) |
@@ -438,7 +438,7 @@ int __init au1xxx_nand_init (void) | |||
438 | this->hwcontrol = au1550_hwcontrol; | 438 | this->hwcontrol = au1550_hwcontrol; |
439 | this->dev_ready = au1550_device_ready; | 439 | this->dev_ready = au1550_device_ready; |
440 | /* 30 us command delay time */ | 440 | /* 30 us command delay time */ |
441 | this->chip_delay = 30; | 441 | this->chip_delay = 30; |
442 | this->eccmode = NAND_ECC_SOFT; | 442 | this->eccmode = NAND_ECC_SOFT; |
443 | 443 | ||
444 | this->options = NAND_NO_AUTOINCR; | 444 | this->options = NAND_NO_AUTOINCR; |
@@ -467,7 +467,7 @@ int __init au1xxx_nand_init (void) | |||
467 | 467 | ||
468 | outio: | 468 | outio: |
469 | iounmap ((void *)p_nand); | 469 | iounmap ((void *)p_nand); |
470 | 470 | ||
471 | outmem: | 471 | outmem: |
472 | kfree (au1550_mtd); | 472 | kfree (au1550_mtd); |
473 | return retval; | 473 | return retval; |
diff --git a/drivers/mtd/nand/autcpu12.c b/drivers/mtd/nand/autcpu12.c index 4afa8ced05ad..056dfc17a075 100644 --- a/drivers/mtd/nand/autcpu12.c +++ b/drivers/mtd/nand/autcpu12.c | |||
@@ -5,8 +5,8 @@ | |||
5 | * | 5 | * |
6 | * Derived from drivers/mtd/spia.c | 6 | * Derived from drivers/mtd/spia.c |
7 | * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) | 7 | * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) |
8 | * | 8 | * |
9 | * $Id: autcpu12.c,v 1.22 2004/11/04 12:53:10 gleixner Exp $ | 9 | * $Id: autcpu12.c,v 1.23 2005/11/07 11:14:30 gleixner Exp $ |
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License version 2 as | 12 | * it under the terms of the GNU General Public License version 2 as |
@@ -14,7 +14,7 @@ | |||
14 | * | 14 | * |
15 | * Overview: | 15 | * Overview: |
16 | * This is a device driver for the NAND flash device found on the | 16 | * This is a device driver for the NAND flash device found on the |
17 | * autronix autcpu12 board, which is a SmartMediaCard. It supports | 17 | * autronix autcpu12 board, which is a SmartMediaCard. It supports |
18 | * 16MiB, 32MiB and 64MiB cards. | 18 | * 16MiB, 32MiB and 64MiB cards. |
19 | * | 19 | * |
20 | * | 20 | * |
@@ -93,7 +93,7 @@ static struct mtd_partition partition_info128k[] = { | |||
93 | #define NUM_PARTITIONS32K 2 | 93 | #define NUM_PARTITIONS32K 2 |
94 | #define NUM_PARTITIONS64K 2 | 94 | #define NUM_PARTITIONS64K 2 |
95 | #define NUM_PARTITIONS128K 2 | 95 | #define NUM_PARTITIONS128K 2 |
96 | /* | 96 | /* |
97 | * hardware specific access to control-lines | 97 | * hardware specific access to control-lines |
98 | */ | 98 | */ |
99 | static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd) | 99 | static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd) |
@@ -163,7 +163,7 @@ int __init autcpu12_init (void) | |||
163 | this->hwcontrol = autcpu12_hwcontrol; | 163 | this->hwcontrol = autcpu12_hwcontrol; |
164 | this->dev_ready = autcpu12_device_ready; | 164 | this->dev_ready = autcpu12_device_ready; |
165 | /* 20 us command delay time */ | 165 | /* 20 us command delay time */ |
166 | this->chip_delay = 20; | 166 | this->chip_delay = 20; |
167 | this->eccmode = NAND_ECC_SOFT; | 167 | this->eccmode = NAND_ECC_SOFT; |
168 | 168 | ||
169 | /* Enable the following for a flash based bad block table */ | 169 | /* Enable the following for a flash based bad block table */ |
@@ -171,21 +171,21 @@ int __init autcpu12_init (void) | |||
171 | this->options = NAND_USE_FLASH_BBT; | 171 | this->options = NAND_USE_FLASH_BBT; |
172 | */ | 172 | */ |
173 | this->options = NAND_USE_FLASH_BBT; | 173 | this->options = NAND_USE_FLASH_BBT; |
174 | 174 | ||
175 | /* Scan to find existance of the device */ | 175 | /* Scan to find existance of the device */ |
176 | if (nand_scan (autcpu12_mtd, 1)) { | 176 | if (nand_scan (autcpu12_mtd, 1)) { |
177 | err = -ENXIO; | 177 | err = -ENXIO; |
178 | goto out_ior; | 178 | goto out_ior; |
179 | } | 179 | } |
180 | 180 | ||
181 | /* Register the partitions */ | 181 | /* Register the partitions */ |
182 | switch(autcpu12_mtd->size){ | 182 | switch(autcpu12_mtd->size){ |
183 | case SZ_16M: add_mtd_partitions(autcpu12_mtd, partition_info16k, NUM_PARTITIONS16K); break; | 183 | case SZ_16M: add_mtd_partitions(autcpu12_mtd, partition_info16k, NUM_PARTITIONS16K); break; |
184 | case SZ_32M: add_mtd_partitions(autcpu12_mtd, partition_info32k, NUM_PARTITIONS32K); break; | 184 | case SZ_32M: add_mtd_partitions(autcpu12_mtd, partition_info32k, NUM_PARTITIONS32K); break; |
185 | case SZ_64M: add_mtd_partitions(autcpu12_mtd, partition_info64k, NUM_PARTITIONS64K); break; | 185 | case SZ_64M: add_mtd_partitions(autcpu12_mtd, partition_info64k, NUM_PARTITIONS64K); break; |
186 | case SZ_128M: add_mtd_partitions(autcpu12_mtd, partition_info128k, NUM_PARTITIONS128K); break; | 186 | case SZ_128M: add_mtd_partitions(autcpu12_mtd, partition_info128k, NUM_PARTITIONS128K); break; |
187 | default: { | 187 | default: { |
188 | printk ("Unsupported SmartMedia device\n"); | 188 | printk ("Unsupported SmartMedia device\n"); |
189 | err = -ENXIO; | 189 | err = -ENXIO; |
190 | goto out_ior; | 190 | goto out_ior; |
191 | } | 191 | } |
@@ -213,7 +213,7 @@ static void __exit autcpu12_cleanup (void) | |||
213 | 213 | ||
214 | /* unmap physical adress */ | 214 | /* unmap physical adress */ |
215 | iounmap((void *)autcpu12_fio_base); | 215 | iounmap((void *)autcpu12_fio_base); |
216 | 216 | ||
217 | /* Free the MTD device structure */ | 217 | /* Free the MTD device structure */ |
218 | kfree (autcpu12_mtd); | 218 | kfree (autcpu12_mtd); |
219 | } | 219 | } |
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index fdb5d4ad3d52..21d4e8f4b7af 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/mtd/nand/diskonchip.c | 2 | * drivers/mtd/nand/diskonchip.c |
3 | * | 3 | * |
4 | * (C) 2003 Red Hat, Inc. | 4 | * (C) 2003 Red Hat, Inc. |
@@ -8,15 +8,15 @@ | |||
8 | * Author: David Woodhouse <dwmw2@infradead.org> | 8 | * Author: David Woodhouse <dwmw2@infradead.org> |
9 | * Additional Diskonchip 2000 and Millennium support by Dan Brown <dan_brown@ieee.org> | 9 | * Additional Diskonchip 2000 and Millennium support by Dan Brown <dan_brown@ieee.org> |
10 | * Diskonchip Millennium Plus support by Kalev Lember <kalev@smartlink.ee> | 10 | * Diskonchip Millennium Plus support by Kalev Lember <kalev@smartlink.ee> |
11 | * | 11 | * |
12 | * Error correction code lifted from the old docecc code | 12 | * Error correction code lifted from the old docecc code |
13 | * Author: Fabrice Bellard (fabrice.bellard@netgem.com) | 13 | * Author: Fabrice Bellard (fabrice.bellard@netgem.com) |
14 | * Copyright (C) 2000 Netgem S.A. | 14 | * Copyright (C) 2000 Netgem S.A. |
15 | * converted to the generic Reed-Solomon library by Thomas Gleixner <tglx@linutronix.de> | 15 | * converted to the generic Reed-Solomon library by Thomas Gleixner <tglx@linutronix.de> |
16 | * | 16 | * |
17 | * Interface to generic NAND code for M-Systems DiskOnChip devices | 17 | * Interface to generic NAND code for M-Systems DiskOnChip devices |
18 | * | 18 | * |
19 | * $Id: diskonchip.c,v 1.54 2005/04/07 14:22:55 dbrown Exp $ | 19 | * $Id: diskonchip.c,v 1.55 2005/11/07 11:14:30 gleixner Exp $ |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
@@ -42,16 +42,16 @@ | |||
42 | static unsigned long __initdata doc_locations[] = { | 42 | static unsigned long __initdata doc_locations[] = { |
43 | #if defined (__alpha__) || defined(__i386__) || defined(__x86_64__) | 43 | #if defined (__alpha__) || defined(__i386__) || defined(__x86_64__) |
44 | #ifdef CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH | 44 | #ifdef CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH |
45 | 0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000, | 45 | 0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000, |
46 | 0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000, | 46 | 0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000, |
47 | 0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000, | 47 | 0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000, |
48 | 0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000, | 48 | 0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000, |
49 | 0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000, | 49 | 0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000, |
50 | #else /* CONFIG_MTD_DOCPROBE_HIGH */ | 50 | #else /* CONFIG_MTD_DOCPROBE_HIGH */ |
51 | 0xc8000, 0xca000, 0xcc000, 0xce000, | 51 | 0xc8000, 0xca000, 0xcc000, 0xce000, |
52 | 0xd0000, 0xd2000, 0xd4000, 0xd6000, | 52 | 0xd0000, 0xd2000, 0xd4000, 0xd6000, |
53 | 0xd8000, 0xda000, 0xdc000, 0xde000, | 53 | 0xd8000, 0xda000, 0xdc000, 0xde000, |
54 | 0xe0000, 0xe2000, 0xe4000, 0xe6000, | 54 | 0xe0000, 0xe2000, 0xe4000, 0xe6000, |
55 | 0xe8000, 0xea000, 0xec000, 0xee000, | 55 | 0xe8000, 0xea000, 0xec000, 0xee000, |
56 | #endif /* CONFIG_MTD_DOCPROBE_HIGH */ | 56 | #endif /* CONFIG_MTD_DOCPROBE_HIGH */ |
57 | #elif defined(__PPC__) | 57 | #elif defined(__PPC__) |
@@ -138,7 +138,7 @@ MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe | |||
138 | /* the Reed Solomon control structure */ | 138 | /* the Reed Solomon control structure */ |
139 | static struct rs_control *rs_decoder; | 139 | static struct rs_control *rs_decoder; |
140 | 140 | ||
141 | /* | 141 | /* |
142 | * The HW decoder in the DoC ASIC's provides us a error syndrome, | 142 | * The HW decoder in the DoC ASIC's provides us a error syndrome, |
143 | * which we must convert to a standard syndrom usable by the generic | 143 | * which we must convert to a standard syndrom usable by the generic |
144 | * Reed-Solomon library code. | 144 | * Reed-Solomon library code. |
@@ -163,8 +163,8 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc) | |||
163 | /* Initialize the syndrom buffer */ | 163 | /* Initialize the syndrom buffer */ |
164 | for (i = 0; i < NROOTS; i++) | 164 | for (i = 0; i < NROOTS; i++) |
165 | s[i] = ds[0]; | 165 | s[i] = ds[0]; |
166 | /* | 166 | /* |
167 | * Evaluate | 167 | * Evaluate |
168 | * s[i] = ds[3]x^3 + ds[2]x^2 + ds[1]x^1 + ds[0] | 168 | * s[i] = ds[3]x^3 + ds[2]x^2 + ds[1]x^1 + ds[0] |
169 | * where x = alpha^(FCR + i) | 169 | * where x = alpha^(FCR + i) |
170 | */ | 170 | */ |
@@ -188,7 +188,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc) | |||
188 | if (nerr < 0) | 188 | if (nerr < 0) |
189 | return nerr; | 189 | return nerr; |
190 | 190 | ||
191 | /* | 191 | /* |
192 | * Correct the errors. The bitpositions are a bit of magic, | 192 | * Correct the errors. The bitpositions are a bit of magic, |
193 | * but they are given by the design of the de/encoder circuit | 193 | * but they are given by the design of the de/encoder circuit |
194 | * in the DoC ASIC's. | 194 | * in the DoC ASIC's. |
@@ -205,7 +205,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc) | |||
205 | can be modified since pos is even */ | 205 | can be modified since pos is even */ |
206 | index = (pos >> 3) ^ 1; | 206 | index = (pos >> 3) ^ 1; |
207 | bitpos = pos & 7; | 207 | bitpos = pos & 7; |
208 | if ((index >= 0 && index < SECTOR_SIZE) || | 208 | if ((index >= 0 && index < SECTOR_SIZE) || |
209 | index == (SECTOR_SIZE + 1)) { | 209 | index == (SECTOR_SIZE + 1)) { |
210 | val = (uint8_t) (errval[i] >> (2 + bitpos)); | 210 | val = (uint8_t) (errval[i] >> (2 + bitpos)); |
211 | parity ^= val; | 211 | parity ^= val; |
@@ -216,7 +216,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc) | |||
216 | bitpos = (bitpos + 10) & 7; | 216 | bitpos = (bitpos + 10) & 7; |
217 | if (bitpos == 0) | 217 | if (bitpos == 0) |
218 | bitpos = 8; | 218 | bitpos = 8; |
219 | if ((index >= 0 && index < SECTOR_SIZE) || | 219 | if ((index >= 0 && index < SECTOR_SIZE) || |
220 | index == (SECTOR_SIZE + 1)) { | 220 | index == (SECTOR_SIZE + 1)) { |
221 | val = (uint8_t)(errval[i] << (8 - bitpos)); | 221 | val = (uint8_t)(errval[i] << (8 - bitpos)); |
222 | parity ^= val; | 222 | parity ^= val; |
@@ -233,7 +233,7 @@ static void DoC_Delay(struct doc_priv *doc, unsigned short cycles) | |||
233 | { | 233 | { |
234 | volatile char dummy; | 234 | volatile char dummy; |
235 | int i; | 235 | int i; |
236 | 236 | ||
237 | for (i = 0; i < cycles; i++) { | 237 | for (i = 0; i < cycles; i++) { |
238 | if (DoC_is_Millennium(doc)) | 238 | if (DoC_is_Millennium(doc)) |
239 | dummy = ReadDOC(doc->virtadr, NOP); | 239 | dummy = ReadDOC(doc->virtadr, NOP); |
@@ -242,7 +242,7 @@ static void DoC_Delay(struct doc_priv *doc, unsigned short cycles) | |||
242 | else | 242 | else |
243 | dummy = ReadDOC(doc->virtadr, DOCStatus); | 243 | dummy = ReadDOC(doc->virtadr, DOCStatus); |
244 | } | 244 | } |
245 | 245 | ||
246 | } | 246 | } |
247 | 247 | ||
248 | #define CDSN_CTRL_FR_B_MASK (CDSN_CTRL_FR_B0 | CDSN_CTRL_FR_B1) | 248 | #define CDSN_CTRL_FR_B_MASK (CDSN_CTRL_FR_B0 | CDSN_CTRL_FR_B1) |
@@ -327,7 +327,7 @@ static u_char doc2000_read_byte(struct mtd_info *mtd) | |||
327 | return ret; | 327 | return ret; |
328 | } | 328 | } |
329 | 329 | ||
330 | static void doc2000_writebuf(struct mtd_info *mtd, | 330 | static void doc2000_writebuf(struct mtd_info *mtd, |
331 | const u_char *buf, int len) | 331 | const u_char *buf, int len) |
332 | { | 332 | { |
333 | struct nand_chip *this = mtd->priv; | 333 | struct nand_chip *this = mtd->priv; |
@@ -343,7 +343,7 @@ static void doc2000_writebuf(struct mtd_info *mtd, | |||
343 | if (debug) printk("\n"); | 343 | if (debug) printk("\n"); |
344 | } | 344 | } |
345 | 345 | ||
346 | static void doc2000_readbuf(struct mtd_info *mtd, | 346 | static void doc2000_readbuf(struct mtd_info *mtd, |
347 | u_char *buf, int len) | 347 | u_char *buf, int len) |
348 | { | 348 | { |
349 | struct nand_chip *this = mtd->priv; | 349 | struct nand_chip *this = mtd->priv; |
@@ -358,7 +358,7 @@ static void doc2000_readbuf(struct mtd_info *mtd, | |||
358 | } | 358 | } |
359 | } | 359 | } |
360 | 360 | ||
361 | static void doc2000_readbuf_dword(struct mtd_info *mtd, | 361 | static void doc2000_readbuf_dword(struct mtd_info *mtd, |
362 | u_char *buf, int len) | 362 | u_char *buf, int len) |
363 | { | 363 | { |
364 | struct nand_chip *this = mtd->priv; | 364 | struct nand_chip *this = mtd->priv; |
@@ -379,7 +379,7 @@ static void doc2000_readbuf_dword(struct mtd_info *mtd, | |||
379 | } | 379 | } |
380 | } | 380 | } |
381 | 381 | ||
382 | static int doc2000_verifybuf(struct mtd_info *mtd, | 382 | static int doc2000_verifybuf(struct mtd_info *mtd, |
383 | const u_char *buf, int len) | 383 | const u_char *buf, int len) |
384 | { | 384 | { |
385 | struct nand_chip *this = mtd->priv; | 385 | struct nand_chip *this = mtd->priv; |
@@ -406,12 +406,12 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr) | |||
406 | doc200x_hwcontrol(mtd, NAND_CTL_SETALE); | 406 | doc200x_hwcontrol(mtd, NAND_CTL_SETALE); |
407 | this->write_byte(mtd, 0); | 407 | this->write_byte(mtd, 0); |
408 | doc200x_hwcontrol(mtd, NAND_CTL_CLRALE); | 408 | doc200x_hwcontrol(mtd, NAND_CTL_CLRALE); |
409 | 409 | ||
410 | /* We cant' use dev_ready here, but at least we wait for the | 410 | /* We cant' use dev_ready here, but at least we wait for the |
411 | * command to complete | 411 | * command to complete |
412 | */ | 412 | */ |
413 | udelay(50); | 413 | udelay(50); |
414 | 414 | ||
415 | ret = this->read_byte(mtd) << 8; | 415 | ret = this->read_byte(mtd) << 8; |
416 | ret |= this->read_byte(mtd); | 416 | ret |= this->read_byte(mtd); |
417 | 417 | ||
@@ -438,7 +438,7 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr) | |||
438 | this->read_buf = &doc2000_readbuf_dword; | 438 | this->read_buf = &doc2000_readbuf_dword; |
439 | } | 439 | } |
440 | } | 440 | } |
441 | 441 | ||
442 | return ret; | 442 | return ret; |
443 | } | 443 | } |
444 | 444 | ||
@@ -469,7 +469,7 @@ static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this, int state) | |||
469 | struct doc_priv *doc = this->priv; | 469 | struct doc_priv *doc = this->priv; |
470 | 470 | ||
471 | int status; | 471 | int status; |
472 | 472 | ||
473 | DoC_WaitReady(doc); | 473 | DoC_WaitReady(doc); |
474 | this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); | 474 | this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); |
475 | DoC_WaitReady(doc); | 475 | DoC_WaitReady(doc); |
@@ -503,7 +503,7 @@ static u_char doc2001_read_byte(struct mtd_info *mtd) | |||
503 | return ReadDOC(docptr, LastDataRead); | 503 | return ReadDOC(docptr, LastDataRead); |
504 | } | 504 | } |
505 | 505 | ||
506 | static void doc2001_writebuf(struct mtd_info *mtd, | 506 | static void doc2001_writebuf(struct mtd_info *mtd, |
507 | const u_char *buf, int len) | 507 | const u_char *buf, int len) |
508 | { | 508 | { |
509 | struct nand_chip *this = mtd->priv; | 509 | struct nand_chip *this = mtd->priv; |
@@ -517,7 +517,7 @@ static void doc2001_writebuf(struct mtd_info *mtd, | |||
517 | WriteDOC(0x00, docptr, WritePipeTerm); | 517 | WriteDOC(0x00, docptr, WritePipeTerm); |
518 | } | 518 | } |
519 | 519 | ||
520 | static void doc2001_readbuf(struct mtd_info *mtd, | 520 | static void doc2001_readbuf(struct mtd_info *mtd, |
521 | u_char *buf, int len) | 521 | u_char *buf, int len) |
522 | { | 522 | { |
523 | struct nand_chip *this = mtd->priv; | 523 | struct nand_chip *this = mtd->priv; |
@@ -535,7 +535,7 @@ static void doc2001_readbuf(struct mtd_info *mtd, | |||
535 | buf[i] = ReadDOC(docptr, LastDataRead); | 535 | buf[i] = ReadDOC(docptr, LastDataRead); |
536 | } | 536 | } |
537 | 537 | ||
538 | static int doc2001_verifybuf(struct mtd_info *mtd, | 538 | static int doc2001_verifybuf(struct mtd_info *mtd, |
539 | const u_char *buf, int len) | 539 | const u_char *buf, int len) |
540 | { | 540 | { |
541 | struct nand_chip *this = mtd->priv; | 541 | struct nand_chip *this = mtd->priv; |
@@ -570,7 +570,7 @@ static u_char doc2001plus_read_byte(struct mtd_info *mtd) | |||
570 | return ret; | 570 | return ret; |
571 | } | 571 | } |
572 | 572 | ||
573 | static void doc2001plus_writebuf(struct mtd_info *mtd, | 573 | static void doc2001plus_writebuf(struct mtd_info *mtd, |
574 | const u_char *buf, int len) | 574 | const u_char *buf, int len) |
575 | { | 575 | { |
576 | struct nand_chip *this = mtd->priv; | 576 | struct nand_chip *this = mtd->priv; |
@@ -587,7 +587,7 @@ static void doc2001plus_writebuf(struct mtd_info *mtd, | |||
587 | if (debug) printk("\n"); | 587 | if (debug) printk("\n"); |
588 | } | 588 | } |
589 | 589 | ||
590 | static void doc2001plus_readbuf(struct mtd_info *mtd, | 590 | static void doc2001plus_readbuf(struct mtd_info *mtd, |
591 | u_char *buf, int len) | 591 | u_char *buf, int len) |
592 | { | 592 | { |
593 | struct nand_chip *this = mtd->priv; | 593 | struct nand_chip *this = mtd->priv; |
@@ -617,7 +617,7 @@ static void doc2001plus_readbuf(struct mtd_info *mtd, | |||
617 | if (debug) printk("\n"); | 617 | if (debug) printk("\n"); |
618 | } | 618 | } |
619 | 619 | ||
620 | static int doc2001plus_verifybuf(struct mtd_info *mtd, | 620 | static int doc2001plus_verifybuf(struct mtd_info *mtd, |
621 | const u_char *buf, int len) | 621 | const u_char *buf, int len) |
622 | { | 622 | { |
623 | struct nand_chip *this = mtd->priv; | 623 | struct nand_chip *this = mtd->priv; |
@@ -797,7 +797,7 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col | |||
797 | WriteDOC(0, docptr, Mplus_FlashControl); | 797 | WriteDOC(0, docptr, Mplus_FlashControl); |
798 | } | 798 | } |
799 | 799 | ||
800 | /* | 800 | /* |
801 | * program and erase have their own busy handlers | 801 | * program and erase have their own busy handlers |
802 | * status and sequential in needs no delay | 802 | * status and sequential in needs no delay |
803 | */ | 803 | */ |
@@ -822,7 +822,7 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col | |||
822 | 822 | ||
823 | /* This applies to read commands */ | 823 | /* This applies to read commands */ |
824 | default: | 824 | default: |
825 | /* | 825 | /* |
826 | * If we don't have access to the busy pin, we apply the given | 826 | * If we don't have access to the busy pin, we apply the given |
827 | * command delay | 827 | * command delay |
828 | */ | 828 | */ |
@@ -945,7 +945,7 @@ static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat, | |||
945 | for (i = 0; i < 6; i++) { | 945 | for (i = 0; i < 6; i++) { |
946 | if (DoC_is_MillenniumPlus(doc)) | 946 | if (DoC_is_MillenniumPlus(doc)) |
947 | ecc_code[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i); | 947 | ecc_code[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i); |
948 | else | 948 | else |
949 | ecc_code[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i); | 949 | ecc_code[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i); |
950 | if (ecc_code[i] != empty_write_ecc[i]) | 950 | if (ecc_code[i] != empty_write_ecc[i]) |
951 | emptymatch = 0; | 951 | emptymatch = 0; |
@@ -982,7 +982,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ | |||
982 | void __iomem *docptr = doc->virtadr; | 982 | void __iomem *docptr = doc->virtadr; |
983 | volatile u_char dummy; | 983 | volatile u_char dummy; |
984 | int emptymatch = 1; | 984 | int emptymatch = 1; |
985 | 985 | ||
986 | /* flush the pipeline */ | 986 | /* flush the pipeline */ |
987 | if (DoC_is_2000(doc)) { | 987 | if (DoC_is_2000(doc)) { |
988 | dummy = ReadDOC(docptr, 2k_ECCStatus); | 988 | dummy = ReadDOC(docptr, 2k_ECCStatus); |
@@ -997,7 +997,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ | |||
997 | dummy = ReadDOC(docptr, ECCConf); | 997 | dummy = ReadDOC(docptr, ECCConf); |
998 | dummy = ReadDOC(docptr, ECCConf); | 998 | dummy = ReadDOC(docptr, ECCConf); |
999 | } | 999 | } |
1000 | 1000 | ||
1001 | /* Error occured ? */ | 1001 | /* Error occured ? */ |
1002 | if (dummy & 0x80) { | 1002 | if (dummy & 0x80) { |
1003 | for (i = 0; i < 6; i++) { | 1003 | for (i = 0; i < 6; i++) { |
@@ -1035,7 +1035,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ | |||
1035 | if (!emptymatch) ret = doc_ecc_decode (rs_decoder, dat, calc_ecc); | 1035 | if (!emptymatch) ret = doc_ecc_decode (rs_decoder, dat, calc_ecc); |
1036 | if (ret > 0) | 1036 | if (ret > 0) |
1037 | printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret); | 1037 | printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret); |
1038 | } | 1038 | } |
1039 | if (DoC_is_MillenniumPlus(doc)) | 1039 | if (DoC_is_MillenniumPlus(doc)) |
1040 | WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf); | 1040 | WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf); |
1041 | else | 1041 | else |
@@ -1046,7 +1046,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ | |||
1046 | } | 1046 | } |
1047 | return ret; | 1047 | return ret; |
1048 | } | 1048 | } |
1049 | 1049 | ||
1050 | //u_char mydatabuf[528]; | 1050 | //u_char mydatabuf[528]; |
1051 | 1051 | ||
1052 | /* The strange out-of-order .oobfree list below is a (possibly unneeded) | 1052 | /* The strange out-of-order .oobfree list below is a (possibly unneeded) |
@@ -1065,7 +1065,7 @@ static struct nand_oobinfo doc200x_oobinfo = { | |||
1065 | .eccpos = {0, 1, 2, 3, 4, 5}, | 1065 | .eccpos = {0, 1, 2, 3, 4, 5}, |
1066 | .oobfree = { {8, 8}, {6, 2} } | 1066 | .oobfree = { {8, 8}, {6, 2} } |
1067 | }; | 1067 | }; |
1068 | 1068 | ||
1069 | /* Find the (I)NFTL Media Header, and optionally also the mirror media header. | 1069 | /* Find the (I)NFTL Media Header, and optionally also the mirror media header. |
1070 | On sucessful return, buf will contain a copy of the media header for | 1070 | On sucessful return, buf will contain a copy of the media header for |
1071 | further processing. id is the string to scan for, and will presumably be | 1071 | further processing. id is the string to scan for, and will presumably be |
@@ -1251,7 +1251,7 @@ static inline int __init inftl_partscan(struct mtd_info *mtd, | |||
1251 | mh->BlockMultiplierBits = le32_to_cpu(mh->BlockMultiplierBits); | 1251 | mh->BlockMultiplierBits = le32_to_cpu(mh->BlockMultiplierBits); |
1252 | mh->FormatFlags = le32_to_cpu(mh->FormatFlags); | 1252 | mh->FormatFlags = le32_to_cpu(mh->FormatFlags); |
1253 | mh->PercentUsed = le32_to_cpu(mh->PercentUsed); | 1253 | mh->PercentUsed = le32_to_cpu(mh->PercentUsed); |
1254 | 1254 | ||
1255 | printk(KERN_INFO " bootRecordID = %s\n" | 1255 | printk(KERN_INFO " bootRecordID = %s\n" |
1256 | " NoOfBootImageBlocks = %d\n" | 1256 | " NoOfBootImageBlocks = %d\n" |
1257 | " NoOfBinaryPartitions = %d\n" | 1257 | " NoOfBinaryPartitions = %d\n" |
@@ -1468,7 +1468,7 @@ static inline int __init doc2001_init(struct mtd_info *mtd) | |||
1468 | ReadDOC(doc->virtadr, ChipID); | 1468 | ReadDOC(doc->virtadr, ChipID); |
1469 | if (ReadDOC(doc->virtadr, ChipID) != DOC_ChipID_DocMil) { | 1469 | if (ReadDOC(doc->virtadr, ChipID) != DOC_ChipID_DocMil) { |
1470 | /* It's not a Millennium; it's one of the newer | 1470 | /* It's not a Millennium; it's one of the newer |
1471 | DiskOnChip 2000 units with a similar ASIC. | 1471 | DiskOnChip 2000 units with a similar ASIC. |
1472 | Treat it like a Millennium, except that it | 1472 | Treat it like a Millennium, except that it |
1473 | can have multiple chips. */ | 1473 | can have multiple chips. */ |
1474 | doc2000_count_chips(mtd); | 1474 | doc2000_count_chips(mtd); |
@@ -1530,20 +1530,20 @@ static inline int __init doc_probe(unsigned long physadr) | |||
1530 | * to the DOCControl register. So we store the current contents | 1530 | * to the DOCControl register. So we store the current contents |
1531 | * of the DOCControl register's location, in case we later decide | 1531 | * of the DOCControl register's location, in case we later decide |
1532 | * that it's not a DiskOnChip, and want to put it back how we | 1532 | * that it's not a DiskOnChip, and want to put it back how we |
1533 | * found it. | 1533 | * found it. |
1534 | */ | 1534 | */ |
1535 | save_control = ReadDOC(virtadr, DOCControl); | 1535 | save_control = ReadDOC(virtadr, DOCControl); |
1536 | 1536 | ||
1537 | /* Reset the DiskOnChip ASIC */ | 1537 | /* Reset the DiskOnChip ASIC */ |
1538 | WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, | 1538 | WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, |
1539 | virtadr, DOCControl); | 1539 | virtadr, DOCControl); |
1540 | WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, | 1540 | WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, |
1541 | virtadr, DOCControl); | 1541 | virtadr, DOCControl); |
1542 | 1542 | ||
1543 | /* Enable the DiskOnChip ASIC */ | 1543 | /* Enable the DiskOnChip ASIC */ |
1544 | WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, | 1544 | WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, |
1545 | virtadr, DOCControl); | 1545 | virtadr, DOCControl); |
1546 | WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, | 1546 | WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, |
1547 | virtadr, DOCControl); | 1547 | virtadr, DOCControl); |
1548 | 1548 | ||
1549 | ChipID = ReadDOC(virtadr, ChipID); | 1549 | ChipID = ReadDOC(virtadr, ChipID); |
@@ -1738,7 +1738,7 @@ static int __init init_nanddoc(void) | |||
1738 | int i, ret = 0; | 1738 | int i, ret = 0; |
1739 | 1739 | ||
1740 | /* We could create the decoder on demand, if memory is a concern. | 1740 | /* We could create the decoder on demand, if memory is a concern. |
1741 | * This way we have it handy, if an error happens | 1741 | * This way we have it handy, if an error happens |
1742 | * | 1742 | * |
1743 | * Symbolsize is 10 (bits) | 1743 | * Symbolsize is 10 (bits) |
1744 | * Primitve polynomial is x^10+x^3+1 | 1744 | * Primitve polynomial is x^10+x^3+1 |
diff --git a/drivers/mtd/nand/edb7312.c b/drivers/mtd/nand/edb7312.c index 5549681ccdce..9b1fd2f387fa 100644 --- a/drivers/mtd/nand/edb7312.c +++ b/drivers/mtd/nand/edb7312.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * Derived from drivers/mtd/nand/autcpu12.c | 6 | * Derived from drivers/mtd/nand/autcpu12.c |
7 | * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) | 7 | * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) |
8 | * | 8 | * |
9 | * $Id: edb7312.c,v 1.11 2004/11/04 12:53:10 gleixner Exp $ | 9 | * $Id: edb7312.c,v 1.12 2005/11/07 11:14:30 gleixner Exp $ |
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License version 2 as | 12 | * it under the terms of the GNU General Public License version 2 as |
@@ -71,27 +71,27 @@ static struct mtd_partition partition_info[] = { | |||
71 | #endif | 71 | #endif |
72 | 72 | ||
73 | 73 | ||
74 | /* | 74 | /* |
75 | * hardware specific access to control-lines | 75 | * hardware specific access to control-lines |
76 | */ | 76 | */ |
77 | static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd) | 77 | static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd) |
78 | { | 78 | { |
79 | switch(cmd) { | 79 | switch(cmd) { |
80 | 80 | ||
81 | case NAND_CTL_SETCLE: | 81 | case NAND_CTL_SETCLE: |
82 | clps_writeb(clps_readb(ep7312_pxdr) | 0x10, ep7312_pxdr); | 82 | clps_writeb(clps_readb(ep7312_pxdr) | 0x10, ep7312_pxdr); |
83 | break; | 83 | break; |
84 | case NAND_CTL_CLRCLE: | 84 | case NAND_CTL_CLRCLE: |
85 | clps_writeb(clps_readb(ep7312_pxdr) & ~0x10, ep7312_pxdr); | 85 | clps_writeb(clps_readb(ep7312_pxdr) & ~0x10, ep7312_pxdr); |
86 | break; | 86 | break; |
87 | 87 | ||
88 | case NAND_CTL_SETALE: | 88 | case NAND_CTL_SETALE: |
89 | clps_writeb(clps_readb(ep7312_pxdr) | 0x20, ep7312_pxdr); | 89 | clps_writeb(clps_readb(ep7312_pxdr) | 0x20, ep7312_pxdr); |
90 | break; | 90 | break; |
91 | case NAND_CTL_CLRALE: | 91 | case NAND_CTL_CLRALE: |
92 | clps_writeb(clps_readb(ep7312_pxdr) & ~0x20, ep7312_pxdr); | 92 | clps_writeb(clps_readb(ep7312_pxdr) & ~0x20, ep7312_pxdr); |
93 | break; | 93 | break; |
94 | 94 | ||
95 | case NAND_CTL_SETNCE: | 95 | case NAND_CTL_SETNCE: |
96 | clps_writeb((clps_readb(ep7312_pxdr) | 0x80) & ~0x40, ep7312_pxdr); | 96 | clps_writeb((clps_readb(ep7312_pxdr) | 0x80) & ~0x40, ep7312_pxdr); |
97 | break; | 97 | break; |
@@ -122,16 +122,16 @@ static int __init ep7312_init (void) | |||
122 | int mtd_parts_nb = 0; | 122 | int mtd_parts_nb = 0; |
123 | struct mtd_partition *mtd_parts = 0; | 123 | struct mtd_partition *mtd_parts = 0; |
124 | void __iomem * ep7312_fio_base; | 124 | void __iomem * ep7312_fio_base; |
125 | 125 | ||
126 | /* Allocate memory for MTD device structure and private data */ | 126 | /* Allocate memory for MTD device structure and private data */ |
127 | ep7312_mtd = kmalloc(sizeof(struct mtd_info) + | 127 | ep7312_mtd = kmalloc(sizeof(struct mtd_info) + |
128 | sizeof(struct nand_chip), | 128 | sizeof(struct nand_chip), |
129 | GFP_KERNEL); | 129 | GFP_KERNEL); |
130 | if (!ep7312_mtd) { | 130 | if (!ep7312_mtd) { |
131 | printk("Unable to allocate EDB7312 NAND MTD device structure.\n"); | 131 | printk("Unable to allocate EDB7312 NAND MTD device structure.\n"); |
132 | return -ENOMEM; | 132 | return -ENOMEM; |
133 | } | 133 | } |
134 | 134 | ||
135 | /* map physical adress */ | 135 | /* map physical adress */ |
136 | ep7312_fio_base = ioremap(ep7312_fio_pbase, SZ_1K); | 136 | ep7312_fio_base = ioremap(ep7312_fio_pbase, SZ_1K); |
137 | if(!ep7312_fio_base) { | 137 | if(!ep7312_fio_base) { |
@@ -139,23 +139,23 @@ static int __init ep7312_init (void) | |||
139 | kfree(ep7312_mtd); | 139 | kfree(ep7312_mtd); |
140 | return -EIO; | 140 | return -EIO; |
141 | } | 141 | } |
142 | 142 | ||
143 | /* Get pointer to private data */ | 143 | /* Get pointer to private data */ |
144 | this = (struct nand_chip *) (&ep7312_mtd[1]); | 144 | this = (struct nand_chip *) (&ep7312_mtd[1]); |
145 | 145 | ||
146 | /* Initialize structures */ | 146 | /* Initialize structures */ |
147 | memset((char *) ep7312_mtd, 0, sizeof(struct mtd_info)); | 147 | memset((char *) ep7312_mtd, 0, sizeof(struct mtd_info)); |
148 | memset((char *) this, 0, sizeof(struct nand_chip)); | 148 | memset((char *) this, 0, sizeof(struct nand_chip)); |
149 | 149 | ||
150 | /* Link the private data with the MTD structure */ | 150 | /* Link the private data with the MTD structure */ |
151 | ep7312_mtd->priv = this; | 151 | ep7312_mtd->priv = this; |
152 | 152 | ||
153 | /* | 153 | /* |
154 | * Set GPIO Port B control register so that the pins are configured | 154 | * Set GPIO Port B control register so that the pins are configured |
155 | * to be outputs for controlling the NAND flash. | 155 | * to be outputs for controlling the NAND flash. |
156 | */ | 156 | */ |
157 | clps_writeb(0xf0, ep7312_pxddr); | 157 | clps_writeb(0xf0, ep7312_pxddr); |
158 | 158 | ||
159 | /* insert callbacks */ | 159 | /* insert callbacks */ |
160 | this->IO_ADDR_R = ep7312_fio_base; | 160 | this->IO_ADDR_R = ep7312_fio_base; |
161 | this->IO_ADDR_W = ep7312_fio_base; | 161 | this->IO_ADDR_W = ep7312_fio_base; |
@@ -163,14 +163,14 @@ static int __init ep7312_init (void) | |||
163 | this->dev_ready = ep7312_device_ready; | 163 | this->dev_ready = ep7312_device_ready; |
164 | /* 15 us command delay time */ | 164 | /* 15 us command delay time */ |
165 | this->chip_delay = 15; | 165 | this->chip_delay = 15; |
166 | 166 | ||
167 | /* Scan to find existence of the device */ | 167 | /* Scan to find existence of the device */ |
168 | if (nand_scan (ep7312_mtd, 1)) { | 168 | if (nand_scan (ep7312_mtd, 1)) { |
169 | iounmap((void *)ep7312_fio_base); | 169 | iounmap((void *)ep7312_fio_base); |
170 | kfree (ep7312_mtd); | 170 | kfree (ep7312_mtd); |
171 | return -ENXIO; | 171 | return -ENXIO; |
172 | } | 172 | } |
173 | 173 | ||
174 | #ifdef CONFIG_MTD_PARTITIONS | 174 | #ifdef CONFIG_MTD_PARTITIONS |
175 | ep7312_mtd->name = "edb7312-nand"; | 175 | ep7312_mtd->name = "edb7312-nand"; |
176 | mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes, | 176 | mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes, |
@@ -185,11 +185,11 @@ static int __init ep7312_init (void) | |||
185 | mtd_parts_nb = NUM_PARTITIONS; | 185 | mtd_parts_nb = NUM_PARTITIONS; |
186 | part_type = "static"; | 186 | part_type = "static"; |
187 | } | 187 | } |
188 | 188 | ||
189 | /* Register the partitions */ | 189 | /* Register the partitions */ |
190 | printk(KERN_NOTICE "Using %s partition definition\n", part_type); | 190 | printk(KERN_NOTICE "Using %s partition definition\n", part_type); |
191 | add_mtd_partitions(ep7312_mtd, mtd_parts, mtd_parts_nb); | 191 | add_mtd_partitions(ep7312_mtd, mtd_parts, mtd_parts_nb); |
192 | 192 | ||
193 | /* Return happy */ | 193 | /* Return happy */ |
194 | return 0; | 194 | return 0; |
195 | } | 195 | } |
@@ -201,13 +201,13 @@ module_init(ep7312_init); | |||
201 | static void __exit ep7312_cleanup (void) | 201 | static void __exit ep7312_cleanup (void) |
202 | { | 202 | { |
203 | struct nand_chip *this = (struct nand_chip *) &ep7312_mtd[1]; | 203 | struct nand_chip *this = (struct nand_chip *) &ep7312_mtd[1]; |
204 | 204 | ||
205 | /* Release resources, unregister device */ | 205 | /* Release resources, unregister device */ |
206 | nand_release (ap7312_mtd); | 206 | nand_release (ap7312_mtd); |
207 | 207 | ||
208 | /* Free internal data buffer */ | 208 | /* Free internal data buffer */ |
209 | kfree (this->data_buf); | 209 | kfree (this->data_buf); |
210 | 210 | ||
211 | /* Free the MTD device structure */ | 211 | /* Free the MTD device structure */ |
212 | kfree (ep7312_mtd); | 212 | kfree (ep7312_mtd); |
213 | } | 213 | } |
diff --git a/drivers/mtd/nand/h1910.c b/drivers/mtd/nand/h1910.c index 3825a7a0900c..041e4b3358fb 100644 --- a/drivers/mtd/nand/h1910.c +++ b/drivers/mtd/nand/h1910.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * Copyright (C) 2002 Marius Gröger (mag@sysgo.de) | 7 | * Copyright (C) 2002 Marius Gröger (mag@sysgo.de) |
8 | * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) | 8 | * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) |
9 | * | 9 | * |
10 | * $Id: h1910.c,v 1.5 2004/11/04 12:53:10 gleixner Exp $ | 10 | * $Id: h1910.c,v 1.6 2005/11/07 11:14:30 gleixner Exp $ |
11 | * | 11 | * |
12 | * This program is free software; you can redistribute it and/or modify | 12 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of the GNU General Public License version 2 as | 13 | * it under the terms of the GNU General Public License version 2 as |
@@ -54,24 +54,24 @@ static struct mtd_partition partition_info[] = { | |||
54 | #endif | 54 | #endif |
55 | 55 | ||
56 | 56 | ||
57 | /* | 57 | /* |
58 | * hardware specific access to control-lines | 58 | * hardware specific access to control-lines |
59 | */ | 59 | */ |
60 | static void h1910_hwcontrol(struct mtd_info *mtd, int cmd) | 60 | static void h1910_hwcontrol(struct mtd_info *mtd, int cmd) |
61 | { | 61 | { |
62 | struct nand_chip* this = (struct nand_chip *) (mtd->priv); | 62 | struct nand_chip* this = (struct nand_chip *) (mtd->priv); |
63 | 63 | ||
64 | switch(cmd) { | 64 | switch(cmd) { |
65 | 65 | ||
66 | case NAND_CTL_SETCLE: | 66 | case NAND_CTL_SETCLE: |
67 | this->IO_ADDR_R |= (1 << 2); | 67 | this->IO_ADDR_R |= (1 << 2); |
68 | this->IO_ADDR_W |= (1 << 2); | 68 | this->IO_ADDR_W |= (1 << 2); |
69 | break; | 69 | break; |
70 | case NAND_CTL_CLRCLE: | 70 | case NAND_CTL_CLRCLE: |
71 | this->IO_ADDR_R &= ~(1 << 2); | 71 | this->IO_ADDR_R &= ~(1 << 2); |
72 | this->IO_ADDR_W &= ~(1 << 2); | 72 | this->IO_ADDR_W &= ~(1 << 2); |
73 | break; | 73 | break; |
74 | 74 | ||
75 | case NAND_CTL_SETALE: | 75 | case NAND_CTL_SETALE: |
76 | this->IO_ADDR_R |= (1 << 3); | 76 | this->IO_ADDR_R |= (1 << 3); |
77 | this->IO_ADDR_W |= (1 << 3); | 77 | this->IO_ADDR_W |= (1 << 3); |
@@ -80,7 +80,7 @@ static void h1910_hwcontrol(struct mtd_info *mtd, int cmd) | |||
80 | this->IO_ADDR_R &= ~(1 << 3); | 80 | this->IO_ADDR_R &= ~(1 << 3); |
81 | this->IO_ADDR_W &= ~(1 << 3); | 81 | this->IO_ADDR_W &= ~(1 << 3); |
82 | break; | 82 | break; |
83 | 83 | ||
84 | case NAND_CTL_SETNCE: | 84 | case NAND_CTL_SETNCE: |
85 | break; | 85 | break; |
86 | case NAND_CTL_CLRNCE: | 86 | case NAND_CTL_CLRNCE: |
@@ -108,18 +108,18 @@ static int __init h1910_init (void) | |||
108 | int mtd_parts_nb = 0; | 108 | int mtd_parts_nb = 0; |
109 | struct mtd_partition *mtd_parts = 0; | 109 | struct mtd_partition *mtd_parts = 0; |
110 | void __iomem *nandaddr; | 110 | void __iomem *nandaddr; |
111 | 111 | ||
112 | if (!machine_is_h1900()) | 112 | if (!machine_is_h1900()) |
113 | return -ENODEV; | 113 | return -ENODEV; |
114 | 114 | ||
115 | nandaddr = __ioremap(0x08000000, 0x1000, 0, 1); | 115 | nandaddr = __ioremap(0x08000000, 0x1000, 0, 1); |
116 | if (!nandaddr) { | 116 | if (!nandaddr) { |
117 | printk("Failed to ioremap nand flash.\n"); | 117 | printk("Failed to ioremap nand flash.\n"); |
118 | return -ENOMEM; | 118 | return -ENOMEM; |
119 | } | 119 | } |
120 | 120 | ||
121 | /* Allocate memory for MTD device structure and private data */ | 121 | /* Allocate memory for MTD device structure and private data */ |
122 | h1910_nand_mtd = kmalloc(sizeof(struct mtd_info) + | 122 | h1910_nand_mtd = kmalloc(sizeof(struct mtd_info) + |
123 | sizeof(struct nand_chip), | 123 | sizeof(struct nand_chip), |
124 | GFP_KERNEL); | 124 | GFP_KERNEL); |
125 | if (!h1910_nand_mtd) { | 125 | if (!h1910_nand_mtd) { |
@@ -127,22 +127,22 @@ static int __init h1910_init (void) | |||
127 | iounmap ((void *) nandaddr); | 127 | iounmap ((void *) nandaddr); |
128 | return -ENOMEM; | 128 | return -ENOMEM; |
129 | } | 129 | } |
130 | 130 | ||
131 | /* Get pointer to private data */ | 131 | /* Get pointer to private data */ |
132 | this = (struct nand_chip *) (&h1910_nand_mtd[1]); | 132 | this = (struct nand_chip *) (&h1910_nand_mtd[1]); |
133 | 133 | ||
134 | /* Initialize structures */ | 134 | /* Initialize structures */ |
135 | memset((char *) h1910_nand_mtd, 0, sizeof(struct mtd_info)); | 135 | memset((char *) h1910_nand_mtd, 0, sizeof(struct mtd_info)); |
136 | memset((char *) this, 0, sizeof(struct nand_chip)); | 136 | memset((char *) this, 0, sizeof(struct nand_chip)); |
137 | 137 | ||
138 | /* Link the private data with the MTD structure */ | 138 | /* Link the private data with the MTD structure */ |
139 | h1910_nand_mtd->priv = this; | 139 | h1910_nand_mtd->priv = this; |
140 | 140 | ||
141 | /* | 141 | /* |
142 | * Enable VPEN | 142 | * Enable VPEN |
143 | */ | 143 | */ |
144 | GPSR(37) = GPIO_bit(37); | 144 | GPSR(37) = GPIO_bit(37); |
145 | 145 | ||
146 | /* insert callbacks */ | 146 | /* insert callbacks */ |
147 | this->IO_ADDR_R = nandaddr; | 147 | this->IO_ADDR_R = nandaddr; |
148 | this->IO_ADDR_W = nandaddr; | 148 | this->IO_ADDR_W = nandaddr; |
@@ -152,7 +152,7 @@ static int __init h1910_init (void) | |||
152 | this->chip_delay = 50; | 152 | this->chip_delay = 50; |
153 | this->eccmode = NAND_ECC_SOFT; | 153 | this->eccmode = NAND_ECC_SOFT; |
154 | this->options = NAND_NO_AUTOINCR; | 154 | this->options = NAND_NO_AUTOINCR; |
155 | 155 | ||
156 | /* Scan to find existence of the device */ | 156 | /* Scan to find existence of the device */ |
157 | if (nand_scan (h1910_nand_mtd, 1)) { | 157 | if (nand_scan (h1910_nand_mtd, 1)) { |
158 | printk(KERN_NOTICE "No NAND device - returning -ENXIO\n"); | 158 | printk(KERN_NOTICE "No NAND device - returning -ENXIO\n"); |
@@ -160,9 +160,9 @@ static int __init h1910_init (void) | |||
160 | iounmap ((void *) nandaddr); | 160 | iounmap ((void *) nandaddr); |
161 | return -ENXIO; | 161 | return -ENXIO; |
162 | } | 162 | } |
163 | 163 | ||
164 | #ifdef CONFIG_MTD_CMDLINE_PARTS | 164 | #ifdef CONFIG_MTD_CMDLINE_PARTS |
165 | mtd_parts_nb = parse_cmdline_partitions(h1910_nand_mtd, &mtd_parts, | 165 | mtd_parts_nb = parse_cmdline_partitions(h1910_nand_mtd, &mtd_parts, |
166 | "h1910-nand"); | 166 | "h1910-nand"); |
167 | if (mtd_parts_nb > 0) | 167 | if (mtd_parts_nb > 0) |
168 | part_type = "command line"; | 168 | part_type = "command line"; |
@@ -175,11 +175,11 @@ static int __init h1910_init (void) | |||
175 | mtd_parts_nb = NUM_PARTITIONS; | 175 | mtd_parts_nb = NUM_PARTITIONS; |
176 | part_type = "static"; | 176 | part_type = "static"; |
177 | } | 177 | } |
178 | 178 | ||
179 | /* Register the partitions */ | 179 | /* Register the partitions */ |
180 | printk(KERN_NOTICE "Using %s partition definition\n", part_type); | 180 | printk(KERN_NOTICE "Using %s partition definition\n", part_type); |
181 | add_mtd_partitions(h1910_nand_mtd, mtd_parts, mtd_parts_nb); | 181 | add_mtd_partitions(h1910_nand_mtd, mtd_parts, mtd_parts_nb); |
182 | 182 | ||
183 | /* Return happy */ | 183 | /* Return happy */ |
184 | return 0; | 184 | return 0; |
185 | } | 185 | } |
@@ -191,7 +191,7 @@ module_init(h1910_init); | |||
191 | static void __exit h1910_cleanup (void) | 191 | static void __exit h1910_cleanup (void) |
192 | { | 192 | { |
193 | struct nand_chip *this = (struct nand_chip *) &h1910_nand_mtd[1]; | 193 | struct nand_chip *this = (struct nand_chip *) &h1910_nand_mtd[1]; |
194 | 194 | ||
195 | /* Release resources, unregister device */ | 195 | /* Release resources, unregister device */ |
196 | nand_release (h1910_nand_mtd); | 196 | nand_release (h1910_nand_mtd); |
197 | 197 | ||
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index c18ea76ed408..4673ba79309b 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -5,14 +5,14 @@ | |||
5 | * This is the generic MTD driver for NAND flash devices. It should be | 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. | 6 | * capable of working with almost all NAND chips currently available. |
7 | * Basic support for AG-AND chips is provided. | 7 | * Basic support for AG-AND chips is provided. |
8 | * | 8 | * |
9 | * Additional technical information is available on | 9 | * Additional technical information is available on |
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 Thomas Gleixner (tglx@linutronix.de) |
14 | * | 14 | * |
15 | * 02-08-2004 tglx: support for strange chips, which cannot auto increment | 15 | * 02-08-2004 tglx: support for strange chips, which cannot auto increment |
16 | * pages on read / read_oob | 16 | * pages on read / read_oob |
17 | * | 17 | * |
18 | * 03-17-2004 tglx: Check ready before auto increment check. Simon Bayes | 18 | * 03-17-2004 tglx: Check ready before auto increment check. Simon Bayes |
@@ -21,7 +21,7 @@ | |||
21 | * Make reads over block boundaries work too | 21 | * Make reads over block boundaries work too |
22 | * | 22 | * |
23 | * 04-14-2004 tglx: first working version for 2k page size chips | 23 | * 04-14-2004 tglx: first working version for 2k page size chips |
24 | * | 24 | * |
25 | * 05-19-2004 tglx: Basic support for Renesas AG-AND chips | 25 | * 05-19-2004 tglx: Basic support for Renesas AG-AND chips |
26 | * | 26 | * |
27 | * 09-24-2004 tglx: add support for hardware controllers (e.g. ECC) shared | 27 | * 09-24-2004 tglx: add support for hardware controllers (e.g. ECC) shared |
@@ -30,27 +30,27 @@ | |||
30 | * | 30 | * |
31 | * 12-05-2004 dmarlin: add workaround for Renesas AG-AND chips "disturb" issue. | 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 | 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 | 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 | 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 | 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 | 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 | 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. | 38 | * in the same area, and rewrite the BBT when any of them are erased. |
39 | * | 39 | * |
40 | * 01-03-2005 dmarlin: added support for the device recovery command sequence for Renesas | 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, | 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 | 42 | * a "device recovery" operation must be performed when power is restored |
43 | * to ensure correct operation. | 43 | * to ensure correct operation. |
44 | * | 44 | * |
45 | * 01-20-2005 dmarlin: added support for optional hardware specific callback routine to | 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 | 46 | * perform extra error status checks on erase and write failures. This required |
47 | * adding a wrapper function for nand_read_ecc. | 47 | * adding a wrapper function for nand_read_ecc. |
48 | * | 48 | * |
49 | * 08-20-2005 vwool: suspend/resume added | 49 | * 08-20-2005 vwool: suspend/resume added |
50 | * | 50 | * |
51 | * Credits: | 51 | * Credits: |
52 | * David Woodhouse for adding multichip support | 52 | * David Woodhouse for adding multichip support |
53 | * | 53 | * |
54 | * Aleph One Ltd. and Toby Churchill Ltd. for supporting the | 54 | * Aleph One Ltd. and Toby Churchill Ltd. for supporting the |
55 | * rework for 2K page size chips | 55 | * rework for 2K page size chips |
56 | * | 56 | * |
@@ -105,8 +105,8 @@ static struct nand_oobinfo nand_oob_64 = { | |||
105 | .useecc = MTD_NANDECC_AUTOPLACE, | 105 | .useecc = MTD_NANDECC_AUTOPLACE, |
106 | .eccbytes = 24, | 106 | .eccbytes = 24, |
107 | .eccpos = { | 107 | .eccpos = { |
108 | 40, 41, 42, 43, 44, 45, 46, 47, | 108 | 40, 41, 42, 43, 44, 45, 46, 47, |
109 | 48, 49, 50, 51, 52, 53, 54, 55, | 109 | 48, 49, 50, 51, 52, 53, 54, 55, |
110 | 56, 57, 58, 59, 60, 61, 62, 63}, | 110 | 56, 57, 58, 59, 60, 61, 62, 63}, |
111 | .oobfree = { {2, 38} } | 111 | .oobfree = { {2, 38} } |
112 | }; | 112 | }; |
@@ -149,19 +149,19 @@ static void nand_sync (struct mtd_info *mtd); | |||
149 | static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf, | 149 | static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf, |
150 | struct nand_oobinfo *oobsel, int mode); | 150 | struct nand_oobinfo *oobsel, int mode); |
151 | #ifdef CONFIG_MTD_NAND_VERIFY_WRITE | 151 | #ifdef CONFIG_MTD_NAND_VERIFY_WRITE |
152 | static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages, | 152 | static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages, |
153 | u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode); | 153 | u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode); |
154 | #else | 154 | #else |
155 | #define nand_verify_pages(...) (0) | 155 | #define nand_verify_pages(...) (0) |
156 | #endif | 156 | #endif |
157 | 157 | ||
158 | static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state); | 158 | static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state); |
159 | 159 | ||
160 | /** | 160 | /** |
161 | * nand_release_device - [GENERIC] release chip | 161 | * nand_release_device - [GENERIC] release chip |
162 | * @mtd: MTD device structure | 162 | * @mtd: MTD device structure |
163 | * | 163 | * |
164 | * Deselect, release chip lock and wake up anyone waiting on the device | 164 | * Deselect, release chip lock and wake up anyone waiting on the device |
165 | */ | 165 | */ |
166 | static void nand_release_device (struct mtd_info *mtd) | 166 | static void nand_release_device (struct mtd_info *mtd) |
167 | { | 167 | { |
@@ -215,7 +215,7 @@ static void nand_write_byte(struct mtd_info *mtd, u_char byte) | |||
215 | * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip | 215 | * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip |
216 | * @mtd: MTD device structure | 216 | * @mtd: MTD device structure |
217 | * | 217 | * |
218 | * Default read function for 16bit buswith with | 218 | * Default read function for 16bit buswith with |
219 | * endianess conversion | 219 | * endianess conversion |
220 | */ | 220 | */ |
221 | static u_char nand_read_byte16(struct mtd_info *mtd) | 221 | static u_char nand_read_byte16(struct mtd_info *mtd) |
@@ -242,7 +242,7 @@ static void nand_write_byte16(struct mtd_info *mtd, u_char byte) | |||
242 | * nand_read_word - [DEFAULT] read one word from the chip | 242 | * nand_read_word - [DEFAULT] read one word from the chip |
243 | * @mtd: MTD device structure | 243 | * @mtd: MTD device structure |
244 | * | 244 | * |
245 | * Default read function for 16bit buswith without | 245 | * Default read function for 16bit buswith without |
246 | * endianess conversion | 246 | * endianess conversion |
247 | */ | 247 | */ |
248 | static u16 nand_read_word(struct mtd_info *mtd) | 248 | static u16 nand_read_word(struct mtd_info *mtd) |
@@ -256,7 +256,7 @@ static u16 nand_read_word(struct mtd_info *mtd) | |||
256 | * @mtd: MTD device structure | 256 | * @mtd: MTD device structure |
257 | * @word: data word to write | 257 | * @word: data word to write |
258 | * | 258 | * |
259 | * Default write function for 16bit buswith without | 259 | * Default write function for 16bit buswith without |
260 | * endianess conversion | 260 | * endianess conversion |
261 | */ | 261 | */ |
262 | static void nand_write_word(struct mtd_info *mtd, u16 word) | 262 | static void nand_write_word(struct mtd_info *mtd, u16 word) |
@@ -277,7 +277,7 @@ static void nand_select_chip(struct mtd_info *mtd, int chip) | |||
277 | struct nand_chip *this = mtd->priv; | 277 | struct nand_chip *this = mtd->priv; |
278 | switch(chip) { | 278 | switch(chip) { |
279 | case -1: | 279 | case -1: |
280 | this->hwcontrol(mtd, NAND_CTL_CLRNCE); | 280 | this->hwcontrol(mtd, NAND_CTL_CLRNCE); |
281 | break; | 281 | break; |
282 | case 0: | 282 | case 0: |
283 | this->hwcontrol(mtd, NAND_CTL_SETNCE); | 283 | this->hwcontrol(mtd, NAND_CTL_SETNCE); |
@@ -306,7 +306,7 @@ static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) | |||
306 | } | 306 | } |
307 | 307 | ||
308 | /** | 308 | /** |
309 | * nand_read_buf - [DEFAULT] read chip data into buffer | 309 | * nand_read_buf - [DEFAULT] read chip data into buffer |
310 | * @mtd: MTD device structure | 310 | * @mtd: MTD device structure |
311 | * @buf: buffer to store date | 311 | * @buf: buffer to store date |
312 | * @len: number of bytes to read | 312 | * @len: number of bytes to read |
@@ -323,7 +323,7 @@ static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) | |||
323 | } | 323 | } |
324 | 324 | ||
325 | /** | 325 | /** |
326 | * nand_verify_buf - [DEFAULT] Verify chip data against buffer | 326 | * nand_verify_buf - [DEFAULT] Verify chip data against buffer |
327 | * @mtd: MTD device structure | 327 | * @mtd: MTD device structure |
328 | * @buf: buffer containing the data to compare | 328 | * @buf: buffer containing the data to compare |
329 | * @len: number of bytes to compare | 329 | * @len: number of bytes to compare |
@@ -356,14 +356,14 @@ static void nand_write_buf16(struct mtd_info *mtd, const u_char *buf, int len) | |||
356 | struct nand_chip *this = mtd->priv; | 356 | struct nand_chip *this = mtd->priv; |
357 | u16 *p = (u16 *) buf; | 357 | u16 *p = (u16 *) buf; |
358 | len >>= 1; | 358 | len >>= 1; |
359 | 359 | ||
360 | for (i=0; i<len; i++) | 360 | for (i=0; i<len; i++) |
361 | writew(p[i], this->IO_ADDR_W); | 361 | writew(p[i], this->IO_ADDR_W); |
362 | 362 | ||
363 | } | 363 | } |
364 | 364 | ||
365 | /** | 365 | /** |
366 | * nand_read_buf16 - [DEFAULT] read chip data into buffer | 366 | * nand_read_buf16 - [DEFAULT] read chip data into buffer |
367 | * @mtd: MTD device structure | 367 | * @mtd: MTD device structure |
368 | * @buf: buffer to store date | 368 | * @buf: buffer to store date |
369 | * @len: number of bytes to read | 369 | * @len: number of bytes to read |
@@ -382,7 +382,7 @@ static void nand_read_buf16(struct mtd_info *mtd, u_char *buf, int len) | |||
382 | } | 382 | } |
383 | 383 | ||
384 | /** | 384 | /** |
385 | * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer | 385 | * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer |
386 | * @mtd: MTD device structure | 386 | * @mtd: MTD device structure |
387 | * @buf: buffer containing the data to compare | 387 | * @buf: buffer containing the data to compare |
388 | * @len: number of bytes to compare | 388 | * @len: number of bytes to compare |
@@ -409,7 +409,7 @@ static int nand_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len) | |||
409 | * @ofs: offset from device start | 409 | * @ofs: offset from device start |
410 | * @getchip: 0, if the chip is already selected | 410 | * @getchip: 0, if the chip is already selected |
411 | * | 411 | * |
412 | * Check, if the block is bad. | 412 | * Check, if the block is bad. |
413 | */ | 413 | */ |
414 | static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) | 414 | static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) |
415 | { | 415 | { |
@@ -426,8 +426,8 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) | |||
426 | 426 | ||
427 | /* Select the NAND device */ | 427 | /* Select the NAND device */ |
428 | this->select_chip(mtd, chipnr); | 428 | this->select_chip(mtd, chipnr); |
429 | } else | 429 | } else |
430 | page = (int) ofs; | 430 | page = (int) ofs; |
431 | 431 | ||
432 | if (this->options & NAND_BUSWIDTH_16) { | 432 | if (this->options & NAND_BUSWIDTH_16) { |
433 | this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page & this->pagemask); | 433 | this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page & this->pagemask); |
@@ -441,12 +441,12 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) | |||
441 | if (this->read_byte(mtd) != 0xff) | 441 | if (this->read_byte(mtd) != 0xff) |
442 | res = 1; | 442 | res = 1; |
443 | } | 443 | } |
444 | 444 | ||
445 | if (getchip) { | 445 | if (getchip) { |
446 | /* Deselect and wake up anyone waiting on the device */ | 446 | /* Deselect and wake up anyone waiting on the device */ |
447 | nand_release_device(mtd); | 447 | nand_release_device(mtd); |
448 | } | 448 | } |
449 | 449 | ||
450 | return res; | 450 | return res; |
451 | } | 451 | } |
452 | 452 | ||
@@ -464,7 +464,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) | |||
464 | u_char buf[2] = {0, 0}; | 464 | u_char buf[2] = {0, 0}; |
465 | size_t retlen; | 465 | size_t retlen; |
466 | int block; | 466 | int block; |
467 | 467 | ||
468 | /* Get block number */ | 468 | /* Get block number */ |
469 | block = ((int) ofs) >> this->bbt_erase_shift; | 469 | block = ((int) ofs) >> this->bbt_erase_shift; |
470 | if (this->bbt) | 470 | if (this->bbt) |
@@ -473,25 +473,25 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) | |||
473 | /* Do we have a flash based bad block table ? */ | 473 | /* Do we have a flash based bad block table ? */ |
474 | if (this->options & NAND_USE_FLASH_BBT) | 474 | if (this->options & NAND_USE_FLASH_BBT) |
475 | return nand_update_bbt (mtd, ofs); | 475 | return nand_update_bbt (mtd, ofs); |
476 | 476 | ||
477 | /* We write two bytes, so we dont have to mess with 16 bit access */ | 477 | /* We write two bytes, so we dont have to mess with 16 bit access */ |
478 | ofs += mtd->oobsize + (this->badblockpos & ~0x01); | 478 | ofs += mtd->oobsize + (this->badblockpos & ~0x01); |
479 | return nand_write_oob (mtd, ofs , 2, &retlen, buf); | 479 | return nand_write_oob (mtd, ofs , 2, &retlen, buf); |
480 | } | 480 | } |
481 | 481 | ||
482 | /** | 482 | /** |
483 | * nand_check_wp - [GENERIC] check if the chip is write protected | 483 | * nand_check_wp - [GENERIC] check if the chip is write protected |
484 | * @mtd: MTD device structure | 484 | * @mtd: MTD device structure |
485 | * Check, if the device is write protected | 485 | * Check, if the device is write protected |
486 | * | 486 | * |
487 | * The function expects, that the device is already selected | 487 | * The function expects, that the device is already selected |
488 | */ | 488 | */ |
489 | static int nand_check_wp (struct mtd_info *mtd) | 489 | static int nand_check_wp (struct mtd_info *mtd) |
490 | { | 490 | { |
491 | struct nand_chip *this = mtd->priv; | 491 | struct nand_chip *this = mtd->priv; |
492 | /* Check the WP bit */ | 492 | /* Check the WP bit */ |
493 | this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); | 493 | this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); |
494 | return (this->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1; | 494 | return (this->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1; |
495 | } | 495 | } |
496 | 496 | ||
497 | /** | 497 | /** |
@@ -507,15 +507,15 @@ static int nand_check_wp (struct mtd_info *mtd) | |||
507 | static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt) | 507 | static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt) |
508 | { | 508 | { |
509 | struct nand_chip *this = mtd->priv; | 509 | struct nand_chip *this = mtd->priv; |
510 | 510 | ||
511 | if (!this->bbt) | 511 | if (!this->bbt) |
512 | return this->block_bad(mtd, ofs, getchip); | 512 | return this->block_bad(mtd, ofs, getchip); |
513 | 513 | ||
514 | /* Return info from the table */ | 514 | /* Return info from the table */ |
515 | return nand_isbad_bbt (mtd, ofs, allowbbt); | 515 | return nand_isbad_bbt (mtd, ofs, allowbbt); |
516 | } | 516 | } |
517 | 517 | ||
518 | /* | 518 | /* |
519 | * Wait for the ready pin, after a command | 519 | * Wait for the ready pin, after a command |
520 | * The timeout is catched later. | 520 | * The timeout is catched later. |
521 | */ | 521 | */ |
@@ -529,7 +529,7 @@ static void nand_wait_ready(struct mtd_info *mtd) | |||
529 | if (this->dev_ready(mtd)) | 529 | if (this->dev_ready(mtd)) |
530 | return; | 530 | return; |
531 | touch_softlockup_watchdog(); | 531 | touch_softlockup_watchdog(); |
532 | } while (time_before(jiffies, timeo)); | 532 | } while (time_before(jiffies, timeo)); |
533 | } | 533 | } |
534 | 534 | ||
535 | /** | 535 | /** |
@@ -592,13 +592,13 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in | |||
592 | /* Latch in address */ | 592 | /* Latch in address */ |
593 | this->hwcontrol(mtd, NAND_CTL_CLRALE); | 593 | this->hwcontrol(mtd, NAND_CTL_CLRALE); |
594 | } | 594 | } |
595 | 595 | ||
596 | /* | 596 | /* |
597 | * program and erase have their own busy handlers | 597 | * program and erase have their own busy handlers |
598 | * status and sequential in needs no delay | 598 | * status and sequential in needs no delay |
599 | */ | 599 | */ |
600 | switch (command) { | 600 | switch (command) { |
601 | 601 | ||
602 | case NAND_CMD_PAGEPROG: | 602 | case NAND_CMD_PAGEPROG: |
603 | case NAND_CMD_ERASE1: | 603 | case NAND_CMD_ERASE1: |
604 | case NAND_CMD_ERASE2: | 604 | case NAND_CMD_ERASE2: |
@@ -607,7 +607,7 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in | |||
607 | return; | 607 | return; |
608 | 608 | ||
609 | case NAND_CMD_RESET: | 609 | case NAND_CMD_RESET: |
610 | if (this->dev_ready) | 610 | if (this->dev_ready) |
611 | break; | 611 | break; |
612 | udelay(this->chip_delay); | 612 | udelay(this->chip_delay); |
613 | this->hwcontrol(mtd, NAND_CTL_SETCLE); | 613 | this->hwcontrol(mtd, NAND_CTL_SETCLE); |
@@ -616,16 +616,16 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in | |||
616 | while ( !(this->read_byte(mtd) & NAND_STATUS_READY)); | 616 | while ( !(this->read_byte(mtd) & NAND_STATUS_READY)); |
617 | return; | 617 | return; |
618 | 618 | ||
619 | /* This applies to read commands */ | 619 | /* This applies to read commands */ |
620 | default: | 620 | default: |
621 | /* | 621 | /* |
622 | * If we don't have access to the busy pin, we apply the given | 622 | * If we don't have access to the busy pin, we apply the given |
623 | * command delay | 623 | * command delay |
624 | */ | 624 | */ |
625 | if (!this->dev_ready) { | 625 | if (!this->dev_ready) { |
626 | udelay (this->chip_delay); | 626 | udelay (this->chip_delay); |
627 | return; | 627 | return; |
628 | } | 628 | } |
629 | } | 629 | } |
630 | /* Apply this short delay always to ensure that we do wait tWB in | 630 | /* Apply this short delay always to ensure that we do wait tWB in |
631 | * any case on any machine. */ | 631 | * any case on any machine. */ |
@@ -655,8 +655,8 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, | |||
655 | column += mtd->oobblock; | 655 | column += mtd->oobblock; |
656 | command = NAND_CMD_READ0; | 656 | command = NAND_CMD_READ0; |
657 | } | 657 | } |
658 | 658 | ||
659 | 659 | ||
660 | /* Begin command latch cycle */ | 660 | /* Begin command latch cycle */ |
661 | this->hwcontrol(mtd, NAND_CTL_SETCLE); | 661 | this->hwcontrol(mtd, NAND_CTL_SETCLE); |
662 | /* Write out the command to the device. */ | 662 | /* Write out the command to the device. */ |
@@ -674,7 +674,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, | |||
674 | column >>= 1; | 674 | column >>= 1; |
675 | this->write_byte(mtd, column & 0xff); | 675 | this->write_byte(mtd, column & 0xff); |
676 | this->write_byte(mtd, column >> 8); | 676 | this->write_byte(mtd, column >> 8); |
677 | } | 677 | } |
678 | if (page_addr != -1) { | 678 | if (page_addr != -1) { |
679 | this->write_byte(mtd, (unsigned char) (page_addr & 0xff)); | 679 | this->write_byte(mtd, (unsigned char) (page_addr & 0xff)); |
680 | this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff)); | 680 | this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff)); |
@@ -685,13 +685,13 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, | |||
685 | /* Latch in address */ | 685 | /* Latch in address */ |
686 | this->hwcontrol(mtd, NAND_CTL_CLRALE); | 686 | this->hwcontrol(mtd, NAND_CTL_CLRALE); |
687 | } | 687 | } |
688 | 688 | ||
689 | /* | 689 | /* |
690 | * program and erase have their own busy handlers | 690 | * program and erase have their own busy handlers |
691 | * status, sequential in, and deplete1 need no delay | 691 | * status, sequential in, and deplete1 need no delay |
692 | */ | 692 | */ |
693 | switch (command) { | 693 | switch (command) { |
694 | 694 | ||
695 | case NAND_CMD_CACHEDPROG: | 695 | case NAND_CMD_CACHEDPROG: |
696 | case NAND_CMD_PAGEPROG: | 696 | case NAND_CMD_PAGEPROG: |
697 | case NAND_CMD_ERASE1: | 697 | case NAND_CMD_ERASE1: |
@@ -701,7 +701,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, | |||
701 | case NAND_CMD_DEPLETE1: | 701 | case NAND_CMD_DEPLETE1: |
702 | return; | 702 | return; |
703 | 703 | ||
704 | /* | 704 | /* |
705 | * read error status commands require only a short delay | 705 | * read error status commands require only a short delay |
706 | */ | 706 | */ |
707 | case NAND_CMD_STATUS_ERROR: | 707 | case NAND_CMD_STATUS_ERROR: |
@@ -713,7 +713,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, | |||
713 | return; | 713 | return; |
714 | 714 | ||
715 | case NAND_CMD_RESET: | 715 | case NAND_CMD_RESET: |
716 | if (this->dev_ready) | 716 | if (this->dev_ready) |
717 | break; | 717 | break; |
718 | udelay(this->chip_delay); | 718 | udelay(this->chip_delay); |
719 | this->hwcontrol(mtd, NAND_CTL_SETCLE); | 719 | this->hwcontrol(mtd, NAND_CTL_SETCLE); |
@@ -730,17 +730,17 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, | |||
730 | /* End command latch cycle */ | 730 | /* End command latch cycle */ |
731 | this->hwcontrol(mtd, NAND_CTL_CLRCLE); | 731 | this->hwcontrol(mtd, NAND_CTL_CLRCLE); |
732 | /* Fall through into ready check */ | 732 | /* Fall through into ready check */ |
733 | 733 | ||
734 | /* This applies to read commands */ | 734 | /* This applies to read commands */ |
735 | default: | 735 | default: |
736 | /* | 736 | /* |
737 | * If we don't have access to the busy pin, we apply the given | 737 | * If we don't have access to the busy pin, we apply the given |
738 | * command delay | 738 | * command delay |
739 | */ | 739 | */ |
740 | if (!this->dev_ready) { | 740 | if (!this->dev_ready) { |
741 | udelay (this->chip_delay); | 741 | udelay (this->chip_delay); |
742 | return; | 742 | return; |
743 | } | 743 | } |
744 | } | 744 | } |
745 | 745 | ||
746 | /* Apply this short delay always to ensure that we do wait tWB in | 746 | /* Apply this short delay always to ensure that we do wait tWB in |
@@ -754,7 +754,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, | |||
754 | * nand_get_device - [GENERIC] Get chip for selected access | 754 | * nand_get_device - [GENERIC] Get chip for selected access |
755 | * @this: the nand chip descriptor | 755 | * @this: the nand chip descriptor |
756 | * @mtd: MTD device structure | 756 | * @mtd: MTD device structure |
757 | * @new_state: the state which is requested | 757 | * @new_state: the state which is requested |
758 | * | 758 | * |
759 | * Get the device and lock it for exclusive access | 759 | * Get the device and lock it for exclusive access |
760 | */ | 760 | */ |
@@ -802,7 +802,7 @@ retry: | |||
802 | * @state: state to select the max. timeout value | 802 | * @state: state to select the max. timeout value |
803 | * | 803 | * |
804 | * Wait for command done. This applies to erase and program only | 804 | * Wait for command done. This applies to erase and program only |
805 | * Erase can take up to 400ms and program up to 20ms according to | 805 | * Erase can take up to 400ms and program up to 20ms according to |
806 | * general NAND and SmartMedia specs | 806 | * general NAND and SmartMedia specs |
807 | * | 807 | * |
808 | */ | 808 | */ |
@@ -811,7 +811,7 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) | |||
811 | 811 | ||
812 | unsigned long timeo = jiffies; | 812 | unsigned long timeo = jiffies; |
813 | int status; | 813 | int status; |
814 | 814 | ||
815 | if (state == FL_ERASING) | 815 | if (state == FL_ERASING) |
816 | timeo += (HZ * 400) / 1000; | 816 | timeo += (HZ * 400) / 1000; |
817 | else | 817 | else |
@@ -823,17 +823,17 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) | |||
823 | 823 | ||
824 | if ((state == FL_ERASING) && (this->options & NAND_IS_AND)) | 824 | if ((state == FL_ERASING) && (this->options & NAND_IS_AND)) |
825 | this->cmdfunc (mtd, NAND_CMD_STATUS_MULTI, -1, -1); | 825 | this->cmdfunc (mtd, NAND_CMD_STATUS_MULTI, -1, -1); |
826 | else | 826 | else |
827 | this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); | 827 | this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); |
828 | 828 | ||
829 | while (time_before(jiffies, timeo)) { | 829 | while (time_before(jiffies, timeo)) { |
830 | /* Check, if we were interrupted */ | 830 | /* Check, if we were interrupted */ |
831 | if (this->state != state) | 831 | if (this->state != state) |
832 | return 0; | 832 | return 0; |
833 | 833 | ||
834 | if (this->dev_ready) { | 834 | if (this->dev_ready) { |
835 | if (this->dev_ready(mtd)) | 835 | if (this->dev_ready(mtd)) |
836 | break; | 836 | break; |
837 | } else { | 837 | } else { |
838 | if (this->read_byte(mtd) & NAND_STATUS_READY) | 838 | if (this->read_byte(mtd) & NAND_STATUS_READY) |
839 | break; | 839 | break; |
@@ -859,7 +859,7 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) | |||
859 | * | 859 | * |
860 | * Cached programming is not supported yet. | 860 | * Cached programming is not supported yet. |
861 | */ | 861 | */ |
862 | static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, | 862 | static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, |
863 | u_char *oob_buf, struct nand_oobinfo *oobsel, int cached) | 863 | u_char *oob_buf, struct nand_oobinfo *oobsel, int cached) |
864 | { | 864 | { |
865 | int i, status; | 865 | int i, status; |
@@ -868,10 +868,10 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa | |||
868 | int *oob_config = oobsel->eccpos; | 868 | int *oob_config = oobsel->eccpos; |
869 | int datidx = 0, eccidx = 0, eccsteps = this->eccsteps; | 869 | int datidx = 0, eccidx = 0, eccsteps = this->eccsteps; |
870 | int eccbytes = 0; | 870 | int eccbytes = 0; |
871 | 871 | ||
872 | /* FIXME: Enable cached programming */ | 872 | /* FIXME: Enable cached programming */ |
873 | cached = 0; | 873 | cached = 0; |
874 | 874 | ||
875 | /* Send command to begin auto page programming */ | 875 | /* Send command to begin auto page programming */ |
876 | this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page); | 876 | this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page); |
877 | 877 | ||
@@ -882,7 +882,7 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa | |||
882 | printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n"); | 882 | printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n"); |
883 | this->write_buf(mtd, this->data_poi, mtd->oobblock); | 883 | this->write_buf(mtd, this->data_poi, mtd->oobblock); |
884 | break; | 884 | break; |
885 | 885 | ||
886 | /* Software ecc 3/256, write all */ | 886 | /* Software ecc 3/256, write all */ |
887 | case NAND_ECC_SOFT: | 887 | case NAND_ECC_SOFT: |
888 | for (; eccsteps; eccsteps--) { | 888 | for (; eccsteps; eccsteps--) { |
@@ -911,11 +911,11 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa | |||
911 | } | 911 | } |
912 | break; | 912 | break; |
913 | } | 913 | } |
914 | 914 | ||
915 | /* Write out OOB data */ | 915 | /* Write out OOB data */ |
916 | if (this->options & NAND_HWECC_SYNDROME) | 916 | if (this->options & NAND_HWECC_SYNDROME) |
917 | this->write_buf(mtd, &oob_buf[oobsel->eccbytes], mtd->oobsize - oobsel->eccbytes); | 917 | this->write_buf(mtd, &oob_buf[oobsel->eccbytes], mtd->oobsize - oobsel->eccbytes); |
918 | else | 918 | else |
919 | this->write_buf(mtd, oob_buf, mtd->oobsize); | 919 | this->write_buf(mtd, oob_buf, mtd->oobsize); |
920 | 920 | ||
921 | /* Send command to actually program the data */ | 921 | /* Send command to actually program the data */ |
@@ -940,7 +940,7 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa | |||
940 | /* wait until cache is ready*/ | 940 | /* wait until cache is ready*/ |
941 | // status = this->waitfunc (mtd, this, FL_CACHEDRPG); | 941 | // status = this->waitfunc (mtd, this, FL_CACHEDRPG); |
942 | } | 942 | } |
943 | return 0; | 943 | return 0; |
944 | } | 944 | } |
945 | 945 | ||
946 | #ifdef CONFIG_MTD_NAND_VERIFY_WRITE | 946 | #ifdef CONFIG_MTD_NAND_VERIFY_WRITE |
@@ -956,19 +956,19 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa | |||
956 | * @oobmode: 1 = full buffer verify, 0 = ecc only | 956 | * @oobmode: 1 = full buffer verify, 0 = ecc only |
957 | * | 957 | * |
958 | * The NAND device assumes that it is always writing to a cleanly erased page. | 958 | * The NAND device assumes that it is always writing to a cleanly erased page. |
959 | * Hence, it performs its internal write verification only on bits that | 959 | * Hence, it performs its internal write verification only on bits that |
960 | * transitioned from 1 to 0. The device does NOT verify the whole page on a | 960 | * transitioned from 1 to 0. The device does NOT verify the whole page on a |
961 | * byte by byte basis. It is possible that the page was not completely erased | 961 | * byte by byte basis. It is possible that the page was not completely erased |
962 | * or the page is becoming unusable due to wear. The read with ECC would catch | 962 | * or the page is becoming unusable due to wear. The read with ECC would catch |
963 | * the error later when the ECC page check fails, but we would rather catch | 963 | * the error later when the ECC page check fails, but we would rather catch |
964 | * it early in the page write stage. Better to write no data than invalid data. | 964 | * it early in the page write stage. Better to write no data than invalid data. |
965 | */ | 965 | */ |
966 | static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages, | 966 | static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages, |
967 | u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode) | 967 | u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode) |
968 | { | 968 | { |
969 | int i, j, datidx = 0, oobofs = 0, res = -EIO; | 969 | int i, j, datidx = 0, oobofs = 0, res = -EIO; |
970 | int eccsteps = this->eccsteps; | 970 | int eccsteps = this->eccsteps; |
971 | int hweccbytes; | 971 | int hweccbytes; |
972 | u_char oobdata[64]; | 972 | u_char oobdata[64]; |
973 | 973 | ||
974 | hweccbytes = (this->options & NAND_HWECC_SYNDROME) ? (oobsel->eccbytes / eccsteps) : 0; | 974 | hweccbytes = (this->options & NAND_HWECC_SYNDROME) ? (oobsel->eccbytes / eccsteps) : 0; |
@@ -1008,7 +1008,7 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int | |||
1008 | 1008 | ||
1009 | if (oobsel->useecc != MTD_NANDECC_OFF && !hweccbytes) { | 1009 | if (oobsel->useecc != MTD_NANDECC_OFF && !hweccbytes) { |
1010 | int ecccnt = oobsel->eccbytes; | 1010 | int ecccnt = oobsel->eccbytes; |
1011 | 1011 | ||
1012 | for (i = 0; i < ecccnt; i++) { | 1012 | for (i = 0; i < ecccnt; i++) { |
1013 | int idx = oobsel->eccpos[i]; | 1013 | int idx = oobsel->eccpos[i]; |
1014 | if (oobdata[idx] != oob_buf[oobofs + idx] ) { | 1014 | if (oobdata[idx] != oob_buf[oobofs + idx] ) { |
@@ -1018,20 +1018,20 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int | |||
1018 | goto out; | 1018 | goto out; |
1019 | } | 1019 | } |
1020 | } | 1020 | } |
1021 | } | 1021 | } |
1022 | } | 1022 | } |
1023 | oobofs += mtd->oobsize - hweccbytes * eccsteps; | 1023 | oobofs += mtd->oobsize - hweccbytes * eccsteps; |
1024 | page++; | 1024 | page++; |
1025 | numpages--; | 1025 | numpages--; |
1026 | 1026 | ||
1027 | /* Apply delay or wait for ready/busy pin | 1027 | /* Apply delay or wait for ready/busy pin |
1028 | * Do this before the AUTOINCR check, so no problems | 1028 | * Do this before the AUTOINCR check, so no problems |
1029 | * arise if a chip which does auto increment | 1029 | * arise if a chip which does auto increment |
1030 | * is marked as NOAUTOINCR by the board driver. | 1030 | * is marked as NOAUTOINCR by the board driver. |
1031 | * Do this also before returning, so the chip is | 1031 | * Do this also before returning, so the chip is |
1032 | * ready for the next command. | 1032 | * ready for the next command. |
1033 | */ | 1033 | */ |
1034 | if (!this->dev_ready) | 1034 | if (!this->dev_ready) |
1035 | udelay (this->chip_delay); | 1035 | udelay (this->chip_delay); |
1036 | else | 1036 | else |
1037 | nand_wait_ready(mtd); | 1037 | nand_wait_ready(mtd); |
@@ -1039,17 +1039,17 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int | |||
1039 | /* All done, return happy */ | 1039 | /* All done, return happy */ |
1040 | if (!numpages) | 1040 | if (!numpages) |
1041 | return 0; | 1041 | return 0; |
1042 | 1042 | ||
1043 | 1043 | ||
1044 | /* Check, if the chip supports auto page increment */ | 1044 | /* Check, if the chip supports auto page increment */ |
1045 | if (!NAND_CANAUTOINCR(this)) | 1045 | if (!NAND_CANAUTOINCR(this)) |
1046 | this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page); | 1046 | this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page); |
1047 | } | 1047 | } |
1048 | /* | 1048 | /* |
1049 | * Terminate the read command. We come here in case of an error | 1049 | * Terminate the read command. We come here in case of an error |
1050 | * So we must issue a reset command. | 1050 | * So we must issue a reset command. |
1051 | */ | 1051 | */ |
1052 | out: | 1052 | out: |
1053 | this->cmdfunc (mtd, NAND_CMD_RESET, -1, -1); | 1053 | this->cmdfunc (mtd, NAND_CMD_RESET, -1, -1); |
1054 | return res; | 1054 | return res; |
1055 | } | 1055 | } |
@@ -1111,7 +1111,7 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, | |||
1111 | * NAND read with ECC | 1111 | * NAND read with ECC |
1112 | */ | 1112 | */ |
1113 | int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, | 1113 | int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, |
1114 | size_t * retlen, u_char * buf, u_char * oob_buf, | 1114 | size_t * retlen, u_char * buf, u_char * oob_buf, |
1115 | struct nand_oobinfo *oobsel, int flags) | 1115 | struct nand_oobinfo *oobsel, int flags) |
1116 | { | 1116 | { |
1117 | 1117 | ||
@@ -1145,7 +1145,7 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, | |||
1145 | /* Autoplace of oob data ? Use the default placement scheme */ | 1145 | /* Autoplace of oob data ? Use the default placement scheme */ |
1146 | if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) | 1146 | if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) |
1147 | oobsel = this->autooob; | 1147 | oobsel = this->autooob; |
1148 | 1148 | ||
1149 | eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE; | 1149 | eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE; |
1150 | oob_config = oobsel->eccpos; | 1150 | oob_config = oobsel->eccpos; |
1151 | 1151 | ||
@@ -1163,28 +1163,28 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, | |||
1163 | end = mtd->oobblock; | 1163 | end = mtd->oobblock; |
1164 | ecc = this->eccsize; | 1164 | ecc = this->eccsize; |
1165 | eccbytes = this->eccbytes; | 1165 | eccbytes = this->eccbytes; |
1166 | 1166 | ||
1167 | if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME)) | 1167 | if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME)) |
1168 | compareecc = 0; | 1168 | compareecc = 0; |
1169 | 1169 | ||
1170 | oobreadlen = mtd->oobsize; | 1170 | oobreadlen = mtd->oobsize; |
1171 | if (this->options & NAND_HWECC_SYNDROME) | 1171 | if (this->options & NAND_HWECC_SYNDROME) |
1172 | oobreadlen -= oobsel->eccbytes; | 1172 | oobreadlen -= oobsel->eccbytes; |
1173 | 1173 | ||
1174 | /* Loop until all data read */ | 1174 | /* Loop until all data read */ |
1175 | while (read < len) { | 1175 | while (read < len) { |
1176 | 1176 | ||
1177 | int aligned = (!col && (len - read) >= end); | 1177 | int aligned = (!col && (len - read) >= end); |
1178 | /* | 1178 | /* |
1179 | * If the read is not page aligned, we have to read into data buffer | 1179 | * If the read is not page aligned, we have to read into data buffer |
1180 | * due to ecc, else we read into return buffer direct | 1180 | * due to ecc, else we read into return buffer direct |
1181 | */ | 1181 | */ |
1182 | if (aligned) | 1182 | if (aligned) |
1183 | data_poi = &buf[read]; | 1183 | data_poi = &buf[read]; |
1184 | else | 1184 | else |
1185 | data_poi = this->data_buf; | 1185 | data_poi = this->data_buf; |
1186 | 1186 | ||
1187 | /* Check, if we have this page in the buffer | 1187 | /* Check, if we have this page in the buffer |
1188 | * | 1188 | * |
1189 | * FIXME: Make it work when we must provide oob data too, | 1189 | * FIXME: Make it work when we must provide oob data too, |
1190 | * check the usage of data_buf oob field | 1190 | * check the usage of data_buf oob field |
@@ -1200,7 +1200,7 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, | |||
1200 | if (sndcmd) { | 1200 | if (sndcmd) { |
1201 | this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page); | 1201 | this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page); |
1202 | sndcmd = 0; | 1202 | sndcmd = 0; |
1203 | } | 1203 | } |
1204 | 1204 | ||
1205 | /* get oob area, if we have no oob buffer from fs-driver */ | 1205 | /* get oob area, if we have no oob buffer from fs-driver */ |
1206 | if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE || | 1206 | if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE || |
@@ -1208,7 +1208,7 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, | |||
1208 | oob_data = &this->data_buf[end]; | 1208 | oob_data = &this->data_buf[end]; |
1209 | 1209 | ||
1210 | eccsteps = this->eccsteps; | 1210 | eccsteps = this->eccsteps; |
1211 | 1211 | ||
1212 | switch (eccmode) { | 1212 | switch (eccmode) { |
1213 | case NAND_ECC_NONE: { /* No ECC, Read in a page */ | 1213 | case NAND_ECC_NONE: { /* No ECC, Read in a page */ |
1214 | static unsigned long lastwhinge = 0; | 1214 | static unsigned long lastwhinge = 0; |
@@ -1219,12 +1219,12 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, | |||
1219 | this->read_buf(mtd, data_poi, end); | 1219 | this->read_buf(mtd, data_poi, end); |
1220 | break; | 1220 | break; |
1221 | } | 1221 | } |
1222 | 1222 | ||
1223 | case NAND_ECC_SOFT: /* Software ECC 3/256: Read in a page + oob data */ | 1223 | case NAND_ECC_SOFT: /* Software ECC 3/256: Read in a page + oob data */ |
1224 | this->read_buf(mtd, data_poi, end); | 1224 | this->read_buf(mtd, data_poi, end); |
1225 | for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc) | 1225 | for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc) |
1226 | this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]); | 1226 | this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]); |
1227 | break; | 1227 | break; |
1228 | 1228 | ||
1229 | default: | 1229 | default: |
1230 | for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) { | 1230 | for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) { |
@@ -1243,15 +1243,15 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, | |||
1243 | * does the error correction on the fly */ | 1243 | * does the error correction on the fly */ |
1244 | ecc_status = this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]); | 1244 | ecc_status = this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]); |
1245 | if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) { | 1245 | if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) { |
1246 | DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " | 1246 | DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " |
1247 | "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr); | 1247 | "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr); |
1248 | ecc_failed++; | 1248 | ecc_failed++; |
1249 | } | 1249 | } |
1250 | } else { | 1250 | } else { |
1251 | this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]); | 1251 | this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]); |
1252 | } | 1252 | } |
1253 | } | 1253 | } |
1254 | break; | 1254 | break; |
1255 | } | 1255 | } |
1256 | 1256 | ||
1257 | /* read oobdata */ | 1257 | /* read oobdata */ |
@@ -1259,8 +1259,8 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, | |||
1259 | 1259 | ||
1260 | /* Skip ECC check, if not requested (ECC_NONE or HW_ECC with syndromes) */ | 1260 | /* Skip ECC check, if not requested (ECC_NONE or HW_ECC with syndromes) */ |
1261 | if (!compareecc) | 1261 | if (!compareecc) |
1262 | goto readoob; | 1262 | goto readoob; |
1263 | 1263 | ||
1264 | /* Pick the ECC bytes out of the oob data */ | 1264 | /* Pick the ECC bytes out of the oob data */ |
1265 | for (j = 0; j < oobsel->eccbytes; j++) | 1265 | for (j = 0; j < oobsel->eccbytes; j++) |
1266 | ecc_code[j] = oob_data[oob_config[j]]; | 1266 | ecc_code[j] = oob_data[oob_config[j]]; |
@@ -1268,24 +1268,24 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, | |||
1268 | /* correct data, if neccecary */ | 1268 | /* correct data, if neccecary */ |
1269 | for (i = 0, j = 0, datidx = 0; i < this->eccsteps; i++, datidx += ecc) { | 1269 | for (i = 0, j = 0, datidx = 0; i < this->eccsteps; i++, datidx += ecc) { |
1270 | ecc_status = this->correct_data(mtd, &data_poi[datidx], &ecc_code[j], &ecc_calc[j]); | 1270 | ecc_status = this->correct_data(mtd, &data_poi[datidx], &ecc_code[j], &ecc_calc[j]); |
1271 | 1271 | ||
1272 | /* Get next chunk of ecc bytes */ | 1272 | /* Get next chunk of ecc bytes */ |
1273 | j += eccbytes; | 1273 | j += eccbytes; |
1274 | 1274 | ||
1275 | /* Check, if we have a fs supplied oob-buffer, | 1275 | /* Check, if we have a fs supplied oob-buffer, |
1276 | * This is the legacy mode. Used by YAFFS1 | 1276 | * This is the legacy mode. Used by YAFFS1 |
1277 | * Should go away some day | 1277 | * Should go away some day |
1278 | */ | 1278 | */ |
1279 | if (oob_buf && oobsel->useecc == MTD_NANDECC_PLACE) { | 1279 | if (oob_buf && oobsel->useecc == MTD_NANDECC_PLACE) { |
1280 | int *p = (int *)(&oob_data[mtd->oobsize]); | 1280 | int *p = (int *)(&oob_data[mtd->oobsize]); |
1281 | p[i] = ecc_status; | 1281 | p[i] = ecc_status; |
1282 | } | 1282 | } |
1283 | 1283 | ||
1284 | if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) { | 1284 | if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) { |
1285 | DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page); | 1285 | DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page); |
1286 | ecc_failed++; | 1286 | ecc_failed++; |
1287 | } | 1287 | } |
1288 | } | 1288 | } |
1289 | 1289 | ||
1290 | readoob: | 1290 | readoob: |
1291 | /* check, if we have a fs supplied oob-buffer */ | 1291 | /* check, if we have a fs supplied oob-buffer */ |
@@ -1311,25 +1311,25 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, | |||
1311 | } | 1311 | } |
1312 | readdata: | 1312 | readdata: |
1313 | /* Partial page read, transfer data into fs buffer */ | 1313 | /* Partial page read, transfer data into fs buffer */ |
1314 | if (!aligned) { | 1314 | if (!aligned) { |
1315 | for (j = col; j < end && read < len; j++) | 1315 | for (j = col; j < end && read < len; j++) |
1316 | buf[read++] = data_poi[j]; | 1316 | buf[read++] = data_poi[j]; |
1317 | this->pagebuf = realpage; | 1317 | this->pagebuf = realpage; |
1318 | } else | 1318 | } else |
1319 | read += mtd->oobblock; | 1319 | read += mtd->oobblock; |
1320 | 1320 | ||
1321 | /* Apply delay or wait for ready/busy pin | 1321 | /* Apply delay or wait for ready/busy pin |
1322 | * Do this before the AUTOINCR check, so no problems | 1322 | * Do this before the AUTOINCR check, so no problems |
1323 | * arise if a chip which does auto increment | 1323 | * arise if a chip which does auto increment |
1324 | * is marked as NOAUTOINCR by the board driver. | 1324 | * is marked as NOAUTOINCR by the board driver. |
1325 | */ | 1325 | */ |
1326 | if (!this->dev_ready) | 1326 | if (!this->dev_ready) |
1327 | udelay (this->chip_delay); | 1327 | udelay (this->chip_delay); |
1328 | else | 1328 | else |
1329 | nand_wait_ready(mtd); | 1329 | nand_wait_ready(mtd); |
1330 | 1330 | ||
1331 | if (read == len) | 1331 | if (read == len) |
1332 | break; | 1332 | break; |
1333 | 1333 | ||
1334 | /* For subsequent reads align to page boundary. */ | 1334 | /* For subsequent reads align to page boundary. */ |
1335 | col = 0; | 1335 | col = 0; |
@@ -1343,11 +1343,11 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, | |||
1343 | this->select_chip(mtd, -1); | 1343 | this->select_chip(mtd, -1); |
1344 | this->select_chip(mtd, chipnr); | 1344 | this->select_chip(mtd, chipnr); |
1345 | } | 1345 | } |
1346 | /* Check, if the chip supports auto page increment | 1346 | /* Check, if the chip supports auto page increment |
1347 | * or if we have hit a block boundary. | 1347 | * or if we have hit a block boundary. |
1348 | */ | 1348 | */ |
1349 | if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) | 1349 | if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) |
1350 | sndcmd = 1; | 1350 | sndcmd = 1; |
1351 | } | 1351 | } |
1352 | 1352 | ||
1353 | /* Deselect and wake up anyone waiting on the device */ | 1353 | /* Deselect and wake up anyone waiting on the device */ |
@@ -1384,7 +1384,7 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t | |||
1384 | /* Shift to get page */ | 1384 | /* Shift to get page */ |
1385 | page = (int)(from >> this->page_shift); | 1385 | page = (int)(from >> this->page_shift); |
1386 | chipnr = (int)(from >> this->chip_shift); | 1386 | chipnr = (int)(from >> this->chip_shift); |
1387 | 1387 | ||
1388 | /* Mask to get column */ | 1388 | /* Mask to get column */ |
1389 | col = from & (mtd->oobsize - 1); | 1389 | col = from & (mtd->oobsize - 1); |
1390 | 1390 | ||
@@ -1406,7 +1406,7 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t | |||
1406 | 1406 | ||
1407 | /* Send the read command */ | 1407 | /* Send the read command */ |
1408 | this->cmdfunc (mtd, NAND_CMD_READOOB, col, page & this->pagemask); | 1408 | this->cmdfunc (mtd, NAND_CMD_READOOB, col, page & this->pagemask); |
1409 | /* | 1409 | /* |
1410 | * Read the data, if we read more than one page | 1410 | * Read the data, if we read more than one page |
1411 | * oob data, let the device transfer the data ! | 1411 | * oob data, let the device transfer the data ! |
1412 | */ | 1412 | */ |
@@ -1428,20 +1428,20 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t | |||
1428 | this->select_chip(mtd, -1); | 1428 | this->select_chip(mtd, -1); |
1429 | this->select_chip(mtd, chipnr); | 1429 | this->select_chip(mtd, chipnr); |
1430 | } | 1430 | } |
1431 | 1431 | ||
1432 | /* Apply delay or wait for ready/busy pin | 1432 | /* Apply delay or wait for ready/busy pin |
1433 | * Do this before the AUTOINCR check, so no problems | 1433 | * Do this before the AUTOINCR check, so no problems |
1434 | * arise if a chip which does auto increment | 1434 | * arise if a chip which does auto increment |
1435 | * is marked as NOAUTOINCR by the board driver. | 1435 | * is marked as NOAUTOINCR by the board driver. |
1436 | */ | 1436 | */ |
1437 | if (!this->dev_ready) | 1437 | if (!this->dev_ready) |
1438 | udelay (this->chip_delay); | 1438 | udelay (this->chip_delay); |
1439 | else | 1439 | else |
1440 | nand_wait_ready(mtd); | 1440 | nand_wait_ready(mtd); |
1441 | 1441 | ||
1442 | /* Check, if the chip supports auto page increment | 1442 | /* Check, if the chip supports auto page increment |
1443 | * or if we have hit a block boundary. | 1443 | * or if we have hit a block boundary. |
1444 | */ | 1444 | */ |
1445 | if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) { | 1445 | if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) { |
1446 | /* For subsequent page reads set offset to 0 */ | 1446 | /* For subsequent page reads set offset to 0 */ |
1447 | this->cmdfunc (mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask); | 1447 | this->cmdfunc (mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask); |
@@ -1487,27 +1487,27 @@ int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, | |||
1487 | nand_get_device (this, mtd , FL_READING); | 1487 | nand_get_device (this, mtd , FL_READING); |
1488 | 1488 | ||
1489 | this->select_chip (mtd, chip); | 1489 | this->select_chip (mtd, chip); |
1490 | 1490 | ||
1491 | /* Add requested oob length */ | 1491 | /* Add requested oob length */ |
1492 | len += ooblen; | 1492 | len += ooblen; |
1493 | 1493 | ||
1494 | while (len) { | 1494 | while (len) { |
1495 | if (sndcmd) | 1495 | if (sndcmd) |
1496 | this->cmdfunc (mtd, NAND_CMD_READ0, 0, page & this->pagemask); | 1496 | this->cmdfunc (mtd, NAND_CMD_READ0, 0, page & this->pagemask); |
1497 | sndcmd = 0; | 1497 | sndcmd = 0; |
1498 | 1498 | ||
1499 | this->read_buf (mtd, &buf[cnt], pagesize); | 1499 | this->read_buf (mtd, &buf[cnt], pagesize); |
1500 | 1500 | ||
1501 | len -= pagesize; | 1501 | len -= pagesize; |
1502 | cnt += pagesize; | 1502 | cnt += pagesize; |
1503 | page++; | 1503 | page++; |
1504 | 1504 | ||
1505 | if (!this->dev_ready) | 1505 | if (!this->dev_ready) |
1506 | udelay (this->chip_delay); | 1506 | udelay (this->chip_delay); |
1507 | else | 1507 | else |
1508 | nand_wait_ready(mtd); | 1508 | nand_wait_ready(mtd); |
1509 | 1509 | ||
1510 | /* Check, if the chip supports auto page increment */ | 1510 | /* Check, if the chip supports auto page increment */ |
1511 | if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) | 1511 | if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) |
1512 | sndcmd = 1; | 1512 | sndcmd = 1; |
1513 | } | 1513 | } |
@@ -1518,8 +1518,8 @@ int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, | |||
1518 | } | 1518 | } |
1519 | 1519 | ||
1520 | 1520 | ||
1521 | /** | 1521 | /** |
1522 | * nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer | 1522 | * nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer |
1523 | * @mtd: MTD device structure | 1523 | * @mtd: MTD device structure |
1524 | * @fsbuf: buffer given by fs driver | 1524 | * @fsbuf: buffer given by fs driver |
1525 | * @oobsel: out of band selection structre | 1525 | * @oobsel: out of band selection structre |
@@ -1548,20 +1548,20 @@ static u_char * nand_prepare_oobbuf (struct mtd_info *mtd, u_char *fsbuf, struct | |||
1548 | int i, len, ofs; | 1548 | int i, len, ofs; |
1549 | 1549 | ||
1550 | /* Zero copy fs supplied buffer */ | 1550 | /* Zero copy fs supplied buffer */ |
1551 | if (fsbuf && !autoplace) | 1551 | if (fsbuf && !autoplace) |
1552 | return fsbuf; | 1552 | return fsbuf; |
1553 | 1553 | ||
1554 | /* Check, if the buffer must be filled with ff again */ | 1554 | /* Check, if the buffer must be filled with ff again */ |
1555 | if (this->oobdirty) { | 1555 | if (this->oobdirty) { |
1556 | memset (this->oob_buf, 0xff, | 1556 | memset (this->oob_buf, 0xff, |
1557 | mtd->oobsize << (this->phys_erase_shift - this->page_shift)); | 1557 | mtd->oobsize << (this->phys_erase_shift - this->page_shift)); |
1558 | this->oobdirty = 0; | 1558 | this->oobdirty = 0; |
1559 | } | 1559 | } |
1560 | 1560 | ||
1561 | /* If we have no autoplacement or no fs buffer use the internal one */ | 1561 | /* If we have no autoplacement or no fs buffer use the internal one */ |
1562 | if (!autoplace || !fsbuf) | 1562 | if (!autoplace || !fsbuf) |
1563 | return this->oob_buf; | 1563 | return this->oob_buf; |
1564 | 1564 | ||
1565 | /* Walk through the pages and place the data */ | 1565 | /* Walk through the pages and place the data */ |
1566 | this->oobdirty = 1; | 1566 | this->oobdirty = 1; |
1567 | ofs = 0; | 1567 | ofs = 0; |
@@ -1595,7 +1595,7 @@ static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * ret | |||
1595 | { | 1595 | { |
1596 | return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, NULL)); | 1596 | return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, NULL)); |
1597 | } | 1597 | } |
1598 | 1598 | ||
1599 | /** | 1599 | /** |
1600 | * nand_write_ecc - [MTD Interface] NAND write with ECC | 1600 | * nand_write_ecc - [MTD Interface] NAND write with ECC |
1601 | * @mtd: MTD device structure | 1601 | * @mtd: MTD device structure |
@@ -1628,7 +1628,7 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, | |||
1628 | return -EINVAL; | 1628 | return -EINVAL; |
1629 | } | 1629 | } |
1630 | 1630 | ||
1631 | /* reject writes, which are not page aligned */ | 1631 | /* reject writes, which are not page aligned */ |
1632 | if (NOTALIGNED (to) || NOTALIGNED(len)) { | 1632 | if (NOTALIGNED (to) || NOTALIGNED(len)) { |
1633 | printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n"); | 1633 | printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n"); |
1634 | return -EINVAL; | 1634 | return -EINVAL; |
@@ -1647,14 +1647,14 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, | |||
1647 | goto out; | 1647 | goto out; |
1648 | 1648 | ||
1649 | /* if oobsel is NULL, use chip defaults */ | 1649 | /* if oobsel is NULL, use chip defaults */ |
1650 | if (oobsel == NULL) | 1650 | if (oobsel == NULL) |
1651 | oobsel = &mtd->oobinfo; | 1651 | oobsel = &mtd->oobinfo; |
1652 | 1652 | ||
1653 | /* Autoplace of oob data ? Use the default placement scheme */ | 1653 | /* Autoplace of oob data ? Use the default placement scheme */ |
1654 | if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) { | 1654 | if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) { |
1655 | oobsel = this->autooob; | 1655 | oobsel = this->autooob; |
1656 | autoplace = 1; | 1656 | autoplace = 1; |
1657 | } | 1657 | } |
1658 | if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR) | 1658 | if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR) |
1659 | autoplace = 1; | 1659 | autoplace = 1; |
1660 | 1660 | ||
@@ -1662,9 +1662,9 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, | |||
1662 | totalpages = len >> this->page_shift; | 1662 | totalpages = len >> this->page_shift; |
1663 | page = (int) (to >> this->page_shift); | 1663 | page = (int) (to >> this->page_shift); |
1664 | /* Invalidate the page cache, if we write to the cached page */ | 1664 | /* Invalidate the page cache, if we write to the cached page */ |
1665 | if (page <= this->pagebuf && this->pagebuf < (page + totalpages)) | 1665 | if (page <= this->pagebuf && this->pagebuf < (page + totalpages)) |
1666 | this->pagebuf = -1; | 1666 | this->pagebuf = -1; |
1667 | 1667 | ||
1668 | /* Set it relative to chip */ | 1668 | /* Set it relative to chip */ |
1669 | page &= this->pagemask; | 1669 | page &= this->pagemask; |
1670 | startpage = page; | 1670 | startpage = page; |
@@ -1686,14 +1686,14 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, | |||
1686 | if (ret) { | 1686 | if (ret) { |
1687 | DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: write_page failed %d\n", ret); | 1687 | DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: write_page failed %d\n", ret); |
1688 | goto out; | 1688 | goto out; |
1689 | } | 1689 | } |
1690 | /* Next oob page */ | 1690 | /* Next oob page */ |
1691 | oob += mtd->oobsize; | 1691 | oob += mtd->oobsize; |
1692 | /* Update written bytes count */ | 1692 | /* Update written bytes count */ |
1693 | written += mtd->oobblock; | 1693 | written += mtd->oobblock; |
1694 | if (written == len) | 1694 | if (written == len) |
1695 | goto cmp; | 1695 | goto cmp; |
1696 | 1696 | ||
1697 | /* Increment page address */ | 1697 | /* Increment page address */ |
1698 | page++; | 1698 | page++; |
1699 | 1699 | ||
@@ -1704,13 +1704,13 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, | |||
1704 | if (!(page & (ppblock - 1))){ | 1704 | if (!(page & (ppblock - 1))){ |
1705 | int ofs; | 1705 | int ofs; |
1706 | this->data_poi = bufstart; | 1706 | this->data_poi = bufstart; |
1707 | ret = nand_verify_pages (mtd, this, startpage, | 1707 | ret = nand_verify_pages (mtd, this, startpage, |
1708 | page - startpage, | 1708 | page - startpage, |
1709 | oobbuf, oobsel, chipnr, (eccbuf != NULL)); | 1709 | oobbuf, oobsel, chipnr, (eccbuf != NULL)); |
1710 | if (ret) { | 1710 | if (ret) { |
1711 | DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret); | 1711 | DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret); |
1712 | goto out; | 1712 | goto out; |
1713 | } | 1713 | } |
1714 | *retlen = written; | 1714 | *retlen = written; |
1715 | 1715 | ||
1716 | ofs = autoplace ? mtd->oobavail : mtd->oobsize; | 1716 | ofs = autoplace ? mtd->oobavail : mtd->oobsize; |
@@ -1720,7 +1720,7 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, | |||
1720 | numpages = min (totalpages, ppblock); | 1720 | numpages = min (totalpages, ppblock); |
1721 | page &= this->pagemask; | 1721 | page &= this->pagemask; |
1722 | startpage = page; | 1722 | startpage = page; |
1723 | oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel, | 1723 | oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel, |
1724 | autoplace, numpages); | 1724 | autoplace, numpages); |
1725 | oob = 0; | 1725 | oob = 0; |
1726 | /* Check, if we cross a chip boundary */ | 1726 | /* Check, if we cross a chip boundary */ |
@@ -1738,7 +1738,7 @@ cmp: | |||
1738 | oobbuf, oobsel, chipnr, (eccbuf != NULL)); | 1738 | oobbuf, oobsel, chipnr, (eccbuf != NULL)); |
1739 | if (!ret) | 1739 | if (!ret) |
1740 | *retlen = written; | 1740 | *retlen = written; |
1741 | else | 1741 | else |
1742 | DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret); | 1742 | DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret); |
1743 | 1743 | ||
1744 | out: | 1744 | out: |
@@ -1798,7 +1798,7 @@ static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * | |||
1798 | /* Check, if it is write protected */ | 1798 | /* Check, if it is write protected */ |
1799 | if (nand_check_wp(mtd)) | 1799 | if (nand_check_wp(mtd)) |
1800 | goto out; | 1800 | goto out; |
1801 | 1801 | ||
1802 | /* Invalidate the page cache, if we write to the cached page */ | 1802 | /* Invalidate the page cache, if we write to the cached page */ |
1803 | if (page == this->pagebuf) | 1803 | if (page == this->pagebuf) |
1804 | this->pagebuf = -1; | 1804 | this->pagebuf = -1; |
@@ -1861,10 +1861,10 @@ out: | |||
1861 | * | 1861 | * |
1862 | * NAND write with kvec. This just calls the ecc function | 1862 | * NAND write with kvec. This just calls the ecc function |
1863 | */ | 1863 | */ |
1864 | static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, | 1864 | static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, |
1865 | loff_t to, size_t * retlen) | 1865 | loff_t to, size_t * retlen) |
1866 | { | 1866 | { |
1867 | return (nand_writev_ecc (mtd, vecs, count, to, retlen, NULL, NULL)); | 1867 | return (nand_writev_ecc (mtd, vecs, count, to, retlen, NULL, NULL)); |
1868 | } | 1868 | } |
1869 | 1869 | ||
1870 | /** | 1870 | /** |
@@ -1879,7 +1879,7 @@ static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned | |||
1879 | * | 1879 | * |
1880 | * NAND write with iovec with ecc | 1880 | * NAND write with iovec with ecc |
1881 | */ | 1881 | */ |
1882 | static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, | 1882 | static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, |
1883 | loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel) | 1883 | loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel) |
1884 | { | 1884 | { |
1885 | int i, page, len, total_len, ret = -EIO, written = 0, chipnr; | 1885 | int i, page, len, total_len, ret = -EIO, written = 0, chipnr; |
@@ -1905,7 +1905,7 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig | |||
1905 | return -EINVAL; | 1905 | return -EINVAL; |
1906 | } | 1906 | } |
1907 | 1907 | ||
1908 | /* reject writes, which are not page aligned */ | 1908 | /* reject writes, which are not page aligned */ |
1909 | if (NOTALIGNED (to) || NOTALIGNED(total_len)) { | 1909 | if (NOTALIGNED (to) || NOTALIGNED(total_len)) { |
1910 | printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n"); | 1910 | printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n"); |
1911 | return -EINVAL; | 1911 | return -EINVAL; |
@@ -1924,21 +1924,21 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig | |||
1924 | goto out; | 1924 | goto out; |
1925 | 1925 | ||
1926 | /* if oobsel is NULL, use chip defaults */ | 1926 | /* if oobsel is NULL, use chip defaults */ |
1927 | if (oobsel == NULL) | 1927 | if (oobsel == NULL) |
1928 | oobsel = &mtd->oobinfo; | 1928 | oobsel = &mtd->oobinfo; |
1929 | 1929 | ||
1930 | /* Autoplace of oob data ? Use the default placement scheme */ | 1930 | /* Autoplace of oob data ? Use the default placement scheme */ |
1931 | if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) { | 1931 | if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) { |
1932 | oobsel = this->autooob; | 1932 | oobsel = this->autooob; |
1933 | autoplace = 1; | 1933 | autoplace = 1; |
1934 | } | 1934 | } |
1935 | if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR) | 1935 | if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR) |
1936 | autoplace = 1; | 1936 | autoplace = 1; |
1937 | 1937 | ||
1938 | /* Setup start page */ | 1938 | /* Setup start page */ |
1939 | page = (int) (to >> this->page_shift); | 1939 | page = (int) (to >> this->page_shift); |
1940 | /* Invalidate the page cache, if we write to the cached page */ | 1940 | /* Invalidate the page cache, if we write to the cached page */ |
1941 | if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift)) | 1941 | if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift)) |
1942 | this->pagebuf = -1; | 1942 | this->pagebuf = -1; |
1943 | 1943 | ||
1944 | startpage = page & this->pagemask; | 1944 | startpage = page & this->pagemask; |
@@ -1962,10 +1962,10 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig | |||
1962 | oob = 0; | 1962 | oob = 0; |
1963 | for (i = 1; i <= numpages; i++) { | 1963 | for (i = 1; i <= numpages; i++) { |
1964 | /* Write one page. If this is the last page to write | 1964 | /* Write one page. If this is the last page to write |
1965 | * then use the real pageprogram command, else select | 1965 | * then use the real pageprogram command, else select |
1966 | * cached programming if supported by the chip. | 1966 | * cached programming if supported by the chip. |
1967 | */ | 1967 | */ |
1968 | ret = nand_write_page (mtd, this, page & this->pagemask, | 1968 | ret = nand_write_page (mtd, this, page & this->pagemask, |
1969 | &oobbuf[oob], oobsel, i != numpages); | 1969 | &oobbuf[oob], oobsel, i != numpages); |
1970 | if (ret) | 1970 | if (ret) |
1971 | goto out; | 1971 | goto out; |
@@ -1981,12 +1981,12 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig | |||
1981 | count--; | 1981 | count--; |
1982 | } | 1982 | } |
1983 | } else { | 1983 | } else { |
1984 | /* We must use the internal buffer, read data out of each | 1984 | /* We must use the internal buffer, read data out of each |
1985 | * tuple until we have a full page to write | 1985 | * tuple until we have a full page to write |
1986 | */ | 1986 | */ |
1987 | int cnt = 0; | 1987 | int cnt = 0; |
1988 | while (cnt < mtd->oobblock) { | 1988 | while (cnt < mtd->oobblock) { |
1989 | if (vecs->iov_base != NULL && vecs->iov_len) | 1989 | if (vecs->iov_base != NULL && vecs->iov_len) |
1990 | this->data_buf[cnt++] = ((u_char *) vecs->iov_base)[len++]; | 1990 | this->data_buf[cnt++] = ((u_char *) vecs->iov_base)[len++]; |
1991 | /* Check, if we have to switch to the next tuple */ | 1991 | /* Check, if we have to switch to the next tuple */ |
1992 | if (len >= (int) vecs->iov_len) { | 1992 | if (len >= (int) vecs->iov_len) { |
@@ -1995,10 +1995,10 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig | |||
1995 | count--; | 1995 | count--; |
1996 | } | 1996 | } |
1997 | } | 1997 | } |
1998 | this->pagebuf = page; | 1998 | this->pagebuf = page; |
1999 | this->data_poi = this->data_buf; | 1999 | this->data_poi = this->data_buf; |
2000 | bufstart = this->data_poi; | 2000 | bufstart = this->data_poi; |
2001 | numpages = 1; | 2001 | numpages = 1; |
2002 | oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages); | 2002 | oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages); |
2003 | ret = nand_write_page (mtd, this, page & this->pagemask, | 2003 | ret = nand_write_page (mtd, this, page & this->pagemask, |
2004 | oobbuf, oobsel, 0); | 2004 | oobbuf, oobsel, 0); |
@@ -2011,7 +2011,7 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig | |||
2011 | ret = nand_verify_pages (mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0); | 2011 | ret = nand_verify_pages (mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0); |
2012 | if (ret) | 2012 | if (ret) |
2013 | goto out; | 2013 | goto out; |
2014 | 2014 | ||
2015 | written += mtd->oobblock * numpages; | 2015 | written += mtd->oobblock * numpages; |
2016 | /* All done ? */ | 2016 | /* All done ? */ |
2017 | if (!count) | 2017 | if (!count) |
@@ -2079,7 +2079,7 @@ static int nand_erase (struct mtd_info *mtd, struct erase_info *instr) | |||
2079 | { | 2079 | { |
2080 | return nand_erase_nand (mtd, instr, 0); | 2080 | return nand_erase_nand (mtd, instr, 0); |
2081 | } | 2081 | } |
2082 | 2082 | ||
2083 | #define BBT_PAGE_MASK 0xffffff3f | 2083 | #define BBT_PAGE_MASK 0xffffff3f |
2084 | /** | 2084 | /** |
2085 | * nand_erase_intern - [NAND Interface] erase block(s) | 2085 | * nand_erase_intern - [NAND Interface] erase block(s) |
@@ -2161,14 +2161,14 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb | |||
2161 | instr->state = MTD_ERASE_FAILED; | 2161 | instr->state = MTD_ERASE_FAILED; |
2162 | goto erase_exit; | 2162 | goto erase_exit; |
2163 | } | 2163 | } |
2164 | 2164 | ||
2165 | /* Invalidate the page cache, if we erase the block which contains | 2165 | /* Invalidate the page cache, if we erase the block which contains |
2166 | the current cached page */ | 2166 | the current cached page */ |
2167 | if (page <= this->pagebuf && this->pagebuf < (page + pages_per_block)) | 2167 | if (page <= this->pagebuf && this->pagebuf < (page + pages_per_block)) |
2168 | this->pagebuf = -1; | 2168 | this->pagebuf = -1; |
2169 | 2169 | ||
2170 | this->erase_cmd (mtd, page & this->pagemask); | 2170 | this->erase_cmd (mtd, page & this->pagemask); |
2171 | 2171 | ||
2172 | status = this->waitfunc (mtd, this, FL_ERASING); | 2172 | status = this->waitfunc (mtd, this, FL_ERASING); |
2173 | 2173 | ||
2174 | /* See if operation failed and additional status checks are available */ | 2174 | /* See if operation failed and additional status checks are available */ |
@@ -2186,12 +2186,12 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb | |||
2186 | 2186 | ||
2187 | /* if BBT requires refresh, set the BBT rewrite flag to the page being erased */ | 2187 | /* if BBT requires refresh, set the BBT rewrite flag to the page being erased */ |
2188 | if (this->options & BBT_AUTO_REFRESH) { | 2188 | if (this->options & BBT_AUTO_REFRESH) { |
2189 | if (((page & BBT_PAGE_MASK) == bbt_masked_page) && | 2189 | if (((page & BBT_PAGE_MASK) == bbt_masked_page) && |
2190 | (page != this->bbt_td->pages[chipnr])) { | 2190 | (page != this->bbt_td->pages[chipnr])) { |
2191 | rewrite_bbt[chipnr] = (page << this->page_shift); | 2191 | rewrite_bbt[chipnr] = (page << this->page_shift); |
2192 | } | 2192 | } |
2193 | } | 2193 | } |
2194 | 2194 | ||
2195 | /* Increment page address and decrement length */ | 2195 | /* Increment page address and decrement length */ |
2196 | len -= (1 << this->phys_erase_shift); | 2196 | len -= (1 << this->phys_erase_shift); |
2197 | page += pages_per_block; | 2197 | page += pages_per_block; |
@@ -2202,7 +2202,7 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb | |||
2202 | this->select_chip(mtd, -1); | 2202 | this->select_chip(mtd, -1); |
2203 | this->select_chip(mtd, chipnr); | 2203 | this->select_chip(mtd, chipnr); |
2204 | 2204 | ||
2205 | /* if BBT requires refresh and BBT-PERCHIP, | 2205 | /* if BBT requires refresh and BBT-PERCHIP, |
2206 | * set the BBT page mask to see if this BBT should be rewritten */ | 2206 | * set the BBT page mask to see if this BBT should be rewritten */ |
2207 | if ((this->options & BBT_AUTO_REFRESH) && (this->bbt_td->options & NAND_BBT_PERCHIP)) { | 2207 | if ((this->options & BBT_AUTO_REFRESH) && (this->bbt_td->options & NAND_BBT_PERCHIP)) { |
2208 | bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK; | 2208 | bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK; |
@@ -2227,7 +2227,7 @@ erase_exit: | |||
2227 | for (chipnr = 0; chipnr < this->numchips; chipnr++) { | 2227 | for (chipnr = 0; chipnr < this->numchips; chipnr++) { |
2228 | if (rewrite_bbt[chipnr]) { | 2228 | if (rewrite_bbt[chipnr]) { |
2229 | /* update the BBT for chip */ | 2229 | /* update the BBT for chip */ |
2230 | DEBUG (MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt (%d:0x%0x 0x%0x)\n", | 2230 | DEBUG (MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt (%d:0x%0x 0x%0x)\n", |
2231 | chipnr, rewrite_bbt[chipnr], this->bbt_td->pages[chipnr]); | 2231 | chipnr, rewrite_bbt[chipnr], this->bbt_td->pages[chipnr]); |
2232 | nand_update_bbt (mtd, rewrite_bbt[chipnr]); | 2232 | nand_update_bbt (mtd, rewrite_bbt[chipnr]); |
2233 | } | 2233 | } |
@@ -2265,9 +2265,9 @@ static void nand_sync (struct mtd_info *mtd) | |||
2265 | static int nand_block_isbad (struct mtd_info *mtd, loff_t ofs) | 2265 | static int nand_block_isbad (struct mtd_info *mtd, loff_t ofs) |
2266 | { | 2266 | { |
2267 | /* Check for invalid offset */ | 2267 | /* Check for invalid offset */ |
2268 | if (ofs > mtd->size) | 2268 | if (ofs > mtd->size) |
2269 | return -EINVAL; | 2269 | return -EINVAL; |
2270 | 2270 | ||
2271 | return nand_block_checkbad (mtd, ofs, 1, 0); | 2271 | return nand_block_checkbad (mtd, ofs, 1, 0); |
2272 | } | 2272 | } |
2273 | 2273 | ||
@@ -2386,13 +2386,13 @@ int nand_scan (struct mtd_info *mtd, int maxchips) | |||
2386 | 2386 | ||
2387 | /* Print and store flash device information */ | 2387 | /* Print and store flash device information */ |
2388 | for (i = 0; nand_flash_ids[i].name != NULL; i++) { | 2388 | for (i = 0; nand_flash_ids[i].name != NULL; i++) { |
2389 | 2389 | ||
2390 | if (nand_dev_id != nand_flash_ids[i].id) | 2390 | if (nand_dev_id != nand_flash_ids[i].id) |
2391 | continue; | 2391 | continue; |
2392 | 2392 | ||
2393 | if (!mtd->name) mtd->name = nand_flash_ids[i].name; | 2393 | if (!mtd->name) mtd->name = nand_flash_ids[i].name; |
2394 | this->chipsize = nand_flash_ids[i].chipsize << 20; | 2394 | this->chipsize = nand_flash_ids[i].chipsize << 20; |
2395 | 2395 | ||
2396 | /* New devices have all the information in additional id bytes */ | 2396 | /* New devices have all the information in additional id bytes */ |
2397 | if (!nand_flash_ids[i].pagesize) { | 2397 | if (!nand_flash_ids[i].pagesize) { |
2398 | int extid; | 2398 | int extid; |
@@ -2411,7 +2411,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips) | |||
2411 | extid >>= 2; | 2411 | extid >>= 2; |
2412 | /* Get buswidth information */ | 2412 | /* Get buswidth information */ |
2413 | busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0; | 2413 | busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0; |
2414 | 2414 | ||
2415 | } else { | 2415 | } else { |
2416 | /* Old devices have this data hardcoded in the | 2416 | /* Old devices have this data hardcoded in the |
2417 | * device id table */ | 2417 | * device id table */ |
@@ -2431,23 +2431,23 @@ int nand_scan (struct mtd_info *mtd, int maxchips) | |||
2431 | * this correct ! */ | 2431 | * this correct ! */ |
2432 | if (busw != (this->options & NAND_BUSWIDTH_16)) { | 2432 | if (busw != (this->options & NAND_BUSWIDTH_16)) { |
2433 | printk (KERN_INFO "NAND device: Manufacturer ID:" | 2433 | printk (KERN_INFO "NAND device: Manufacturer ID:" |
2434 | " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, | 2434 | " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, |
2435 | nand_manuf_ids[maf_id].name , mtd->name); | 2435 | nand_manuf_ids[maf_id].name , mtd->name); |
2436 | printk (KERN_WARNING | 2436 | printk (KERN_WARNING |
2437 | "NAND bus width %d instead %d bit\n", | 2437 | "NAND bus width %d instead %d bit\n", |
2438 | (this->options & NAND_BUSWIDTH_16) ? 16 : 8, | 2438 | (this->options & NAND_BUSWIDTH_16) ? 16 : 8, |
2439 | busw ? 16 : 8); | 2439 | busw ? 16 : 8); |
2440 | this->select_chip(mtd, -1); | 2440 | this->select_chip(mtd, -1); |
2441 | return 1; | 2441 | return 1; |
2442 | } | 2442 | } |
2443 | 2443 | ||
2444 | /* Calculate the address shift from the page size */ | 2444 | /* Calculate the address shift from the page size */ |
2445 | this->page_shift = ffs(mtd->oobblock) - 1; | 2445 | this->page_shift = ffs(mtd->oobblock) - 1; |
2446 | this->bbt_erase_shift = this->phys_erase_shift = ffs(mtd->erasesize) - 1; | 2446 | this->bbt_erase_shift = this->phys_erase_shift = ffs(mtd->erasesize) - 1; |
2447 | this->chip_shift = ffs(this->chipsize) - 1; | 2447 | this->chip_shift = ffs(this->chipsize) - 1; |
2448 | 2448 | ||
2449 | /* Set the bad block position */ | 2449 | /* Set the bad block position */ |
2450 | this->badblockpos = mtd->oobblock > 512 ? | 2450 | this->badblockpos = mtd->oobblock > 512 ? |
2451 | NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS; | 2451 | NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS; |
2452 | 2452 | ||
2453 | /* Get chip options, preserve non chip based options */ | 2453 | /* Get chip options, preserve non chip based options */ |
@@ -2457,10 +2457,10 @@ int nand_scan (struct mtd_info *mtd, int maxchips) | |||
2457 | this->options |= NAND_NO_AUTOINCR; | 2457 | this->options |= NAND_NO_AUTOINCR; |
2458 | /* Check if this is a not a samsung device. Do not clear the options | 2458 | /* Check if this is a not a samsung device. Do not clear the options |
2459 | * for chips which are not having an extended id. | 2459 | * for chips which are not having an extended id. |
2460 | */ | 2460 | */ |
2461 | if (nand_maf_id != NAND_MFR_SAMSUNG && !nand_flash_ids[i].pagesize) | 2461 | if (nand_maf_id != NAND_MFR_SAMSUNG && !nand_flash_ids[i].pagesize) |
2462 | this->options &= ~NAND_SAMSUNG_LP_OPTIONS; | 2462 | this->options &= ~NAND_SAMSUNG_LP_OPTIONS; |
2463 | 2463 | ||
2464 | /* Check for AND chips with 4 page planes */ | 2464 | /* Check for AND chips with 4 page planes */ |
2465 | if (this->options & NAND_4PAGE_ARRAY) | 2465 | if (this->options & NAND_4PAGE_ARRAY) |
2466 | this->erase_cmd = multi_erase_cmd; | 2466 | this->erase_cmd = multi_erase_cmd; |
@@ -2470,9 +2470,9 @@ int nand_scan (struct mtd_info *mtd, int maxchips) | |||
2470 | /* Do not replace user supplied command function ! */ | 2470 | /* Do not replace user supplied command function ! */ |
2471 | if (mtd->oobblock > 512 && this->cmdfunc == nand_command) | 2471 | if (mtd->oobblock > 512 && this->cmdfunc == nand_command) |
2472 | this->cmdfunc = nand_command_lp; | 2472 | this->cmdfunc = nand_command_lp; |
2473 | 2473 | ||
2474 | printk (KERN_INFO "NAND device: Manufacturer ID:" | 2474 | printk (KERN_INFO "NAND device: Manufacturer ID:" |
2475 | " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, | 2475 | " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, |
2476 | nand_manuf_ids[maf_id].name , nand_flash_ids[i].name); | 2476 | nand_manuf_ids[maf_id].name , nand_flash_ids[i].name); |
2477 | break; | 2477 | break; |
2478 | } | 2478 | } |
@@ -2496,7 +2496,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips) | |||
2496 | } | 2496 | } |
2497 | if (i > 1) | 2497 | if (i > 1) |
2498 | printk(KERN_INFO "%d NAND chips detected\n", i); | 2498 | printk(KERN_INFO "%d NAND chips detected\n", i); |
2499 | 2499 | ||
2500 | /* Allocate buffers, if neccecary */ | 2500 | /* Allocate buffers, if neccecary */ |
2501 | if (!this->oob_buf) { | 2501 | if (!this->oob_buf) { |
2502 | size_t len; | 2502 | size_t len; |
@@ -2508,7 +2508,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips) | |||
2508 | } | 2508 | } |
2509 | this->options |= NAND_OOBBUF_ALLOC; | 2509 | this->options |= NAND_OOBBUF_ALLOC; |
2510 | } | 2510 | } |
2511 | 2511 | ||
2512 | if (!this->data_buf) { | 2512 | if (!this->data_buf) { |
2513 | size_t len; | 2513 | size_t len; |
2514 | len = mtd->oobblock + mtd->oobsize; | 2514 | len = mtd->oobblock + mtd->oobsize; |
@@ -2535,7 +2535,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips) | |||
2535 | if (!this->autooob) { | 2535 | if (!this->autooob) { |
2536 | /* Select the appropriate default oob placement scheme for | 2536 | /* Select the appropriate default oob placement scheme for |
2537 | * placement agnostic filesystems */ | 2537 | * placement agnostic filesystems */ |
2538 | switch (mtd->oobsize) { | 2538 | switch (mtd->oobsize) { |
2539 | case 8: | 2539 | case 8: |
2540 | this->autooob = &nand_oob_8; | 2540 | this->autooob = &nand_oob_8; |
2541 | break; | 2541 | break; |
@@ -2551,19 +2551,19 @@ int nand_scan (struct mtd_info *mtd, int maxchips) | |||
2551 | BUG(); | 2551 | BUG(); |
2552 | } | 2552 | } |
2553 | } | 2553 | } |
2554 | 2554 | ||
2555 | /* The number of bytes available for the filesystem to place fs dependend | 2555 | /* The number of bytes available for the filesystem to place fs dependend |
2556 | * oob data */ | 2556 | * oob data */ |
2557 | mtd->oobavail = 0; | 2557 | mtd->oobavail = 0; |
2558 | for (i = 0; this->autooob->oobfree[i][1]; i++) | 2558 | for (i = 0; this->autooob->oobfree[i][1]; i++) |
2559 | mtd->oobavail += this->autooob->oobfree[i][1]; | 2559 | mtd->oobavail += this->autooob->oobfree[i][1]; |
2560 | 2560 | ||
2561 | /* | 2561 | /* |
2562 | * check ECC mode, default to software | 2562 | * check ECC mode, default to software |
2563 | * if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize | 2563 | * if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize |
2564 | * fallback to software ECC | 2564 | * fallback to software ECC |
2565 | */ | 2565 | */ |
2566 | this->eccsize = 256; /* set default eccsize */ | 2566 | this->eccsize = 256; /* set default eccsize */ |
2567 | this->eccbytes = 3; | 2567 | this->eccbytes = 3; |
2568 | 2568 | ||
2569 | switch (this->eccmode) { | 2569 | switch (this->eccmode) { |
@@ -2578,56 +2578,56 @@ int nand_scan (struct mtd_info *mtd, int maxchips) | |||
2578 | this->eccsize = 2048; | 2578 | this->eccsize = 2048; |
2579 | break; | 2579 | break; |
2580 | 2580 | ||
2581 | case NAND_ECC_HW3_512: | 2581 | case NAND_ECC_HW3_512: |
2582 | case NAND_ECC_HW6_512: | 2582 | case NAND_ECC_HW6_512: |
2583 | case NAND_ECC_HW8_512: | 2583 | case NAND_ECC_HW8_512: |
2584 | if (mtd->oobblock == 256) { | 2584 | if (mtd->oobblock == 256) { |
2585 | printk (KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n"); | 2585 | printk (KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n"); |
2586 | this->eccmode = NAND_ECC_SOFT; | 2586 | this->eccmode = NAND_ECC_SOFT; |
2587 | this->calculate_ecc = nand_calculate_ecc; | 2587 | this->calculate_ecc = nand_calculate_ecc; |
2588 | this->correct_data = nand_correct_data; | 2588 | this->correct_data = nand_correct_data; |
2589 | } else | 2589 | } else |
2590 | this->eccsize = 512; /* set eccsize to 512 */ | 2590 | this->eccsize = 512; /* set eccsize to 512 */ |
2591 | break; | 2591 | break; |
2592 | 2592 | ||
2593 | case NAND_ECC_HW3_256: | 2593 | case NAND_ECC_HW3_256: |
2594 | break; | 2594 | break; |
2595 | 2595 | ||
2596 | case NAND_ECC_NONE: | 2596 | case NAND_ECC_NONE: |
2597 | printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n"); | 2597 | printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n"); |
2598 | this->eccmode = NAND_ECC_NONE; | 2598 | this->eccmode = NAND_ECC_NONE; |
2599 | break; | 2599 | break; |
2600 | 2600 | ||
2601 | case NAND_ECC_SOFT: | 2601 | case NAND_ECC_SOFT: |
2602 | this->calculate_ecc = nand_calculate_ecc; | 2602 | this->calculate_ecc = nand_calculate_ecc; |
2603 | this->correct_data = nand_correct_data; | 2603 | this->correct_data = nand_correct_data; |
2604 | break; | 2604 | break; |
2605 | 2605 | ||
2606 | default: | 2606 | default: |
2607 | printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode); | 2607 | printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode); |
2608 | BUG(); | 2608 | BUG(); |
2609 | } | 2609 | } |
2610 | 2610 | ||
2611 | /* Check hardware ecc function availability and adjust number of ecc bytes per | 2611 | /* Check hardware ecc function availability and adjust number of ecc bytes per |
2612 | * calculation step | 2612 | * calculation step |
2613 | */ | 2613 | */ |
2614 | switch (this->eccmode) { | 2614 | switch (this->eccmode) { |
2615 | case NAND_ECC_HW12_2048: | 2615 | case NAND_ECC_HW12_2048: |
2616 | this->eccbytes += 4; | 2616 | this->eccbytes += 4; |
2617 | case NAND_ECC_HW8_512: | 2617 | case NAND_ECC_HW8_512: |
2618 | this->eccbytes += 2; | 2618 | this->eccbytes += 2; |
2619 | case NAND_ECC_HW6_512: | 2619 | case NAND_ECC_HW6_512: |
2620 | this->eccbytes += 3; | 2620 | this->eccbytes += 3; |
2621 | case NAND_ECC_HW3_512: | 2621 | case NAND_ECC_HW3_512: |
2622 | case NAND_ECC_HW3_256: | 2622 | case NAND_ECC_HW3_256: |
2623 | if (this->calculate_ecc && this->correct_data && this->enable_hwecc) | 2623 | if (this->calculate_ecc && this->correct_data && this->enable_hwecc) |
2624 | break; | 2624 | break; |
2625 | printk (KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n"); | 2625 | printk (KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n"); |
2626 | BUG(); | 2626 | BUG(); |
2627 | } | 2627 | } |
2628 | 2628 | ||
2629 | mtd->eccsize = this->eccsize; | 2629 | mtd->eccsize = this->eccsize; |
2630 | 2630 | ||
2631 | /* Set the number of read / write steps for one page to ensure ECC generation */ | 2631 | /* Set the number of read / write steps for one page to ensure ECC generation */ |
2632 | switch (this->eccmode) { | 2632 | switch (this->eccmode) { |
2633 | case NAND_ECC_HW12_2048: | 2633 | case NAND_ECC_HW12_2048: |
@@ -2639,15 +2639,15 @@ int nand_scan (struct mtd_info *mtd, int maxchips) | |||
2639 | this->eccsteps = mtd->oobblock / 512; | 2639 | this->eccsteps = mtd->oobblock / 512; |
2640 | break; | 2640 | break; |
2641 | case NAND_ECC_HW3_256: | 2641 | case NAND_ECC_HW3_256: |
2642 | case NAND_ECC_SOFT: | 2642 | case NAND_ECC_SOFT: |
2643 | this->eccsteps = mtd->oobblock / 256; | 2643 | this->eccsteps = mtd->oobblock / 256; |
2644 | break; | 2644 | break; |
2645 | 2645 | ||
2646 | case NAND_ECC_NONE: | 2646 | case NAND_ECC_NONE: |
2647 | this->eccsteps = 1; | 2647 | this->eccsteps = 1; |
2648 | break; | 2648 | break; |
2649 | } | 2649 | } |
2650 | 2650 | ||
2651 | /* Initialize state, waitqueue and spinlock */ | 2651 | /* Initialize state, waitqueue and spinlock */ |
2652 | this->state = FL_READY; | 2652 | this->state = FL_READY; |
2653 | init_waitqueue_head (&this->wq); | 2653 | init_waitqueue_head (&this->wq); |
@@ -2687,7 +2687,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips) | |||
2687 | memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo)); | 2687 | memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo)); |
2688 | 2688 | ||
2689 | mtd->owner = THIS_MODULE; | 2689 | mtd->owner = THIS_MODULE; |
2690 | 2690 | ||
2691 | /* Check, if we should skip the bad block table scan */ | 2691 | /* Check, if we should skip the bad block table scan */ |
2692 | if (this->options & NAND_SKIP_BBTSCAN) | 2692 | if (this->options & NAND_SKIP_BBTSCAN) |
2693 | return 0; | 2693 | return 0; |
@@ -2697,7 +2697,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips) | |||
2697 | } | 2697 | } |
2698 | 2698 | ||
2699 | /** | 2699 | /** |
2700 | * nand_release - [NAND Interface] Free resources held by the NAND device | 2700 | * nand_release - [NAND Interface] Free resources held by the NAND device |
2701 | * @mtd: MTD device structure | 2701 | * @mtd: MTD device structure |
2702 | */ | 2702 | */ |
2703 | void nand_release (struct mtd_info *mtd) | 2703 | void nand_release (struct mtd_info *mtd) |
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 7535ef53685e..ca286999fe08 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c | |||
@@ -3,10 +3,10 @@ | |||
3 | * | 3 | * |
4 | * Overview: | 4 | * Overview: |
5 | * Bad block table support for the NAND driver | 5 | * Bad block table support for the NAND driver |
6 | * | 6 | * |
7 | * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de) | 7 | * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de) |
8 | * | 8 | * |
9 | * $Id: nand_bbt.c,v 1.35 2005/07/15 13:53:47 gleixner Exp $ | 9 | * $Id: nand_bbt.c,v 1.36 2005/11/07 11:14:30 gleixner Exp $ |
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License version 2 as | 12 | * it under the terms of the GNU General Public License version 2 as |
@@ -14,23 +14,23 @@ | |||
14 | * | 14 | * |
15 | * Description: | 15 | * Description: |
16 | * | 16 | * |
17 | * When nand_scan_bbt is called, then it tries to find the bad block table | 17 | * When nand_scan_bbt is called, then it tries to find the bad block table |
18 | * depending on the options in the bbt descriptor(s). If a bbt is found | 18 | * depending on the options in the bbt descriptor(s). If a bbt is found |
19 | * then the contents are read and the memory based bbt is created. If a | 19 | * then the contents are read and the memory based bbt is created. If a |
20 | * mirrored bbt is selected then the mirror is searched too and the | 20 | * mirrored bbt is selected then the mirror is searched too and the |
21 | * versions are compared. If the mirror has a greater version number | 21 | * versions are compared. If the mirror has a greater version number |
22 | * than the mirror bbt is used to build the memory based bbt. | 22 | * than the mirror bbt is used to build the memory based bbt. |
23 | * If the tables are not versioned, then we "or" the bad block information. | 23 | * If the tables are not versioned, then we "or" the bad block information. |
24 | * If one of the bbt's is out of date or does not exist it is (re)created. | 24 | * If one of the bbt's is out of date or does not exist it is (re)created. |
25 | * If no bbt exists at all then the device is scanned for factory marked | 25 | * If no bbt exists at all then the device is scanned for factory marked |
26 | * good / bad blocks and the bad block tables are created. | 26 | * good / bad blocks and the bad block tables are created. |
27 | * | 27 | * |
28 | * For manufacturer created bbts like the one found on M-SYS DOC devices | 28 | * For manufacturer created bbts like the one found on M-SYS DOC devices |
29 | * the bbt is searched and read but never created | 29 | * the bbt is searched and read but never created |
30 | * | 30 | * |
31 | * The autogenerated bad block table is located in the last good blocks | 31 | * The autogenerated bad block table is located in the last good blocks |
32 | * of the device. The table is mirrored, so it can be updated eventually. | 32 | * of the device. The table is mirrored, so it can be updated eventually. |
33 | * The table is marked in the oob area with an ident pattern and a version | 33 | * The table is marked in the oob area with an ident pattern and a version |
34 | * number which indicates which of both tables is more up to date. | 34 | * number which indicates which of both tables is more up to date. |
35 | * | 35 | * |
36 | * The table uses 2 bits per block | 36 | * The table uses 2 bits per block |
@@ -43,13 +43,13 @@ | |||
43 | * 01b: block is marked bad due to wear | 43 | * 01b: block is marked bad due to wear |
44 | * 10b: block is reserved (to protect the bbt area) | 44 | * 10b: block is reserved (to protect the bbt area) |
45 | * 11b: block is factory marked bad | 45 | * 11b: block is factory marked bad |
46 | * | 46 | * |
47 | * Multichip devices like DOC store the bad block info per floor. | 47 | * Multichip devices like DOC store the bad block info per floor. |
48 | * | 48 | * |
49 | * Following assumptions are made: | 49 | * Following assumptions are made: |
50 | * - bbts start at a page boundary, if autolocated on a block boundary | 50 | * - bbts start at a page boundary, if autolocated on a block boundary |
51 | * - the space neccecary for a bbt in FLASH does not exceed a block boundary | 51 | * - the space neccecary for a bbt in FLASH does not exceed a block boundary |
52 | * | 52 | * |
53 | */ | 53 | */ |
54 | 54 | ||
55 | #include <linux/slab.h> | 55 | #include <linux/slab.h> |
@@ -62,7 +62,7 @@ | |||
62 | #include <linux/delay.h> | 62 | #include <linux/delay.h> |
63 | 63 | ||
64 | 64 | ||
65 | /** | 65 | /** |
66 | * check_pattern - [GENERIC] check if a pattern is in the buffer | 66 | * check_pattern - [GENERIC] check if a pattern is in the buffer |
67 | * @buf: the buffer to search | 67 | * @buf: the buffer to search |
68 | * @len: the length of buffer to search | 68 | * @len: the length of buffer to search |
@@ -86,9 +86,9 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des | |||
86 | if (p[i] != 0xff) | 86 | if (p[i] != 0xff) |
87 | return -1; | 87 | return -1; |
88 | } | 88 | } |
89 | } | 89 | } |
90 | p += end; | 90 | p += end; |
91 | 91 | ||
92 | /* Compare the pattern */ | 92 | /* Compare the pattern */ |
93 | for (i = 0; i < td->len; i++) { | 93 | for (i = 0; i < td->len; i++) { |
94 | if (p[i] != td->pattern[i]) | 94 | if (p[i] != td->pattern[i]) |
@@ -106,13 +106,13 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des | |||
106 | return 0; | 106 | return 0; |
107 | } | 107 | } |
108 | 108 | ||
109 | /** | 109 | /** |
110 | * check_short_pattern - [GENERIC] check if a pattern is in the buffer | 110 | * check_short_pattern - [GENERIC] check if a pattern is in the buffer |
111 | * @buf: the buffer to search | 111 | * @buf: the buffer to search |
112 | * @td: search pattern descriptor | 112 | * @td: search pattern descriptor |
113 | * | 113 | * |
114 | * Check for a pattern at the given place. Used to search bad block | 114 | * Check for a pattern at the given place. Used to search bad block |
115 | * tables and good / bad block identifiers. Same as check_pattern, but | 115 | * tables and good / bad block identifiers. Same as check_pattern, but |
116 | * no optional empty check | 116 | * no optional empty check |
117 | * | 117 | * |
118 | */ | 118 | */ |
@@ -142,7 +142,7 @@ static int check_short_pattern (uint8_t *buf, struct nand_bbt_descr *td) | |||
142 | * Read the bad block table starting from page. | 142 | * Read the bad block table starting from page. |
143 | * | 143 | * |
144 | */ | 144 | */ |
145 | static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num, | 145 | static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num, |
146 | int bits, int offs, int reserved_block_code) | 146 | int bits, int offs, int reserved_block_code) |
147 | { | 147 | { |
148 | int res, i, j, act = 0; | 148 | int res, i, j, act = 0; |
@@ -153,7 +153,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num, | |||
153 | 153 | ||
154 | totlen = (num * bits) >> 3; | 154 | totlen = (num * bits) >> 3; |
155 | from = ((loff_t)page) << this->page_shift; | 155 | from = ((loff_t)page) << this->page_shift; |
156 | 156 | ||
157 | while (totlen) { | 157 | while (totlen) { |
158 | len = min (totlen, (size_t) (1 << this->bbt_erase_shift)); | 158 | len = min (totlen, (size_t) (1 << this->bbt_erase_shift)); |
159 | res = mtd->read_ecc (mtd, from, len, &retlen, buf, NULL, this->autooob); | 159 | res = mtd->read_ecc (mtd, from, len, &retlen, buf, NULL, this->autooob); |
@@ -163,7 +163,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num, | |||
163 | return res; | 163 | return res; |
164 | } | 164 | } |
165 | printk (KERN_WARNING "nand_bbt: ECC error while reading bad block table\n"); | 165 | printk (KERN_WARNING "nand_bbt: ECC error while reading bad block table\n"); |
166 | } | 166 | } |
167 | 167 | ||
168 | /* Analyse data */ | 168 | /* Analyse data */ |
169 | for (i = 0; i < len; i++) { | 169 | for (i = 0; i < len; i++) { |
@@ -183,12 +183,12 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num, | |||
183 | * message to MTD_DEBUG_LEVEL0 */ | 183 | * message to MTD_DEBUG_LEVEL0 */ |
184 | printk (KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n", | 184 | printk (KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n", |
185 | ((offs << 2) + (act >> 1)) << this->bbt_erase_shift); | 185 | ((offs << 2) + (act >> 1)) << this->bbt_erase_shift); |
186 | /* Factory marked bad or worn out ? */ | 186 | /* Factory marked bad or worn out ? */ |
187 | if (tmp == 0) | 187 | if (tmp == 0) |
188 | this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06); | 188 | this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06); |
189 | else | 189 | else |
190 | this->bbt[offs + (act >> 3)] |= 0x1 << (act & 0x06); | 190 | this->bbt[offs + (act >> 3)] |= 0x1 << (act & 0x06); |
191 | } | 191 | } |
192 | } | 192 | } |
193 | totlen -= len; | 193 | totlen -= len; |
194 | from += len; | 194 | from += len; |
@@ -200,7 +200,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num, | |||
200 | * read_abs_bbt - [GENERIC] Read the bad block table starting at a given page | 200 | * read_abs_bbt - [GENERIC] Read the bad block table starting at a given page |
201 | * @mtd: MTD device structure | 201 | * @mtd: MTD device structure |
202 | * @buf: temporary buffer | 202 | * @buf: temporary buffer |
203 | * @td: descriptor for the bad block table | 203 | * @td: descriptor for the bad block table |
204 | * @chip: read the table for a specific chip, -1 read all chips. | 204 | * @chip: read the table for a specific chip, -1 read all chips. |
205 | * Applies only if NAND_BBT_PERCHIP option is set | 205 | * Applies only if NAND_BBT_PERCHIP option is set |
206 | * | 206 | * |
@@ -235,7 +235,7 @@ static int read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des | |||
235 | * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page | 235 | * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page |
236 | * @mtd: MTD device structure | 236 | * @mtd: MTD device structure |
237 | * @buf: temporary buffer | 237 | * @buf: temporary buffer |
238 | * @td: descriptor for the bad block table | 238 | * @td: descriptor for the bad block table |
239 | * @md: descriptor for the bad block table mirror | 239 | * @md: descriptor for the bad block table mirror |
240 | * | 240 | * |
241 | * Read the bad block table(s) for all chips starting at a given page | 241 | * Read the bad block table(s) for all chips starting at a given page |
@@ -247,16 +247,16 @@ static int read_abs_bbts (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_de | |||
247 | { | 247 | { |
248 | struct nand_chip *this = mtd->priv; | 248 | struct nand_chip *this = mtd->priv; |
249 | 249 | ||
250 | /* Read the primary version, if available */ | 250 | /* Read the primary version, if available */ |
251 | if (td->options & NAND_BBT_VERSION) { | 251 | if (td->options & NAND_BBT_VERSION) { |
252 | nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize); | 252 | nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize); |
253 | td->version[0] = buf[mtd->oobblock + td->veroffs]; | 253 | td->version[0] = buf[mtd->oobblock + td->veroffs]; |
254 | printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]); | 254 | printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]); |
255 | } | 255 | } |
256 | 256 | ||
257 | /* Read the mirror version, if available */ | 257 | /* Read the mirror version, if available */ |
258 | if (md && (md->options & NAND_BBT_VERSION)) { | 258 | if (md && (md->options & NAND_BBT_VERSION)) { |
259 | nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize); | 259 | nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize); |
260 | md->version[0] = buf[mtd->oobblock + md->veroffs]; | 260 | md->version[0] = buf[mtd->oobblock + md->veroffs]; |
261 | printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]); | 261 | printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]); |
262 | } | 262 | } |
@@ -290,7 +290,7 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr | |||
290 | else { | 290 | else { |
291 | if (bd->options & NAND_BBT_SCAN2NDPAGE) | 291 | if (bd->options & NAND_BBT_SCAN2NDPAGE) |
292 | len = 2; | 292 | len = 2; |
293 | else | 293 | else |
294 | len = 1; | 294 | len = 1; |
295 | } | 295 | } |
296 | 296 | ||
@@ -322,10 +322,10 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr | |||
322 | numblocks += startblock; | 322 | numblocks += startblock; |
323 | from = startblock << (this->bbt_erase_shift - 1); | 323 | from = startblock << (this->bbt_erase_shift - 1); |
324 | } | 324 | } |
325 | 325 | ||
326 | for (i = startblock; i < numblocks;) { | 326 | for (i = startblock; i < numblocks;) { |
327 | int ret; | 327 | int ret; |
328 | 328 | ||
329 | if (bd->options & NAND_BBT_SCANEMPTY) | 329 | if (bd->options & NAND_BBT_SCANEMPTY) |
330 | if ((ret = nand_read_raw (mtd, buf, from, readlen, ooblen))) | 330 | if ((ret = nand_read_raw (mtd, buf, from, readlen, ooblen))) |
331 | return ret; | 331 | return ret; |
@@ -333,8 +333,8 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr | |||
333 | for (j = 0; j < len; j++) { | 333 | for (j = 0; j < len; j++) { |
334 | if (!(bd->options & NAND_BBT_SCANEMPTY)) { | 334 | if (!(bd->options & NAND_BBT_SCANEMPTY)) { |
335 | size_t retlen; | 335 | size_t retlen; |
336 | 336 | ||
337 | /* Read the full oob until read_oob is fixed to | 337 | /* Read the full oob until read_oob is fixed to |
338 | * handle single byte reads for 16 bit buswidth */ | 338 | * handle single byte reads for 16 bit buswidth */ |
339 | ret = mtd->read_oob(mtd, from + j * mtd->oobblock, | 339 | ret = mtd->read_oob(mtd, from + j * mtd->oobblock, |
340 | mtd->oobsize, &retlen, buf); | 340 | mtd->oobsize, &retlen, buf); |
@@ -343,14 +343,14 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr | |||
343 | 343 | ||
344 | if (check_short_pattern (buf, bd)) { | 344 | if (check_short_pattern (buf, bd)) { |
345 | this->bbt[i >> 3] |= 0x03 << (i & 0x6); | 345 | this->bbt[i >> 3] |= 0x03 << (i & 0x6); |
346 | printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", | 346 | printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", |
347 | i >> 1, (unsigned int) from); | 347 | i >> 1, (unsigned int) from); |
348 | break; | 348 | break; |
349 | } | 349 | } |
350 | } else { | 350 | } else { |
351 | if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) { | 351 | if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) { |
352 | this->bbt[i >> 3] |= 0x03 << (i & 0x6); | 352 | this->bbt[i >> 3] |= 0x03 << (i & 0x6); |
353 | printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", | 353 | printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", |
354 | i >> 1, (unsigned int) from); | 354 | i >> 1, (unsigned int) from); |
355 | break; | 355 | break; |
356 | } | 356 | } |
@@ -369,15 +369,15 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr | |||
369 | * @td: descriptor for the bad block table | 369 | * @td: descriptor for the bad block table |
370 | * | 370 | * |
371 | * Read the bad block table by searching for a given ident pattern. | 371 | * Read the bad block table by searching for a given ident pattern. |
372 | * Search is preformed either from the beginning up or from the end of | 372 | * Search is preformed either from the beginning up or from the end of |
373 | * the device downwards. The search starts always at the start of a | 373 | * the device downwards. The search starts always at the start of a |
374 | * block. | 374 | * block. |
375 | * If the option NAND_BBT_PERCHIP is given, each chip is searched | 375 | * If the option NAND_BBT_PERCHIP is given, each chip is searched |
376 | * for a bbt, which contains the bad block information of this chip. | 376 | * for a bbt, which contains the bad block information of this chip. |
377 | * This is neccecary to provide support for certain DOC devices. | 377 | * This is neccecary to provide support for certain DOC devices. |
378 | * | 378 | * |
379 | * The bbt ident pattern resides in the oob area of the first page | 379 | * The bbt ident pattern resides in the oob area of the first page |
380 | * in a block. | 380 | * in a block. |
381 | */ | 381 | */ |
382 | static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td) | 382 | static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td) |
383 | { | 383 | { |
@@ -392,10 +392,10 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr | |||
392 | startblock = (mtd->size >> this->bbt_erase_shift) -1; | 392 | startblock = (mtd->size >> this->bbt_erase_shift) -1; |
393 | dir = -1; | 393 | dir = -1; |
394 | } else { | 394 | } else { |
395 | startblock = 0; | 395 | startblock = 0; |
396 | dir = 1; | 396 | dir = 1; |
397 | } | 397 | } |
398 | 398 | ||
399 | /* Do we have a bbt per chip ? */ | 399 | /* Do we have a bbt per chip ? */ |
400 | if (td->options & NAND_BBT_PERCHIP) { | 400 | if (td->options & NAND_BBT_PERCHIP) { |
401 | chips = this->numchips; | 401 | chips = this->numchips; |
@@ -405,19 +405,19 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr | |||
405 | chips = 1; | 405 | chips = 1; |
406 | bbtblocks = mtd->size >> this->bbt_erase_shift; | 406 | bbtblocks = mtd->size >> this->bbt_erase_shift; |
407 | } | 407 | } |
408 | 408 | ||
409 | /* Number of bits for each erase block in the bbt */ | 409 | /* Number of bits for each erase block in the bbt */ |
410 | bits = td->options & NAND_BBT_NRBITS_MSK; | 410 | bits = td->options & NAND_BBT_NRBITS_MSK; |
411 | 411 | ||
412 | for (i = 0; i < chips; i++) { | 412 | for (i = 0; i < chips; i++) { |
413 | /* Reset version information */ | 413 | /* Reset version information */ |
414 | td->version[i] = 0; | 414 | td->version[i] = 0; |
415 | td->pages[i] = -1; | 415 | td->pages[i] = -1; |
416 | /* Scan the maximum number of blocks */ | 416 | /* Scan the maximum number of blocks */ |
417 | for (block = 0; block < td->maxblocks; block++) { | 417 | for (block = 0; block < td->maxblocks; block++) { |
418 | int actblock = startblock + dir * block; | 418 | int actblock = startblock + dir * block; |
419 | /* Read first page */ | 419 | /* Read first page */ |
420 | nand_read_raw (mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize); | 420 | nand_read_raw (mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize); |
421 | if (!check_pattern(buf, scanlen, mtd->oobblock, td)) { | 421 | if (!check_pattern(buf, scanlen, mtd->oobblock, td)) { |
422 | td->pages[i] = actblock << (this->bbt_erase_shift - this->page_shift); | 422 | td->pages[i] = actblock << (this->bbt_erase_shift - this->page_shift); |
423 | if (td->options & NAND_BBT_VERSION) { | 423 | if (td->options & NAND_BBT_VERSION) { |
@@ -435,46 +435,46 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr | |||
435 | else | 435 | else |
436 | printk (KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i], td->version[i]); | 436 | printk (KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i], td->version[i]); |
437 | } | 437 | } |
438 | return 0; | 438 | return 0; |
439 | } | 439 | } |
440 | 440 | ||
441 | /** | 441 | /** |
442 | * search_read_bbts - [GENERIC] scan the device for bad block table(s) | 442 | * search_read_bbts - [GENERIC] scan the device for bad block table(s) |
443 | * @mtd: MTD device structure | 443 | * @mtd: MTD device structure |
444 | * @buf: temporary buffer | 444 | * @buf: temporary buffer |
445 | * @td: descriptor for the bad block table | 445 | * @td: descriptor for the bad block table |
446 | * @md: descriptor for the bad block table mirror | 446 | * @md: descriptor for the bad block table mirror |
447 | * | 447 | * |
448 | * Search and read the bad block table(s) | 448 | * Search and read the bad block table(s) |
449 | */ | 449 | */ |
450 | static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf, | 450 | static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf, |
451 | struct nand_bbt_descr *td, struct nand_bbt_descr *md) | 451 | struct nand_bbt_descr *td, struct nand_bbt_descr *md) |
452 | { | 452 | { |
453 | /* Search the primary table */ | 453 | /* Search the primary table */ |
454 | search_bbt (mtd, buf, td); | 454 | search_bbt (mtd, buf, td); |
455 | 455 | ||
456 | /* Search the mirror table */ | 456 | /* Search the mirror table */ |
457 | if (md) | 457 | if (md) |
458 | search_bbt (mtd, buf, md); | 458 | search_bbt (mtd, buf, md); |
459 | 459 | ||
460 | /* Force result check */ | 460 | /* Force result check */ |
461 | return 1; | 461 | return 1; |
462 | } | 462 | } |
463 | |||
464 | 463 | ||
465 | /** | 464 | |
465 | /** | ||
466 | * write_bbt - [GENERIC] (Re)write the bad block table | 466 | * write_bbt - [GENERIC] (Re)write the bad block table |
467 | * | 467 | * |
468 | * @mtd: MTD device structure | 468 | * @mtd: MTD device structure |
469 | * @buf: temporary buffer | 469 | * @buf: temporary buffer |
470 | * @td: descriptor for the bad block table | 470 | * @td: descriptor for the bad block table |
471 | * @md: descriptor for the bad block table mirror | 471 | * @md: descriptor for the bad block table mirror |
472 | * @chipsel: selector for a specific chip, -1 for all | 472 | * @chipsel: selector for a specific chip, -1 for all |
473 | * | 473 | * |
474 | * (Re)write the bad block table | 474 | * (Re)write the bad block table |
475 | * | 475 | * |
476 | */ | 476 | */ |
477 | static int write_bbt (struct mtd_info *mtd, uint8_t *buf, | 477 | static int write_bbt (struct mtd_info *mtd, uint8_t *buf, |
478 | struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel) | 478 | struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel) |
479 | { | 479 | { |
480 | struct nand_chip *this = mtd->priv; | 480 | struct nand_chip *this = mtd->priv; |
@@ -493,7 +493,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf, | |||
493 | /* Write bad block table per chip rather than per device ? */ | 493 | /* Write bad block table per chip rather than per device ? */ |
494 | if (td->options & NAND_BBT_PERCHIP) { | 494 | if (td->options & NAND_BBT_PERCHIP) { |
495 | numblocks = (int) (this->chipsize >> this->bbt_erase_shift); | 495 | numblocks = (int) (this->chipsize >> this->bbt_erase_shift); |
496 | /* Full device write or specific chip ? */ | 496 | /* Full device write or specific chip ? */ |
497 | if (chipsel == -1) { | 497 | if (chipsel == -1) { |
498 | nrchips = this->numchips; | 498 | nrchips = this->numchips; |
499 | } else { | 499 | } else { |
@@ -503,19 +503,19 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf, | |||
503 | } else { | 503 | } else { |
504 | numblocks = (int) (mtd->size >> this->bbt_erase_shift); | 504 | numblocks = (int) (mtd->size >> this->bbt_erase_shift); |
505 | nrchips = 1; | 505 | nrchips = 1; |
506 | } | 506 | } |
507 | 507 | ||
508 | /* Loop through the chips */ | 508 | /* Loop through the chips */ |
509 | for (; chip < nrchips; chip++) { | 509 | for (; chip < nrchips; chip++) { |
510 | 510 | ||
511 | /* There was already a version of the table, reuse the page | 511 | /* There was already a version of the table, reuse the page |
512 | * This applies for absolute placement too, as we have the | 512 | * This applies for absolute placement too, as we have the |
513 | * page nr. in td->pages. | 513 | * page nr. in td->pages. |
514 | */ | 514 | */ |
515 | if (td->pages[chip] != -1) { | 515 | if (td->pages[chip] != -1) { |
516 | page = td->pages[chip]; | 516 | page = td->pages[chip]; |
517 | goto write; | 517 | goto write; |
518 | } | 518 | } |
519 | 519 | ||
520 | /* Automatic placement of the bad block table */ | 520 | /* Automatic placement of the bad block table */ |
521 | /* Search direction top -> down ? */ | 521 | /* Search direction top -> down ? */ |
@@ -525,7 +525,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf, | |||
525 | } else { | 525 | } else { |
526 | startblock = chip * numblocks; | 526 | startblock = chip * numblocks; |
527 | dir = 1; | 527 | dir = 1; |
528 | } | 528 | } |
529 | 529 | ||
530 | for (i = 0; i < td->maxblocks; i++) { | 530 | for (i = 0; i < td->maxblocks; i++) { |
531 | int block = startblock + dir * i; | 531 | int block = startblock + dir * i; |
@@ -542,7 +542,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf, | |||
542 | } | 542 | } |
543 | printk (KERN_ERR "No space left to write bad block table\n"); | 543 | printk (KERN_ERR "No space left to write bad block table\n"); |
544 | return -ENOSPC; | 544 | return -ENOSPC; |
545 | write: | 545 | write: |
546 | 546 | ||
547 | /* Set up shift count and masks for the flash table */ | 547 | /* Set up shift count and masks for the flash table */ |
548 | bits = td->options & NAND_BBT_NRBITS_MSK; | 548 | bits = td->options & NAND_BBT_NRBITS_MSK; |
@@ -553,14 +553,14 @@ write: | |||
553 | case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F; msk[2] = ~rcode; msk[3] = 0xff; break; | 553 | case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F; msk[2] = ~rcode; msk[3] = 0xff; break; |
554 | default: return -EINVAL; | 554 | default: return -EINVAL; |
555 | } | 555 | } |
556 | 556 | ||
557 | bbtoffs = chip * (numblocks >> 2); | 557 | bbtoffs = chip * (numblocks >> 2); |
558 | 558 | ||
559 | to = ((loff_t) page) << this->page_shift; | 559 | to = ((loff_t) page) << this->page_shift; |
560 | 560 | ||
561 | memcpy (&oobinfo, this->autooob, sizeof(oobinfo)); | 561 | memcpy (&oobinfo, this->autooob, sizeof(oobinfo)); |
562 | oobinfo.useecc = MTD_NANDECC_PLACEONLY; | 562 | oobinfo.useecc = MTD_NANDECC_PLACEONLY; |
563 | 563 | ||
564 | /* Must we save the block contents ? */ | 564 | /* Must we save the block contents ? */ |
565 | if (td->options & NAND_BBT_SAVECONTENT) { | 565 | if (td->options & NAND_BBT_SAVECONTENT) { |
566 | /* Make it block aligned */ | 566 | /* Make it block aligned */ |
@@ -599,7 +599,7 @@ write: | |||
599 | buf[len + td->veroffs] = td->version[chip]; | 599 | buf[len + td->veroffs] = td->version[chip]; |
600 | } | 600 | } |
601 | } | 601 | } |
602 | 602 | ||
603 | /* walk through the memory table */ | 603 | /* walk through the memory table */ |
604 | for (i = 0; i < numblocks; ) { | 604 | for (i = 0; i < numblocks; ) { |
605 | uint8_t dat; | 605 | uint8_t dat; |
@@ -611,7 +611,7 @@ write: | |||
611 | dat >>= 2; | 611 | dat >>= 2; |
612 | } | 612 | } |
613 | } | 613 | } |
614 | 614 | ||
615 | memset (&einfo, 0, sizeof (einfo)); | 615 | memset (&einfo, 0, sizeof (einfo)); |
616 | einfo.mtd = mtd; | 616 | einfo.mtd = mtd; |
617 | einfo.addr = (unsigned long) to; | 617 | einfo.addr = (unsigned long) to; |
@@ -621,18 +621,18 @@ write: | |||
621 | printk (KERN_WARNING "nand_bbt: Error during block erase: %d\n", res); | 621 | printk (KERN_WARNING "nand_bbt: Error during block erase: %d\n", res); |
622 | return res; | 622 | return res; |
623 | } | 623 | } |
624 | 624 | ||
625 | res = mtd->write_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo); | 625 | res = mtd->write_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo); |
626 | if (res < 0) { | 626 | if (res < 0) { |
627 | printk (KERN_WARNING "nand_bbt: Error while writing bad block table %d\n", res); | 627 | printk (KERN_WARNING "nand_bbt: Error while writing bad block table %d\n", res); |
628 | return res; | 628 | return res; |
629 | } | 629 | } |
630 | printk (KERN_DEBUG "Bad block table written to 0x%08x, version 0x%02X\n", | 630 | printk (KERN_DEBUG "Bad block table written to 0x%08x, version 0x%02X\n", |
631 | (unsigned int) to, td->version[chip]); | 631 | (unsigned int) to, td->version[chip]); |
632 | 632 | ||
633 | /* Mark it as used */ | 633 | /* Mark it as used */ |
634 | td->pages[chip] = page; | 634 | td->pages[chip] = page; |
635 | } | 635 | } |
636 | return 0; | 636 | return 0; |
637 | } | 637 | } |
638 | 638 | ||
@@ -641,7 +641,7 @@ write: | |||
641 | * @mtd: MTD device structure | 641 | * @mtd: MTD device structure |
642 | * @bd: descriptor for the good/bad block search pattern | 642 | * @bd: descriptor for the good/bad block search pattern |
643 | * | 643 | * |
644 | * The function creates a memory based bbt by scanning the device | 644 | * The function creates a memory based bbt by scanning the device |
645 | * for manufacturer / software marked good / bad blocks | 645 | * for manufacturer / software marked good / bad blocks |
646 | */ | 646 | */ |
647 | static inline int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd) | 647 | static inline int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd) |
@@ -673,11 +673,11 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des | |||
673 | struct nand_bbt_descr *rd, *rd2; | 673 | struct nand_bbt_descr *rd, *rd2; |
674 | 674 | ||
675 | /* Do we have a bbt per chip ? */ | 675 | /* Do we have a bbt per chip ? */ |
676 | if (td->options & NAND_BBT_PERCHIP) | 676 | if (td->options & NAND_BBT_PERCHIP) |
677 | chips = this->numchips; | 677 | chips = this->numchips; |
678 | else | 678 | else |
679 | chips = 1; | 679 | chips = 1; |
680 | 680 | ||
681 | for (i = 0; i < chips; i++) { | 681 | for (i = 0; i < chips; i++) { |
682 | writeops = 0; | 682 | writeops = 0; |
683 | rd = NULL; | 683 | rd = NULL; |
@@ -692,7 +692,7 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des | |||
692 | } | 692 | } |
693 | 693 | ||
694 | if (td->pages[i] == -1) { | 694 | if (td->pages[i] == -1) { |
695 | rd = md; | 695 | rd = md; |
696 | td->version[i] = md->version[i]; | 696 | td->version[i] = md->version[i]; |
697 | writeops = 1; | 697 | writeops = 1; |
698 | goto writecheck; | 698 | goto writecheck; |
@@ -710,7 +710,7 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des | |||
710 | if (!(td->options & NAND_BBT_VERSION)) | 710 | if (!(td->options & NAND_BBT_VERSION)) |
711 | rd2 = md; | 711 | rd2 = md; |
712 | goto writecheck; | 712 | goto writecheck; |
713 | } | 713 | } |
714 | 714 | ||
715 | if (((int8_t) (td->version[i] - md->version[i])) > 0) { | 715 | if (((int8_t) (td->version[i] - md->version[i])) > 0) { |
716 | rd = td; | 716 | rd = td; |
@@ -735,15 +735,15 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des | |||
735 | create: | 735 | create: |
736 | /* Create the bad block table by scanning the device ? */ | 736 | /* Create the bad block table by scanning the device ? */ |
737 | if (!(td->options & NAND_BBT_CREATE)) | 737 | if (!(td->options & NAND_BBT_CREATE)) |
738 | continue; | 738 | continue; |
739 | 739 | ||
740 | /* Create the table in memory by scanning the chip(s) */ | 740 | /* Create the table in memory by scanning the chip(s) */ |
741 | create_bbt (mtd, buf, bd, chipsel); | 741 | create_bbt (mtd, buf, bd, chipsel); |
742 | 742 | ||
743 | td->version[i] = 1; | 743 | td->version[i] = 1; |
744 | if (md) | 744 | if (md) |
745 | md->version[i] = 1; | 745 | md->version[i] = 1; |
746 | writecheck: | 746 | writecheck: |
747 | /* read back first ? */ | 747 | /* read back first ? */ |
748 | if (rd) | 748 | if (rd) |
749 | read_abs_bbt (mtd, buf, rd, chipsel); | 749 | read_abs_bbt (mtd, buf, rd, chipsel); |
@@ -757,7 +757,7 @@ writecheck: | |||
757 | if (res < 0) | 757 | if (res < 0) |
758 | return res; | 758 | return res; |
759 | } | 759 | } |
760 | 760 | ||
761 | /* Write the mirror bad block table to the device ? */ | 761 | /* Write the mirror bad block table to the device ? */ |
762 | if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) { | 762 | if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) { |
763 | res = write_bbt (mtd, buf, md, td, chipsel); | 763 | res = write_bbt (mtd, buf, md, td, chipsel); |
@@ -765,11 +765,11 @@ writecheck: | |||
765 | return res; | 765 | return res; |
766 | } | 766 | } |
767 | } | 767 | } |
768 | return 0; | 768 | return 0; |
769 | } | 769 | } |
770 | 770 | ||
771 | /** | 771 | /** |
772 | * mark_bbt_regions - [GENERIC] mark the bad block table regions | 772 | * mark_bbt_regions - [GENERIC] mark the bad block table regions |
773 | * @mtd: MTD device structure | 773 | * @mtd: MTD device structure |
774 | * @td: bad block table descriptor | 774 | * @td: bad block table descriptor |
775 | * | 775 | * |
@@ -790,14 +790,14 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td) | |||
790 | } else { | 790 | } else { |
791 | chips = 1; | 791 | chips = 1; |
792 | nrblocks = (int)(mtd->size >> this->bbt_erase_shift); | 792 | nrblocks = (int)(mtd->size >> this->bbt_erase_shift); |
793 | } | 793 | } |
794 | 794 | ||
795 | for (i = 0; i < chips; i++) { | 795 | for (i = 0; i < chips; i++) { |
796 | if ((td->options & NAND_BBT_ABSPAGE) || | 796 | if ((td->options & NAND_BBT_ABSPAGE) || |
797 | !(td->options & NAND_BBT_WRITE)) { | 797 | !(td->options & NAND_BBT_WRITE)) { |
798 | if (td->pages[i] == -1) continue; | 798 | if (td->pages[i] == -1) continue; |
799 | block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift); | 799 | block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift); |
800 | block <<= 1; | 800 | block <<= 1; |
801 | oldval = this->bbt[(block >> 3)]; | 801 | oldval = this->bbt[(block >> 3)]; |
802 | newval = oldval | (0x2 << (block & 0x06)); | 802 | newval = oldval | (0x2 << (block & 0x06)); |
803 | this->bbt[(block >> 3)] = newval; | 803 | this->bbt[(block >> 3)] = newval; |
@@ -808,16 +808,16 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td) | |||
808 | update = 0; | 808 | update = 0; |
809 | if (td->options & NAND_BBT_LASTBLOCK) | 809 | if (td->options & NAND_BBT_LASTBLOCK) |
810 | block = ((i + 1) * nrblocks) - td->maxblocks; | 810 | block = ((i + 1) * nrblocks) - td->maxblocks; |
811 | else | 811 | else |
812 | block = i * nrblocks; | 812 | block = i * nrblocks; |
813 | block <<= 1; | 813 | block <<= 1; |
814 | for (j = 0; j < td->maxblocks; j++) { | 814 | for (j = 0; j < td->maxblocks; j++) { |
815 | oldval = this->bbt[(block >> 3)]; | 815 | oldval = this->bbt[(block >> 3)]; |
816 | newval = oldval | (0x2 << (block & 0x06)); | 816 | newval = oldval | (0x2 << (block & 0x06)); |
817 | this->bbt[(block >> 3)] = newval; | 817 | this->bbt[(block >> 3)] = newval; |
818 | if (oldval != newval) update = 1; | 818 | if (oldval != newval) update = 1; |
819 | block += 2; | 819 | block += 2; |
820 | } | 820 | } |
821 | /* If we want reserved blocks to be recorded to flash, and some | 821 | /* If we want reserved blocks to be recorded to flash, and some |
822 | new ones have been marked, then we need to update the stored | 822 | new ones have been marked, then we need to update the stored |
823 | bbts. This should only happen once. */ | 823 | bbts. This should only happen once. */ |
@@ -831,7 +831,7 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td) | |||
831 | * @mtd: MTD device structure | 831 | * @mtd: MTD device structure |
832 | * @bd: descriptor for the good/bad block search pattern | 832 | * @bd: descriptor for the good/bad block search pattern |
833 | * | 833 | * |
834 | * The function checks, if a bad block table(s) is/are already | 834 | * The function checks, if a bad block table(s) is/are already |
835 | * available. If not it scans the device for manufacturer | 835 | * available. If not it scans the device for manufacturer |
836 | * marked good / bad blocks and writes the bad block table(s) to | 836 | * marked good / bad blocks and writes the bad block table(s) to |
837 | * the selected place. | 837 | * the selected place. |
@@ -880,30 +880,30 @@ int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd) | |||
880 | this->bbt = NULL; | 880 | this->bbt = NULL; |
881 | return -ENOMEM; | 881 | return -ENOMEM; |
882 | } | 882 | } |
883 | 883 | ||
884 | /* Is the bbt at a given page ? */ | 884 | /* Is the bbt at a given page ? */ |
885 | if (td->options & NAND_BBT_ABSPAGE) { | 885 | if (td->options & NAND_BBT_ABSPAGE) { |
886 | res = read_abs_bbts (mtd, buf, td, md); | 886 | res = read_abs_bbts (mtd, buf, td, md); |
887 | } else { | 887 | } else { |
888 | /* Search the bad block table using a pattern in oob */ | 888 | /* Search the bad block table using a pattern in oob */ |
889 | res = search_read_bbts (mtd, buf, td, md); | 889 | res = search_read_bbts (mtd, buf, td, md); |
890 | } | 890 | } |
891 | 891 | ||
892 | if (res) | 892 | if (res) |
893 | res = check_create (mtd, buf, bd); | 893 | res = check_create (mtd, buf, bd); |
894 | 894 | ||
895 | /* Prevent the bbt regions from erasing / writing */ | 895 | /* Prevent the bbt regions from erasing / writing */ |
896 | mark_bbt_region (mtd, td); | 896 | mark_bbt_region (mtd, td); |
897 | if (md) | 897 | if (md) |
898 | mark_bbt_region (mtd, md); | 898 | mark_bbt_region (mtd, md); |
899 | 899 | ||
900 | kfree (buf); | 900 | kfree (buf); |
901 | return res; | 901 | return res; |
902 | } | 902 | } |
903 | 903 | ||
904 | 904 | ||
905 | /** | 905 | /** |
906 | * nand_update_bbt - [NAND Interface] update bad block table(s) | 906 | * nand_update_bbt - [NAND Interface] update bad block table(s) |
907 | * @mtd: MTD device structure | 907 | * @mtd: MTD device structure |
908 | * @offs: the offset of the newly marked block | 908 | * @offs: the offset of the newly marked block |
909 | * | 909 | * |
@@ -930,7 +930,7 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs) | |||
930 | printk (KERN_ERR "nand_update_bbt: Out of memory\n"); | 930 | printk (KERN_ERR "nand_update_bbt: Out of memory\n"); |
931 | return -ENOMEM; | 931 | return -ENOMEM; |
932 | } | 932 | } |
933 | 933 | ||
934 | writeops = md != NULL ? 0x03 : 0x01; | 934 | writeops = md != NULL ? 0x03 : 0x01; |
935 | 935 | ||
936 | /* Do we have a bbt per chip ? */ | 936 | /* Do we have a bbt per chip ? */ |
@@ -944,7 +944,7 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs) | |||
944 | 944 | ||
945 | td->version[chip]++; | 945 | td->version[chip]++; |
946 | if (md) | 946 | if (md) |
947 | md->version[chip]++; | 947 | md->version[chip]++; |
948 | 948 | ||
949 | /* Write the bad block table to the device ? */ | 949 | /* Write the bad block table to the device ? */ |
950 | if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) { | 950 | if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) { |
@@ -957,12 +957,12 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs) | |||
957 | res = write_bbt (mtd, buf, md, td, chipsel); | 957 | res = write_bbt (mtd, buf, md, td, chipsel); |
958 | } | 958 | } |
959 | 959 | ||
960 | out: | 960 | out: |
961 | kfree (buf); | 961 | kfree (buf); |
962 | return res; | 962 | return res; |
963 | } | 963 | } |
964 | 964 | ||
965 | /* Define some generic bad / good block scan pattern which are used | 965 | /* Define some generic bad / good block scan pattern which are used |
966 | * while scanning a device for factory marked good / bad blocks. */ | 966 | * while scanning a device for factory marked good / bad blocks. */ |
967 | static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; | 967 | static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; |
968 | 968 | ||
@@ -1009,7 +1009,7 @@ static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' }; | |||
1009 | static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' }; | 1009 | static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' }; |
1010 | 1010 | ||
1011 | static struct nand_bbt_descr bbt_main_descr = { | 1011 | static struct nand_bbt_descr bbt_main_descr = { |
1012 | .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | 1012 | .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
1013 | | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, | 1013 | | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, |
1014 | .offs = 8, | 1014 | .offs = 8, |
1015 | .len = 4, | 1015 | .len = 4, |
@@ -1019,7 +1019,7 @@ static struct nand_bbt_descr bbt_main_descr = { | |||
1019 | }; | 1019 | }; |
1020 | 1020 | ||
1021 | static struct nand_bbt_descr bbt_mirror_descr = { | 1021 | static struct nand_bbt_descr bbt_mirror_descr = { |
1022 | .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | 1022 | .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
1023 | | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, | 1023 | | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, |
1024 | .offs = 8, | 1024 | .offs = 8, |
1025 | .len = 4, | 1025 | .len = 4, |
@@ -1029,7 +1029,7 @@ static struct nand_bbt_descr bbt_mirror_descr = { | |||
1029 | }; | 1029 | }; |
1030 | 1030 | ||
1031 | /** | 1031 | /** |
1032 | * nand_default_bbt - [NAND Interface] Select a default bad block table for the device | 1032 | * nand_default_bbt - [NAND Interface] Select a default bad block table for the device |
1033 | * @mtd: MTD device structure | 1033 | * @mtd: MTD device structure |
1034 | * | 1034 | * |
1035 | * This function selects the default bad block table | 1035 | * This function selects the default bad block table |
@@ -1039,29 +1039,29 @@ static struct nand_bbt_descr bbt_mirror_descr = { | |||
1039 | int nand_default_bbt (struct mtd_info *mtd) | 1039 | int nand_default_bbt (struct mtd_info *mtd) |
1040 | { | 1040 | { |
1041 | struct nand_chip *this = mtd->priv; | 1041 | struct nand_chip *this = mtd->priv; |
1042 | 1042 | ||
1043 | /* Default for AG-AND. We must use a flash based | 1043 | /* Default for AG-AND. We must use a flash based |
1044 | * bad block table as the devices have factory marked | 1044 | * bad block table as the devices have factory marked |
1045 | * _good_ blocks. Erasing those blocks leads to loss | 1045 | * _good_ blocks. Erasing those blocks leads to loss |
1046 | * of the good / bad information, so we _must_ store | 1046 | * of the good / bad information, so we _must_ store |
1047 | * this information in a good / bad table during | 1047 | * this information in a good / bad table during |
1048 | * startup | 1048 | * startup |
1049 | */ | 1049 | */ |
1050 | if (this->options & NAND_IS_AND) { | 1050 | if (this->options & NAND_IS_AND) { |
1051 | /* Use the default pattern descriptors */ | 1051 | /* Use the default pattern descriptors */ |
1052 | if (!this->bbt_td) { | 1052 | if (!this->bbt_td) { |
1053 | this->bbt_td = &bbt_main_descr; | 1053 | this->bbt_td = &bbt_main_descr; |
1054 | this->bbt_md = &bbt_mirror_descr; | 1054 | this->bbt_md = &bbt_mirror_descr; |
1055 | } | 1055 | } |
1056 | this->options |= NAND_USE_FLASH_BBT; | 1056 | this->options |= NAND_USE_FLASH_BBT; |
1057 | return nand_scan_bbt (mtd, &agand_flashbased); | 1057 | return nand_scan_bbt (mtd, &agand_flashbased); |
1058 | } | 1058 | } |
1059 | 1059 | ||
1060 | 1060 | ||
1061 | /* Is a flash based bad block table requested ? */ | 1061 | /* Is a flash based bad block table requested ? */ |
1062 | if (this->options & NAND_USE_FLASH_BBT) { | 1062 | if (this->options & NAND_USE_FLASH_BBT) { |
1063 | /* Use the default pattern descriptors */ | 1063 | /* Use the default pattern descriptors */ |
1064 | if (!this->bbt_td) { | 1064 | if (!this->bbt_td) { |
1065 | this->bbt_td = &bbt_main_descr; | 1065 | this->bbt_td = &bbt_main_descr; |
1066 | this->bbt_md = &bbt_mirror_descr; | 1066 | this->bbt_md = &bbt_mirror_descr; |
1067 | } | 1067 | } |
@@ -1081,7 +1081,7 @@ int nand_default_bbt (struct mtd_info *mtd) | |||
1081 | } | 1081 | } |
1082 | 1082 | ||
1083 | /** | 1083 | /** |
1084 | * nand_isbad_bbt - [NAND Interface] Check if a block is bad | 1084 | * nand_isbad_bbt - [NAND Interface] Check if a block is bad |
1085 | * @mtd: MTD device structure | 1085 | * @mtd: MTD device structure |
1086 | * @offs: offset in the device | 1086 | * @offs: offset in the device |
1087 | * @allowbbt: allow access to bad block table region | 1087 | * @allowbbt: allow access to bad block table region |
@@ -1092,12 +1092,12 @@ int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt) | |||
1092 | struct nand_chip *this = mtd->priv; | 1092 | struct nand_chip *this = mtd->priv; |
1093 | int block; | 1093 | int block; |
1094 | uint8_t res; | 1094 | uint8_t res; |
1095 | 1095 | ||
1096 | /* Get block number * 2 */ | 1096 | /* Get block number * 2 */ |
1097 | block = (int) (offs >> (this->bbt_erase_shift - 1)); | 1097 | block = (int) (offs >> (this->bbt_erase_shift - 1)); |
1098 | res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03; | 1098 | res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03; |
1099 | 1099 | ||
1100 | DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n", | 1100 | DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n", |
1101 | (unsigned int)offs, block >> 1, res); | 1101 | (unsigned int)offs, block >> 1, res); |
1102 | 1102 | ||
1103 | switch ((int)res) { | 1103 | switch ((int)res) { |
diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c index 2e341b75437a..40ac909150a3 100644 --- a/drivers/mtd/nand/nand_ecc.c +++ b/drivers/mtd/nand/nand_ecc.c | |||
@@ -7,22 +7,22 @@ | |||
7 | * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com) | 7 | * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com) |
8 | * Toshiba America Electronics Components, Inc. | 8 | * Toshiba America Electronics Components, Inc. |
9 | * | 9 | * |
10 | * $Id: nand_ecc.c,v 1.14 2004/06/16 15:34:37 gleixner Exp $ | 10 | * $Id: nand_ecc.c,v 1.15 2005/11/07 11:14:30 gleixner Exp $ |
11 | * | 11 | * |
12 | * This file is free software; you can redistribute it and/or modify it | 12 | * This file is free software; you can redistribute it and/or modify it |
13 | * under the terms of the GNU General Public License as published by the | 13 | * under the terms of the GNU General Public License as published by the |
14 | * Free Software Foundation; either version 2 or (at your option) any | 14 | * Free Software Foundation; either version 2 or (at your option) any |
15 | * later version. | 15 | * later version. |
16 | * | 16 | * |
17 | * This file is distributed in the hope that it will be useful, but WITHOUT | 17 | * This file is distributed in the hope that it will be useful, but WITHOUT |
18 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 18 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
19 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | 19 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
20 | * for more details. | 20 | * for more details. |
21 | * | 21 | * |
22 | * You should have received a copy of the GNU General Public License along | 22 | * You should have received a copy of the GNU General Public License along |
23 | * with this file; if not, write to the Free Software Foundation, Inc., | 23 | * with this file; if not, write to the Free Software Foundation, Inc., |
24 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | 24 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
25 | * | 25 | * |
26 | * As a special exception, if other files instantiate templates or use | 26 | * As a special exception, if other files instantiate templates or use |
27 | * macros or inline functions from these files, or you compile these | 27 | * macros or inline functions from these files, or you compile these |
28 | * files and link them with other works to produce a work based on these | 28 | * files and link them with other works to produce a work based on these |
@@ -30,7 +30,7 @@ | |||
30 | * covered by the GNU General Public License. However the source code for | 30 | * covered by the GNU General Public License. However the source code for |
31 | * these files must still be made available in accordance with section (3) | 31 | * these files must still be made available in accordance with section (3) |
32 | * of the GNU General Public License. | 32 | * of the GNU General Public License. |
33 | * | 33 | * |
34 | * This exception does not invalidate any other reasons why a work based on | 34 | * This exception does not invalidate any other reasons why a work based on |
35 | * this file might be covered by the GNU General Public License. | 35 | * this file might be covered by the GNU General Public License. |
36 | */ | 36 | */ |
@@ -67,7 +67,7 @@ static const u_char nand_ecc_precalc_table[] = { | |||
67 | * nand_trans_result - [GENERIC] create non-inverted ECC | 67 | * nand_trans_result - [GENERIC] create non-inverted ECC |
68 | * @reg2: line parity reg 2 | 68 | * @reg2: line parity reg 2 |
69 | * @reg3: line parity reg 3 | 69 | * @reg3: line parity reg 3 |
70 | * @ecc_code: ecc | 70 | * @ecc_code: ecc |
71 | * | 71 | * |
72 | * Creates non-inverted ECC code from line parity | 72 | * Creates non-inverted ECC code from line parity |
73 | */ | 73 | */ |
@@ -75,11 +75,11 @@ static void nand_trans_result(u_char reg2, u_char reg3, | |||
75 | u_char *ecc_code) | 75 | u_char *ecc_code) |
76 | { | 76 | { |
77 | u_char a, b, i, tmp1, tmp2; | 77 | u_char a, b, i, tmp1, tmp2; |
78 | 78 | ||
79 | /* Initialize variables */ | 79 | /* Initialize variables */ |
80 | a = b = 0x80; | 80 | a = b = 0x80; |
81 | tmp1 = tmp2 = 0; | 81 | tmp1 = tmp2 = 0; |
82 | 82 | ||
83 | /* Calculate first ECC byte */ | 83 | /* Calculate first ECC byte */ |
84 | for (i = 0; i < 4; i++) { | 84 | for (i = 0; i < 4; i++) { |
85 | if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */ | 85 | if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */ |
@@ -90,7 +90,7 @@ static void nand_trans_result(u_char reg2, u_char reg3, | |||
90 | b >>= 1; | 90 | b >>= 1; |
91 | a >>= 1; | 91 | a >>= 1; |
92 | } | 92 | } |
93 | 93 | ||
94 | /* Calculate second ECC byte */ | 94 | /* Calculate second ECC byte */ |
95 | b = 0x80; | 95 | b = 0x80; |
96 | for (i = 0; i < 4; i++) { | 96 | for (i = 0; i < 4; i++) { |
@@ -102,7 +102,7 @@ static void nand_trans_result(u_char reg2, u_char reg3, | |||
102 | b >>= 1; | 102 | b >>= 1; |
103 | a >>= 1; | 103 | a >>= 1; |
104 | } | 104 | } |
105 | 105 | ||
106 | /* Store two of the ECC bytes */ | 106 | /* Store two of the ECC bytes */ |
107 | ecc_code[0] = tmp1; | 107 | ecc_code[0] = tmp1; |
108 | ecc_code[1] = tmp2; | 108 | ecc_code[1] = tmp2; |
@@ -118,28 +118,28 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code | |||
118 | { | 118 | { |
119 | u_char idx, reg1, reg2, reg3; | 119 | u_char idx, reg1, reg2, reg3; |
120 | int j; | 120 | int j; |
121 | 121 | ||
122 | /* Initialize variables */ | 122 | /* Initialize variables */ |
123 | reg1 = reg2 = reg3 = 0; | 123 | reg1 = reg2 = reg3 = 0; |
124 | ecc_code[0] = ecc_code[1] = ecc_code[2] = 0; | 124 | ecc_code[0] = ecc_code[1] = ecc_code[2] = 0; |
125 | 125 | ||
126 | /* Build up column parity */ | 126 | /* Build up column parity */ |
127 | for(j = 0; j < 256; j++) { | 127 | for(j = 0; j < 256; j++) { |
128 | 128 | ||
129 | /* Get CP0 - CP5 from table */ | 129 | /* Get CP0 - CP5 from table */ |
130 | idx = nand_ecc_precalc_table[dat[j]]; | 130 | idx = nand_ecc_precalc_table[dat[j]]; |
131 | reg1 ^= (idx & 0x3f); | 131 | reg1 ^= (idx & 0x3f); |
132 | 132 | ||
133 | /* All bit XOR = 1 ? */ | 133 | /* All bit XOR = 1 ? */ |
134 | if (idx & 0x40) { | 134 | if (idx & 0x40) { |
135 | reg3 ^= (u_char) j; | 135 | reg3 ^= (u_char) j; |
136 | reg2 ^= ~((u_char) j); | 136 | reg2 ^= ~((u_char) j); |
137 | } | 137 | } |
138 | } | 138 | } |
139 | 139 | ||
140 | /* Create non-inverted ECC code from line parity */ | 140 | /* Create non-inverted ECC code from line parity */ |
141 | nand_trans_result(reg2, reg3, ecc_code); | 141 | nand_trans_result(reg2, reg3, ecc_code); |
142 | 142 | ||
143 | /* Calculate final ECC code */ | 143 | /* Calculate final ECC code */ |
144 | ecc_code[0] = ~ecc_code[0]; | 144 | ecc_code[0] = ~ecc_code[0]; |
145 | ecc_code[1] = ~ecc_code[1]; | 145 | ecc_code[1] = ~ecc_code[1]; |
@@ -159,12 +159,12 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code | |||
159 | int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) | 159 | int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) |
160 | { | 160 | { |
161 | u_char a, b, c, d1, d2, d3, add, bit, i; | 161 | u_char a, b, c, d1, d2, d3, add, bit, i; |
162 | 162 | ||
163 | /* Do error detection */ | 163 | /* Do error detection */ |
164 | d1 = calc_ecc[0] ^ read_ecc[0]; | 164 | d1 = calc_ecc[0] ^ read_ecc[0]; |
165 | d2 = calc_ecc[1] ^ read_ecc[1]; | 165 | d2 = calc_ecc[1] ^ read_ecc[1]; |
166 | d3 = calc_ecc[2] ^ read_ecc[2]; | 166 | d3 = calc_ecc[2] ^ read_ecc[2]; |
167 | 167 | ||
168 | if ((d1 | d2 | d3) == 0) { | 168 | if ((d1 | d2 | d3) == 0) { |
169 | /* No errors */ | 169 | /* No errors */ |
170 | return 0; | 170 | return 0; |
@@ -173,7 +173,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha | |||
173 | a = (d1 ^ (d1 >> 1)) & 0x55; | 173 | a = (d1 ^ (d1 >> 1)) & 0x55; |
174 | b = (d2 ^ (d2 >> 1)) & 0x55; | 174 | b = (d2 ^ (d2 >> 1)) & 0x55; |
175 | c = (d3 ^ (d3 >> 1)) & 0x54; | 175 | c = (d3 ^ (d3 >> 1)) & 0x54; |
176 | 176 | ||
177 | /* Found and will correct single bit error in the data */ | 177 | /* Found and will correct single bit error in the data */ |
178 | if ((a == 0x55) && (b == 0x55) && (c == 0x54)) { | 178 | if ((a == 0x55) && (b == 0x55) && (c == 0x54)) { |
179 | c = 0x80; | 179 | c = 0x80; |
@@ -237,7 +237,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha | |||
237 | } | 237 | } |
238 | } | 238 | } |
239 | } | 239 | } |
240 | 240 | ||
241 | /* Should never happen */ | 241 | /* Should never happen */ |
242 | return -1; | 242 | return -1; |
243 | } | 243 | } |
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c index efe246961b69..dbc7e55a4247 100644 --- a/drivers/mtd/nand/nand_ids.c +++ b/drivers/mtd/nand/nand_ids.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de) | 4 | * Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de) |
5 | * | 5 | * |
6 | * $Id: nand_ids.c,v 1.14 2005/06/23 09:38:50 gleixner Exp $ | 6 | * $Id: nand_ids.c,v 1.16 2005/11/07 11:14:31 gleixner Exp $ |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
@@ -14,14 +14,14 @@ | |||
14 | #include <linux/mtd/nand.h> | 14 | #include <linux/mtd/nand.h> |
15 | /* | 15 | /* |
16 | * Chip ID list | 16 | * Chip ID list |
17 | * | 17 | * |
18 | * Name. ID code, pagesize, chipsize in MegaByte, eraseblock size, | 18 | * Name. ID code, pagesize, chipsize in MegaByte, eraseblock size, |
19 | * options | 19 | * options |
20 | * | 20 | * |
21 | * Pagesize; 0, 256, 512 | 21 | * Pagesize; 0, 256, 512 |
22 | * 0 get this information from the extended chip ID | 22 | * 0 get this information from the extended chip ID |
23 | + 256 256 Byte page size | 23 | + 256 256 Byte page size |
24 | * 512 512 Byte page size | 24 | * 512 512 Byte page size |
25 | */ | 25 | */ |
26 | struct nand_flash_dev nand_flash_ids[] = { | 26 | struct nand_flash_dev nand_flash_ids[] = { |
27 | {"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0}, | 27 | {"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0}, |
@@ -34,27 +34,27 @@ struct nand_flash_dev nand_flash_ids[] = { | |||
34 | {"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, 0}, | 34 | {"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, 0}, |
35 | {"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, 0}, | 35 | {"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, 0}, |
36 | {"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, 0}, | 36 | {"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, 0}, |
37 | 37 | ||
38 | {"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, 0}, | 38 | {"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, 0}, |
39 | {"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, 0}, | 39 | {"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, 0}, |
40 | {"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16}, | 40 | {"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16}, |
41 | {"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16}, | 41 | {"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16}, |
42 | 42 | ||
43 | {"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, 0}, | 43 | {"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, 0}, |
44 | {"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, 0}, | 44 | {"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, 0}, |
45 | {"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16}, | 45 | {"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16}, |
46 | {"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16}, | 46 | {"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16}, |
47 | 47 | ||
48 | {"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, 0}, | 48 | {"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, 0}, |
49 | {"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, 0}, | 49 | {"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, 0}, |
50 | {"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16}, | 50 | {"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16}, |
51 | {"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16}, | 51 | {"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16}, |
52 | 52 | ||
53 | {"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, 0}, | 53 | {"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, 0}, |
54 | {"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, 0}, | 54 | {"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, 0}, |
55 | {"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16}, | 55 | {"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16}, |
56 | {"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16}, | 56 | {"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16}, |
57 | 57 | ||
58 | {"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0}, | 58 | {"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0}, |
59 | {"NAND 128MiB 1,8V 8-bit", 0x39, 512, 128, 0x4000, 0}, | 59 | {"NAND 128MiB 1,8V 8-bit", 0x39, 512, 128, 0x4000, 0}, |
60 | {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0}, | 60 | {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0}, |
@@ -62,7 +62,7 @@ struct nand_flash_dev nand_flash_ids[] = { | |||
62 | {"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16}, | 62 | {"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16}, |
63 | {"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16}, | 63 | {"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16}, |
64 | {"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16}, | 64 | {"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16}, |
65 | 65 | ||
66 | {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0}, | 66 | {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0}, |
67 | 67 | ||
68 | /* These are the new chips with large page size. The pagesize | 68 | /* These are the new chips with large page size. The pagesize |
@@ -73,7 +73,7 @@ struct nand_flash_dev nand_flash_ids[] = { | |||
73 | {"NAND 64MiB 3,3V 8-bit", 0xF2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, | 73 | {"NAND 64MiB 3,3V 8-bit", 0xF2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, |
74 | {"NAND 64MiB 1,8V 16-bit", 0xB2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, | 74 | {"NAND 64MiB 1,8V 16-bit", 0xB2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, |
75 | {"NAND 64MiB 3,3V 16-bit", 0xC2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, | 75 | {"NAND 64MiB 3,3V 16-bit", 0xC2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, |
76 | 76 | ||
77 | /* 1 Gigabit */ | 77 | /* 1 Gigabit */ |
78 | {"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, | 78 | {"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, |
79 | {"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, | 79 | {"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, |
@@ -85,13 +85,13 @@ struct nand_flash_dev nand_flash_ids[] = { | |||
85 | {"NAND 256MiB 3,3V 8-bit", 0xDA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, | 85 | {"NAND 256MiB 3,3V 8-bit", 0xDA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, |
86 | {"NAND 256MiB 1,8V 16-bit", 0xBA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, | 86 | {"NAND 256MiB 1,8V 16-bit", 0xBA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, |
87 | {"NAND 256MiB 3,3V 16-bit", 0xCA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, | 87 | {"NAND 256MiB 3,3V 16-bit", 0xCA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, |
88 | 88 | ||
89 | /* 4 Gigabit */ | 89 | /* 4 Gigabit */ |
90 | {"NAND 512MiB 1,8V 8-bit", 0xAC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, | 90 | {"NAND 512MiB 1,8V 8-bit", 0xAC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, |
91 | {"NAND 512MiB 3,3V 8-bit", 0xDC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, | 91 | {"NAND 512MiB 3,3V 8-bit", 0xDC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, |
92 | {"NAND 512MiB 1,8V 16-bit", 0xBC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, | 92 | {"NAND 512MiB 1,8V 16-bit", 0xBC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, |
93 | {"NAND 512MiB 3,3V 16-bit", 0xCC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, | 93 | {"NAND 512MiB 3,3V 16-bit", 0xCC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, |
94 | 94 | ||
95 | /* 8 Gigabit */ | 95 | /* 8 Gigabit */ |
96 | {"NAND 1GiB 1,8V 8-bit", 0xA3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, | 96 | {"NAND 1GiB 1,8V 8-bit", 0xA3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, |
97 | {"NAND 1GiB 3,3V 8-bit", 0xD3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, | 97 | {"NAND 1GiB 3,3V 8-bit", 0xD3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, |
@@ -104,11 +104,11 @@ struct nand_flash_dev nand_flash_ids[] = { | |||
104 | {"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, | 104 | {"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, |
105 | {"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, | 105 | {"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, |
106 | 106 | ||
107 | /* Renesas AND 1 Gigabit. Those chips do not support extended id and have a strange page/block layout ! | 107 | /* Renesas AND 1 Gigabit. Those chips do not support extended id and have a strange page/block layout ! |
108 | * The chosen minimum erasesize is 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page planes | 108 | * The chosen minimum erasesize is 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page planes |
109 | * 1 block = 2 pages, but due to plane arrangement the blocks 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7 | 109 | * 1 block = 2 pages, but due to plane arrangement the blocks 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7 |
110 | * Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go | 110 | * Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go |
111 | * There are more speed improvements for reads and writes possible, but not implemented now | 111 | * There are more speed improvements for reads and writes possible, but not implemented now |
112 | */ | 112 | */ |
113 | {"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH}, | 113 | {"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH}, |
114 | 114 | ||
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index 754b6ed7ce14..de4500395300 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Author: Artem B. Bityuckiy <dedekind@oktetlabs.ru>, <dedekind@infradead.org> | 4 | * Author: Artem B. Bityuckiy <dedekind@oktetlabs.ru>, <dedekind@infradead.org> |
5 | * | 5 | * |
6 | * Copyright (C) 2004 Nokia Corporation | 6 | * Copyright (C) 2004 Nokia Corporation |
7 | * | 7 | * |
8 | * Note: NS means "NAND Simulator". | 8 | * Note: NS means "NAND Simulator". |
9 | * Note: Input means input TO flash chip, output means output FROM chip. | 9 | * Note: Input means input TO flash chip, output means output FROM chip. |
@@ -126,7 +126,7 @@ MODULE_PARM_DESC(dbg, "Output debug information if not zero"); | |||
126 | 126 | ||
127 | /* The largest possible page size */ | 127 | /* The largest possible page size */ |
128 | #define NS_LARGEST_PAGE_SIZE 2048 | 128 | #define NS_LARGEST_PAGE_SIZE 2048 |
129 | 129 | ||
130 | /* The prefix for simulator output */ | 130 | /* The prefix for simulator output */ |
131 | #define NS_OUTPUT_PREFIX "[nandsim]" | 131 | #define NS_OUTPUT_PREFIX "[nandsim]" |
132 | 132 | ||
@@ -145,7 +145,7 @@ MODULE_PARM_DESC(dbg, "Output debug information if not zero"); | |||
145 | do { if (do_delays) udelay(us); } while(0) | 145 | do { if (do_delays) udelay(us); } while(0) |
146 | #define NS_MDELAY(us) \ | 146 | #define NS_MDELAY(us) \ |
147 | do { if (do_delays) mdelay(us); } while(0) | 147 | do { if (do_delays) mdelay(us); } while(0) |
148 | 148 | ||
149 | /* Is the nandsim structure initialized ? */ | 149 | /* Is the nandsim structure initialized ? */ |
150 | #define NS_IS_INITIALIZED(ns) ((ns)->geom.totsz != 0) | 150 | #define NS_IS_INITIALIZED(ns) ((ns)->geom.totsz != 0) |
151 | 151 | ||
@@ -153,12 +153,12 @@ MODULE_PARM_DESC(dbg, "Output debug information if not zero"); | |||
153 | #define NS_STATUS_OK(ns) (NAND_STATUS_READY | (NAND_STATUS_WP * ((ns)->lines.wp == 0))) | 153 | #define NS_STATUS_OK(ns) (NAND_STATUS_READY | (NAND_STATUS_WP * ((ns)->lines.wp == 0))) |
154 | 154 | ||
155 | /* Operation failed completion status */ | 155 | /* Operation failed completion status */ |
156 | #define NS_STATUS_FAILED(ns) (NAND_STATUS_FAIL | NS_STATUS_OK(ns)) | 156 | #define NS_STATUS_FAILED(ns) (NAND_STATUS_FAIL | NS_STATUS_OK(ns)) |
157 | 157 | ||
158 | /* Calculate the page offset in flash RAM image by (row, column) address */ | 158 | /* Calculate the page offset in flash RAM image by (row, column) address */ |
159 | #define NS_RAW_OFFSET(ns) \ | 159 | #define NS_RAW_OFFSET(ns) \ |
160 | (((ns)->regs.row << (ns)->geom.pgshift) + ((ns)->regs.row * (ns)->geom.oobsz) + (ns)->regs.column) | 160 | (((ns)->regs.row << (ns)->geom.pgshift) + ((ns)->regs.row * (ns)->geom.oobsz) + (ns)->regs.column) |
161 | 161 | ||
162 | /* Calculate the OOB offset in flash RAM image by (row, column) address */ | 162 | /* Calculate the OOB offset in flash RAM image by (row, column) address */ |
163 | #define NS_RAW_OFFSET_OOB(ns) (NS_RAW_OFFSET(ns) + ns->geom.pgsz) | 163 | #define NS_RAW_OFFSET_OOB(ns) (NS_RAW_OFFSET(ns) + ns->geom.pgsz) |
164 | 164 | ||
@@ -223,15 +223,15 @@ MODULE_PARM_DESC(dbg, "Output debug information if not zero"); | |||
223 | 223 | ||
224 | /* Remove action bits ftom state */ | 224 | /* Remove action bits ftom state */ |
225 | #define NS_STATE(x) ((x) & ~ACTION_MASK) | 225 | #define NS_STATE(x) ((x) & ~ACTION_MASK) |
226 | 226 | ||
227 | /* | 227 | /* |
228 | * Maximum previous states which need to be saved. Currently saving is | 228 | * Maximum previous states which need to be saved. Currently saving is |
229 | * only needed for page programm operation with preceeded read command | 229 | * only needed for page programm operation with preceeded read command |
230 | * (which is only valid for 512-byte pages). | 230 | * (which is only valid for 512-byte pages). |
231 | */ | 231 | */ |
232 | #define NS_MAX_PREVSTATES 1 | 232 | #define NS_MAX_PREVSTATES 1 |
233 | 233 | ||
234 | /* | 234 | /* |
235 | * The structure which describes all the internal simulator data. | 235 | * The structure which describes all the internal simulator data. |
236 | */ | 236 | */ |
237 | struct nandsim { | 237 | struct nandsim { |
@@ -242,7 +242,7 @@ struct nandsim { | |||
242 | uint32_t options; /* chip's characteristic bits */ | 242 | uint32_t options; /* chip's characteristic bits */ |
243 | uint32_t state; /* current chip state */ | 243 | uint32_t state; /* current chip state */ |
244 | uint32_t nxstate; /* next expected state */ | 244 | uint32_t nxstate; /* next expected state */ |
245 | 245 | ||
246 | uint32_t *op; /* current operation, NULL operations isn't known yet */ | 246 | uint32_t *op; /* current operation, NULL operations isn't known yet */ |
247 | uint32_t pstates[NS_MAX_PREVSTATES]; /* previous states */ | 247 | uint32_t pstates[NS_MAX_PREVSTATES]; /* previous states */ |
248 | uint16_t npstates; /* number of previous states saved */ | 248 | uint16_t npstates; /* number of previous states saved */ |
@@ -413,7 +413,7 @@ init_nandsim(struct mtd_info *mtd) | |||
413 | ns->geom.secaddrbytes = 3; | 413 | ns->geom.secaddrbytes = 3; |
414 | } | 414 | } |
415 | } | 415 | } |
416 | 416 | ||
417 | /* Detect how many ID bytes the NAND chip outputs */ | 417 | /* Detect how many ID bytes the NAND chip outputs */ |
418 | for (i = 0; nand_flash_ids[i].name != NULL; i++) { | 418 | for (i = 0; nand_flash_ids[i].name != NULL; i++) { |
419 | if (second_id_byte != nand_flash_ids[i].id) | 419 | if (second_id_byte != nand_flash_ids[i].id) |
@@ -444,7 +444,7 @@ init_nandsim(struct mtd_info *mtd) | |||
444 | #ifdef CONFIG_NS_ABS_POS | 444 | #ifdef CONFIG_NS_ABS_POS |
445 | ns->mem.byte = ioremap(CONFIG_NS_ABS_POS, ns->geom.totszoob); | 445 | ns->mem.byte = ioremap(CONFIG_NS_ABS_POS, ns->geom.totszoob); |
446 | if (!ns->mem.byte) { | 446 | if (!ns->mem.byte) { |
447 | NS_ERR("init_nandsim: failed to map the NAND flash image at address %p\n", | 447 | NS_ERR("init_nandsim: failed to map the NAND flash image at address %p\n", |
448 | (void *)CONFIG_NS_ABS_POS); | 448 | (void *)CONFIG_NS_ABS_POS); |
449 | return -ENOMEM; | 449 | return -ENOMEM; |
450 | } | 450 | } |
@@ -567,7 +567,7 @@ static int | |||
567 | check_command(int cmd) | 567 | check_command(int cmd) |
568 | { | 568 | { |
569 | switch (cmd) { | 569 | switch (cmd) { |
570 | 570 | ||
571 | case NAND_CMD_READ0: | 571 | case NAND_CMD_READ0: |
572 | case NAND_CMD_READSTART: | 572 | case NAND_CMD_READSTART: |
573 | case NAND_CMD_PAGEPROG: | 573 | case NAND_CMD_PAGEPROG: |
@@ -580,7 +580,7 @@ check_command(int cmd) | |||
580 | case NAND_CMD_RESET: | 580 | case NAND_CMD_RESET: |
581 | case NAND_CMD_READ1: | 581 | case NAND_CMD_READ1: |
582 | return 0; | 582 | return 0; |
583 | 583 | ||
584 | case NAND_CMD_STATUS_MULTI: | 584 | case NAND_CMD_STATUS_MULTI: |
585 | default: | 585 | default: |
586 | return 1; | 586 | return 1; |
@@ -631,7 +631,7 @@ static inline void | |||
631 | accept_addr_byte(struct nandsim *ns, u_char bt) | 631 | accept_addr_byte(struct nandsim *ns, u_char bt) |
632 | { | 632 | { |
633 | uint byte = (uint)bt; | 633 | uint byte = (uint)bt; |
634 | 634 | ||
635 | if (ns->regs.count < (ns->geom.pgaddrbytes - ns->geom.secaddrbytes)) | 635 | if (ns->regs.count < (ns->geom.pgaddrbytes - ns->geom.secaddrbytes)) |
636 | ns->regs.column |= (byte << 8 * ns->regs.count); | 636 | ns->regs.column |= (byte << 8 * ns->regs.count); |
637 | else { | 637 | else { |
@@ -642,11 +642,11 @@ accept_addr_byte(struct nandsim *ns, u_char bt) | |||
642 | 642 | ||
643 | return; | 643 | return; |
644 | } | 644 | } |
645 | 645 | ||
646 | /* | 646 | /* |
647 | * Switch to STATE_READY state. | 647 | * Switch to STATE_READY state. |
648 | */ | 648 | */ |
649 | static inline void | 649 | static inline void |
650 | switch_to_ready_state(struct nandsim *ns, u_char status) | 650 | switch_to_ready_state(struct nandsim *ns, u_char status) |
651 | { | 651 | { |
652 | NS_DBG("switch_to_ready_state: switch to %s state\n", get_state_name(STATE_READY)); | 652 | NS_DBG("switch_to_ready_state: switch to %s state\n", get_state_name(STATE_READY)); |
@@ -675,7 +675,7 @@ switch_to_ready_state(struct nandsim *ns, u_char status) | |||
675 | * (for example program from the second half and read from the | 675 | * (for example program from the second half and read from the |
676 | * second half operations both begin with the READ1 command). In this | 676 | * second half operations both begin with the READ1 command). In this |
677 | * case the ns->pstates[] array contains previous states. | 677 | * case the ns->pstates[] array contains previous states. |
678 | * | 678 | * |
679 | * Thus, the function tries to find operation containing the following | 679 | * Thus, the function tries to find operation containing the following |
680 | * states (if the 'flag' parameter is 0): | 680 | * states (if the 'flag' parameter is 0): |
681 | * ns->pstates[0], ... ns->pstates[ns->npstates], ns->state | 681 | * ns->pstates[0], ... ns->pstates[ns->npstates], ns->state |
@@ -683,7 +683,7 @@ switch_to_ready_state(struct nandsim *ns, u_char status) | |||
683 | * If (one and only one) matching operation is found, it is accepted ( | 683 | * If (one and only one) matching operation is found, it is accepted ( |
684 | * ns->ops, ns->state, ns->nxstate are initialized, ns->npstate is | 684 | * ns->ops, ns->state, ns->nxstate are initialized, ns->npstate is |
685 | * zeroed). | 685 | * zeroed). |
686 | * | 686 | * |
687 | * If there are several maches, the current state is pushed to the | 687 | * If there are several maches, the current state is pushed to the |
688 | * ns->pstates. | 688 | * ns->pstates. |
689 | * | 689 | * |
@@ -692,7 +692,7 @@ switch_to_ready_state(struct nandsim *ns, u_char status) | |||
692 | * In such situation the function is called with 'flag' != 0, and the | 692 | * In such situation the function is called with 'flag' != 0, and the |
693 | * operation is searched using the following pattern: | 693 | * operation is searched using the following pattern: |
694 | * ns->pstates[0], ... ns->pstates[ns->npstates], <address input> | 694 | * ns->pstates[0], ... ns->pstates[ns->npstates], <address input> |
695 | * | 695 | * |
696 | * It is supposed that this pattern must either match one operation on | 696 | * It is supposed that this pattern must either match one operation on |
697 | * none. There can't be ambiguity in that case. | 697 | * none. There can't be ambiguity in that case. |
698 | * | 698 | * |
@@ -711,15 +711,15 @@ find_operation(struct nandsim *ns, uint32_t flag) | |||
711 | { | 711 | { |
712 | int opsfound = 0; | 712 | int opsfound = 0; |
713 | int i, j, idx = 0; | 713 | int i, j, idx = 0; |
714 | 714 | ||
715 | for (i = 0; i < NS_OPER_NUM; i++) { | 715 | for (i = 0; i < NS_OPER_NUM; i++) { |
716 | 716 | ||
717 | int found = 1; | 717 | int found = 1; |
718 | 718 | ||
719 | if (!(ns->options & ops[i].reqopts)) | 719 | if (!(ns->options & ops[i].reqopts)) |
720 | /* Ignore operations we can't perform */ | 720 | /* Ignore operations we can't perform */ |
721 | continue; | 721 | continue; |
722 | 722 | ||
723 | if (flag) { | 723 | if (flag) { |
724 | if (!(ops[i].states[ns->npstates] & STATE_ADDR_MASK)) | 724 | if (!(ops[i].states[ns->npstates] & STATE_ADDR_MASK)) |
725 | continue; | 725 | continue; |
@@ -728,7 +728,7 @@ find_operation(struct nandsim *ns, uint32_t flag) | |||
728 | continue; | 728 | continue; |
729 | } | 729 | } |
730 | 730 | ||
731 | for (j = 0; j < ns->npstates; j++) | 731 | for (j = 0; j < ns->npstates; j++) |
732 | if (NS_STATE(ops[i].states[j]) != NS_STATE(ns->pstates[j]) | 732 | if (NS_STATE(ops[i].states[j]) != NS_STATE(ns->pstates[j]) |
733 | && (ns->options & ops[idx].reqopts)) { | 733 | && (ns->options & ops[idx].reqopts)) { |
734 | found = 0; | 734 | found = 0; |
@@ -745,7 +745,7 @@ find_operation(struct nandsim *ns, uint32_t flag) | |||
745 | /* Exact match */ | 745 | /* Exact match */ |
746 | ns->op = &ops[idx].states[0]; | 746 | ns->op = &ops[idx].states[0]; |
747 | if (flag) { | 747 | if (flag) { |
748 | /* | 748 | /* |
749 | * In this case the find_operation function was | 749 | * In this case the find_operation function was |
750 | * called when address has just began input. But it isn't | 750 | * called when address has just began input. But it isn't |
751 | * yet fully input and the current state must | 751 | * yet fully input and the current state must |
@@ -763,7 +763,7 @@ find_operation(struct nandsim *ns, uint32_t flag) | |||
763 | idx, get_state_name(ns->state), get_state_name(ns->nxstate)); | 763 | idx, get_state_name(ns->state), get_state_name(ns->nxstate)); |
764 | return 0; | 764 | return 0; |
765 | } | 765 | } |
766 | 766 | ||
767 | if (opsfound == 0) { | 767 | if (opsfound == 0) { |
768 | /* Nothing was found. Try to ignore previous commands (if any) and search again */ | 768 | /* Nothing was found. Try to ignore previous commands (if any) and search again */ |
769 | if (ns->npstates != 0) { | 769 | if (ns->npstates != 0) { |
@@ -777,13 +777,13 @@ find_operation(struct nandsim *ns, uint32_t flag) | |||
777 | switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); | 777 | switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); |
778 | return -2; | 778 | return -2; |
779 | } | 779 | } |
780 | 780 | ||
781 | if (flag) { | 781 | if (flag) { |
782 | /* This shouldn't happen */ | 782 | /* This shouldn't happen */ |
783 | NS_DBG("find_operation: BUG, operation must be known if address is input\n"); | 783 | NS_DBG("find_operation: BUG, operation must be known if address is input\n"); |
784 | return -2; | 784 | return -2; |
785 | } | 785 | } |
786 | 786 | ||
787 | NS_DBG("find_operation: there is still ambiguity\n"); | 787 | NS_DBG("find_operation: there is still ambiguity\n"); |
788 | 788 | ||
789 | ns->pstates[ns->npstates++] = ns->state; | 789 | ns->pstates[ns->npstates++] = ns->state; |
@@ -803,7 +803,7 @@ do_state_action(struct nandsim *ns, uint32_t action) | |||
803 | int busdiv = ns->busw == 8 ? 1 : 2; | 803 | int busdiv = ns->busw == 8 ? 1 : 2; |
804 | 804 | ||
805 | action &= ACTION_MASK; | 805 | action &= ACTION_MASK; |
806 | 806 | ||
807 | /* Check that page address input is correct */ | 807 | /* Check that page address input is correct */ |
808 | if (action != ACTION_SECERASE && ns->regs.row >= ns->geom.pgnum) { | 808 | if (action != ACTION_SECERASE && ns->regs.row >= ns->geom.pgnum) { |
809 | NS_WARN("do_state_action: wrong page number (%#x)\n", ns->regs.row); | 809 | NS_WARN("do_state_action: wrong page number (%#x)\n", ns->regs.row); |
@@ -827,14 +827,14 @@ do_state_action(struct nandsim *ns, uint32_t action) | |||
827 | 827 | ||
828 | NS_DBG("do_state_action: (ACTION_CPY:) copy %d bytes to int buf, raw offset %d\n", | 828 | NS_DBG("do_state_action: (ACTION_CPY:) copy %d bytes to int buf, raw offset %d\n", |
829 | num, NS_RAW_OFFSET(ns) + ns->regs.off); | 829 | num, NS_RAW_OFFSET(ns) + ns->regs.off); |
830 | 830 | ||
831 | if (ns->regs.off == 0) | 831 | if (ns->regs.off == 0) |
832 | NS_LOG("read page %d\n", ns->regs.row); | 832 | NS_LOG("read page %d\n", ns->regs.row); |
833 | else if (ns->regs.off < ns->geom.pgsz) | 833 | else if (ns->regs.off < ns->geom.pgsz) |
834 | NS_LOG("read page %d (second half)\n", ns->regs.row); | 834 | NS_LOG("read page %d (second half)\n", ns->regs.row); |
835 | else | 835 | else |
836 | NS_LOG("read OOB of page %d\n", ns->regs.row); | 836 | NS_LOG("read OOB of page %d\n", ns->regs.row); |
837 | 837 | ||
838 | NS_UDELAY(access_delay); | 838 | NS_UDELAY(access_delay); |
839 | NS_UDELAY(input_cycle * ns->geom.pgsz / 1000 / busdiv); | 839 | NS_UDELAY(input_cycle * ns->geom.pgsz / 1000 / busdiv); |
840 | 840 | ||
@@ -844,30 +844,30 @@ do_state_action(struct nandsim *ns, uint32_t action) | |||
844 | /* | 844 | /* |
845 | * Erase sector. | 845 | * Erase sector. |
846 | */ | 846 | */ |
847 | 847 | ||
848 | if (ns->lines.wp) { | 848 | if (ns->lines.wp) { |
849 | NS_ERR("do_state_action: device is write-protected, ignore sector erase\n"); | 849 | NS_ERR("do_state_action: device is write-protected, ignore sector erase\n"); |
850 | return -1; | 850 | return -1; |
851 | } | 851 | } |
852 | 852 | ||
853 | if (ns->regs.row >= ns->geom.pgnum - ns->geom.pgsec | 853 | if (ns->regs.row >= ns->geom.pgnum - ns->geom.pgsec |
854 | || (ns->regs.row & ~(ns->geom.secsz - 1))) { | 854 | || (ns->regs.row & ~(ns->geom.secsz - 1))) { |
855 | NS_ERR("do_state_action: wrong sector address (%#x)\n", ns->regs.row); | 855 | NS_ERR("do_state_action: wrong sector address (%#x)\n", ns->regs.row); |
856 | return -1; | 856 | return -1; |
857 | } | 857 | } |
858 | 858 | ||
859 | ns->regs.row = (ns->regs.row << | 859 | ns->regs.row = (ns->regs.row << |
860 | 8 * (ns->geom.pgaddrbytes - ns->geom.secaddrbytes)) | ns->regs.column; | 860 | 8 * (ns->geom.pgaddrbytes - ns->geom.secaddrbytes)) | ns->regs.column; |
861 | ns->regs.column = 0; | 861 | ns->regs.column = 0; |
862 | 862 | ||
863 | NS_DBG("do_state_action: erase sector at address %#x, off = %d\n", | 863 | NS_DBG("do_state_action: erase sector at address %#x, off = %d\n", |
864 | ns->regs.row, NS_RAW_OFFSET(ns)); | 864 | ns->regs.row, NS_RAW_OFFSET(ns)); |
865 | NS_LOG("erase sector %d\n", ns->regs.row >> (ns->geom.secshift - ns->geom.pgshift)); | 865 | NS_LOG("erase sector %d\n", ns->regs.row >> (ns->geom.secshift - ns->geom.pgshift)); |
866 | 866 | ||
867 | memset(ns->mem.byte + NS_RAW_OFFSET(ns), 0xFF, ns->geom.secszoob); | 867 | memset(ns->mem.byte + NS_RAW_OFFSET(ns), 0xFF, ns->geom.secszoob); |
868 | 868 | ||
869 | NS_MDELAY(erase_delay); | 869 | NS_MDELAY(erase_delay); |
870 | 870 | ||
871 | break; | 871 | break; |
872 | 872 | ||
873 | case ACTION_PRGPAGE: | 873 | case ACTION_PRGPAGE: |
@@ -893,12 +893,12 @@ do_state_action(struct nandsim *ns, uint32_t action) | |||
893 | NS_DBG("do_state_action: copy %d bytes from int buf to (%#x, %#x), raw off = %d\n", | 893 | NS_DBG("do_state_action: copy %d bytes from int buf to (%#x, %#x), raw off = %d\n", |
894 | num, ns->regs.row, ns->regs.column, NS_RAW_OFFSET(ns) + ns->regs.off); | 894 | num, ns->regs.row, ns->regs.column, NS_RAW_OFFSET(ns) + ns->regs.off); |
895 | NS_LOG("programm page %d\n", ns->regs.row); | 895 | NS_LOG("programm page %d\n", ns->regs.row); |
896 | 896 | ||
897 | NS_UDELAY(programm_delay); | 897 | NS_UDELAY(programm_delay); |
898 | NS_UDELAY(output_cycle * ns->geom.pgsz / 1000 / busdiv); | 898 | NS_UDELAY(output_cycle * ns->geom.pgsz / 1000 / busdiv); |
899 | 899 | ||
900 | break; | 900 | break; |
901 | 901 | ||
902 | case ACTION_ZEROOFF: | 902 | case ACTION_ZEROOFF: |
903 | NS_DBG("do_state_action: set internal offset to 0\n"); | 903 | NS_DBG("do_state_action: set internal offset to 0\n"); |
904 | ns->regs.off = 0; | 904 | ns->regs.off = 0; |
@@ -918,7 +918,7 @@ do_state_action(struct nandsim *ns, uint32_t action) | |||
918 | NS_DBG("do_state_action: set internal offset to %d\n", ns->geom.pgsz); | 918 | NS_DBG("do_state_action: set internal offset to %d\n", ns->geom.pgsz); |
919 | ns->regs.off = ns->geom.pgsz; | 919 | ns->regs.off = ns->geom.pgsz; |
920 | break; | 920 | break; |
921 | 921 | ||
922 | default: | 922 | default: |
923 | NS_DBG("do_state_action: BUG! unknown action\n"); | 923 | NS_DBG("do_state_action: BUG! unknown action\n"); |
924 | } | 924 | } |
@@ -937,7 +937,7 @@ switch_state(struct nandsim *ns) | |||
937 | * The current operation have already been identified. | 937 | * The current operation have already been identified. |
938 | * Just follow the states chain. | 938 | * Just follow the states chain. |
939 | */ | 939 | */ |
940 | 940 | ||
941 | ns->stateidx += 1; | 941 | ns->stateidx += 1; |
942 | ns->state = ns->nxstate; | 942 | ns->state = ns->nxstate; |
943 | ns->nxstate = ns->op[ns->stateidx + 1]; | 943 | ns->nxstate = ns->op[ns->stateidx + 1]; |
@@ -951,14 +951,14 @@ switch_state(struct nandsim *ns) | |||
951 | switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); | 951 | switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); |
952 | return; | 952 | return; |
953 | } | 953 | } |
954 | 954 | ||
955 | } else { | 955 | } else { |
956 | /* | 956 | /* |
957 | * We don't yet know which operation we perform. | 957 | * We don't yet know which operation we perform. |
958 | * Try to identify it. | 958 | * Try to identify it. |
959 | */ | 959 | */ |
960 | 960 | ||
961 | /* | 961 | /* |
962 | * The only event causing the switch_state function to | 962 | * The only event causing the switch_state function to |
963 | * be called with yet unknown operation is new command. | 963 | * be called with yet unknown operation is new command. |
964 | */ | 964 | */ |
@@ -987,7 +987,7 @@ switch_state(struct nandsim *ns) | |||
987 | */ | 987 | */ |
988 | 988 | ||
989 | u_char status = NS_STATUS_OK(ns); | 989 | u_char status = NS_STATUS_OK(ns); |
990 | 990 | ||
991 | /* In case of data states, see if all bytes were input/output */ | 991 | /* In case of data states, see if all bytes were input/output */ |
992 | if ((ns->state & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK)) | 992 | if ((ns->state & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK)) |
993 | && ns->regs.count != ns->regs.num) { | 993 | && ns->regs.count != ns->regs.num) { |
@@ -995,17 +995,17 @@ switch_state(struct nandsim *ns) | |||
995 | ns->regs.num - ns->regs.count); | 995 | ns->regs.num - ns->regs.count); |
996 | status = NS_STATUS_FAILED(ns); | 996 | status = NS_STATUS_FAILED(ns); |
997 | } | 997 | } |
998 | 998 | ||
999 | NS_DBG("switch_state: operation complete, switch to STATE_READY state\n"); | 999 | NS_DBG("switch_state: operation complete, switch to STATE_READY state\n"); |
1000 | 1000 | ||
1001 | switch_to_ready_state(ns, status); | 1001 | switch_to_ready_state(ns, status); |
1002 | 1002 | ||
1003 | return; | 1003 | return; |
1004 | } else if (ns->nxstate & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK)) { | 1004 | } else if (ns->nxstate & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK)) { |
1005 | /* | 1005 | /* |
1006 | * If the next state is data input/output, switch to it now | 1006 | * If the next state is data input/output, switch to it now |
1007 | */ | 1007 | */ |
1008 | 1008 | ||
1009 | ns->state = ns->nxstate; | 1009 | ns->state = ns->nxstate; |
1010 | ns->nxstate = ns->op[++ns->stateidx + 1]; | 1010 | ns->nxstate = ns->op[++ns->stateidx + 1]; |
1011 | ns->regs.num = ns->regs.count = 0; | 1011 | ns->regs.num = ns->regs.count = 0; |
@@ -1023,16 +1023,16 @@ switch_state(struct nandsim *ns) | |||
1023 | case STATE_DATAOUT: | 1023 | case STATE_DATAOUT: |
1024 | ns->regs.num = ns->geom.pgszoob - ns->regs.off - ns->regs.column; | 1024 | ns->regs.num = ns->geom.pgszoob - ns->regs.off - ns->regs.column; |
1025 | break; | 1025 | break; |
1026 | 1026 | ||
1027 | case STATE_DATAOUT_ID: | 1027 | case STATE_DATAOUT_ID: |
1028 | ns->regs.num = ns->geom.idbytes; | 1028 | ns->regs.num = ns->geom.idbytes; |
1029 | break; | 1029 | break; |
1030 | 1030 | ||
1031 | case STATE_DATAOUT_STATUS: | 1031 | case STATE_DATAOUT_STATUS: |
1032 | case STATE_DATAOUT_STATUS_M: | 1032 | case STATE_DATAOUT_STATUS_M: |
1033 | ns->regs.count = ns->regs.num = 0; | 1033 | ns->regs.count = ns->regs.num = 0; |
1034 | break; | 1034 | break; |
1035 | 1035 | ||
1036 | default: | 1036 | default: |
1037 | NS_ERR("switch_state: BUG! unknown data state\n"); | 1037 | NS_ERR("switch_state: BUG! unknown data state\n"); |
1038 | } | 1038 | } |
@@ -1044,16 +1044,16 @@ switch_state(struct nandsim *ns) | |||
1044 | */ | 1044 | */ |
1045 | 1045 | ||
1046 | ns->regs.count = 0; | 1046 | ns->regs.count = 0; |
1047 | 1047 | ||
1048 | switch (NS_STATE(ns->nxstate)) { | 1048 | switch (NS_STATE(ns->nxstate)) { |
1049 | case STATE_ADDR_PAGE: | 1049 | case STATE_ADDR_PAGE: |
1050 | ns->regs.num = ns->geom.pgaddrbytes; | 1050 | ns->regs.num = ns->geom.pgaddrbytes; |
1051 | 1051 | ||
1052 | break; | 1052 | break; |
1053 | case STATE_ADDR_SEC: | 1053 | case STATE_ADDR_SEC: |
1054 | ns->regs.num = ns->geom.secaddrbytes; | 1054 | ns->regs.num = ns->geom.secaddrbytes; |
1055 | break; | 1055 | break; |
1056 | 1056 | ||
1057 | case STATE_ADDR_ZERO: | 1057 | case STATE_ADDR_ZERO: |
1058 | ns->regs.num = 1; | 1058 | ns->regs.num = 1; |
1059 | break; | 1059 | break; |
@@ -1062,7 +1062,7 @@ switch_state(struct nandsim *ns) | |||
1062 | NS_ERR("switch_state: BUG! unknown address state\n"); | 1062 | NS_ERR("switch_state: BUG! unknown address state\n"); |
1063 | } | 1063 | } |
1064 | } else { | 1064 | } else { |
1065 | /* | 1065 | /* |
1066 | * Just reset internal counters. | 1066 | * Just reset internal counters. |
1067 | */ | 1067 | */ |
1068 | 1068 | ||
@@ -1184,7 +1184,7 @@ ns_nand_read_byte(struct mtd_info *mtd) | |||
1184 | default: | 1184 | default: |
1185 | BUG(); | 1185 | BUG(); |
1186 | } | 1186 | } |
1187 | 1187 | ||
1188 | if (ns->regs.count == ns->regs.num) { | 1188 | if (ns->regs.count == ns->regs.num) { |
1189 | NS_DBG("read_byte: all bytes were read\n"); | 1189 | NS_DBG("read_byte: all bytes were read\n"); |
1190 | 1190 | ||
@@ -1201,9 +1201,9 @@ ns_nand_read_byte(struct mtd_info *mtd) | |||
1201 | } | 1201 | } |
1202 | else if (NS_STATE(ns->nxstate) == STATE_READY) | 1202 | else if (NS_STATE(ns->nxstate) == STATE_READY) |
1203 | switch_state(ns); | 1203 | switch_state(ns); |
1204 | 1204 | ||
1205 | } | 1205 | } |
1206 | 1206 | ||
1207 | return outb; | 1207 | return outb; |
1208 | } | 1208 | } |
1209 | 1209 | ||
@@ -1211,7 +1211,7 @@ static void | |||
1211 | ns_nand_write_byte(struct mtd_info *mtd, u_char byte) | 1211 | ns_nand_write_byte(struct mtd_info *mtd, u_char byte) |
1212 | { | 1212 | { |
1213 | struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; | 1213 | struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; |
1214 | 1214 | ||
1215 | /* Sanity and correctness checks */ | 1215 | /* Sanity and correctness checks */ |
1216 | if (!ns->lines.ce) { | 1216 | if (!ns->lines.ce) { |
1217 | NS_ERR("write_byte: chip is disabled, ignore write\n"); | 1217 | NS_ERR("write_byte: chip is disabled, ignore write\n"); |
@@ -1221,7 +1221,7 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte) | |||
1221 | NS_ERR("write_byte: ALE and CLE pins are high simultaneously, ignore write\n"); | 1221 | NS_ERR("write_byte: ALE and CLE pins are high simultaneously, ignore write\n"); |
1222 | return; | 1222 | return; |
1223 | } | 1223 | } |
1224 | 1224 | ||
1225 | if (ns->lines.cle == 1) { | 1225 | if (ns->lines.cle == 1) { |
1226 | /* | 1226 | /* |
1227 | * The byte written is a command. | 1227 | * The byte written is a command. |
@@ -1233,7 +1233,7 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte) | |||
1233 | return; | 1233 | return; |
1234 | } | 1234 | } |
1235 | 1235 | ||
1236 | /* | 1236 | /* |
1237 | * Chip might still be in STATE_DATAOUT | 1237 | * Chip might still be in STATE_DATAOUT |
1238 | * (if OPT_AUTOINCR feature is supported), STATE_DATAOUT_STATUS or | 1238 | * (if OPT_AUTOINCR feature is supported), STATE_DATAOUT_STATUS or |
1239 | * STATE_DATAOUT_STATUS_M state. If so, switch state. | 1239 | * STATE_DATAOUT_STATUS_M state. If so, switch state. |
@@ -1254,13 +1254,13 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte) | |||
1254 | "ignore previous states\n", (uint)byte, get_state_name(ns->nxstate)); | 1254 | "ignore previous states\n", (uint)byte, get_state_name(ns->nxstate)); |
1255 | switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); | 1255 | switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); |
1256 | } | 1256 | } |
1257 | 1257 | ||
1258 | /* Check that the command byte is correct */ | 1258 | /* Check that the command byte is correct */ |
1259 | if (check_command(byte)) { | 1259 | if (check_command(byte)) { |
1260 | NS_ERR("write_byte: unknown command %#x\n", (uint)byte); | 1260 | NS_ERR("write_byte: unknown command %#x\n", (uint)byte); |
1261 | return; | 1261 | return; |
1262 | } | 1262 | } |
1263 | 1263 | ||
1264 | NS_DBG("command byte corresponding to %s state accepted\n", | 1264 | NS_DBG("command byte corresponding to %s state accepted\n", |
1265 | get_state_name(get_state_by_command(byte))); | 1265 | get_state_name(get_state_by_command(byte))); |
1266 | ns->regs.command = byte; | 1266 | ns->regs.command = byte; |
@@ -1277,12 +1277,12 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte) | |||
1277 | 1277 | ||
1278 | if (find_operation(ns, 1) < 0) | 1278 | if (find_operation(ns, 1) < 0) |
1279 | return; | 1279 | return; |
1280 | 1280 | ||
1281 | if ((ns->state & ACTION_MASK) && do_state_action(ns, ns->state) < 0) { | 1281 | if ((ns->state & ACTION_MASK) && do_state_action(ns, ns->state) < 0) { |
1282 | switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); | 1282 | switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); |
1283 | return; | 1283 | return; |
1284 | } | 1284 | } |
1285 | 1285 | ||
1286 | ns->regs.count = 0; | 1286 | ns->regs.count = 0; |
1287 | switch (NS_STATE(ns->nxstate)) { | 1287 | switch (NS_STATE(ns->nxstate)) { |
1288 | case STATE_ADDR_PAGE: | 1288 | case STATE_ADDR_PAGE: |
@@ -1306,7 +1306,7 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte) | |||
1306 | switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); | 1306 | switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); |
1307 | return; | 1307 | return; |
1308 | } | 1308 | } |
1309 | 1309 | ||
1310 | /* Check if this is expected byte */ | 1310 | /* Check if this is expected byte */ |
1311 | if (ns->regs.count == ns->regs.num) { | 1311 | if (ns->regs.count == ns->regs.num) { |
1312 | NS_ERR("write_byte: no more address bytes expected\n"); | 1312 | NS_ERR("write_byte: no more address bytes expected\n"); |
@@ -1325,12 +1325,12 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte) | |||
1325 | NS_DBG("address (%#x, %#x) is accepted\n", ns->regs.row, ns->regs.column); | 1325 | NS_DBG("address (%#x, %#x) is accepted\n", ns->regs.row, ns->regs.column); |
1326 | switch_state(ns); | 1326 | switch_state(ns); |
1327 | } | 1327 | } |
1328 | 1328 | ||
1329 | } else { | 1329 | } else { |
1330 | /* | 1330 | /* |
1331 | * The byte written is an input data. | 1331 | * The byte written is an input data. |
1332 | */ | 1332 | */ |
1333 | 1333 | ||
1334 | /* Check that chip is expecting data input */ | 1334 | /* Check that chip is expecting data input */ |
1335 | if (!(ns->state & STATE_DATAIN_MASK)) { | 1335 | if (!(ns->state & STATE_DATAIN_MASK)) { |
1336 | NS_ERR("write_byte: data input (%#x) isn't expected, state is %s, " | 1336 | NS_ERR("write_byte: data input (%#x) isn't expected, state is %s, " |
@@ -1372,7 +1372,7 @@ ns_nand_read_word(struct mtd_info *mtd) | |||
1372 | struct nand_chip *chip = (struct nand_chip *)mtd->priv; | 1372 | struct nand_chip *chip = (struct nand_chip *)mtd->priv; |
1373 | 1373 | ||
1374 | NS_DBG("read_word\n"); | 1374 | NS_DBG("read_word\n"); |
1375 | 1375 | ||
1376 | return chip->read_byte(mtd) | (chip->read_byte(mtd) << 8); | 1376 | return chip->read_byte(mtd) | (chip->read_byte(mtd) << 8); |
1377 | } | 1377 | } |
1378 | 1378 | ||
@@ -1380,14 +1380,14 @@ static void | |||
1380 | ns_nand_write_word(struct mtd_info *mtd, uint16_t word) | 1380 | ns_nand_write_word(struct mtd_info *mtd, uint16_t word) |
1381 | { | 1381 | { |
1382 | struct nand_chip *chip = (struct nand_chip *)mtd->priv; | 1382 | struct nand_chip *chip = (struct nand_chip *)mtd->priv; |
1383 | 1383 | ||
1384 | NS_DBG("write_word\n"); | 1384 | NS_DBG("write_word\n"); |
1385 | 1385 | ||
1386 | chip->write_byte(mtd, word & 0xFF); | 1386 | chip->write_byte(mtd, word & 0xFF); |
1387 | chip->write_byte(mtd, word >> 8); | 1387 | chip->write_byte(mtd, word >> 8); |
1388 | } | 1388 | } |
1389 | 1389 | ||
1390 | static void | 1390 | static void |
1391 | ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) | 1391 | ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) |
1392 | { | 1392 | { |
1393 | struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; | 1393 | struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; |
@@ -1409,13 +1409,13 @@ ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) | |||
1409 | 1409 | ||
1410 | memcpy(ns->buf.byte + ns->regs.count, buf, len); | 1410 | memcpy(ns->buf.byte + ns->regs.count, buf, len); |
1411 | ns->regs.count += len; | 1411 | ns->regs.count += len; |
1412 | 1412 | ||
1413 | if (ns->regs.count == ns->regs.num) { | 1413 | if (ns->regs.count == ns->regs.num) { |
1414 | NS_DBG("write_buf: %d bytes were written\n", ns->regs.count); | 1414 | NS_DBG("write_buf: %d bytes were written\n", ns->regs.count); |
1415 | } | 1415 | } |
1416 | } | 1416 | } |
1417 | 1417 | ||
1418 | static void | 1418 | static void |
1419 | ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) | 1419 | ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) |
1420 | { | 1420 | { |
1421 | struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; | 1421 | struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; |
@@ -1453,7 +1453,7 @@ ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) | |||
1453 | 1453 | ||
1454 | memcpy(buf, ns->buf.byte + ns->regs.count, len); | 1454 | memcpy(buf, ns->buf.byte + ns->regs.count, len); |
1455 | ns->regs.count += len; | 1455 | ns->regs.count += len; |
1456 | 1456 | ||
1457 | if (ns->regs.count == ns->regs.num) { | 1457 | if (ns->regs.count == ns->regs.num) { |
1458 | if ((ns->options & OPT_AUTOINCR) && NS_STATE(ns->state) == STATE_DATAOUT) { | 1458 | if ((ns->options & OPT_AUTOINCR) && NS_STATE(ns->state) == STATE_DATAOUT) { |
1459 | ns->regs.count = 0; | 1459 | ns->regs.count = 0; |
@@ -1465,11 +1465,11 @@ ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) | |||
1465 | else if (NS_STATE(ns->nxstate) == STATE_READY) | 1465 | else if (NS_STATE(ns->nxstate) == STATE_READY) |
1466 | switch_state(ns); | 1466 | switch_state(ns); |
1467 | } | 1467 | } |
1468 | 1468 | ||
1469 | return; | 1469 | return; |
1470 | } | 1470 | } |
1471 | 1471 | ||
1472 | static int | 1472 | static int |
1473 | ns_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) | 1473 | ns_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) |
1474 | { | 1474 | { |
1475 | ns_nand_read_buf(mtd, (u_char *)&ns_verify_buf[0], len); | 1475 | ns_nand_read_buf(mtd, (u_char *)&ns_verify_buf[0], len); |
@@ -1496,7 +1496,7 @@ int __init ns_init_module(void) | |||
1496 | NS_ERR("wrong bus width (%d), use only 8 or 16\n", bus_width); | 1496 | NS_ERR("wrong bus width (%d), use only 8 or 16\n", bus_width); |
1497 | return -EINVAL; | 1497 | return -EINVAL; |
1498 | } | 1498 | } |
1499 | 1499 | ||
1500 | /* Allocate and initialize mtd_info, nand_chip and nandsim structures */ | 1500 | /* Allocate and initialize mtd_info, nand_chip and nandsim structures */ |
1501 | nsmtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip) | 1501 | nsmtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip) |
1502 | + sizeof(struct nandsim), GFP_KERNEL); | 1502 | + sizeof(struct nandsim), GFP_KERNEL); |
@@ -1509,7 +1509,7 @@ int __init ns_init_module(void) | |||
1509 | chip = (struct nand_chip *)(nsmtd + 1); | 1509 | chip = (struct nand_chip *)(nsmtd + 1); |
1510 | nsmtd->priv = (void *)chip; | 1510 | nsmtd->priv = (void *)chip; |
1511 | nand = (struct nandsim *)(chip + 1); | 1511 | nand = (struct nandsim *)(chip + 1); |
1512 | chip->priv = (void *)nand; | 1512 | chip->priv = (void *)nand; |
1513 | 1513 | ||
1514 | /* | 1514 | /* |
1515 | * Register simulator's callbacks. | 1515 | * Register simulator's callbacks. |
@@ -1526,9 +1526,9 @@ int __init ns_init_module(void) | |||
1526 | chip->eccmode = NAND_ECC_SOFT; | 1526 | chip->eccmode = NAND_ECC_SOFT; |
1527 | chip->options |= NAND_SKIP_BBTSCAN; | 1527 | chip->options |= NAND_SKIP_BBTSCAN; |
1528 | 1528 | ||
1529 | /* | 1529 | /* |
1530 | * Perform minimum nandsim structure initialization to handle | 1530 | * Perform minimum nandsim structure initialization to handle |
1531 | * the initial ID read command correctly | 1531 | * the initial ID read command correctly |
1532 | */ | 1532 | */ |
1533 | if (third_id_byte != 0xFF || fourth_id_byte != 0xFF) | 1533 | if (third_id_byte != 0xFF || fourth_id_byte != 0xFF) |
1534 | nand->geom.idbytes = 4; | 1534 | nand->geom.idbytes = 4; |
@@ -1557,7 +1557,7 @@ int __init ns_init_module(void) | |||
1557 | NS_ERR("scan_bbt: can't initialize the nandsim structure\n"); | 1557 | NS_ERR("scan_bbt: can't initialize the nandsim structure\n"); |
1558 | goto error; | 1558 | goto error; |
1559 | } | 1559 | } |
1560 | 1560 | ||
1561 | if ((retval = nand_default_bbt(nsmtd)) != 0) { | 1561 | if ((retval = nand_default_bbt(nsmtd)) != 0) { |
1562 | free_nandsim(nand); | 1562 | free_nandsim(nand); |
1563 | goto error; | 1563 | goto error; |
diff --git a/drivers/mtd/nand/ppchameleonevb.c b/drivers/mtd/nand/ppchameleonevb.c index e510a83d7bdb..91a95f34a6ee 100644 --- a/drivers/mtd/nand/ppchameleonevb.c +++ b/drivers/mtd/nand/ppchameleonevb.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * Derived from drivers/mtd/nand/edb7312.c | 6 | * Derived from drivers/mtd/nand/edb7312.c |
7 | * | 7 | * |
8 | * | 8 | * |
9 | * $Id: ppchameleonevb.c,v 1.6 2004/11/05 16:07:16 kalev Exp $ | 9 | * $Id: ppchameleonevb.c,v 1.7 2005/11/07 11:14:31 gleixner Exp $ |
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License version 2 as | 12 | * it under the terms of the GNU General Public License version 2 as |
@@ -338,7 +338,7 @@ nand_evb_init: | |||
338 | out_be32((volatile unsigned*)GPIO0_TSRH, in_be32((volatile unsigned*)GPIO0_TSRH) & 0xFFFFFFF0); | 338 | out_be32((volatile unsigned*)GPIO0_TSRH, in_be32((volatile unsigned*)GPIO0_TSRH) & 0xFFFFFFF0); |
339 | out_be32((volatile unsigned*)GPIO0_TSRL, in_be32((volatile unsigned*)GPIO0_TSRL) & 0x3FFFFFFF); | 339 | out_be32((volatile unsigned*)GPIO0_TSRL, in_be32((volatile unsigned*)GPIO0_TSRL) & 0x3FFFFFFF); |
340 | /* enable output driver */ | 340 | /* enable output driver */ |
341 | out_be32((volatile unsigned*)GPIO0_TCR, in_be32((volatile unsigned*)GPIO0_TCR) | NAND_EVB_nCE_GPIO_PIN | | 341 | out_be32((volatile unsigned*)GPIO0_TCR, in_be32((volatile unsigned*)GPIO0_TCR) | NAND_EVB_nCE_GPIO_PIN | |
342 | NAND_EVB_CLE_GPIO_PIN | NAND_EVB_ALE_GPIO_PIN); | 342 | NAND_EVB_CLE_GPIO_PIN | NAND_EVB_ALE_GPIO_PIN); |
343 | #ifdef USE_READY_BUSY_PIN | 343 | #ifdef USE_READY_BUSY_PIN |
344 | /* three-state select */ | 344 | /* three-state select */ |
@@ -402,7 +402,7 @@ static void __exit ppchameleonevb_cleanup (void) | |||
402 | /* Release resources, unregister device(s) */ | 402 | /* Release resources, unregister device(s) */ |
403 | nand_release (ppchameleon_mtd); | 403 | nand_release (ppchameleon_mtd); |
404 | nand_release (ppchameleonevb_mtd); | 404 | nand_release (ppchameleonevb_mtd); |
405 | 405 | ||
406 | /* Release iomaps */ | 406 | /* Release iomaps */ |
407 | this = (struct nand_chip *) &ppchameleon_mtd[1]; | 407 | this = (struct nand_chip *) &ppchameleon_mtd[1]; |
408 | iounmap((void *) this->IO_ADDR_R; | 408 | iounmap((void *) this->IO_ADDR_R; |
diff --git a/drivers/mtd/nand/rtc_from4.c b/drivers/mtd/nand/rtc_from4.c index 031051cbde76..3a5841c9d950 100644 --- a/drivers/mtd/nand/rtc_from4.c +++ b/drivers/mtd/nand/rtc_from4.c | |||
@@ -2,11 +2,11 @@ | |||
2 | * drivers/mtd/nand/rtc_from4.c | 2 | * drivers/mtd/nand/rtc_from4.c |
3 | * | 3 | * |
4 | * Copyright (C) 2004 Red Hat, Inc. | 4 | * Copyright (C) 2004 Red Hat, Inc. |
5 | * | 5 | * |
6 | * Derived from drivers/mtd/nand/spia.c | 6 | * Derived from drivers/mtd/nand/spia.c |
7 | * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) | 7 | * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) |
8 | * | 8 | * |
9 | * $Id: rtc_from4.c,v 1.9 2005/01/24 20:40:11 dmarlin Exp $ | 9 | * $Id: rtc_from4.c,v 1.10 2005/11/07 11:14:31 gleixner Exp $ |
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License version 2 as | 12 | * it under the terms of the GNU General Public License version 2 as |
@@ -14,8 +14,8 @@ | |||
14 | * | 14 | * |
15 | * Overview: | 15 | * Overview: |
16 | * This is a device driver for the AG-AND flash device found on the | 16 | * This is a device driver for the AG-AND flash device found on the |
17 | * Renesas Technology Corp. Flash ROM 4-slot interface board (FROM_BOARD4), | 17 | * Renesas Technology Corp. Flash ROM 4-slot interface board (FROM_BOARD4), |
18 | * which utilizes the Renesas HN29V1G91T-30 part. | 18 | * which utilizes the Renesas HN29V1G91T-30 part. |
19 | * This chip is a 1 GBibit (128MiB x 8 bits) AG-AND flash device. | 19 | * This chip is a 1 GBibit (128MiB x 8 bits) AG-AND flash device. |
20 | */ | 20 | */ |
21 | 21 | ||
@@ -105,9 +105,9 @@ const static struct mtd_partition partition_info[] = { | |||
105 | }; | 105 | }; |
106 | #define NUM_PARTITIONS 1 | 106 | #define NUM_PARTITIONS 1 |
107 | 107 | ||
108 | /* | 108 | /* |
109 | * hardware specific flash bbt decriptors | 109 | * hardware specific flash bbt decriptors |
110 | * Note: this is to allow debugging by disabling | 110 | * Note: this is to allow debugging by disabling |
111 | * NAND_BBT_CREATE and/or NAND_BBT_WRITE | 111 | * NAND_BBT_CREATE and/or NAND_BBT_WRITE |
112 | * | 112 | * |
113 | */ | 113 | */ |
@@ -141,7 +141,7 @@ static struct nand_bbt_descr rtc_from4_bbt_mirror_descr = { | |||
141 | /* the Reed Solomon control structure */ | 141 | /* the Reed Solomon control structure */ |
142 | static struct rs_control *rs_decoder; | 142 | static struct rs_control *rs_decoder; |
143 | 143 | ||
144 | /* | 144 | /* |
145 | * hardware specific Out Of Band information | 145 | * hardware specific Out Of Band information |
146 | */ | 146 | */ |
147 | static struct nand_oobinfo rtc_from4_nand_oobinfo = { | 147 | static struct nand_oobinfo rtc_from4_nand_oobinfo = { |
@@ -200,38 +200,38 @@ static uint8_t revbits[256] = { | |||
200 | 200 | ||
201 | 201 | ||
202 | 202 | ||
203 | /* | 203 | /* |
204 | * rtc_from4_hwcontrol - hardware specific access to control-lines | 204 | * rtc_from4_hwcontrol - hardware specific access to control-lines |
205 | * @mtd: MTD device structure | 205 | * @mtd: MTD device structure |
206 | * @cmd: hardware control command | 206 | * @cmd: hardware control command |
207 | * | 207 | * |
208 | * Address lines (A5 and A4) are used to control Command and Address Latch | 208 | * Address lines (A5 and A4) are used to control Command and Address Latch |
209 | * Enable on this board, so set the read/write address appropriately. | 209 | * Enable on this board, so set the read/write address appropriately. |
210 | * | 210 | * |
211 | * Chip Enable is also controlled by the Chip Select (CS5) and | 211 | * Chip Enable is also controlled by the Chip Select (CS5) and |
212 | * Address lines (A24-A22), so no action is required here. | 212 | * Address lines (A24-A22), so no action is required here. |
213 | * | 213 | * |
214 | */ | 214 | */ |
215 | static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd) | 215 | static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd) |
216 | { | 216 | { |
217 | struct nand_chip* this = (struct nand_chip *) (mtd->priv); | 217 | struct nand_chip* this = (struct nand_chip *) (mtd->priv); |
218 | 218 | ||
219 | switch(cmd) { | 219 | switch(cmd) { |
220 | 220 | ||
221 | case NAND_CTL_SETCLE: | 221 | case NAND_CTL_SETCLE: |
222 | this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_CLE); | 222 | this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_CLE); |
223 | break; | 223 | break; |
224 | case NAND_CTL_CLRCLE: | 224 | case NAND_CTL_CLRCLE: |
225 | this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_CLE); | 225 | this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_CLE); |
226 | break; | 226 | break; |
227 | 227 | ||
228 | case NAND_CTL_SETALE: | 228 | case NAND_CTL_SETALE: |
229 | this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_ALE); | 229 | this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_ALE); |
230 | break; | 230 | break; |
231 | case NAND_CTL_CLRALE: | 231 | case NAND_CTL_CLRALE: |
232 | this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_ALE); | 232 | this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_ALE); |
233 | break; | 233 | break; |
234 | 234 | ||
235 | case NAND_CTL_SETNCE: | 235 | case NAND_CTL_SETNCE: |
236 | break; | 236 | break; |
237 | case NAND_CTL_CLRNCE: | 237 | case NAND_CTL_CLRNCE: |
@@ -296,7 +296,7 @@ static int rtc_from4_nand_device_ready(struct mtd_info *mtd) | |||
296 | * @mtd: MTD device structure | 296 | * @mtd: MTD device structure |
297 | * @chip: Chip to select (0 == slot 3, 1 == slot 4) | 297 | * @chip: Chip to select (0 == slot 3, 1 == slot 4) |
298 | * | 298 | * |
299 | * If there was a sudden loss of power during an erase operation, a | 299 | * If there was a sudden loss of power during an erase operation, a |
300 | * "device recovery" operation must be performed when power is restored | 300 | * "device recovery" operation must be performed when power is restored |
301 | * to ensure correct operation. This routine performs the required steps | 301 | * to ensure correct operation. This routine performs the required steps |
302 | * for the requested chip. | 302 | * for the requested chip. |
@@ -312,7 +312,7 @@ static void deplete(struct mtd_info *mtd, int chip) | |||
312 | while (!this->dev_ready(mtd)); | 312 | while (!this->dev_ready(mtd)); |
313 | 313 | ||
314 | this->select_chip(mtd, chip); | 314 | this->select_chip(mtd, chip); |
315 | 315 | ||
316 | /* Send the commands for device recovery, phase 1 */ | 316 | /* Send the commands for device recovery, phase 1 */ |
317 | this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0000); | 317 | this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0000); |
318 | this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1); | 318 | this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1); |
@@ -330,7 +330,7 @@ static void deplete(struct mtd_info *mtd, int chip) | |||
330 | * @mtd: MTD device structure | 330 | * @mtd: MTD device structure |
331 | * @mode: I/O mode; read or write | 331 | * @mode: I/O mode; read or write |
332 | * | 332 | * |
333 | * enable hardware ECC for data read or write | 333 | * enable hardware ECC for data read or write |
334 | * | 334 | * |
335 | */ | 335 | */ |
336 | static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode) | 336 | static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode) |
@@ -340,7 +340,7 @@ static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode) | |||
340 | 340 | ||
341 | switch (mode) { | 341 | switch (mode) { |
342 | case NAND_ECC_READ : | 342 | case NAND_ECC_READ : |
343 | status = RTC_FROM4_RS_ECC_CTL_CLR | 343 | status = RTC_FROM4_RS_ECC_CTL_CLR |
344 | | RTC_FROM4_RS_ECC_CTL_FD_E; | 344 | | RTC_FROM4_RS_ECC_CTL_FD_E; |
345 | 345 | ||
346 | *rs_ecc_ctl = status; | 346 | *rs_ecc_ctl = status; |
@@ -353,8 +353,8 @@ static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode) | |||
353 | break; | 353 | break; |
354 | 354 | ||
355 | case NAND_ECC_WRITE : | 355 | case NAND_ECC_WRITE : |
356 | status = RTC_FROM4_RS_ECC_CTL_CLR | 356 | status = RTC_FROM4_RS_ECC_CTL_CLR |
357 | | RTC_FROM4_RS_ECC_CTL_GEN | 357 | | RTC_FROM4_RS_ECC_CTL_GEN |
358 | | RTC_FROM4_RS_ECC_CTL_FD_E; | 358 | | RTC_FROM4_RS_ECC_CTL_FD_E; |
359 | 359 | ||
360 | *rs_ecc_ctl = status; | 360 | *rs_ecc_ctl = status; |
@@ -411,7 +411,7 @@ static void rtc_from4_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_c | |||
411 | static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_char *ecc1, u_char *ecc2) | 411 | static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_char *ecc1, u_char *ecc2) |
412 | { | 412 | { |
413 | int i, j, res; | 413 | int i, j, res; |
414 | unsigned short status; | 414 | unsigned short status; |
415 | uint16_t par[6], syn[6]; | 415 | uint16_t par[6], syn[6]; |
416 | uint8_t ecc[8]; | 416 | uint8_t ecc[8]; |
417 | volatile unsigned short *rs_ecc; | 417 | volatile unsigned short *rs_ecc; |
@@ -430,7 +430,7 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha | |||
430 | } | 430 | } |
431 | 431 | ||
432 | /* convert into 6 10bit syndrome fields */ | 432 | /* convert into 6 10bit syndrome fields */ |
433 | par[5] = rs_decoder->index_of[(((uint16_t)ecc[0] >> 0) & 0x0ff) | | 433 | par[5] = rs_decoder->index_of[(((uint16_t)ecc[0] >> 0) & 0x0ff) | |
434 | (((uint16_t)ecc[1] << 8) & 0x300)]; | 434 | (((uint16_t)ecc[1] << 8) & 0x300)]; |
435 | par[4] = rs_decoder->index_of[(((uint16_t)ecc[1] >> 2) & 0x03f) | | 435 | par[4] = rs_decoder->index_of[(((uint16_t)ecc[1] >> 2) & 0x03f) | |
436 | (((uint16_t)ecc[2] << 6) & 0x3c0)]; | 436 | (((uint16_t)ecc[2] << 6) & 0x3c0)]; |
@@ -456,7 +456,7 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha | |||
456 | /* Let the library code do its magic.*/ | 456 | /* Let the library code do its magic.*/ |
457 | res = decode_rs8(rs_decoder, (uint8_t *)buf, par, 512, syn, 0, NULL, 0xff, NULL); | 457 | res = decode_rs8(rs_decoder, (uint8_t *)buf, par, 512, syn, 0, NULL, 0xff, NULL); |
458 | if (res > 0) { | 458 | if (res > 0) { |
459 | DEBUG (MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: " | 459 | DEBUG (MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: " |
460 | "ECC corrected %d errors on read\n", res); | 460 | "ECC corrected %d errors on read\n", res); |
461 | } | 461 | } |
462 | return res; | 462 | return res; |
@@ -470,9 +470,9 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha | |||
470 | * @state: state or the operation | 470 | * @state: state or the operation |
471 | * @status: status code returned from read status | 471 | * @status: status code returned from read status |
472 | * @page: startpage inside the chip, must be called with (page & this->pagemask) | 472 | * @page: startpage inside the chip, must be called with (page & this->pagemask) |
473 | * | 473 | * |
474 | * Perform additional error status checks on erase and write failures | 474 | * Perform additional error status checks on erase and write failures |
475 | * to determine if errors are correctable. For this device, correctable | 475 | * to determine if errors are correctable. For this device, correctable |
476 | * 1-bit errors on erase and write are considered acceptable. | 476 | * 1-bit errors on erase and write are considered acceptable. |
477 | * | 477 | * |
478 | * note: see pages 34..37 of data sheet for details. | 478 | * note: see pages 34..37 of data sheet for details. |
@@ -633,7 +633,7 @@ int __init rtc_from4_init (void) | |||
633 | 633 | ||
634 | #ifdef RTC_FROM4_HWECC | 634 | #ifdef RTC_FROM4_HWECC |
635 | /* We could create the decoder on demand, if memory is a concern. | 635 | /* We could create the decoder on demand, if memory is a concern. |
636 | * This way we have it handy, if an error happens | 636 | * This way we have it handy, if an error happens |
637 | * | 637 | * |
638 | * Symbolsize is 10 (bits) | 638 | * Symbolsize is 10 (bits) |
639 | * Primitve polynomial is x^10+x^3+1 | 639 | * Primitve polynomial is x^10+x^3+1 |
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 24f4199eaee8..97e9b7892d29 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c | |||
@@ -19,7 +19,7 @@ | |||
19 | * 08-Jul-2005 BJD Fix OOPS when no platform data supplied | 19 | * 08-Jul-2005 BJD Fix OOPS when no platform data supplied |
20 | * 20-Oct-2005 BJD Fix timing calculation bug | 20 | * 20-Oct-2005 BJD Fix timing calculation bug |
21 | * | 21 | * |
22 | * $Id: s3c2410.c,v 1.18 2005/10/20 21:22:55 bjd Exp $ | 22 | * $Id: s3c2410.c,v 1.20 2005/11/07 11:14:31 gleixner Exp $ |
23 | * | 23 | * |
24 | * This program is free software; you can redistribute it and/or modify | 24 | * This program is free software; you can redistribute it and/or modify |
25 | * it under the terms of the GNU General Public License as published by | 25 | * it under the terms of the GNU General Public License as published by |
@@ -164,7 +164,7 @@ static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max) | |||
164 | 164 | ||
165 | /* controller setup */ | 165 | /* controller setup */ |
166 | 166 | ||
167 | static int s3c2410_nand_inithw(struct s3c2410_nand_info *info, | 167 | static int s3c2410_nand_inithw(struct s3c2410_nand_info *info, |
168 | struct device *dev) | 168 | struct device *dev) |
169 | { | 169 | { |
170 | struct s3c2410_platform_nand *plat = to_nand_plat(dev); | 170 | struct s3c2410_platform_nand *plat = to_nand_plat(dev); |
@@ -186,7 +186,7 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info, | |||
186 | twrph0 = 8; | 186 | twrph0 = 8; |
187 | twrph1 = 8; | 187 | twrph1 = 8; |
188 | } | 188 | } |
189 | 189 | ||
190 | if (tacls < 0 || twrph0 < 0 || twrph1 < 0) { | 190 | if (tacls < 0 || twrph0 < 0 || twrph1 < 0) { |
191 | printk(KERN_ERR PFX "cannot get timings suitable for board\n"); | 191 | printk(KERN_ERR PFX "cannot get timings suitable for board\n"); |
192 | return -EINVAL; | 192 | return -EINVAL; |
@@ -194,7 +194,7 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info, | |||
194 | 194 | ||
195 | printk(KERN_INFO PFX "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n", | 195 | printk(KERN_INFO PFX "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n", |
196 | tacls, to_ns(tacls, clkrate), | 196 | tacls, to_ns(tacls, clkrate), |
197 | twrph0, to_ns(twrph0, clkrate), | 197 | twrph0, to_ns(twrph0, clkrate), |
198 | twrph1, to_ns(twrph1, clkrate)); | 198 | twrph1, to_ns(twrph1, clkrate)); |
199 | 199 | ||
200 | if (!info->is_s3c2440) { | 200 | if (!info->is_s3c2440) { |
@@ -219,7 +219,7 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info, | |||
219 | static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) | 219 | static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) |
220 | { | 220 | { |
221 | struct s3c2410_nand_info *info; | 221 | struct s3c2410_nand_info *info; |
222 | struct s3c2410_nand_mtd *nmtd; | 222 | struct s3c2410_nand_mtd *nmtd; |
223 | struct nand_chip *this = mtd->priv; | 223 | struct nand_chip *this = mtd->priv; |
224 | void __iomem *reg; | 224 | void __iomem *reg; |
225 | unsigned long cur; | 225 | unsigned long cur; |
@@ -252,7 +252,7 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) | |||
252 | writel(cur, reg); | 252 | writel(cur, reg); |
253 | } | 253 | } |
254 | 254 | ||
255 | /* command and control functions | 255 | /* command and control functions |
256 | * | 256 | * |
257 | * Note, these all use tglx's method of changing the IO_ADDR_W field | 257 | * Note, these all use tglx's method of changing the IO_ADDR_W field |
258 | * to make the code simpler, and use the nand layer's code to issue the | 258 | * to make the code simpler, and use the nand layer's code to issue the |
@@ -324,7 +324,7 @@ static void s3c2440_nand_hwcontrol(struct mtd_info *mtd, int cmd) | |||
324 | static int s3c2410_nand_devready(struct mtd_info *mtd) | 324 | static int s3c2410_nand_devready(struct mtd_info *mtd) |
325 | { | 325 | { |
326 | struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); | 326 | struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); |
327 | 327 | ||
328 | if (info->is_s3c2440) | 328 | if (info->is_s3c2440) |
329 | return readb(info->regs + S3C2440_NFSTAT) & S3C2440_NFSTAT_READY; | 329 | return readb(info->regs + S3C2440_NFSTAT) & S3C2440_NFSTAT_READY; |
330 | return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY; | 330 | return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY; |
@@ -345,7 +345,7 @@ static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, | |||
345 | 345 | ||
346 | if (read_ecc[0] == calc_ecc[0] && | 346 | if (read_ecc[0] == calc_ecc[0] && |
347 | read_ecc[1] == calc_ecc[1] && | 347 | read_ecc[1] == calc_ecc[1] && |
348 | read_ecc[2] == calc_ecc[2]) | 348 | read_ecc[2] == calc_ecc[2]) |
349 | return 0; | 349 | return 0; |
350 | 350 | ||
351 | /* we curently have no method for correcting the error */ | 351 | /* we curently have no method for correcting the error */ |
@@ -436,14 +436,14 @@ static int s3c2410_nand_remove(struct device *dev) | |||
436 | 436 | ||
437 | dev_set_drvdata(dev, NULL); | 437 | dev_set_drvdata(dev, NULL); |
438 | 438 | ||
439 | if (info == NULL) | 439 | if (info == NULL) |
440 | return 0; | 440 | return 0; |
441 | 441 | ||
442 | /* first thing we need to do is release all our mtds | 442 | /* first thing we need to do is release all our mtds |
443 | * and their partitions, then go through freeing the | 443 | * and their partitions, then go through freeing the |
444 | * resources used | 444 | * resources used |
445 | */ | 445 | */ |
446 | 446 | ||
447 | if (info->mtds != NULL) { | 447 | if (info->mtds != NULL) { |
448 | struct s3c2410_nand_mtd *ptr = info->mtds; | 448 | struct s3c2410_nand_mtd *ptr = info->mtds; |
449 | int mtdno; | 449 | int mtdno; |
@@ -507,7 +507,7 @@ static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info, | |||
507 | 507 | ||
508 | /* s3c2410_nand_init_chip | 508 | /* s3c2410_nand_init_chip |
509 | * | 509 | * |
510 | * init a single instance of an chip | 510 | * init a single instance of an chip |
511 | */ | 511 | */ |
512 | 512 | ||
513 | static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, | 513 | static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, |
@@ -625,7 +625,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440) | |||
625 | dev_err(dev, "cannot reserve register region\n"); | 625 | dev_err(dev, "cannot reserve register region\n"); |
626 | err = -EIO; | 626 | err = -EIO; |
627 | goto exit_error; | 627 | goto exit_error; |
628 | } | 628 | } |
629 | 629 | ||
630 | dev_dbg(dev, "mapped registers at %p\n", info->regs); | 630 | dev_dbg(dev, "mapped registers at %p\n", info->regs); |
631 | 631 | ||
@@ -659,7 +659,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440) | |||
659 | for (setno = 0; setno < nr_sets; setno++, nmtd++) { | 659 | for (setno = 0; setno < nr_sets; setno++, nmtd++) { |
660 | pr_debug("initialising set %d (%p, info %p)\n", | 660 | pr_debug("initialising set %d (%p, info %p)\n", |
661 | setno, nmtd, info); | 661 | setno, nmtd, info); |
662 | 662 | ||
663 | s3c2410_nand_init_chip(info, nmtd, sets); | 663 | s3c2410_nand_init_chip(info, nmtd, sets); |
664 | 664 | ||
665 | nmtd->scan_res = nand_scan(&nmtd->mtd, | 665 | nmtd->scan_res = nand_scan(&nmtd->mtd, |
@@ -672,7 +672,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440) | |||
672 | if (sets != NULL) | 672 | if (sets != NULL) |
673 | sets++; | 673 | sets++; |
674 | } | 674 | } |
675 | 675 | ||
676 | pr_debug("initialised ok\n"); | 676 | pr_debug("initialised ok\n"); |
677 | return 0; | 677 | return 0; |
678 | 678 | ||
diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c index 6def3d33b060..1924a4f137c7 100644 --- a/drivers/mtd/nand/sharpsl.c +++ b/drivers/mtd/nand/sharpsl.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2004 Richard Purdie | 4 | * Copyright (C) 2004 Richard Purdie |
5 | * | 5 | * |
6 | * $Id: sharpsl.c,v 1.6 2005/11/03 11:36:42 rpurdie Exp $ | 6 | * $Id: sharpsl.c,v 1.7 2005/11/07 11:14:31 gleixner Exp $ |
7 | * | 7 | * |
8 | * Based on Sharp's NAND driver sharp_sl.c | 8 | * Based on Sharp's NAND driver sharp_sl.c |
9 | * | 9 | * |
@@ -76,14 +76,14 @@ static struct mtd_partition sharpsl_nand_default_partition_info[] = { | |||
76 | }, | 76 | }, |
77 | }; | 77 | }; |
78 | 78 | ||
79 | /* | 79 | /* |
80 | * hardware specific access to control-lines | 80 | * hardware specific access to control-lines |
81 | */ | 81 | */ |
82 | static void | 82 | static void |
83 | sharpsl_nand_hwcontrol(struct mtd_info* mtd, int cmd) | 83 | sharpsl_nand_hwcontrol(struct mtd_info* mtd, int cmd) |
84 | { | 84 | { |
85 | switch (cmd) { | 85 | switch (cmd) { |
86 | case NAND_CTL_SETCLE: | 86 | case NAND_CTL_SETCLE: |
87 | writeb(readb(FLASHCTL) | FLCLE, FLASHCTL); | 87 | writeb(readb(FLASHCTL) | FLCLE, FLASHCTL); |
88 | break; | 88 | break; |
89 | case NAND_CTL_CLRCLE: | 89 | case NAND_CTL_CLRCLE: |
@@ -97,10 +97,10 @@ sharpsl_nand_hwcontrol(struct mtd_info* mtd, int cmd) | |||
97 | writeb(readb(FLASHCTL) & ~FLALE, FLASHCTL); | 97 | writeb(readb(FLASHCTL) & ~FLALE, FLASHCTL); |
98 | break; | 98 | break; |
99 | 99 | ||
100 | case NAND_CTL_SETNCE: | 100 | case NAND_CTL_SETNCE: |
101 | writeb(readb(FLASHCTL) & ~(FLCE0|FLCE1), FLASHCTL); | 101 | writeb(readb(FLASHCTL) & ~(FLCE0|FLCE1), FLASHCTL); |
102 | break; | 102 | break; |
103 | case NAND_CTL_CLRNCE: | 103 | case NAND_CTL_CLRNCE: |
104 | writeb(readb(FLASHCTL) | (FLCE0|FLCE1), FLASHCTL); | 104 | writeb(readb(FLASHCTL) | (FLCE0|FLCE1), FLASHCTL); |
105 | break; | 105 | break; |
106 | } | 106 | } |
@@ -126,8 +126,8 @@ static struct nand_oobinfo akita_oobinfo = { | |||
126 | .useecc = MTD_NANDECC_AUTOPLACE, | 126 | .useecc = MTD_NANDECC_AUTOPLACE, |
127 | .eccbytes = 24, | 127 | .eccbytes = 24, |
128 | .eccpos = { | 128 | .eccpos = { |
129 | 0x5, 0x1, 0x2, 0x3, 0x6, 0x7, 0x15, 0x11, | 129 | 0x5, 0x1, 0x2, 0x3, 0x6, 0x7, 0x15, 0x11, |
130 | 0x12, 0x13, 0x16, 0x17, 0x25, 0x21, 0x22, 0x23, | 130 | 0x12, 0x13, 0x16, 0x17, 0x25, 0x21, 0x22, 0x23, |
131 | 0x26, 0x27, 0x35, 0x31, 0x32, 0x33, 0x36, 0x37}, | 131 | 0x26, 0x27, 0x35, 0x31, 0x32, 0x33, 0x36, 0x37}, |
132 | .oobfree = { {0x08, 0x09} } | 132 | .oobfree = { {0x08, 0x09} } |
133 | }; | 133 | }; |
@@ -177,7 +177,7 @@ sharpsl_nand_init(void) | |||
177 | printk ("Unable to allocate SharpSL NAND MTD device structure.\n"); | 177 | printk ("Unable to allocate SharpSL NAND MTD device structure.\n"); |
178 | return -ENOMEM; | 178 | return -ENOMEM; |
179 | } | 179 | } |
180 | 180 | ||
181 | /* map physical adress */ | 181 | /* map physical adress */ |
182 | sharpsl_io_base = ioremap(sharpsl_phys_base, 0x1000); | 182 | sharpsl_io_base = ioremap(sharpsl_phys_base, 0x1000); |
183 | if(!sharpsl_io_base){ | 183 | if(!sharpsl_io_base){ |
@@ -185,7 +185,7 @@ sharpsl_nand_init(void) | |||
185 | kfree(sharpsl_mtd); | 185 | kfree(sharpsl_mtd); |
186 | return -EIO; | 186 | return -EIO; |
187 | } | 187 | } |
188 | 188 | ||
189 | /* Get pointer to private data */ | 189 | /* Get pointer to private data */ |
190 | this = (struct nand_chip *) (&sharpsl_mtd[1]); | 190 | this = (struct nand_chip *) (&sharpsl_mtd[1]); |
191 | 191 | ||
@@ -211,7 +211,7 @@ sharpsl_nand_init(void) | |||
211 | this->chip_delay = 15; | 211 | this->chip_delay = 15; |
212 | /* set eccmode using hardware ECC */ | 212 | /* set eccmode using hardware ECC */ |
213 | this->eccmode = NAND_ECC_HW3_256; | 213 | this->eccmode = NAND_ECC_HW3_256; |
214 | this->badblock_pattern = &sharpsl_bbt; | 214 | this->badblock_pattern = &sharpsl_bbt; |
215 | if (machine_is_akita() || machine_is_borzoi()) { | 215 | if (machine_is_akita() || machine_is_borzoi()) { |
216 | this->badblock_pattern = &sharpsl_akita_bbt; | 216 | this->badblock_pattern = &sharpsl_akita_bbt; |
217 | this->autooob = &akita_oobinfo; | 217 | this->autooob = &akita_oobinfo; |
@@ -232,7 +232,7 @@ sharpsl_nand_init(void) | |||
232 | sharpsl_mtd->name = "sharpsl-nand"; | 232 | sharpsl_mtd->name = "sharpsl-nand"; |
233 | nr_partitions = parse_mtd_partitions(sharpsl_mtd, part_probes, | 233 | nr_partitions = parse_mtd_partitions(sharpsl_mtd, part_probes, |
234 | &sharpsl_partition_info, 0); | 234 | &sharpsl_partition_info, 0); |
235 | 235 | ||
236 | if (nr_partitions <= 0) { | 236 | if (nr_partitions <= 0) { |
237 | nr_partitions = DEFAULT_NUM_PARTITIONS; | 237 | nr_partitions = DEFAULT_NUM_PARTITIONS; |
238 | sharpsl_partition_info = sharpsl_nand_default_partition_info; | 238 | sharpsl_partition_info = sharpsl_nand_default_partition_info; |
diff --git a/drivers/mtd/nand/spia.c b/drivers/mtd/nand/spia.c index b777c412b758..32541cbb0103 100644 --- a/drivers/mtd/nand/spia.c +++ b/drivers/mtd/nand/spia.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * to controllines (due to change in nand.c) | 8 | * to controllines (due to change in nand.c) |
9 | * page_cache added | 9 | * page_cache added |
10 | * | 10 | * |
11 | * $Id: spia.c,v 1.24 2004/11/04 12:53:10 gleixner Exp $ | 11 | * $Id: spia.c,v 1.25 2005/11/07 11:14:31 gleixner Exp $ |
12 | * | 12 | * |
13 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
14 | * it under the terms of the GNU General Public License version 2 as | 14 | * it under the terms of the GNU General Public License version 2 as |
@@ -82,7 +82,7 @@ const static struct mtd_partition partition_info[] = { | |||
82 | #define NUM_PARTITIONS 2 | 82 | #define NUM_PARTITIONS 2 |
83 | 83 | ||
84 | 84 | ||
85 | /* | 85 | /* |
86 | * hardware specific access to control-lines | 86 | * hardware specific access to control-lines |
87 | */ | 87 | */ |
88 | static void spia_hwcontrol(struct mtd_info *mtd, int cmd){ | 88 | static void spia_hwcontrol(struct mtd_info *mtd, int cmd){ |
@@ -137,7 +137,7 @@ int __init spia_init (void) | |||
137 | /* Set address of hardware control function */ | 137 | /* Set address of hardware control function */ |
138 | this->hwcontrol = spia_hwcontrol; | 138 | this->hwcontrol = spia_hwcontrol; |
139 | /* 15 us command delay time */ | 139 | /* 15 us command delay time */ |
140 | this->chip_delay = 15; | 140 | this->chip_delay = 15; |
141 | 141 | ||
142 | /* Scan to find existence of the device */ | 142 | /* Scan to find existence of the device */ |
143 | if (nand_scan (spia_mtd, 1)) { | 143 | if (nand_scan (spia_mtd, 1)) { |
diff --git a/drivers/mtd/nand/toto.c b/drivers/mtd/nand/toto.c index 52c808fb5fa9..7609c43cb3ec 100644 --- a/drivers/mtd/nand/toto.c +++ b/drivers/mtd/nand/toto.c | |||
@@ -15,7 +15,7 @@ | |||
15 | * This is a device driver for the NAND flash device found on the | 15 | * This is a device driver for the NAND flash device found on the |
16 | * TI fido board. It supports 32MiB and 64MiB cards | 16 | * TI fido board. It supports 32MiB and 64MiB cards |
17 | * | 17 | * |
18 | * $Id: toto.c,v 1.4 2004/10/05 13:50:20 gleixner Exp $ | 18 | * $Id: toto.c,v 1.5 2005/11/07 11:14:31 gleixner Exp $ |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
@@ -57,7 +57,7 @@ static unsigned long toto_io_base = OMAP_FLASH_1_BASE; | |||
57 | #endif | 57 | #endif |
58 | #define T_NAND_CTL_SETNCE(iob) gpiosetout(NAND_NCE, 0) | 58 | #define T_NAND_CTL_SETNCE(iob) gpiosetout(NAND_NCE, 0) |
59 | #define T_NAND_CTL_CLRNCE(iob) gpiosetout(NAND_NCE, NAND_NCE) | 59 | #define T_NAND_CTL_CLRNCE(iob) gpiosetout(NAND_NCE, NAND_NCE) |
60 | 60 | ||
61 | /* | 61 | /* |
62 | * Define partitions for flash devices | 62 | * Define partitions for flash devices |
63 | */ | 63 | */ |
@@ -91,7 +91,7 @@ static struct mtd_partition partition_info32M[] = { | |||
91 | 91 | ||
92 | #define NUM_PARTITIONS32M 3 | 92 | #define NUM_PARTITIONS32M 3 |
93 | #define NUM_PARTITIONS64M 4 | 93 | #define NUM_PARTITIONS64M 4 |
94 | /* | 94 | /* |
95 | * hardware specific access to control-lines | 95 | * hardware specific access to control-lines |
96 | */ | 96 | */ |
97 | 97 | ||
@@ -146,7 +146,7 @@ int __init toto_init (void) | |||
146 | this->hwcontrol = toto_hwcontrol; | 146 | this->hwcontrol = toto_hwcontrol; |
147 | this->dev_ready = NULL; | 147 | this->dev_ready = NULL; |
148 | /* 25 us command delay time */ | 148 | /* 25 us command delay time */ |
149 | this->chip_delay = 30; | 149 | this->chip_delay = 30; |
150 | this->eccmode = NAND_ECC_SOFT; | 150 | this->eccmode = NAND_ECC_SOFT; |
151 | 151 | ||
152 | /* Scan to find existance of the device */ | 152 | /* Scan to find existance of the device */ |
@@ -157,10 +157,10 @@ int __init toto_init (void) | |||
157 | 157 | ||
158 | /* Register the partitions */ | 158 | /* Register the partitions */ |
159 | switch(toto_mtd->size){ | 159 | switch(toto_mtd->size){ |
160 | case SZ_64M: add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M); break; | 160 | case SZ_64M: add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M); break; |
161 | case SZ_32M: add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M); break; | 161 | case SZ_32M: add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M); break; |
162 | default: { | 162 | default: { |
163 | printk (KERN_WARNING "Unsupported Nand device\n"); | 163 | printk (KERN_WARNING "Unsupported Nand device\n"); |
164 | err = -ENXIO; | 164 | err = -ENXIO; |
165 | goto out_buf; | 165 | goto out_buf; |
166 | } | 166 | } |
@@ -170,9 +170,9 @@ int __init toto_init (void) | |||
170 | archflashwp(0,0); /* open up flash for writing */ | 170 | archflashwp(0,0); /* open up flash for writing */ |
171 | 171 | ||
172 | goto out; | 172 | goto out; |
173 | 173 | ||
174 | out_buf: | 174 | out_buf: |
175 | kfree (this->data_buf); | 175 | kfree (this->data_buf); |
176 | out_mtd: | 176 | out_mtd: |
177 | kfree (toto_mtd); | 177 | kfree (toto_mtd); |
178 | out: | 178 | out: |
@@ -194,7 +194,7 @@ static void __exit toto_cleanup (void) | |||
194 | 194 | ||
195 | /* stop flash writes */ | 195 | /* stop flash writes */ |
196 | archflashwp(0,1); | 196 | archflashwp(0,1); |
197 | 197 | ||
198 | /* release gpios to system */ | 198 | /* release gpios to system */ |
199 | gpiorelease(NAND_MASK); | 199 | gpiorelease(NAND_MASK); |
200 | } | 200 | } |