aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-19 16:34:11 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-19 16:34:11 -0500
commit4935361766cc73949fe032cd157d314f288922ba (patch)
tree1584f81525ae05a04d515b13a4787cd8eed46029
parent2874b391bd78a5b8cb84be67297a345fbdec4ac8 (diff)
parent4f65992381112acd7d2732665a9eae492c2c9de6 (diff)
Merge git://git.infradead.org/mtd-2.6
* git://git.infradead.org/mtd-2.6: (49 commits) [MTD] [NAND] S3C2412 fix hw ecc [MTD] [NAND] Work around false compiler warning in CAFÉ driver [JFFS2] printk warning fixes [MTD] [MAPS] ichxrom warning fix [MTD] [MAPS] amd76xrom warning fix [MTD] [MAPS] esb2rom warning fixes [MTD] [MAPS] ck804xrom warning fix [MTD] [MAPS] netsc520 warning fix [MTD] [MAPS] sc520cdp warning fix [MTD] [ONENAND] onenand_base warning fix [MTD] [NAND] eXcite nand flash driver [MTD] Improve heuristic for detecting wrong-endian RedBoot partition table [MTD] Fix RedBoot partition parsing regression harder. [MTD] [NAND] S3C2410: Hardware ECC correction code [JFFS2] Use MTD_OOB_AUTO to automatically place cleanmarker on NAND [MTD] Clarify OOB-operation interface comments [MTD] remove unused ecctype,eccsize fields from struct mtd_info [MTD] [NOR] Intel: remove ugly PROGREGION macros [MTD] [NOR] STAA: use writesize instead off eccsize to represent ECC block [MTD] OneNAND: Invalidate bufferRAM after erase ...
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c26
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0020.c2
-rw-r--r--drivers/mtd/devices/doc2000.c1
-rw-r--r--drivers/mtd/devices/doc2001.c1
-rw-r--r--drivers/mtd/devices/doc2001plus.c1
-rw-r--r--drivers/mtd/maps/Kconfig2
-rw-r--r--drivers/mtd/maps/amd76xrom.c4
-rw-r--r--drivers/mtd/maps/ck804xrom.c6
-rw-r--r--drivers/mtd/maps/esb2rom.c4
-rw-r--r--drivers/mtd/maps/ichxrom.c4
-rw-r--r--drivers/mtd/maps/netsc520.c4
-rw-r--r--drivers/mtd/maps/sc520cdp.c5
-rw-r--r--drivers/mtd/mtdchar.c5
-rw-r--r--drivers/mtd/mtdconcat.c4
-rw-r--r--drivers/mtd/mtdpart.c2
-rw-r--r--drivers/mtd/nand/Kconfig14
-rw-r--r--drivers/mtd/nand/Makefile1
-rw-r--r--drivers/mtd/nand/cafe.c89
-rw-r--r--drivers/mtd/nand/cafe_ecc.c2
-rw-r--r--drivers/mtd/nand/excite_nandflash.c248
-rw-r--r--drivers/mtd/nand/nand_base.c47
-rw-r--r--drivers/mtd/nand/s3c2410.c96
-rw-r--r--drivers/mtd/onenand/onenand_base.c596
-rw-r--r--drivers/mtd/onenand/onenand_bbt.c27
-rw-r--r--drivers/mtd/redboot.c19
-rw-r--r--fs/jffs2/build.c22
-rw-r--r--fs/jffs2/jffs2_fs_sb.h12
-rw-r--r--fs/jffs2/scan.c10
-rw-r--r--fs/jffs2/wbuf.c203
-rw-r--r--include/linux/mtd/bbm.h7
-rw-r--r--include/linux/mtd/map.h2
-rw-r--r--include/linux/mtd/mtd.h16
-rw-r--r--include/linux/mtd/nand.h1
-rw-r--r--include/linux/mtd/onenand.h15
-rw-r--r--include/linux/mtd/onenand_regs.h7
-rw-r--r--include/linux/mtd/physmap.h3
-rw-r--r--include/mtd/mtd-abi.h8
37 files changed, 1048 insertions, 468 deletions
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index f69184a92eb2..f334959a335b 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -397,9 +397,23 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
397 cfi_fixup(mtd, fixup_table); 397 cfi_fixup(mtd, fixup_table);
398 398
399 for (i=0; i< cfi->numchips; i++) { 399 for (i=0; i< cfi->numchips; i++) {
400 cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp; 400 if (cfi->cfiq->WordWriteTimeoutTyp)
401 cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp; 401 cfi->chips[i].word_write_time =
402 cfi->chips[i].erase_time = 1000<<cfi->cfiq->BlockEraseTimeoutTyp; 402 1<<cfi->cfiq->WordWriteTimeoutTyp;
403 else
404 cfi->chips[i].word_write_time = 50000;
405
406 if (cfi->cfiq->BufWriteTimeoutTyp)
407 cfi->chips[i].buffer_write_time =
408 1<<cfi->cfiq->BufWriteTimeoutTyp;
409 /* No default; if it isn't specified, we won't use it */
410
411 if (cfi->cfiq->BlockEraseTimeoutTyp)
412 cfi->chips[i].erase_time =
413 1000<<cfi->cfiq->BlockEraseTimeoutTyp;
414 else
415 cfi->chips[i].erase_time = 2000000;
416
403 cfi->chips[i].ref_point_counter = 0; 417 cfi->chips[i].ref_point_counter = 0;
404 init_waitqueue_head(&(cfi->chips[i].wq)); 418 init_waitqueue_head(&(cfi->chips[i].wq));
405 } 419 }
@@ -546,13 +560,11 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
546 struct cfi_intelext_programming_regioninfo *prinfo; 560 struct cfi_intelext_programming_regioninfo *prinfo;
547 prinfo = (struct cfi_intelext_programming_regioninfo *)&extp->extra[offs]; 561 prinfo = (struct cfi_intelext_programming_regioninfo *)&extp->extra[offs];
548 mtd->writesize = cfi->interleave << prinfo->ProgRegShift; 562 mtd->writesize = cfi->interleave << prinfo->ProgRegShift;
549 MTD_PROGREGION_CTRLMODE_VALID(mtd) = cfi->interleave * prinfo->ControlValid;
550 MTD_PROGREGION_CTRLMODE_INVALID(mtd) = cfi->interleave * prinfo->ControlInvalid;
551 mtd->flags &= ~MTD_BIT_WRITEABLE; 563 mtd->flags &= ~MTD_BIT_WRITEABLE;
552 printk(KERN_DEBUG "%s: program region size/ctrl_valid/ctrl_inval = %d/%d/%d\n", 564 printk(KERN_DEBUG "%s: program region size/ctrl_valid/ctrl_inval = %d/%d/%d\n",
553 map->name, mtd->writesize, 565 map->name, mtd->writesize,
554 MTD_PROGREGION_CTRLMODE_VALID(mtd), 566 cfi->interleave * prinfo->ControlValid,
555 MTD_PROGREGION_CTRLMODE_INVALID(mtd)); 567 cfi->interleave * prinfo->ControlInvalid);
556 } 568 }
557 569
558 /* 570 /*
diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c
index d56849f5f107..69d49e0250a9 100644
--- a/drivers/mtd/chips/cfi_cmdset_0020.c
+++ b/drivers/mtd/chips/cfi_cmdset_0020.c
@@ -662,7 +662,7 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
662 * a small buffer for this. 662 * a small buffer for this.
663 * XXX: If the buffer size is not a multiple of 2, this will break 663 * XXX: If the buffer size is not a multiple of 2, this will break
664 */ 664 */
665#define ECCBUF_SIZE (mtd->eccsize) 665#define ECCBUF_SIZE (mtd->writesize)
666#define ECCBUF_DIV(x) ((x) & ~(ECCBUF_SIZE - 1)) 666#define ECCBUF_DIV(x) ((x) & ~(ECCBUF_SIZE - 1))
667#define ECCBUF_MOD(x) ((x) & (ECCBUF_SIZE - 1)) 667#define ECCBUF_MOD(x) ((x) & (ECCBUF_SIZE - 1))
668static int 668static int
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
index 603a7951ac9b..8a0c4dec6351 100644
--- a/drivers/mtd/devices/doc2000.c
+++ b/drivers/mtd/devices/doc2000.c
@@ -569,7 +569,6 @@ void DoC2k_init(struct mtd_info *mtd)
569 569
570 mtd->type = MTD_NANDFLASH; 570 mtd->type = MTD_NANDFLASH;
571 mtd->flags = MTD_CAP_NANDFLASH; 571 mtd->flags = MTD_CAP_NANDFLASH;
572 mtd->ecctype = MTD_ECC_RS_DiskOnChip;
573 mtd->size = 0; 572 mtd->size = 0;
574 mtd->erasesize = 0; 573 mtd->erasesize = 0;
575 mtd->writesize = 512; 574 mtd->writesize = 512;
diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c
index fe71a12c2627..6f368aec5d5d 100644
--- a/drivers/mtd/devices/doc2001.c
+++ b/drivers/mtd/devices/doc2001.c
@@ -348,7 +348,6 @@ void DoCMil_init(struct mtd_info *mtd)
348 348
349 mtd->type = MTD_NANDFLASH; 349 mtd->type = MTD_NANDFLASH;
350 mtd->flags = MTD_CAP_NANDFLASH; 350 mtd->flags = MTD_CAP_NANDFLASH;
351 mtd->ecctype = MTD_ECC_RS_DiskOnChip;
352 mtd->size = 0; 351 mtd->size = 0;
353 352
354 /* FIXME: erase size is not always 8KiB */ 353 /* FIXME: erase size is not always 8KiB */
diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c
index ba4db686285a..88ba82df0fbb 100644
--- a/drivers/mtd/devices/doc2001plus.c
+++ b/drivers/mtd/devices/doc2001plus.c
@@ -472,7 +472,6 @@ void DoCMilPlus_init(struct mtd_info *mtd)
472 472
473 mtd->type = MTD_NANDFLASH; 473 mtd->type = MTD_NANDFLASH;
474 mtd->flags = MTD_CAP_NANDFLASH; 474 mtd->flags = MTD_CAP_NANDFLASH;
475 mtd->ecctype = MTD_ECC_RS_DiskOnChip;
476 mtd->size = 0; 475 mtd->size = 0;
477 476
478 mtd->erasesize = 0; 477 mtd->erasesize = 0;
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index f457315579db..bbf0553bdb2e 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -204,7 +204,7 @@ config MTD_ESB2ROM
204 204
205config MTD_CK804XROM 205config MTD_CK804XROM
206 tristate "BIOS flash chip on Nvidia CK804" 206 tristate "BIOS flash chip on Nvidia CK804"
207 depends on X86 && MTD_JEDECPROBE 207 depends on X86 && MTD_JEDECPROBE && PCI
208 help 208 help
209 Support for treating the BIOS flash chip on nvidia motherboards 209 Support for treating the BIOS flash chip on nvidia motherboards
210 as an MTD device - with this you can reprogram your BIOS. 210 as an MTD device - with this you can reprogram your BIOS.
diff --git a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c
index 78b671172bb2..728aed6ad722 100644
--- a/drivers/mtd/maps/amd76xrom.c
+++ b/drivers/mtd/maps/amd76xrom.c
@@ -205,8 +205,8 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
205 (((unsigned long)(window->virt)) + offset); 205 (((unsigned long)(window->virt)) + offset);
206 map->map.size = 0xffffffffUL - map_top + 1UL; 206 map->map.size = 0xffffffffUL - map_top + 1UL;
207 /* Set the name of the map to the address I am trying */ 207 /* Set the name of the map to the address I am trying */
208 sprintf(map->map_name, "%s @%08lx", 208 sprintf(map->map_name, "%s @%08Lx",
209 MOD_NAME, map->map.phys); 209 MOD_NAME, (unsigned long long)map->map.phys);
210 210
211 /* There is no generic VPP support */ 211 /* There is no generic VPP support */
212 for(map->map.bankwidth = 32; map->map.bankwidth; 212 for(map->map.bankwidth = 32; map->map.bankwidth;
diff --git a/drivers/mtd/maps/ck804xrom.c b/drivers/mtd/maps/ck804xrom.c
index 238d42e88ec5..3d4a4d8ac789 100644
--- a/drivers/mtd/maps/ck804xrom.c
+++ b/drivers/mtd/maps/ck804xrom.c
@@ -207,8 +207,8 @@ static int __devinit ck804xrom_init_one (struct pci_dev *pdev,
207 (((unsigned long)(window->virt)) + offset); 207 (((unsigned long)(window->virt)) + offset);
208 map->map.size = 0xffffffffUL - map_top + 1UL; 208 map->map.size = 0xffffffffUL - map_top + 1UL;
209 /* Set the name of the map to the address I am trying */ 209 /* Set the name of the map to the address I am trying */
210 sprintf(map->map_name, "%s @%08lx", 210 sprintf(map->map_name, "%s @%08Lx",
211 MOD_NAME, map->map.phys); 211 MOD_NAME, (unsigned long long)map->map.phys);
212 212
213 /* There is no generic VPP support */ 213 /* There is no generic VPP support */
214 for(map->map.bankwidth = 32; map->map.bankwidth; 214 for(map->map.bankwidth = 32; map->map.bankwidth;
@@ -327,7 +327,7 @@ static int __init init_ck804xrom(void)
327 pdev = NULL; 327 pdev = NULL;
328 328
329 for(id = ck804xrom_pci_tbl; id->vendor; id++) { 329 for(id = ck804xrom_pci_tbl; id->vendor; id++) {
330 pdev = pci_find_device(id->vendor, id->device, NULL); 330 pdev = pci_get_device(id->vendor, id->device, NULL);
331 if (pdev) 331 if (pdev)
332 break; 332 break;
333 } 333 }
diff --git a/drivers/mtd/maps/esb2rom.c b/drivers/mtd/maps/esb2rom.c
index a9d808a617c9..0bc013fd66a3 100644
--- a/drivers/mtd/maps/esb2rom.c
+++ b/drivers/mtd/maps/esb2rom.c
@@ -289,8 +289,8 @@ static int __devinit esb2rom_init_one(struct pci_dev *pdev,
289 (((unsigned long)(window->virt)) + offset); 289 (((unsigned long)(window->virt)) + offset);
290 map->map.size = 0xffffffffUL - map_top + 1UL; 290 map->map.size = 0xffffffffUL - map_top + 1UL;
291 /* Set the name of the map to the address I am trying */ 291 /* Set the name of the map to the address I am trying */
292 sprintf(map->map_name, "%s @%08lx", 292 sprintf(map->map_name, "%s @%08Lx",
293 MOD_NAME, map->map.phys); 293 MOD_NAME, (unsigned long long)map->map.phys);
294 294
295 /* Firmware hubs only use vpp when being programmed 295 /* Firmware hubs only use vpp when being programmed
296 * in a factory setting. So in-place programming 296 * in a factory setting. So in-place programming
diff --git a/drivers/mtd/maps/ichxrom.c b/drivers/mtd/maps/ichxrom.c
index 2bb3e63606e5..2c884c49e84a 100644
--- a/drivers/mtd/maps/ichxrom.c
+++ b/drivers/mtd/maps/ichxrom.c
@@ -227,8 +227,8 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
227 (((unsigned long)(window->virt)) + offset); 227 (((unsigned long)(window->virt)) + offset);
228 map->map.size = 0xffffffffUL - map_top + 1UL; 228 map->map.size = 0xffffffffUL - map_top + 1UL;
229 /* Set the name of the map to the address I am trying */ 229 /* Set the name of the map to the address I am trying */
230 sprintf(map->map_name, "%s @%08lx", 230 sprintf(map->map_name, "%s @%08Lx",
231 MOD_NAME, map->map.phys); 231 MOD_NAME, (unsigned long long)map->map.phys);
232 232
233 /* Firmware hubs only use vpp when being programmed 233 /* Firmware hubs only use vpp when being programmed
234 * in a factory setting. So in-place programming 234 * in a factory setting. So in-place programming
diff --git a/drivers/mtd/maps/netsc520.c b/drivers/mtd/maps/netsc520.c
index ed215470158b..95dcab2146ad 100644
--- a/drivers/mtd/maps/netsc520.c
+++ b/drivers/mtd/maps/netsc520.c
@@ -94,7 +94,9 @@ static struct mtd_info *mymtd;
94 94
95static int __init init_netsc520(void) 95static int __init init_netsc520(void)
96{ 96{
97 printk(KERN_NOTICE "NetSc520 flash device: 0x%lx at 0x%lx\n", netsc520_map.size, netsc520_map.phys); 97 printk(KERN_NOTICE "NetSc520 flash device: 0x%Lx at 0x%Lx\n",
98 (unsigned long long)netsc520_map.size,
99 (unsigned long long)netsc520_map.phys);
98 netsc520_map.virt = ioremap_nocache(netsc520_map.phys, netsc520_map.size); 100 netsc520_map.virt = ioremap_nocache(netsc520_map.phys, netsc520_map.size);
99 101
100 if (!netsc520_map.virt) { 102 if (!netsc520_map.virt) {
diff --git a/drivers/mtd/maps/sc520cdp.c b/drivers/mtd/maps/sc520cdp.c
index 9b50cfc355b1..4045e372b90d 100644
--- a/drivers/mtd/maps/sc520cdp.c
+++ b/drivers/mtd/maps/sc520cdp.c
@@ -237,8 +237,9 @@ static int __init init_sc520cdp(void)
237#endif 237#endif
238 238
239 for (i = 0; i < NUM_FLASH_BANKS; i++) { 239 for (i = 0; i < NUM_FLASH_BANKS; i++) {
240 printk(KERN_NOTICE "SC520 CDP flash device: 0x%lx at 0x%lx\n", 240 printk(KERN_NOTICE "SC520 CDP flash device: 0x%Lx at 0x%Lx\n",
241 sc520cdp_map[i].size, sc520cdp_map[i].phys); 241 (unsigned long long)sc520cdp_map[i].size,
242 (unsigned long long)sc520cdp_map[i].phys);
242 243
243 sc520cdp_map[i].virt = ioremap_nocache(sc520cdp_map[i].phys, sc520cdp_map[i].size); 244 sc520cdp_map[i].virt = ioremap_nocache(sc520cdp_map[i].phys, sc520cdp_map[i].size);
244 245
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 61a994ea8af1..1592eac64e57 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -419,8 +419,9 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
419 info.erasesize = mtd->erasesize; 419 info.erasesize = mtd->erasesize;
420 info.writesize = mtd->writesize; 420 info.writesize = mtd->writesize;
421 info.oobsize = mtd->oobsize; 421 info.oobsize = mtd->oobsize;
422 info.ecctype = mtd->ecctype; 422 /* The below fields are obsolete */
423 info.eccsize = mtd->eccsize; 423 info.ecctype = -1;
424 info.eccsize = 0;
424 if (copy_to_user(argp, &info, sizeof(struct mtd_info_user))) 425 if (copy_to_user(argp, &info, sizeof(struct mtd_info_user)))
425 return -EFAULT; 426 return -EFAULT;
426 break; 427 break;
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 06902683bc2a..880580c44e01 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -727,8 +727,6 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
727 concat->mtd.erasesize = subdev[0]->erasesize; 727 concat->mtd.erasesize = subdev[0]->erasesize;
728 concat->mtd.writesize = subdev[0]->writesize; 728 concat->mtd.writesize = subdev[0]->writesize;
729 concat->mtd.oobsize = subdev[0]->oobsize; 729 concat->mtd.oobsize = subdev[0]->oobsize;
730 concat->mtd.ecctype = subdev[0]->ecctype;
731 concat->mtd.eccsize = subdev[0]->eccsize;
732 if (subdev[0]->writev) 730 if (subdev[0]->writev)
733 concat->mtd.writev = concat_writev; 731 concat->mtd.writev = concat_writev;
734 if (subdev[0]->read_oob) 732 if (subdev[0]->read_oob)
@@ -774,8 +772,6 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
774 if (concat->mtd.writesize != subdev[i]->writesize || 772 if (concat->mtd.writesize != subdev[i]->writesize ||
775 concat->mtd.subpage_sft != subdev[i]->subpage_sft || 773 concat->mtd.subpage_sft != subdev[i]->subpage_sft ||
776 concat->mtd.oobsize != subdev[i]->oobsize || 774 concat->mtd.oobsize != subdev[i]->oobsize ||
777 concat->mtd.ecctype != subdev[i]->ecctype ||
778 concat->mtd.eccsize != subdev[i]->eccsize ||
779 !concat->mtd.read_oob != !subdev[i]->read_oob || 775 !concat->mtd.read_oob != !subdev[i]->read_oob ||
780 !concat->mtd.write_oob != !subdev[i]->write_oob) { 776 !concat->mtd.write_oob != !subdev[i]->write_oob) {
781 kfree(concat); 777 kfree(concat);
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index bafd2fba87bd..633def3fb087 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -338,8 +338,6 @@ int add_mtd_partitions(struct mtd_info *master,
338 slave->mtd.size = parts[i].size; 338 slave->mtd.size = parts[i].size;
339 slave->mtd.writesize = master->writesize; 339 slave->mtd.writesize = master->writesize;
340 slave->mtd.oobsize = master->oobsize; 340 slave->mtd.oobsize = master->oobsize;
341 slave->mtd.ecctype = master->ecctype;
342 slave->mtd.eccsize = master->eccsize;
343 slave->mtd.subpage_sft = master->subpage_sft; 341 slave->mtd.subpage_sft = master->subpage_sft;
344 342
345 slave->mtd.name = parts[i].name; 343 slave->mtd.name = parts[i].name;
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 358f55a82dbe..2d12dcdd740c 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -126,10 +126,6 @@ config MTD_NAND_S3C2410_HWECC
126 incorrect ECC generation, and if using these, the default of 126 incorrect ECC generation, and if using these, the default of
127 software ECC is preferable. 127 software ECC is preferable.
128 128
129 If you lay down a device with the hardware ECC, then you will
130 currently not be able to switch to software, as there is no
131 implementation for ECC method used by the S3C2410
132
133config MTD_NAND_NDFC 129config MTD_NAND_NDFC
134 tristate "NDFC NanD Flash Controller" 130 tristate "NDFC NanD Flash Controller"
135 depends on MTD_NAND && 44x 131 depends on MTD_NAND && 44x
@@ -221,9 +217,17 @@ config MTD_NAND_SHARPSL
221 tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)" 217 tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)"
222 depends on MTD_NAND && ARCH_PXA 218 depends on MTD_NAND && ARCH_PXA
223 219
220config MTD_NAND_BASLER_EXCITE
221 tristate "Support for NAND Flash on Basler eXcite"
222 depends on MTD_NAND && BASLER_EXCITE
223 help
224 This enables the driver for the NAND flash device found on the
225 Basler eXcite Smart Camera. If built as a module, the driver
226 will be named "excite_nandflash.ko".
227
224config MTD_NAND_CAFE 228config MTD_NAND_CAFE
225 tristate "NAND support for OLPC CAFÉ chip" 229 tristate "NAND support for OLPC CAFÉ chip"
226 depends on PCI 230 depends on MTD_NAND && PCI
227 help 231 help
228 Use NAND flash attached to the CAFÉ chip designed for the $100 232 Use NAND flash attached to the CAFÉ chip designed for the $100
229 laptop. 233 laptop.
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index f7a53f0b7017..80f1dfc77949 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_MTD_NAND_NANDSIM) += nandsim.o
24obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o 24obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o
25obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o 25obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o
26obj-$(CONFIG_MTD_NAND_AT91) += at91_nand.o 26obj-$(CONFIG_MTD_NAND_AT91) += at91_nand.o
27obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o
27 28
28nand-objs := nand_base.o nand_bbt.o 29nand-objs := nand_base.o nand_bbt.o
29cafe_nand-objs := cafe.o cafe_ecc.o 30cafe_nand-objs := cafe.o cafe_ecc.o
diff --git a/drivers/mtd/nand/cafe.c b/drivers/mtd/nand/cafe.c
index 08cb060dfa3d..fd6bb3ed40df 100644
--- a/drivers/mtd/nand/cafe.c
+++ b/drivers/mtd/nand/cafe.c
@@ -78,8 +78,9 @@ module_param(regdebug, int, 0644);
78static int checkecc = 1; 78static int checkecc = 1;
79module_param(checkecc, int, 0644); 79module_param(checkecc, int, 0644);
80 80
81static int slowtiming = 0; 81static int numtimings;
82module_param(slowtiming, int, 0644); 82static int timing[3];
83module_param_array(timing, int, &numtimings, 0644);
83 84
84/* Hrm. Why isn't this already conditional on something in the struct device? */ 85/* Hrm. Why isn't this already conditional on something in the struct device? */
85#define cafe_dev_dbg(dev, args...) do { if (debug) dev_dbg(dev, ##args); } while(0) 86#define cafe_dev_dbg(dev, args...) do { if (debug) dev_dbg(dev, ##args); } while(0)
@@ -264,10 +265,10 @@ static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
264 ndelay(100); 265 ndelay(100);
265 266
266 if (1) { 267 if (1) {
267 int c = 500000; 268 int c;
268 uint32_t irqs; 269 uint32_t irqs;
269 270
270 while (c--) { 271 for (c = 500000; c != 0; c--) {
271 irqs = cafe_readl(cafe, NAND_IRQ); 272 irqs = cafe_readl(cafe, NAND_IRQ);
272 if (irqs & doneint) 273 if (irqs & doneint)
273 break; 274 break;
@@ -529,6 +530,7 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev,
529{ 530{
530 struct mtd_info *mtd; 531 struct mtd_info *mtd;
531 struct cafe_priv *cafe; 532 struct cafe_priv *cafe;
533 uint32_t timing1, timing2, timing3;
532 uint32_t ctrl; 534 uint32_t ctrl;
533 int err = 0; 535 int err = 0;
534 536
@@ -580,31 +582,45 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev,
580 cafe->nand.block_bad = cafe_nand_block_bad; 582 cafe->nand.block_bad = cafe_nand_block_bad;
581 } 583 }
582 584
585 if (numtimings && numtimings != 3) {
586 dev_warn(&cafe->pdev->dev, "%d timing register values ignored; precisely three are required\n", numtimings);
587 }
588
589 if (numtimings == 3) {
590 timing1 = timing[0];
591 timing2 = timing[1];
592 timing3 = timing[2];
593 cafe_dev_dbg(&cafe->pdev->dev, "Using provided timings (%08x %08x %08x)\n",
594 timing1, timing2, timing3);
595 } else {
596 timing1 = cafe_readl(cafe, NAND_TIMING1);
597 timing2 = cafe_readl(cafe, NAND_TIMING2);
598 timing3 = cafe_readl(cafe, NAND_TIMING3);
599
600 if (timing1 | timing2 | timing3) {
601 cafe_dev_dbg(&cafe->pdev->dev, "Timing registers already set (%08x %08x %08x)\n", timing1, timing2, timing3);
602 } else {
603 dev_warn(&cafe->pdev->dev, "Timing registers unset; using most conservative defaults\n");
604 timing1 = timing2 = timing3 = 0xffffffff;
605 }
606 }
607
583 /* Start off by resetting the NAND controller completely */ 608 /* Start off by resetting the NAND controller completely */
584 cafe_writel(cafe, 1, NAND_RESET); 609 cafe_writel(cafe, 1, NAND_RESET);
585 cafe_writel(cafe, 0, NAND_RESET); 610 cafe_writel(cafe, 0, NAND_RESET);
586 611
587 cafe_writel(cafe, 0xffffffff, NAND_IRQ_MASK); 612 cafe_writel(cafe, timing1, NAND_TIMING1);
613 cafe_writel(cafe, timing2, NAND_TIMING2);
614 cafe_writel(cafe, timing3, NAND_TIMING3);
588 615
589 /* Timings from Marvell's test code (not verified or calculated by us) */
590 if (!slowtiming) {
591 cafe_writel(cafe, 0x01010a0a, NAND_TIMING1);
592 cafe_writel(cafe, 0x24121212, NAND_TIMING2);
593 cafe_writel(cafe, 0x11000000, NAND_TIMING3);
594 } else {
595 cafe_writel(cafe, 0xffffffff, NAND_TIMING1);
596 cafe_writel(cafe, 0xffffffff, NAND_TIMING2);
597 cafe_writel(cafe, 0xffffffff, NAND_TIMING3);
598 }
599 cafe_writel(cafe, 0xffffffff, NAND_IRQ_MASK); 616 cafe_writel(cafe, 0xffffffff, NAND_IRQ_MASK);
600 err = request_irq(pdev->irq, &cafe_nand_interrupt, IRQF_SHARED, 617 err = request_irq(pdev->irq, &cafe_nand_interrupt, IRQF_SHARED,
601 "CAFE NAND", mtd); 618 "CAFE NAND", mtd);
602 if (err) { 619 if (err) {
603 dev_warn(&pdev->dev, "Could not register IRQ %d\n", pdev->irq); 620 dev_warn(&pdev->dev, "Could not register IRQ %d\n", pdev->irq);
604
605 goto out_free_dma; 621 goto out_free_dma;
606 } 622 }
607#if 1 623
608 /* Disable master reset, enable NAND clock */ 624 /* Disable master reset, enable NAND clock */
609 ctrl = cafe_readl(cafe, GLOBAL_CTRL); 625 ctrl = cafe_readl(cafe, GLOBAL_CTRL);
610 ctrl &= 0xffffeff0; 626 ctrl &= 0xffffeff0;
@@ -631,32 +647,8 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev,
631 cafe_writel(cafe, 0x80000007, GLOBAL_IRQ_MASK); 647 cafe_writel(cafe, 0x80000007, GLOBAL_IRQ_MASK);
632 cafe_dev_dbg(&cafe->pdev->dev, "Control %x, IRQ mask %x\n", 648 cafe_dev_dbg(&cafe->pdev->dev, "Control %x, IRQ mask %x\n",
633 cafe_readl(cafe, GLOBAL_CTRL), cafe_readl(cafe, GLOBAL_IRQ_MASK)); 649 cafe_readl(cafe, GLOBAL_CTRL), cafe_readl(cafe, GLOBAL_IRQ_MASK));
634#endif 650
635#if 1 651 /* Scan to find existence of the device */
636 mtd->writesize=2048;
637 mtd->oobsize = 0x40;
638 memset(cafe->dmabuf, 0x5a, 2112);
639 cafe->nand.cmdfunc(mtd, NAND_CMD_READID, 0, -1);
640 cafe->nand.read_byte(mtd);
641 cafe->nand.read_byte(mtd);
642 cafe->nand.read_byte(mtd);
643 cafe->nand.read_byte(mtd);
644 cafe->nand.read_byte(mtd);
645#endif
646#if 0
647 cafe->nand.cmdfunc(mtd, NAND_CMD_READ0, 0, 0);
648 // nand_wait_ready(mtd);
649 cafe->nand.read_byte(mtd);
650 cafe->nand.read_byte(mtd);
651 cafe->nand.read_byte(mtd);
652 cafe->nand.read_byte(mtd);
653#endif
654#if 0
655 writel(0x84600070, cafe->mmio);
656 udelay(10);
657 cafe_dev_dbg(&cafe->pdev->dev, "Status %x\n", cafe_readl(cafe, NAND_NONMEM));
658#endif
659 /* Scan to find existance of the device */
660 if (nand_scan_ident(mtd, 1)) { 652 if (nand_scan_ident(mtd, 1)) {
661 err = -ENXIO; 653 err = -ENXIO;
662 goto out_irq; 654 goto out_irq;
@@ -760,13 +752,4 @@ module_exit(cafe_nand_exit);
760 752
761MODULE_LICENSE("GPL"); 753MODULE_LICENSE("GPL");
762MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); 754MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
763MODULE_DESCRIPTION("NAND flash driver for OLPC CAFE chip"); 755MODULE_DESCRIPTION("NAND flash driver for OLPC CAFÉ chip");
764
765/* Correct ECC for 2048 bytes of 0xff:
766 41 a0 71 65 54 27 f3 93 ec a9 be ed 0b a1 */
767
768/* dwmw2's B-test board, in case of completely screwing it:
769Bad eraseblock 2394 at 0x12b40000
770Bad eraseblock 2627 at 0x14860000
771Bad eraseblock 3349 at 0x1a2a0000
772*/
diff --git a/drivers/mtd/nand/cafe_ecc.c b/drivers/mtd/nand/cafe_ecc.c
index 1b9fa05a4474..ea5c8491d2c5 100644
--- a/drivers/mtd/nand/cafe_ecc.c
+++ b/drivers/mtd/nand/cafe_ecc.c
@@ -1045,7 +1045,7 @@ static unsigned short err_pos_lut[4096] = {
1045 1045
1046static unsigned short err_pos(unsigned short din) 1046static unsigned short err_pos(unsigned short din)
1047{ 1047{
1048 BUG_ON(din > 4096); 1048 BUG_ON(din >= ARRAY_SIZE(err_pos_lut));
1049 return err_pos_lut[din]; 1049 return err_pos_lut[din];
1050} 1050}
1051static int chk_no_err_only(unsigned short *chk_syndrome_list, unsigned short *err_info) 1051static int chk_no_err_only(unsigned short *chk_syndrome_list, unsigned short *err_info)
diff --git a/drivers/mtd/nand/excite_nandflash.c b/drivers/mtd/nand/excite_nandflash.c
new file mode 100644
index 000000000000..7e9afc4c7757
--- /dev/null
+++ b/drivers/mtd/nand/excite_nandflash.c
@@ -0,0 +1,248 @@
1/*
2* Copyright (C) 2005 - 2007 by Basler Vision Technologies AG
3* Author: Thomas Koeller <thomas.koeller.qbaslerweb.com>
4* Original code by Thies Moeller <thies.moeller@baslerweb.com>
5*
6* This program is free software; you can redistribute it and/or modify
7* it under the terms of the GNU General Public License as published by
8* the Free Software Foundation; either version 2 of the License, or
9* (at your option) any later version.
10*
11* This program is distributed in the hope that it will be useful,
12* but WITHOUT ANY WARRANTY; without even the implied warranty of
13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14* GNU General Public License for more details.
15*
16* You should have received a copy of the GNU General Public License
17* along with this program; if not, write to the Free Software
18* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19*/
20
21#include <linux/module.h>
22#include <linux/types.h>
23#include <linux/init.h>
24#include <linux/kernel.h>
25#include <linux/string.h>
26#include <linux/ioport.h>
27#include <linux/platform_device.h>
28#include <linux/delay.h>
29#include <linux/err.h>
30#include <linux/kernel.h>
31
32#include <linux/mtd/mtd.h>
33#include <linux/mtd/nand.h>
34#include <linux/mtd/nand_ecc.h>
35#include <linux/mtd/partitions.h>
36
37#include <asm/io.h>
38#include <asm/rm9k-ocd.h>
39
40#include <excite_nandflash.h>
41
42#define EXCITE_NANDFLASH_VERSION "0.1"
43
44/* I/O register offsets */
45#define EXCITE_NANDFLASH_DATA_BYTE 0x00
46#define EXCITE_NANDFLASH_STATUS_BYTE 0x0c
47#define EXCITE_NANDFLASH_ADDR_BYTE 0x10
48#define EXCITE_NANDFLASH_CMD_BYTE 0x14
49
50/* prefix for debug output */
51static const char module_id[] = "excite_nandflash";
52
53/*
54 * partition definition
55 */
56static const struct mtd_partition partition_info[] = {
57 {
58 .name = "eXcite RootFS",
59 .offset = 0,
60 .size = MTDPART_SIZ_FULL
61 }
62};
63
64static inline const struct resource *
65excite_nand_get_resource(struct platform_device *d, unsigned long flags,
66 const char *basename)
67{
68 char buf[80];
69
70 if (snprintf(buf, sizeof buf, "%s_%u", basename, d->id) >= sizeof buf)
71 return NULL;
72 return platform_get_resource_byname(d, flags, buf);
73}
74
75static inline void __iomem *
76excite_nand_map_regs(struct platform_device *d, const char *basename)
77{
78 void *result = NULL;
79 const struct resource *const r =
80 excite_nand_get_resource(d, IORESOURCE_MEM, basename);
81
82 if (r)
83 result = ioremap_nocache(r->start, r->end + 1 - r->start);
84 return result;
85}
86
87/* controller and mtd information */
88struct excite_nand_drvdata {
89 struct mtd_info board_mtd;
90 struct nand_chip board_chip;
91 void __iomem *regs;
92 void __iomem *tgt;
93};
94
95/* Control function */
96static void excite_nand_control(struct mtd_info *mtd, int cmd,
97 unsigned int ctrl)
98{
99 struct excite_nand_drvdata * const d =
100 container_of(mtd, struct excite_nand_drvdata, board_mtd);
101
102 switch (ctrl) {
103 case NAND_CTRL_CHANGE | NAND_CTRL_CLE:
104 d->tgt = d->regs + EXCITE_NANDFLASH_CMD_BYTE;
105 break;
106 case NAND_CTRL_CHANGE | NAND_CTRL_ALE:
107 d->tgt = d->regs + EXCITE_NANDFLASH_ADDR_BYTE;
108 break;
109 case NAND_CTRL_CHANGE | NAND_NCE:
110 d->tgt = d->regs + EXCITE_NANDFLASH_DATA_BYTE;
111 break;
112 }
113
114 if (cmd != NAND_CMD_NONE)
115 __raw_writeb(cmd, d->tgt);
116}
117
118/* Return 0 if flash is busy, 1 if ready */
119static int excite_nand_devready(struct mtd_info *mtd)
120{
121 struct excite_nand_drvdata * const drvdata =
122 container_of(mtd, struct excite_nand_drvdata, board_mtd);
123
124 return __raw_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS_BYTE);
125}
126
127/*
128 * Called by device layer to remove the driver.
129 * The binding to the mtd and all allocated
130 * resources are released.
131 */
132static int __exit excite_nand_remove(struct device *dev)
133{
134 struct excite_nand_drvdata * const this = dev_get_drvdata(dev);
135
136 dev_set_drvdata(dev, NULL);
137
138 if (unlikely(!this)) {
139 printk(KERN_ERR "%s: called %s without private data!!",
140 module_id, __func__);
141 return -EINVAL;
142 }
143
144 /* first thing we need to do is release our mtd
145 * then go through freeing the resource used
146 */
147 nand_release(&this->board_mtd);
148
149 /* free the common resources */
150 iounmap(this->regs);
151 kfree(this);
152
153 DEBUG(MTD_DEBUG_LEVEL1, "%s: removed\n", module_id);
154 return 0;
155}
156
157/*
158 * Called by device layer when it finds a device matching
159 * one our driver can handle. This code checks to see if
160 * it can allocate all necessary resources then calls the
161 * nand layer to look for devices.
162*/
163static int __init excite_nand_probe(struct device *dev)
164{
165 struct platform_device * const pdev = to_platform_device(dev);
166 struct excite_nand_drvdata *drvdata; /* private driver data */
167 struct nand_chip *board_chip; /* private flash chip data */
168 struct mtd_info *board_mtd; /* mtd info for this board */
169 int scan_res;
170
171 drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
172 if (unlikely(!drvdata)) {
173 printk(KERN_ERR "%s: no memory for drvdata\n",
174 module_id);
175 return -ENOMEM;
176 }
177
178 /* bind private data into driver */
179 dev_set_drvdata(dev, drvdata);
180
181 /* allocate and map the resource */
182 drvdata->regs =
183 excite_nand_map_regs(pdev, EXCITE_NANDFLASH_RESOURCE_REGS);
184
185 if (unlikely(!drvdata->regs)) {
186 printk(KERN_ERR "%s: cannot reserve register region\n",
187 module_id);
188 kfree(drvdata);
189 return -ENXIO;
190 }
191
192 drvdata->tgt = drvdata->regs + EXCITE_NANDFLASH_DATA_BYTE;
193
194 /* initialise our chip */
195 board_chip = &drvdata->board_chip;
196 board_chip->IO_ADDR_R = board_chip->IO_ADDR_W =
197 drvdata->regs + EXCITE_NANDFLASH_DATA_BYTE;
198 board_chip->cmd_ctrl = excite_nand_control;
199 board_chip->dev_ready = excite_nand_devready;
200 board_chip->chip_delay = 25;
201 board_chip->ecc.mode = NAND_ECC_SOFT;
202
203 /* link chip to mtd */
204 board_mtd = &drvdata->board_mtd;
205 board_mtd->priv = board_chip;
206
207 DEBUG(MTD_DEBUG_LEVEL2, "%s: device scan\n", module_id);
208 scan_res = nand_scan(&drvdata->board_mtd, 1);
209
210 if (likely(!scan_res)) {
211 DEBUG(MTD_DEBUG_LEVEL2, "%s: register partitions\n", module_id);
212 add_mtd_partitions(&drvdata->board_mtd, partition_info,
213 sizeof partition_info / sizeof partition_info[0]);
214 } else {
215 iounmap(drvdata->regs);
216 kfree(drvdata);
217 printk(KERN_ERR "%s: device scan failed\n", module_id);
218 return -EIO;
219 }
220 return 0;
221}
222
223static struct device_driver excite_nand_driver = {
224 .name = "excite_nand",
225 .bus = &platform_bus_type,
226 .probe = excite_nand_probe,
227 .remove = __exit_p(excite_nand_remove)
228};
229
230static int __init excite_nand_init(void)
231{
232 pr_info("Basler eXcite nand flash driver Version "
233 EXCITE_NANDFLASH_VERSION "\n");
234 return driver_register(&excite_nand_driver);
235}
236
237static void __exit excite_nand_exit(void)
238{
239 driver_unregister(&excite_nand_driver);
240}
241
242module_init(excite_nand_init);
243module_exit(excite_nand_exit);
244
245MODULE_AUTHOR("Thomas Koeller <thomas.koeller@baslerweb.com>");
246MODULE_DESCRIPTION("Basler eXcite NAND-Flash driver");
247MODULE_LICENSE("GPL");
248MODULE_VERSION(EXCITE_NANDFLASH_VERSION)
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index dfe56e03e48b..acaf97bc80d1 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1272,10 +1272,25 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
1272 DEBUG(MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08Lx, len = %i\n", 1272 DEBUG(MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08Lx, len = %i\n",
1273 (unsigned long long)from, readlen); 1273 (unsigned long long)from, readlen);
1274 1274
1275 if (ops->mode == MTD_OOB_RAW) 1275 if (ops->mode == MTD_OOB_AUTO)
1276 len = mtd->oobsize;
1277 else
1278 len = chip->ecc.layout->oobavail; 1276 len = chip->ecc.layout->oobavail;
1277 else
1278 len = mtd->oobsize;
1279
1280 if (unlikely(ops->ooboffs >= len)) {
1281 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
1282 "Attempt to start read outside oob\n");
1283 return -EINVAL;
1284 }
1285
1286 /* Do not allow reads past end of device */
1287 if (unlikely(from >= mtd->size ||
1288 ops->ooboffs + readlen > ((mtd->size >> chip->page_shift) -
1289 (from >> chip->page_shift)) * len)) {
1290 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
1291 "Attempt read beyond end of device\n");
1292 return -EINVAL;
1293 }
1279 1294
1280 chipnr = (int)(from >> chip->chip_shift); 1295 chipnr = (int)(from >> chip->chip_shift);
1281 chip->select_chip(mtd, chipnr); 1296 chip->select_chip(mtd, chipnr);
@@ -1742,19 +1757,40 @@ static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
1742static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, 1757static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
1743 struct mtd_oob_ops *ops) 1758 struct mtd_oob_ops *ops)
1744{ 1759{
1745 int chipnr, page, status; 1760 int chipnr, page, status, len;
1746 struct nand_chip *chip = mtd->priv; 1761 struct nand_chip *chip = mtd->priv;
1747 1762
1748 DEBUG(MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n", 1763 DEBUG(MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n",
1749 (unsigned int)to, (int)ops->ooblen); 1764 (unsigned int)to, (int)ops->ooblen);
1750 1765
1766 if (ops->mode == MTD_OOB_AUTO)
1767 len = chip->ecc.layout->oobavail;
1768 else
1769 len = mtd->oobsize;
1770
1751 /* Do not allow write past end of page */ 1771 /* Do not allow write past end of page */
1752 if ((ops->ooboffs + ops->ooblen) > mtd->oobsize) { 1772 if ((ops->ooboffs + ops->ooblen) > len) {
1753 DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: " 1773 DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: "
1754 "Attempt to write past end of page\n"); 1774 "Attempt to write past end of page\n");
1755 return -EINVAL; 1775 return -EINVAL;
1756 } 1776 }
1757 1777
1778 if (unlikely(ops->ooboffs >= len)) {
1779 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
1780 "Attempt to start write outside oob\n");
1781 return -EINVAL;
1782 }
1783
1784 /* Do not allow reads past end of device */
1785 if (unlikely(to >= mtd->size ||
1786 ops->ooboffs + ops->ooblen >
1787 ((mtd->size >> chip->page_shift) -
1788 (to >> chip->page_shift)) * len)) {
1789 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
1790 "Attempt write beyond end of device\n");
1791 return -EINVAL;
1792 }
1793
1758 chipnr = (int)(to >> chip->chip_shift); 1794 chipnr = (int)(to >> chip->chip_shift);
1759 chip->select_chip(mtd, chipnr); 1795 chip->select_chip(mtd, chipnr);
1760 1796
@@ -2530,7 +2566,6 @@ int nand_scan_tail(struct mtd_info *mtd)
2530 /* Fill in remaining MTD driver data */ 2566 /* Fill in remaining MTD driver data */
2531 mtd->type = MTD_NANDFLASH; 2567 mtd->type = MTD_NANDFLASH;
2532 mtd->flags = MTD_CAP_NANDFLASH; 2568 mtd->flags = MTD_CAP_NANDFLASH;
2533 mtd->ecctype = MTD_ECC_SW;
2534 mtd->erase = nand_erase; 2569 mtd->erase = nand_erase;
2535 mtd->point = NULL; 2570 mtd->point = NULL;
2536 mtd->unpoint = NULL; 2571 mtd->unpoint = NULL;
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index 8b3203571eeb..0ddfd6de75c5 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -337,17 +337,69 @@ static int s3c2412_nand_devready(struct mtd_info *mtd)
337static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, 337static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat,
338 u_char *read_ecc, u_char *calc_ecc) 338 u_char *read_ecc, u_char *calc_ecc)
339{ 339{
340 pr_debug("s3c2410_nand_correct_data(%p,%p,%p,%p)\n", mtd, dat, read_ecc, calc_ecc); 340 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
341 unsigned int diff0, diff1, diff2;
342 unsigned int bit, byte;
341 343
342 pr_debug("eccs: read %02x,%02x,%02x vs calc %02x,%02x,%02x\n", 344 pr_debug("%s(%p,%p,%p,%p)\n", __func__, mtd, dat, read_ecc, calc_ecc);
343 read_ecc[0], read_ecc[1], read_ecc[2], calc_ecc[0], calc_ecc[1], calc_ecc[2]);
344 345
345 if (read_ecc[0] == calc_ecc[0] && read_ecc[1] == calc_ecc[1] && read_ecc[2] == calc_ecc[2]) 346 diff0 = read_ecc[0] ^ calc_ecc[0];
346 return 0; 347 diff1 = read_ecc[1] ^ calc_ecc[1];
348 diff2 = read_ecc[2] ^ calc_ecc[2];
349
350 pr_debug("%s: rd %02x%02x%02x calc %02x%02x%02x diff %02x%02x%02x\n",
351 __func__,
352 read_ecc[0], read_ecc[1], read_ecc[2],
353 calc_ecc[0], calc_ecc[1], calc_ecc[2],
354 diff0, diff1, diff2);
355
356 if (diff0 == 0 && diff1 == 0 && diff2 == 0)
357 return 0; /* ECC is ok */
358
359 /* Can we correct this ECC (ie, one row and column change).
360 * Note, this is similar to the 256 error code on smartmedia */
361
362 if (((diff0 ^ (diff0 >> 1)) & 0x55) == 0x55 &&
363 ((diff1 ^ (diff1 >> 1)) & 0x55) == 0x55 &&
364 ((diff2 ^ (diff2 >> 1)) & 0x55) == 0x55) {
365 /* calculate the bit position of the error */
366
367 bit = (diff2 >> 2) & 1;
368 bit |= (diff2 >> 3) & 2;
369 bit |= (diff2 >> 4) & 4;
370
371 /* calculate the byte position of the error */
372
373 byte = (diff1 << 1) & 0x80;
374 byte |= (diff1 << 2) & 0x40;
375 byte |= (diff1 << 3) & 0x20;
376 byte |= (diff1 << 4) & 0x10;
377
378 byte |= (diff0 >> 3) & 0x08;
379 byte |= (diff0 >> 2) & 0x04;
380 byte |= (diff0 >> 1) & 0x02;
381 byte |= (diff0 >> 0) & 0x01;
347 382
348 /* we curently have no method for correcting the error */ 383 byte |= (diff2 << 8) & 0x100;
349 384
350 return -1; 385 dev_dbg(info->device, "correcting error bit %d, byte %d\n",
386 bit, byte);
387
388 dat[byte] ^= (1 << bit);
389 return 1;
390 }
391
392 /* if there is only one bit difference in the ECC, then
393 * one of only a row or column parity has changed, which
394 * means the error is most probably in the ECC itself */
395
396 diff0 |= (diff1 << 8);
397 diff0 |= (diff2 << 16);
398
399 if ((diff0 & ~(1<<fls(diff0))) == 0)
400 return 1;
401
402 return 0;
351} 403}
352 404
353/* ECC functions 405/* ECC functions
@@ -366,6 +418,15 @@ static void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode)
366 writel(ctrl, info->regs + S3C2410_NFCONF); 418 writel(ctrl, info->regs + S3C2410_NFCONF);
367} 419}
368 420
421static void s3c2412_nand_enable_hwecc(struct mtd_info *mtd, int mode)
422{
423 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
424 unsigned long ctrl;
425
426 ctrl = readl(info->regs + S3C2440_NFCONT);
427 writel(ctrl | S3C2412_NFCONT_INIT_MAIN_ECC, info->regs + S3C2440_NFCONT);
428}
429
369static void s3c2440_nand_enable_hwecc(struct mtd_info *mtd, int mode) 430static void s3c2440_nand_enable_hwecc(struct mtd_info *mtd, int mode)
370{ 431{
371 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 432 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
@@ -383,6 +444,21 @@ static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u
383 ecc_code[1] = readb(info->regs + S3C2410_NFECC + 1); 444 ecc_code[1] = readb(info->regs + S3C2410_NFECC + 1);
384 ecc_code[2] = readb(info->regs + S3C2410_NFECC + 2); 445 ecc_code[2] = readb(info->regs + S3C2410_NFECC + 2);
385 446
447 pr_debug("%s: returning ecc %02x%02x%02x\n", __func__,
448 ecc_code[0], ecc_code[1], ecc_code[2]);
449
450 return 0;
451}
452
453static int s3c2412_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
454{
455 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
456 unsigned long ecc = readl(info->regs + S3C2412_NFMECC0);
457
458 ecc_code[0] = ecc;
459 ecc_code[1] = ecc >> 8;
460 ecc_code[2] = ecc >> 16;
461
386 pr_debug("calculate_ecc: returning ecc %02x,%02x,%02x\n", ecc_code[0], ecc_code[1], ecc_code[2]); 462 pr_debug("calculate_ecc: returning ecc %02x,%02x,%02x\n", ecc_code[0], ecc_code[1], ecc_code[2]);
387 463
388 return 0; 464 return 0;
@@ -397,7 +473,7 @@ static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u
397 ecc_code[1] = ecc >> 8; 473 ecc_code[1] = ecc >> 8;
398 ecc_code[2] = ecc >> 16; 474 ecc_code[2] = ecc >> 16;
399 475
400 pr_debug("calculate_ecc: returning ecc %02x,%02x,%02x\n", ecc_code[0], ecc_code[1], ecc_code[2]); 476 pr_debug("%s: returning ecc %06x\n", __func__, ecc);
401 477
402 return 0; 478 return 0;
403} 479}
@@ -565,6 +641,10 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
565 break; 641 break;
566 642
567 case TYPE_S3C2412: 643 case TYPE_S3C2412:
644 chip->ecc.hwctl = s3c2412_nand_enable_hwecc;
645 chip->ecc.calculate = s3c2412_nand_calculate_ecc;
646 break;
647
568 case TYPE_S3C2440: 648 case TYPE_S3C2440:
569 chip->ecc.hwctl = s3c2440_nand_enable_hwecc; 649 chip->ecc.hwctl = s3c2440_nand_enable_hwecc;
570 chip->ecc.calculate = s3c2440_nand_calculate_ecc; 650 chip->ecc.calculate = s3c2440_nand_calculate_ecc;
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 2da6bb26353e..7f1cb6e5dccb 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * linux/drivers/mtd/onenand/onenand_base.c 2 * linux/drivers/mtd/onenand/onenand_base.c
3 * 3 *
4 * Copyright (C) 2005-2006 Samsung Electronics 4 * Copyright (C) 2005-2007 Samsung Electronics
5 * Kyungmin Park <kyungmin.park@samsung.com> 5 * Kyungmin Park <kyungmin.park@samsung.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -94,16 +94,9 @@ static void onenand_writew(unsigned short value, void __iomem *addr)
94 */ 94 */
95static int onenand_block_address(struct onenand_chip *this, int block) 95static int onenand_block_address(struct onenand_chip *this, int block)
96{ 96{
97 if (this->device_id & ONENAND_DEVICE_IS_DDP) { 97 /* Device Flash Core select, NAND Flash Block Address */
98 /* Device Flash Core select, NAND Flash Block Address */ 98 if (block & this->density_mask)
99 int dfs = 0; 99 return ONENAND_DDP_CHIP1 | (block ^ this->density_mask);
100
101 if (block & this->density_mask)
102 dfs = 1;
103
104 return (dfs << ONENAND_DDP_SHIFT) |
105 (block & (this->density_mask - 1));
106 }
107 100
108 return block; 101 return block;
109} 102}
@@ -118,17 +111,11 @@ static int onenand_block_address(struct onenand_chip *this, int block)
118 */ 111 */
119static int onenand_bufferram_address(struct onenand_chip *this, int block) 112static int onenand_bufferram_address(struct onenand_chip *this, int block)
120{ 113{
121 if (this->device_id & ONENAND_DEVICE_IS_DDP) { 114 /* Device BufferRAM Select */
122 /* Device BufferRAM Select */ 115 if (block & this->density_mask)
123 int dbs = 0; 116 return ONENAND_DDP_CHIP1;
124
125 if (block & this->density_mask)
126 dbs = 1;
127 117
128 return (dbs << ONENAND_DDP_SHIFT); 118 return ONENAND_DDP_CHIP0;
129 }
130
131 return 0;
132} 119}
133 120
134/** 121/**
@@ -317,22 +304,25 @@ static int onenand_wait(struct mtd_info *mtd, int state)
317 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); 304 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
318 305
319 if (ctrl & ONENAND_CTRL_ERROR) { 306 if (ctrl & ONENAND_CTRL_ERROR) {
320 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: controller error = 0x%04x\n", ctrl); 307 printk(KERN_ERR "onenand_wait: controller error = 0x%04x\n", ctrl);
321 if (ctrl & ONENAND_CTRL_LOCK) 308 if (ctrl & ONENAND_CTRL_LOCK)
322 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: it's locked error.\n"); 309 printk(KERN_ERR "onenand_wait: it's locked error.\n");
323 return ctrl; 310 return ctrl;
324 } 311 }
325 312
326 if (interrupt & ONENAND_INT_READ) { 313 if (interrupt & ONENAND_INT_READ) {
327 int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS); 314 int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);
328 if (ecc) { 315 if (ecc) {
329 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: ECC error = 0x%04x\n", ecc); 316 printk(KERN_ERR "onenand_wait: ECC error = 0x%04x\n", ecc);
330 if (ecc & ONENAND_ECC_2BIT_ALL) { 317 if (ecc & ONENAND_ECC_2BIT_ALL) {
331 mtd->ecc_stats.failed++; 318 mtd->ecc_stats.failed++;
332 return ecc; 319 return ecc;
333 } else if (ecc & ONENAND_ECC_1BIT_ALL) 320 } else if (ecc & ONENAND_ECC_1BIT_ALL)
334 mtd->ecc_stats.corrected++; 321 mtd->ecc_stats.corrected++;
335 } 322 }
323 } else if (state == FL_READING) {
324 printk(KERN_ERR "onenand_wait: read timeout! ctrl=0x%04x intr=0x%04x\n", ctrl, interrupt);
325 return -EIO;
336 } 326 }
337 327
338 return 0; 328 return 0;
@@ -587,22 +577,32 @@ static int onenand_write_bufferram(struct mtd_info *mtd, int area,
587static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr) 577static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
588{ 578{
589 struct onenand_chip *this = mtd->priv; 579 struct onenand_chip *this = mtd->priv;
590 int block, page; 580 int blockpage, found = 0;
591 int i; 581 unsigned int i;
592 582
593 block = (int) (addr >> this->erase_shift); 583 blockpage = (int) (addr >> this->page_shift);
594 page = (int) (addr >> this->page_shift);
595 page &= this->page_mask;
596 584
585 /* Is there valid data? */
597 i = ONENAND_CURRENT_BUFFERRAM(this); 586 i = ONENAND_CURRENT_BUFFERRAM(this);
587 if (this->bufferram[i].blockpage == blockpage)
588 found = 1;
589 else {
590 /* Check another BufferRAM */
591 i = ONENAND_NEXT_BUFFERRAM(this);
592 if (this->bufferram[i].blockpage == blockpage) {
593 ONENAND_SET_NEXT_BUFFERRAM(this);
594 found = 1;
595 }
596 }
598 597
599 /* Is there valid data? */ 598 if (found && ONENAND_IS_DDP(this)) {
600 if (this->bufferram[i].block == block && 599 /* Select DataRAM for DDP */
601 this->bufferram[i].page == page && 600 int block = (int) (addr >> this->erase_shift);
602 this->bufferram[i].valid) 601 int value = onenand_bufferram_address(this, block);
603 return 1; 602 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
603 }
604 604
605 return 0; 605 return found;
606} 606}
607 607
608/** 608/**
@@ -613,31 +613,49 @@ static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
613 * 613 *
614 * Update BufferRAM information 614 * Update BufferRAM information
615 */ 615 */
616static int onenand_update_bufferram(struct mtd_info *mtd, loff_t addr, 616static void onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,
617 int valid) 617 int valid)
618{ 618{
619 struct onenand_chip *this = mtd->priv; 619 struct onenand_chip *this = mtd->priv;
620 int block, page; 620 int blockpage;
621 int i; 621 unsigned int i;
622 622
623 block = (int) (addr >> this->erase_shift); 623 blockpage = (int) (addr >> this->page_shift);
624 page = (int) (addr >> this->page_shift);
625 page &= this->page_mask;
626 624
627 /* Invalidate BufferRAM */ 625 /* Invalidate another BufferRAM */
628 for (i = 0; i < MAX_BUFFERRAM; i++) { 626 i = ONENAND_NEXT_BUFFERRAM(this);
629 if (this->bufferram[i].block == block && 627 if (this->bufferram[i].blockpage == blockpage)
630 this->bufferram[i].page == page) 628 this->bufferram[i].blockpage = -1;
631 this->bufferram[i].valid = 0;
632 }
633 629
634 /* Update BufferRAM */ 630 /* Update BufferRAM */
635 i = ONENAND_CURRENT_BUFFERRAM(this); 631 i = ONENAND_CURRENT_BUFFERRAM(this);
636 this->bufferram[i].block = block; 632 if (valid)
637 this->bufferram[i].page = page; 633 this->bufferram[i].blockpage = blockpage;
638 this->bufferram[i].valid = valid; 634 else
635 this->bufferram[i].blockpage = -1;
636}
639 637
640 return 0; 638/**
639 * onenand_invalidate_bufferram - [GENERIC] Invalidate BufferRAM information
640 * @param mtd MTD data structure
641 * @param addr start address to invalidate
642 * @param len length to invalidate
643 *
644 * Invalidate BufferRAM information
645 */
646static void onenand_invalidate_bufferram(struct mtd_info *mtd, loff_t addr,
647 unsigned int len)
648{
649 struct onenand_chip *this = mtd->priv;
650 int i;
651 loff_t end_addr = addr + len;
652
653 /* Invalidate BufferRAM */
654 for (i = 0; i < MAX_BUFFERRAM; i++) {
655 loff_t buf_addr = this->bufferram[i].blockpage << this->page_shift;
656 if (buf_addr >= addr && buf_addr < end_addr)
657 this->bufferram[i].blockpage = -1;
658 }
641} 659}
642 660
643/** 661/**
@@ -716,7 +734,7 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
716 734
717 /* Do not allow reads past end of device */ 735 /* Do not allow reads past end of device */
718 if ((from + len) > mtd->size) { 736 if ((from + len) > mtd->size) {
719 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read: Attempt read beyond end of device\n"); 737 printk(KERN_ERR "onenand_read: Attempt read beyond end of device\n");
720 *retlen = 0; 738 *retlen = 0;
721 return -EINVAL; 739 return -EINVAL;
722 } 740 }
@@ -724,8 +742,6 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
724 /* Grab the lock and see if the device is available */ 742 /* Grab the lock and see if the device is available */
725 onenand_get_device(mtd, FL_READING); 743 onenand_get_device(mtd, FL_READING);
726 744
727 /* TODO handling oob */
728
729 stats = mtd->ecc_stats; 745 stats = mtd->ecc_stats;
730 746
731 /* Read-while-load method */ 747 /* Read-while-load method */
@@ -754,9 +770,9 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
754 * Now we issued chip 1 read and pointed chip 1 770 * Now we issued chip 1 read and pointed chip 1
755 * bufferam so we have to point chip 0 bufferam. 771 * bufferam so we have to point chip 0 bufferam.
756 */ 772 */
757 if (this->device_id & ONENAND_DEVICE_IS_DDP && 773 if (ONENAND_IS_DDP(this) &&
758 unlikely(from == (this->chipsize >> 1))) { 774 unlikely(from == (this->chipsize >> 1))) {
759 this->write_word(0, this->base + ONENAND_REG_START_ADDRESS2); 775 this->write_word(ONENAND_DDP_CHIP0, this->base + ONENAND_REG_START_ADDRESS2);
760 boundary = 1; 776 boundary = 1;
761 } else 777 } else
762 boundary = 0; 778 boundary = 0;
@@ -770,7 +786,7 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
770 break; 786 break;
771 /* Set up for next read from bufferRAM */ 787 /* Set up for next read from bufferRAM */
772 if (unlikely(boundary)) 788 if (unlikely(boundary))
773 this->write_word(0x8000, this->base + ONENAND_REG_START_ADDRESS2); 789 this->write_word(ONENAND_DDP_CHIP1, this->base + ONENAND_REG_START_ADDRESS2);
774 ONENAND_SET_NEXT_BUFFERRAM(this); 790 ONENAND_SET_NEXT_BUFFERRAM(this);
775 buf += thislen; 791 buf += thislen;
776 thislen = min_t(int, mtd->writesize, len - read); 792 thislen = min_t(int, mtd->writesize, len - read);
@@ -801,20 +817,59 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
801} 817}
802 818
803/** 819/**
820 * onenand_transfer_auto_oob - [Internal] oob auto-placement transfer
821 * @param mtd MTD device structure
822 * @param buf destination address
823 * @param column oob offset to read from
824 * @param thislen oob length to read
825 */
826static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf, int column,
827 int thislen)
828{
829 struct onenand_chip *this = mtd->priv;
830 struct nand_oobfree *free;
831 int readcol = column;
832 int readend = column + thislen;
833 int lastgap = 0;
834 uint8_t *oob_buf = this->page_buf + mtd->writesize;
835
836 for (free = this->ecclayout->oobfree; free->length; ++free) {
837 if (readcol >= lastgap)
838 readcol += free->offset - lastgap;
839 if (readend >= lastgap)
840 readend += free->offset - lastgap;
841 lastgap = free->offset + free->length;
842 }
843 this->read_bufferram(mtd, ONENAND_SPARERAM, oob_buf, 0, mtd->oobsize);
844 for (free = this->ecclayout->oobfree; free->length; ++free) {
845 int free_end = free->offset + free->length;
846 if (free->offset < readend && free_end > readcol) {
847 int st = max_t(int,free->offset,readcol);
848 int ed = min_t(int,free_end,readend);
849 int n = ed - st;
850 memcpy(buf, oob_buf + st, n);
851 buf += n;
852 }
853 }
854 return 0;
855}
856
857/**
804 * onenand_do_read_oob - [MTD Interface] OneNAND read out-of-band 858 * onenand_do_read_oob - [MTD Interface] OneNAND read out-of-band
805 * @param mtd MTD device structure 859 * @param mtd MTD device structure
806 * @param from offset to read from 860 * @param from offset to read from
807 * @param len number of bytes to read 861 * @param len number of bytes to read
808 * @param retlen pointer to variable to store the number of read bytes 862 * @param retlen pointer to variable to store the number of read bytes
809 * @param buf the databuffer to put data 863 * @param buf the databuffer to put data
864 * @param mode operation mode
810 * 865 *
811 * OneNAND read out-of-band data from the spare area 866 * OneNAND read out-of-band data from the spare area
812 */ 867 */
813int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len, 868static int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
814 size_t *retlen, u_char *buf) 869 size_t *retlen, u_char *buf, mtd_oob_mode_t mode)
815{ 870{
816 struct onenand_chip *this = mtd->priv; 871 struct onenand_chip *this = mtd->priv;
817 int read = 0, thislen, column; 872 int read = 0, thislen, column, oobsize;
818 int ret = 0; 873 int ret = 0;
819 874
820 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); 875 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
@@ -822,21 +877,33 @@ int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
822 /* Initialize return length value */ 877 /* Initialize return length value */
823 *retlen = 0; 878 *retlen = 0;
824 879
880 if (mode == MTD_OOB_AUTO)
881 oobsize = this->ecclayout->oobavail;
882 else
883 oobsize = mtd->oobsize;
884
885 column = from & (mtd->oobsize - 1);
886
887 if (unlikely(column >= oobsize)) {
888 printk(KERN_ERR "onenand_read_oob: Attempted to start read outside oob\n");
889 return -EINVAL;
890 }
891
825 /* Do not allow reads past end of device */ 892 /* Do not allow reads past end of device */
826 if (unlikely((from + len) > mtd->size)) { 893 if (unlikely(from >= mtd->size ||
827 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: Attempt read beyond end of device\n"); 894 column + len > ((mtd->size >> this->page_shift) -
895 (from >> this->page_shift)) * oobsize)) {
896 printk(KERN_ERR "onenand_read_oob: Attempted to read beyond end of device\n");
828 return -EINVAL; 897 return -EINVAL;
829 } 898 }
830 899
831 /* Grab the lock and see if the device is available */ 900 /* Grab the lock and see if the device is available */
832 onenand_get_device(mtd, FL_READING); 901 onenand_get_device(mtd, FL_READING);
833 902
834 column = from & (mtd->oobsize - 1);
835
836 while (read < len) { 903 while (read < len) {
837 cond_resched(); 904 cond_resched();
838 905
839 thislen = mtd->oobsize - column; 906 thislen = oobsize - column;
840 thislen = min_t(int, thislen, len); 907 thislen = min_t(int, thislen, len);
841 908
842 this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize); 909 this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize);
@@ -846,11 +913,14 @@ int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
846 ret = this->wait(mtd, FL_READING); 913 ret = this->wait(mtd, FL_READING);
847 /* First copy data and check return value for ECC handling */ 914 /* First copy data and check return value for ECC handling */
848 915
849 this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen); 916 if (mode == MTD_OOB_AUTO)
917 onenand_transfer_auto_oob(mtd, buf, column, thislen);
918 else
919 this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
850 920
851 if (ret) { 921 if (ret) {
852 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: read failed = 0x%x\n", ret); 922 printk(KERN_ERR "onenand_read_oob: read failed = 0x%x\n", ret);
853 goto out; 923 break;
854 } 924 }
855 925
856 read += thislen; 926 read += thislen;
@@ -868,7 +938,6 @@ int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
868 } 938 }
869 } 939 }
870 940
871out:
872 /* Deselect and wake up anyone waiting on the device */ 941 /* Deselect and wake up anyone waiting on the device */
873 onenand_release_device(mtd); 942 onenand_release_device(mtd);
874 943
@@ -885,10 +954,132 @@ out:
885static int onenand_read_oob(struct mtd_info *mtd, loff_t from, 954static int onenand_read_oob(struct mtd_info *mtd, loff_t from,
886 struct mtd_oob_ops *ops) 955 struct mtd_oob_ops *ops)
887{ 956{
888 BUG_ON(ops->mode != MTD_OOB_PLACE); 957 switch (ops->mode) {
889 958 case MTD_OOB_PLACE:
959 case MTD_OOB_AUTO:
960 break;
961 case MTD_OOB_RAW:
962 /* Not implemented yet */
963 default:
964 return -EINVAL;
965 }
890 return onenand_do_read_oob(mtd, from + ops->ooboffs, ops->ooblen, 966 return onenand_do_read_oob(mtd, from + ops->ooboffs, ops->ooblen,
891 &ops->oobretlen, ops->oobbuf); 967 &ops->oobretlen, ops->oobbuf, ops->mode);
968}
969
970/**
971 * onenand_bbt_wait - [DEFAULT] wait until the command is done
972 * @param mtd MTD device structure
973 * @param state state to select the max. timeout value
974 *
975 * Wait for command done.
976 */
977static int onenand_bbt_wait(struct mtd_info *mtd, int state)
978{
979 struct onenand_chip *this = mtd->priv;
980 unsigned long timeout;
981 unsigned int interrupt;
982 unsigned int ctrl;
983
984 /* The 20 msec is enough */
985 timeout = jiffies + msecs_to_jiffies(20);
986 while (time_before(jiffies, timeout)) {
987 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
988 if (interrupt & ONENAND_INT_MASTER)
989 break;
990 }
991 /* To get correct interrupt status in timeout case */
992 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
993 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
994
995 if (ctrl & ONENAND_CTRL_ERROR) {
996 printk(KERN_DEBUG "onenand_bbt_wait: controller error = 0x%04x\n", ctrl);
997 /* Initial bad block case */
998 if (ctrl & ONENAND_CTRL_LOAD)
999 return ONENAND_BBT_READ_ERROR;
1000 return ONENAND_BBT_READ_FATAL_ERROR;
1001 }
1002
1003 if (interrupt & ONENAND_INT_READ) {
1004 int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);
1005 if (ecc & ONENAND_ECC_2BIT_ALL)
1006 return ONENAND_BBT_READ_ERROR;
1007 } else {
1008 printk(KERN_ERR "onenand_bbt_wait: read timeout!"
1009 "ctrl=0x%04x intr=0x%04x\n", ctrl, interrupt);
1010 return ONENAND_BBT_READ_FATAL_ERROR;
1011 }
1012
1013 return 0;
1014}
1015
1016/**
1017 * onenand_bbt_read_oob - [MTD Interface] OneNAND read out-of-band for bbt scan
1018 * @param mtd MTD device structure
1019 * @param from offset to read from
1020 * @param @ops oob operation description structure
1021 *
1022 * OneNAND read out-of-band data from the spare area for bbt scan
1023 */
1024int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
1025 struct mtd_oob_ops *ops)
1026{
1027 struct onenand_chip *this = mtd->priv;
1028 int read = 0, thislen, column;
1029 int ret = 0;
1030 size_t len = ops->ooblen;
1031 u_char *buf = ops->oobbuf;
1032
1033 DEBUG(MTD_DEBUG_LEVEL3, "onenand_bbt_read_oob: from = 0x%08x, len = %zi\n", (unsigned int) from, len);
1034
1035 /* Initialize return value */
1036 ops->oobretlen = 0;
1037
1038 /* Do not allow reads past end of device */
1039 if (unlikely((from + len) > mtd->size)) {
1040 printk(KERN_ERR "onenand_bbt_read_oob: Attempt read beyond end of device\n");
1041 return ONENAND_BBT_READ_FATAL_ERROR;
1042 }
1043
1044 /* Grab the lock and see if the device is available */
1045 onenand_get_device(mtd, FL_READING);
1046
1047 column = from & (mtd->oobsize - 1);
1048
1049 while (read < len) {
1050 cond_resched();
1051
1052 thislen = mtd->oobsize - column;
1053 thislen = min_t(int, thislen, len);
1054
1055 this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize);
1056
1057 onenand_update_bufferram(mtd, from, 0);
1058
1059 ret = onenand_bbt_wait(mtd, FL_READING);
1060 if (ret)
1061 break;
1062
1063 this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
1064 read += thislen;
1065 if (read == len)
1066 break;
1067
1068 buf += thislen;
1069
1070 /* Read more? */
1071 if (read < len) {
1072 /* Update Page size */
1073 from += mtd->writesize;
1074 column = 0;
1075 }
1076 }
1077
1078 /* Deselect and wake up anyone waiting on the device */
1079 onenand_release_device(mtd);
1080
1081 ops->oobretlen = read;
1082 return ret;
892} 1083}
893 1084
894#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE 1085#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
@@ -897,14 +1088,12 @@ static int onenand_read_oob(struct mtd_info *mtd, loff_t from,
897 * @param mtd MTD device structure 1088 * @param mtd MTD device structure
898 * @param buf the databuffer to verify 1089 * @param buf the databuffer to verify
899 * @param to offset to read from 1090 * @param to offset to read from
900 * @param len number of bytes to read and compare
901 * 1091 *
902 */ 1092 */
903static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to, int len) 1093static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to)
904{ 1094{
905 struct onenand_chip *this = mtd->priv; 1095 struct onenand_chip *this = mtd->priv;
906 char *readp = this->page_buf; 1096 char *readp = this->page_buf + mtd->writesize;
907 int column = to & (mtd->oobsize - 1);
908 int status, i; 1097 int status, i;
909 1098
910 this->command(mtd, ONENAND_CMD_READOOB, to, mtd->oobsize); 1099 this->command(mtd, ONENAND_CMD_READOOB, to, mtd->oobsize);
@@ -913,9 +1102,8 @@ static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to
913 if (status) 1102 if (status)
914 return status; 1103 return status;
915 1104
916 this->read_bufferram(mtd, ONENAND_SPARERAM, readp, column, len); 1105 this->read_bufferram(mtd, ONENAND_SPARERAM, readp, 0, mtd->oobsize);
917 1106 for(i = 0; i < mtd->oobsize; i++)
918 for(i = 0; i < len; i++)
919 if (buf[i] != 0xFF && buf[i] != readp[i]) 1107 if (buf[i] != 0xFF && buf[i] != readp[i])
920 return -EBADMSG; 1108 return -EBADMSG;
921 1109
@@ -923,41 +1111,51 @@ static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to
923} 1111}
924 1112
925/** 1113/**
926 * onenand_verify_page - [GENERIC] verify the chip contents after a write 1114 * onenand_verify - [GENERIC] verify the chip contents after a write
927 * @param mtd MTD device structure 1115 * @param mtd MTD device structure
928 * @param buf the databuffer to verify 1116 * @param buf the databuffer to verify
1117 * @param addr offset to read from
1118 * @param len number of bytes to read and compare
929 * 1119 *
930 * Check DataRAM area directly
931 */ 1120 */
932static int onenand_verify_page(struct mtd_info *mtd, u_char *buf, loff_t addr) 1121static int onenand_verify(struct mtd_info *mtd, const u_char *buf, loff_t addr, size_t len)
933{ 1122{
934 struct onenand_chip *this = mtd->priv; 1123 struct onenand_chip *this = mtd->priv;
935 void __iomem *dataram0, *dataram1; 1124 void __iomem *dataram;
936 int ret = 0; 1125 int ret = 0;
1126 int thislen, column;
937 1127
938 /* In partial page write, just skip it */ 1128 while (len != 0) {
939 if ((addr & (mtd->writesize - 1)) != 0) 1129 thislen = min_t(int, mtd->writesize, len);
940 return 0; 1130 column = addr & (mtd->writesize - 1);
1131 if (column + thislen > mtd->writesize)
1132 thislen = mtd->writesize - column;
941 1133
942 this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize); 1134 this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize);
943 1135
944 ret = this->wait(mtd, FL_READING); 1136 onenand_update_bufferram(mtd, addr, 0);
945 if (ret) 1137
946 return ret; 1138 ret = this->wait(mtd, FL_READING);
1139 if (ret)
1140 return ret;
947 1141
948 onenand_update_bufferram(mtd, addr, 1); 1142 onenand_update_bufferram(mtd, addr, 1);
949 1143
950 /* Check, if the two dataram areas are same */ 1144 dataram = this->base + ONENAND_DATARAM;
951 dataram0 = this->base + ONENAND_DATARAM; 1145 dataram += onenand_bufferram_offset(mtd, ONENAND_DATARAM);
952 dataram1 = dataram0 + mtd->writesize;
953 1146
954 if (memcmp(dataram0, dataram1, mtd->writesize)) 1147 if (memcmp(buf, dataram + column, thislen))
955 return -EBADMSG; 1148 return -EBADMSG;
1149
1150 len -= thislen;
1151 buf += thislen;
1152 addr += thislen;
1153 }
956 1154
957 return 0; 1155 return 0;
958} 1156}
959#else 1157#else
960#define onenand_verify_page(...) (0) 1158#define onenand_verify(...) (0)
961#define onenand_verify_oob(...) (0) 1159#define onenand_verify_oob(...) (0)
962#endif 1160#endif
963 1161
@@ -988,60 +1186,57 @@ static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
988 1186
989 /* Do not allow writes past end of device */ 1187 /* Do not allow writes past end of device */
990 if (unlikely((to + len) > mtd->size)) { 1188 if (unlikely((to + len) > mtd->size)) {
991 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: Attempt write to past end of device\n"); 1189 printk(KERN_ERR "onenand_write: Attempt write to past end of device\n");
992 return -EINVAL; 1190 return -EINVAL;
993 } 1191 }
994 1192
995 /* Reject writes, which are not page aligned */ 1193 /* Reject writes, which are not page aligned */
996 if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) { 1194 if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) {
997 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: Attempt to write not page aligned data\n"); 1195 printk(KERN_ERR "onenand_write: Attempt to write not page aligned data\n");
998 return -EINVAL; 1196 return -EINVAL;
999 } 1197 }
1000 1198
1001 column = to & (mtd->writesize - 1); 1199 column = to & (mtd->writesize - 1);
1002 subpage = column || (len & (mtd->writesize - 1));
1003 1200
1004 /* Grab the lock and see if the device is available */ 1201 /* Grab the lock and see if the device is available */
1005 onenand_get_device(mtd, FL_WRITING); 1202 onenand_get_device(mtd, FL_WRITING);
1006 1203
1007 /* Loop until all data write */ 1204 /* Loop until all data write */
1008 while (written < len) { 1205 while (written < len) {
1009 int bytes = mtd->writesize; 1206 int thislen = min_t(int, mtd->writesize - column, len - written);
1010 int thislen = min_t(int, bytes, len - written);
1011 u_char *wbuf = (u_char *) buf; 1207 u_char *wbuf = (u_char *) buf;
1012 1208
1013 cond_resched(); 1209 cond_resched();
1014 1210
1015 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, bytes); 1211 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, thislen);
1016 1212
1017 /* Partial page write */ 1213 /* Partial page write */
1214 subpage = thislen < mtd->writesize;
1018 if (subpage) { 1215 if (subpage) {
1019 bytes = min_t(int, bytes - column, (int) len);
1020 memset(this->page_buf, 0xff, mtd->writesize); 1216 memset(this->page_buf, 0xff, mtd->writesize);
1021 memcpy(this->page_buf + column, buf, bytes); 1217 memcpy(this->page_buf + column, buf, thislen);
1022 wbuf = this->page_buf; 1218 wbuf = this->page_buf;
1023 /* Even though partial write, we need page size */
1024 thislen = mtd->writesize;
1025 } 1219 }
1026 1220
1027 this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, thislen); 1221 this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, mtd->writesize);
1028 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize); 1222 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
1029 1223
1030 this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize); 1224 this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
1031 1225
1226 ret = this->wait(mtd, FL_WRITING);
1227
1032 /* In partial page write we don't update bufferram */ 1228 /* In partial page write we don't update bufferram */
1033 onenand_update_bufferram(mtd, to, !subpage); 1229 onenand_update_bufferram(mtd, to, !ret && !subpage);
1034 1230
1035 ret = this->wait(mtd, FL_WRITING);
1036 if (ret) { 1231 if (ret) {
1037 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: write filaed %d\n", ret); 1232 printk(KERN_ERR "onenand_write: write filaed %d\n", ret);
1038 break; 1233 break;
1039 } 1234 }
1040 1235
1041 /* Only check verify write turn on */ 1236 /* Only check verify write turn on */
1042 ret = onenand_verify_page(mtd, (u_char *) wbuf, to); 1237 ret = onenand_verify(mtd, (u_char *) wbuf, to, thislen);
1043 if (ret) { 1238 if (ret) {
1044 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: verify failed %d\n", ret); 1239 printk(KERN_ERR "onenand_write: verify failed %d\n", ret);
1045 break; 1240 break;
1046 } 1241 }
1047 1242
@@ -1064,20 +1259,58 @@ static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
1064} 1259}
1065 1260
1066/** 1261/**
1262 * onenand_fill_auto_oob - [Internal] oob auto-placement transfer
1263 * @param mtd MTD device structure
1264 * @param oob_buf oob buffer
1265 * @param buf source address
1266 * @param column oob offset to write to
1267 * @param thislen oob length to write
1268 */
1269static int onenand_fill_auto_oob(struct mtd_info *mtd, u_char *oob_buf,
1270 const u_char *buf, int column, int thislen)
1271{
1272 struct onenand_chip *this = mtd->priv;
1273 struct nand_oobfree *free;
1274 int writecol = column;
1275 int writeend = column + thislen;
1276 int lastgap = 0;
1277
1278 for (free = this->ecclayout->oobfree; free->length; ++free) {
1279 if (writecol >= lastgap)
1280 writecol += free->offset - lastgap;
1281 if (writeend >= lastgap)
1282 writeend += free->offset - lastgap;
1283 lastgap = free->offset + free->length;
1284 }
1285 for (free = this->ecclayout->oobfree; free->length; ++free) {
1286 int free_end = free->offset + free->length;
1287 if (free->offset < writeend && free_end > writecol) {
1288 int st = max_t(int,free->offset,writecol);
1289 int ed = min_t(int,free_end,writeend);
1290 int n = ed - st;
1291 memcpy(oob_buf + st, buf, n);
1292 buf += n;
1293 }
1294 }
1295 return 0;
1296}
1297
1298/**
1067 * onenand_do_write_oob - [Internal] OneNAND write out-of-band 1299 * onenand_do_write_oob - [Internal] OneNAND write out-of-band
1068 * @param mtd MTD device structure 1300 * @param mtd MTD device structure
1069 * @param to offset to write to 1301 * @param to offset to write to
1070 * @param len number of bytes to write 1302 * @param len number of bytes to write
1071 * @param retlen pointer to variable to store the number of written bytes 1303 * @param retlen pointer to variable to store the number of written bytes
1072 * @param buf the data to write 1304 * @param buf the data to write
1305 * @param mode operation mode
1073 * 1306 *
1074 * OneNAND write out-of-band 1307 * OneNAND write out-of-band
1075 */ 1308 */
1076static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len, 1309static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
1077 size_t *retlen, const u_char *buf) 1310 size_t *retlen, const u_char *buf, mtd_oob_mode_t mode)
1078{ 1311{
1079 struct onenand_chip *this = mtd->priv; 1312 struct onenand_chip *this = mtd->priv;
1080 int column, ret = 0; 1313 int column, ret = 0, oobsize;
1081 int written = 0; 1314 int written = 0;
1082 1315
1083 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); 1316 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
@@ -1085,9 +1318,30 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
1085 /* Initialize retlen, in case of early exit */ 1318 /* Initialize retlen, in case of early exit */
1086 *retlen = 0; 1319 *retlen = 0;
1087 1320
1088 /* Do not allow writes past end of device */ 1321 if (mode == MTD_OOB_AUTO)
1089 if (unlikely((to + len) > mtd->size)) { 1322 oobsize = this->ecclayout->oobavail;
1090 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_oob: Attempt write to past end of device\n"); 1323 else
1324 oobsize = mtd->oobsize;
1325
1326 column = to & (mtd->oobsize - 1);
1327
1328 if (unlikely(column >= oobsize)) {
1329 printk(KERN_ERR "onenand_write_oob: Attempted to start write outside oob\n");
1330 return -EINVAL;
1331 }
1332
1333 /* For compatibility with NAND: Do not allow write past end of page */
1334 if (column + len > oobsize) {
1335 printk(KERN_ERR "onenand_write_oob: "
1336 "Attempt to write past end of page\n");
1337 return -EINVAL;
1338 }
1339
1340 /* Do not allow reads past end of device */
1341 if (unlikely(to >= mtd->size ||
1342 column + len > ((mtd->size >> this->page_shift) -
1343 (to >> this->page_shift)) * oobsize)) {
1344 printk(KERN_ERR "onenand_write_oob: Attempted to write past end of device\n");
1091 return -EINVAL; 1345 return -EINVAL;
1092 } 1346 }
1093 1347
@@ -1096,18 +1350,19 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
1096 1350
1097 /* Loop until all data write */ 1351 /* Loop until all data write */
1098 while (written < len) { 1352 while (written < len) {
1099 int thislen = min_t(int, mtd->oobsize, len - written); 1353 int thislen = min_t(int, oobsize, len - written);
1100 1354
1101 cond_resched(); 1355 cond_resched();
1102 1356
1103 column = to & (mtd->oobsize - 1);
1104
1105 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobsize); 1357 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobsize);
1106 1358
1107 /* We send data to spare ram with oobsize 1359 /* We send data to spare ram with oobsize
1108 * to prevent byte access */ 1360 * to prevent byte access */
1109 memset(this->page_buf, 0xff, mtd->oobsize); 1361 memset(this->page_buf, 0xff, mtd->oobsize);
1110 memcpy(this->page_buf + column, buf, thislen); 1362 if (mode == MTD_OOB_AUTO)
1363 onenand_fill_auto_oob(mtd, this->page_buf, buf, column, thislen);
1364 else
1365 memcpy(this->page_buf + column, buf, thislen);
1111 this->write_bufferram(mtd, ONENAND_SPARERAM, this->page_buf, 0, mtd->oobsize); 1366 this->write_bufferram(mtd, ONENAND_SPARERAM, this->page_buf, 0, mtd->oobsize);
1112 1367
1113 this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize); 1368 this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
@@ -1116,26 +1371,25 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
1116 1371
1117 ret = this->wait(mtd, FL_WRITING); 1372 ret = this->wait(mtd, FL_WRITING);
1118 if (ret) { 1373 if (ret) {
1119 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_oob: write filaed %d\n", ret); 1374 printk(KERN_ERR "onenand_write_oob: write failed %d\n", ret);
1120 goto out; 1375 break;
1121 } 1376 }
1122 1377
1123 ret = onenand_verify_oob(mtd, buf, to, thislen); 1378 ret = onenand_verify_oob(mtd, this->page_buf, to);
1124 if (ret) { 1379 if (ret) {
1125 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_oob: verify failed %d\n", ret); 1380 printk(KERN_ERR "onenand_write_oob: verify failed %d\n", ret);
1126 goto out; 1381 break;
1127 } 1382 }
1128 1383
1129 written += thislen; 1384 written += thislen;
1130
1131 if (written == len) 1385 if (written == len)
1132 break; 1386 break;
1133 1387
1134 to += thislen; 1388 to += mtd->writesize;
1135 buf += thislen; 1389 buf += thislen;
1390 column = 0;
1136 } 1391 }
1137 1392
1138out:
1139 /* Deselect and wake up anyone waiting on the device */ 1393 /* Deselect and wake up anyone waiting on the device */
1140 onenand_release_device(mtd); 1394 onenand_release_device(mtd);
1141 1395
@@ -1153,10 +1407,17 @@ out:
1153static int onenand_write_oob(struct mtd_info *mtd, loff_t to, 1407static int onenand_write_oob(struct mtd_info *mtd, loff_t to,
1154 struct mtd_oob_ops *ops) 1408 struct mtd_oob_ops *ops)
1155{ 1409{
1156 BUG_ON(ops->mode != MTD_OOB_PLACE); 1410 switch (ops->mode) {
1157 1411 case MTD_OOB_PLACE:
1412 case MTD_OOB_AUTO:
1413 break;
1414 case MTD_OOB_RAW:
1415 /* Not implemented yet */
1416 default:
1417 return -EINVAL;
1418 }
1158 return onenand_do_write_oob(mtd, to + ops->ooboffs, ops->ooblen, 1419 return onenand_do_write_oob(mtd, to + ops->ooboffs, ops->ooblen,
1159 &ops->oobretlen, ops->oobbuf); 1420 &ops->oobretlen, ops->oobbuf, ops->mode);
1160} 1421}
1161 1422
1162/** 1423/**
@@ -1199,19 +1460,19 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
1199 1460
1200 /* Start address must align on block boundary */ 1461 /* Start address must align on block boundary */
1201 if (unlikely(instr->addr & (block_size - 1))) { 1462 if (unlikely(instr->addr & (block_size - 1))) {
1202 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Unaligned address\n"); 1463 printk(KERN_ERR "onenand_erase: Unaligned address\n");
1203 return -EINVAL; 1464 return -EINVAL;
1204 } 1465 }
1205 1466
1206 /* Length must align on block boundary */ 1467 /* Length must align on block boundary */
1207 if (unlikely(instr->len & (block_size - 1))) { 1468 if (unlikely(instr->len & (block_size - 1))) {
1208 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Length not block aligned\n"); 1469 printk(KERN_ERR "onenand_erase: Length not block aligned\n");
1209 return -EINVAL; 1470 return -EINVAL;
1210 } 1471 }
1211 1472
1212 /* Do not allow erase past end of device */ 1473 /* Do not allow erase past end of device */
1213 if (unlikely((instr->len + instr->addr) > mtd->size)) { 1474 if (unlikely((instr->len + instr->addr) > mtd->size)) {
1214 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Erase past end of device\n"); 1475 printk(KERN_ERR "onenand_erase: Erase past end of device\n");
1215 return -EINVAL; 1476 return -EINVAL;
1216 } 1477 }
1217 1478
@@ -1238,10 +1499,12 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
1238 1499
1239 this->command(mtd, ONENAND_CMD_ERASE, addr, block_size); 1500 this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
1240 1501
1502 onenand_invalidate_bufferram(mtd, addr, block_size);
1503
1241 ret = this->wait(mtd, FL_ERASING); 1504 ret = this->wait(mtd, FL_ERASING);
1242 /* Check, if it is write protected */ 1505 /* Check, if it is write protected */
1243 if (ret) { 1506 if (ret) {
1244 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift)); 1507 printk(KERN_ERR "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift));
1245 instr->state = MTD_ERASE_FAILED; 1508 instr->state = MTD_ERASE_FAILED;
1246 instr->fail_addr = addr; 1509 instr->fail_addr = addr;
1247 goto erase_exit; 1510 goto erase_exit;
@@ -1322,7 +1585,7 @@ static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
1322 1585
1323 /* We write two bytes, so we dont have to mess with 16 bit access */ 1586 /* We write two bytes, so we dont have to mess with 16 bit access */
1324 ofs += mtd->oobsize + (bbm->badblockpos & ~0x01); 1587 ofs += mtd->oobsize + (bbm->badblockpos & ~0x01);
1325 return onenand_do_write_oob(mtd, ofs , 2, &retlen, buf); 1588 return onenand_do_write_oob(mtd, ofs , 2, &retlen, buf, MTD_OOB_PLACE);
1326} 1589}
1327 1590
1328/** 1591/**
@@ -1491,6 +1754,8 @@ static int onenand_unlock_all(struct mtd_info *mtd)
1491 struct onenand_chip *this = mtd->priv; 1754 struct onenand_chip *this = mtd->priv;
1492 1755
1493 if (this->options & ONENAND_HAS_UNLOCK_ALL) { 1756 if (this->options & ONENAND_HAS_UNLOCK_ALL) {
1757 /* Set start block address */
1758 this->write_word(0, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
1494 /* Write unlock command */ 1759 /* Write unlock command */
1495 this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0); 1760 this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0);
1496 1761
@@ -1503,13 +1768,10 @@ static int onenand_unlock_all(struct mtd_info *mtd)
1503 continue; 1768 continue;
1504 1769
1505 /* Workaround for all block unlock in DDP */ 1770 /* Workaround for all block unlock in DDP */
1506 if (this->device_id & ONENAND_DEVICE_IS_DDP) { 1771 if (ONENAND_IS_DDP(this)) {
1507 loff_t ofs;
1508 size_t len;
1509
1510 /* 1st block on another chip */ 1772 /* 1st block on another chip */
1511 ofs = this->chipsize >> 1; 1773 loff_t ofs = this->chipsize >> 1;
1512 len = 1 << this->erase_shift; 1774 size_t len = mtd->erasesize;
1513 1775
1514 onenand_unlock(mtd, ofs, len); 1776 onenand_unlock(mtd, ofs, len);
1515 } 1777 }
@@ -1617,7 +1879,7 @@ static int do_otp_lock(struct mtd_info *mtd, loff_t from, size_t len,
1617 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0); 1879 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
1618 this->wait(mtd, FL_OTPING); 1880 this->wait(mtd, FL_OTPING);
1619 1881
1620 ret = onenand_do_write_oob(mtd, from, len, retlen, buf); 1882 ret = onenand_do_write_oob(mtd, from, len, retlen, buf, MTD_OOB_PLACE);
1621 1883
1622 /* Exit OTP access mode */ 1884 /* Exit OTP access mode */
1623 this->command(mtd, ONENAND_CMD_RESET, 0, 0); 1885 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
@@ -1823,12 +2085,13 @@ static int onenand_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
1823#endif /* CONFIG_MTD_ONENAND_OTP */ 2085#endif /* CONFIG_MTD_ONENAND_OTP */
1824 2086
1825/** 2087/**
1826 * onenand_lock_scheme - Check and set OneNAND lock scheme 2088 * onenand_check_features - Check and set OneNAND features
1827 * @param mtd MTD data structure 2089 * @param mtd MTD data structure
1828 * 2090 *
1829 * Check and set OneNAND lock scheme 2091 * Check and set OneNAND features
2092 * - lock scheme
1830 */ 2093 */
1831static void onenand_lock_scheme(struct mtd_info *mtd) 2094static void onenand_check_features(struct mtd_info *mtd)
1832{ 2095{
1833 struct onenand_chip *this = mtd->priv; 2096 struct onenand_chip *this = mtd->priv;
1834 unsigned int density, process; 2097 unsigned int density, process;
@@ -1961,26 +2224,28 @@ static int onenand_probe(struct mtd_info *mtd)
1961 density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT; 2224 density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
1962 this->chipsize = (16 << density) << 20; 2225 this->chipsize = (16 << density) << 20;
1963 /* Set density mask. it is used for DDP */ 2226 /* Set density mask. it is used for DDP */
1964 this->density_mask = (1 << (density + 6)); 2227 if (ONENAND_IS_DDP(this))
2228 this->density_mask = (1 << (density + 6));
2229 else
2230 this->density_mask = 0;
1965 2231
1966 /* OneNAND page size & block size */ 2232 /* OneNAND page size & block size */
1967 /* The data buffer size is equal to page size */ 2233 /* The data buffer size is equal to page size */
1968 mtd->writesize = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE); 2234 mtd->writesize = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
1969 mtd->oobsize = mtd->writesize >> 5; 2235 mtd->oobsize = mtd->writesize >> 5;
1970 /* Pagers per block is always 64 in OneNAND */ 2236 /* Pages per a block are always 64 in OneNAND */
1971 mtd->erasesize = mtd->writesize << 6; 2237 mtd->erasesize = mtd->writesize << 6;
1972 2238
1973 this->erase_shift = ffs(mtd->erasesize) - 1; 2239 this->erase_shift = ffs(mtd->erasesize) - 1;
1974 this->page_shift = ffs(mtd->writesize) - 1; 2240 this->page_shift = ffs(mtd->writesize) - 1;
1975 this->ppb_shift = (this->erase_shift - this->page_shift); 2241 this->page_mask = (1 << (this->erase_shift - this->page_shift)) - 1;
1976 this->page_mask = (mtd->erasesize / mtd->writesize) - 1;
1977 2242
1978 /* REVIST: Multichip handling */ 2243 /* REVIST: Multichip handling */
1979 2244
1980 mtd->size = this->chipsize; 2245 mtd->size = this->chipsize;
1981 2246
1982 /* Check OneNAND lock scheme */ 2247 /* Check OneNAND features */
1983 onenand_lock_scheme(mtd); 2248 onenand_check_features(mtd);
1984 2249
1985 return 0; 2250 return 0;
1986} 2251}
@@ -2021,6 +2286,7 @@ static void onenand_resume(struct mtd_info *mtd)
2021 */ 2286 */
2022int onenand_scan(struct mtd_info *mtd, int maxchips) 2287int onenand_scan(struct mtd_info *mtd, int maxchips)
2023{ 2288{
2289 int i;
2024 struct onenand_chip *this = mtd->priv; 2290 struct onenand_chip *this = mtd->priv;
2025 2291
2026 if (!this->read_word) 2292 if (!this->read_word)
@@ -2092,12 +2358,21 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
2092 } 2358 }
2093 2359
2094 this->subpagesize = mtd->writesize >> mtd->subpage_sft; 2360 this->subpagesize = mtd->writesize >> mtd->subpage_sft;
2361
2362 /*
2363 * The number of bytes available for a client to place data into
2364 * the out of band area
2365 */
2366 this->ecclayout->oobavail = 0;
2367 for (i = 0; this->ecclayout->oobfree[i].length; i++)
2368 this->ecclayout->oobavail +=
2369 this->ecclayout->oobfree[i].length;
2370
2095 mtd->ecclayout = this->ecclayout; 2371 mtd->ecclayout = this->ecclayout;
2096 2372
2097 /* Fill in remaining MTD driver data */ 2373 /* Fill in remaining MTD driver data */
2098 mtd->type = MTD_NANDFLASH; 2374 mtd->type = MTD_NANDFLASH;
2099 mtd->flags = MTD_CAP_NANDFLASH; 2375 mtd->flags = MTD_CAP_NANDFLASH;
2100 mtd->ecctype = MTD_ECC_SW;
2101 mtd->erase = onenand_erase; 2376 mtd->erase = onenand_erase;
2102 mtd->point = NULL; 2377 mtd->point = NULL;
2103 mtd->unpoint = NULL; 2378 mtd->unpoint = NULL;
@@ -2144,8 +2419,11 @@ void onenand_release(struct mtd_info *mtd)
2144 del_mtd_device (mtd); 2419 del_mtd_device (mtd);
2145 2420
2146 /* Free bad block table memory, if allocated */ 2421 /* Free bad block table memory, if allocated */
2147 if (this->bbm) 2422 if (this->bbm) {
2423 struct bbm_info *bbm = this->bbm;
2424 kfree(bbm->bbt);
2148 kfree(this->bbm); 2425 kfree(this->bbm);
2426 }
2149 /* Buffer allocated by onenand_scan */ 2427 /* Buffer allocated by onenand_scan */
2150 if (this->options & ONENAND_PAGEBUF_ALLOC) 2428 if (this->options & ONENAND_PAGEBUF_ALLOC)
2151 kfree(this->page_buf); 2429 kfree(this->page_buf);
diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c
index 98f8fd1c6375..aecdd50a1781 100644
--- a/drivers/mtd/onenand/onenand_bbt.c
+++ b/drivers/mtd/onenand/onenand_bbt.c
@@ -17,8 +17,8 @@
17#include <linux/mtd/onenand.h> 17#include <linux/mtd/onenand.h>
18#include <linux/mtd/compatmac.h> 18#include <linux/mtd/compatmac.h>
19 19
20extern int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len, 20extern int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
21 size_t *retlen, u_char *buf); 21 struct mtd_oob_ops *ops);
22 22
23/** 23/**
24 * check_short_pattern - [GENERIC] check if a pattern is in the buffer 24 * check_short_pattern - [GENERIC] check if a pattern is in the buffer
@@ -65,10 +65,11 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
65 int startblock; 65 int startblock;
66 loff_t from; 66 loff_t from;
67 size_t readlen, ooblen; 67 size_t readlen, ooblen;
68 struct mtd_oob_ops ops;
68 69
69 printk(KERN_INFO "Scanning device for bad blocks\n"); 70 printk(KERN_INFO "Scanning device for bad blocks\n");
70 71
71 len = 1; 72 len = 2;
72 73
73 /* We need only read few bytes from the OOB area */ 74 /* We need only read few bytes from the OOB area */
74 scanlen = ooblen = 0; 75 scanlen = ooblen = 0;
@@ -82,22 +83,24 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
82 startblock = 0; 83 startblock = 0;
83 from = 0; 84 from = 0;
84 85
86 ops.mode = MTD_OOB_PLACE;
87 ops.ooblen = readlen;
88 ops.oobbuf = buf;
89 ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
90
85 for (i = startblock; i < numblocks; ) { 91 for (i = startblock; i < numblocks; ) {
86 int ret; 92 int ret;
87 93
88 for (j = 0; j < len; j++) { 94 for (j = 0; j < len; j++) {
89 size_t retlen;
90
91 /* No need to read pages fully, 95 /* No need to read pages fully,
92 * just read required OOB bytes */ 96 * just read required OOB bytes */
93 ret = onenand_do_read_oob(mtd, from + j * mtd->writesize + bd->offs, 97 ret = onenand_bbt_read_oob(mtd, from + j * mtd->writesize + bd->offs, &ops);
94 readlen, &retlen, &buf[0]);
95 98
96 /* If it is a initial bad block, just ignore it */ 99 /* If it is a initial bad block, just ignore it */
97 if (ret && !(ret & ONENAND_CTRL_LOAD)) 100 if (ret == ONENAND_BBT_READ_FATAL_ERROR)
98 return ret; 101 return -EIO;
99 102
100 if (check_short_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) { 103 if (ret || check_short_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) {
101 bbm->bbt[i >> 3] |= 0x03 << (i & 0x6); 104 bbm->bbt[i >> 3] |= 0x03 << (i & 0x6);
102 printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n", 105 printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
103 i >> 1, (unsigned int) from); 106 i >> 1, (unsigned int) from);
@@ -168,8 +171,8 @@ static int onenand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
168 * marked good / bad blocks and writes the bad block table(s) to 171 * marked good / bad blocks and writes the bad block table(s) to
169 * the selected place. 172 * the selected place.
170 * 173 *
171 * The bad block table memory is allocated here. It must be freed 174 * The bad block table memory is allocated here. It is freed
172 * by calling the onenand_free_bbt function. 175 * by the onenand_release function.
173 * 176 *
174 */ 177 */
175int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) 178int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c
index 035cd9b0cc08..a61351f88ec0 100644
--- a/drivers/mtd/redboot.c
+++ b/drivers/mtd/redboot.c
@@ -94,8 +94,19 @@ static int parse_redboot_partitions(struct mtd_info *master,
94 * (NOTE: this is 'size' not 'data_length'; size is 94 * (NOTE: this is 'size' not 'data_length'; size is
95 * the full size of the entry.) 95 * the full size of the entry.)
96 */ 96 */
97 if (swab32(buf[i].size) == master->erasesize) { 97
98 /* RedBoot can combine the FIS directory and
99 config partitions into a single eraseblock;
100 we assume wrong-endian if either the swapped
101 'size' matches the eraseblock size precisely,
102 or if the swapped size actually fits in an
103 eraseblock while the unswapped size doesn't. */
104 if (swab32(buf[i].size) == master->erasesize ||
105 (buf[i].size > master->erasesize
106 && swab32(buf[i].size) < master->erasesize)) {
98 int j; 107 int j;
108 /* Update numslots based on actual FIS directory size */
109 numslots = swab32(buf[i].size) / sizeof (struct fis_image_desc);
99 for (j = 0; j < numslots; ++j) { 110 for (j = 0; j < numslots; ++j) {
100 111
101 /* A single 0xff denotes a deleted entry. 112 /* A single 0xff denotes a deleted entry.
@@ -120,11 +131,11 @@ static int parse_redboot_partitions(struct mtd_info *master,
120 swab32s(&buf[j].desc_cksum); 131 swab32s(&buf[j].desc_cksum);
121 swab32s(&buf[j].file_cksum); 132 swab32s(&buf[j].file_cksum);
122 } 133 }
134 } else if (buf[i].size < master->erasesize) {
135 /* Update numslots based on actual FIS directory size */
136 numslots = buf[i].size / sizeof(struct fis_image_desc);
123 } 137 }
124 break; 138 break;
125 } else {
126 /* re-calculate of real numslots */
127 numslots = buf[i].size / sizeof(struct fis_image_desc);
128 } 139 }
129 } 140 }
130 if (i == numslots) { 141 if (i == numslots) {
diff --git a/fs/jffs2/build.c b/fs/jffs2/build.c
index 02826967ab58..07119c42a861 100644
--- a/fs/jffs2/build.c
+++ b/fs/jffs2/build.c
@@ -348,23 +348,27 @@ int jffs2_do_mount_fs(struct jffs2_sb_info *c)
348 348
349 ret = jffs2_sum_init(c); 349 ret = jffs2_sum_init(c);
350 if (ret) 350 if (ret)
351 return ret; 351 goto out_free;
352 352
353 if (jffs2_build_filesystem(c)) { 353 if (jffs2_build_filesystem(c)) {
354 dbg_fsbuild("build_fs failed\n"); 354 dbg_fsbuild("build_fs failed\n");
355 jffs2_free_ino_caches(c); 355 jffs2_free_ino_caches(c);
356 jffs2_free_raw_node_refs(c); 356 jffs2_free_raw_node_refs(c);
357#ifndef __ECOS 357 ret = -EIO;
358 if (jffs2_blocks_use_vmalloc(c)) 358 goto out_free;
359 vfree(c->blocks);
360 else
361#endif
362 kfree(c->blocks);
363
364 return -EIO;
365 } 359 }
366 360
367 jffs2_calc_trigger_levels(c); 361 jffs2_calc_trigger_levels(c);
368 362
369 return 0; 363 return 0;
364
365 out_free:
366#ifndef __ECOS
367 if (jffs2_blocks_use_vmalloc(c))
368 vfree(c->blocks);
369 else
370#endif
371 kfree(c->blocks);
372
373 return ret;
370} 374}
diff --git a/fs/jffs2/jffs2_fs_sb.h b/fs/jffs2/jffs2_fs_sb.h
index b98594992eed..ea88f69af130 100644
--- a/fs/jffs2/jffs2_fs_sb.h
+++ b/fs/jffs2/jffs2_fs_sb.h
@@ -98,20 +98,14 @@ struct jffs2_sb_info {
98 uint32_t wbuf_pagesize; /* 0 for NOR and other flashes with no wbuf */ 98 uint32_t wbuf_pagesize; /* 0 for NOR and other flashes with no wbuf */
99 99
100#ifdef CONFIG_JFFS2_FS_WRITEBUFFER 100#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
101 /* Write-behind buffer for NAND flash */ 101 unsigned char *wbuf; /* Write-behind buffer for NAND flash */
102 unsigned char *wbuf;
103 unsigned char *oobbuf;
104 uint32_t wbuf_ofs; 102 uint32_t wbuf_ofs;
105 uint32_t wbuf_len; 103 uint32_t wbuf_len;
106 struct jffs2_inodirty *wbuf_inodes; 104 struct jffs2_inodirty *wbuf_inodes;
107
108 struct rw_semaphore wbuf_sem; /* Protects the write buffer */ 105 struct rw_semaphore wbuf_sem; /* Protects the write buffer */
109 106
110 /* Information about out-of-band area usage... */ 107 unsigned char *oobbuf;
111 struct nand_ecclayout *ecclayout; 108 int oobavail; /* How many bytes are available for JFFS2 in OOB */
112 uint32_t badblock_pos;
113 uint32_t fsdata_pos;
114 uint32_t fsdata_len;
115#endif 109#endif
116 110
117 struct jffs2_summary *summary; /* Summary information */ 111 struct jffs2_summary *summary; /* Summary information */
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
index 3af746eaff0e..31c1475d922a 100644
--- a/fs/jffs2/scan.c
+++ b/fs/jffs2/scan.c
@@ -450,16 +450,20 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
450 450
451#ifdef CONFIG_JFFS2_FS_WRITEBUFFER 451#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
452 if (jffs2_cleanmarker_oob(c)) { 452 if (jffs2_cleanmarker_oob(c)) {
453 int ret = jffs2_check_nand_cleanmarker(c, jeb); 453 int ret;
454
455 if (c->mtd->block_isbad(c->mtd, jeb->offset))
456 return BLK_STATE_BADBLOCK;
457
458 ret = jffs2_check_nand_cleanmarker(c, jeb);
454 D2(printk(KERN_NOTICE "jffs_check_nand_cleanmarker returned %d\n",ret)); 459 D2(printk(KERN_NOTICE "jffs_check_nand_cleanmarker returned %d\n",ret));
460
455 /* Even if it's not found, we still scan to see 461 /* Even if it's not found, we still scan to see
456 if the block is empty. We use this information 462 if the block is empty. We use this information
457 to decide whether to erase it or not. */ 463 to decide whether to erase it or not. */
458 switch (ret) { 464 switch (ret) {
459 case 0: cleanmarkerfound = 1; break; 465 case 0: cleanmarkerfound = 1; break;
460 case 1: break; 466 case 1: break;
461 case 2: return BLK_STATE_BADBLOCK;
462 case 3: return BLK_STATE_ALLDIRTY; /* Block has failed to erase min. once */
463 default: return ret; 467 default: return ret;
464 } 468 }
465 } 469 }
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index 9c99859f5edd..de718e3a1692 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -957,43 +957,48 @@ exit:
957 return ret; 957 return ret;
958} 958}
959 959
960#define NR_OOB_SCAN_PAGES 4 960#define NR_OOB_SCAN_PAGES 4
961
962/* For historical reasons we use only 12 bytes for OOB clean marker */
963#define OOB_CM_SIZE 12
964
965static const struct jffs2_unknown_node oob_cleanmarker =
966{
967 .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),
968 .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
969 .totlen = cpu_to_je32(8)
970};
961 971
962/* 972/*
963 * Check, if the out of band area is empty 973 * Check, if the out of band area is empty. This function knows about the clean
974 * marker and if it is present in OOB, treats the OOB as empty anyway.
964 */ 975 */
965int jffs2_check_oob_empty(struct jffs2_sb_info *c, 976int jffs2_check_oob_empty(struct jffs2_sb_info *c,
966 struct jffs2_eraseblock *jeb, int mode) 977 struct jffs2_eraseblock *jeb, int mode)
967{ 978{
968 int i, page, ret; 979 int i, ret;
969 int oobsize = c->mtd->oobsize; 980 int cmlen = min_t(int, c->oobavail, OOB_CM_SIZE);
970 struct mtd_oob_ops ops; 981 struct mtd_oob_ops ops;
971 982
972 ops.ooblen = NR_OOB_SCAN_PAGES * oobsize; 983 ops.mode = MTD_OOB_AUTO;
984 ops.ooblen = NR_OOB_SCAN_PAGES * c->oobavail;
973 ops.oobbuf = c->oobbuf; 985 ops.oobbuf = c->oobbuf;
974 ops.ooboffs = 0; 986 ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
975 ops.datbuf = NULL; 987 ops.datbuf = NULL;
976 ops.mode = MTD_OOB_PLACE;
977 988
978 ret = c->mtd->read_oob(c->mtd, jeb->offset, &ops); 989 ret = c->mtd->read_oob(c->mtd, jeb->offset, &ops);
979 if (ret) { 990 if (ret || ops.oobretlen != ops.ooblen) {
980 D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB " 991 printk(KERN_ERR "cannot read OOB for EB at %08x, requested %zd"
981 "failed %d for block at %08x\n", ret, jeb->offset)); 992 " bytes, read %zd bytes, error %d\n",
993 jeb->offset, ops.ooblen, ops.oobretlen, ret);
994 if (!ret)
995 ret = -EIO;
982 return ret; 996 return ret;
983 } 997 }
984 998
985 if (ops.oobretlen < ops.ooblen) { 999 for(i = 0; i < ops.ooblen; i++) {
986 D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB " 1000 if (mode && i < cmlen)
987 "returned short read (%zd bytes not %d) for block " 1001 /* Yeah, we know about the cleanmarker */
988 "at %08x\n", ops.oobretlen, ops.ooblen, jeb->offset));
989 return -EIO;
990 }
991
992 /* Special check for first page */
993 for(i = 0; i < oobsize ; i++) {
994 /* Yeah, we know about the cleanmarker. */
995 if (mode && i >= c->fsdata_pos &&
996 i < c->fsdata_pos + c->fsdata_len)
997 continue; 1002 continue;
998 1003
999 if (ops.oobbuf[i] != 0xFF) { 1004 if (ops.oobbuf[i] != 0xFF) {
@@ -1003,111 +1008,63 @@ int jffs2_check_oob_empty(struct jffs2_sb_info *c,
1003 } 1008 }
1004 } 1009 }
1005 1010
1006 /* we know, we are aligned :) */
1007 for (page = oobsize; page < ops.ooblen; page += sizeof(long)) {
1008 long dat = *(long *)(&ops.oobbuf[page]);
1009 if(dat != -1)
1010 return 1;
1011 }
1012 return 0; 1011 return 0;
1013} 1012}
1014 1013
1015/* 1014/*
1016 * Scan for a valid cleanmarker and for bad blocks 1015 * Check for a valid cleanmarker.
1016 * Returns: 0 if a valid cleanmarker was found
1017 * 1 if no cleanmarker was found
1018 * negative error code if an error occurred
1017 */ 1019 */
1018int jffs2_check_nand_cleanmarker (struct jffs2_sb_info *c, 1020int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c,
1019 struct jffs2_eraseblock *jeb) 1021 struct jffs2_eraseblock *jeb)
1020{ 1022{
1021 struct jffs2_unknown_node n;
1022 struct mtd_oob_ops ops; 1023 struct mtd_oob_ops ops;
1023 int oobsize = c->mtd->oobsize; 1024 int ret, cmlen = min_t(int, c->oobavail, OOB_CM_SIZE);
1024 unsigned char *p,*b;
1025 int i, ret;
1026 size_t offset = jeb->offset;
1027
1028 /* Check first if the block is bad. */
1029 if (c->mtd->block_isbad(c->mtd, offset)) {
1030 D1 (printk(KERN_WARNING "jffs2_check_nand_cleanmarker()"
1031 ": Bad block at %08x\n", jeb->offset));
1032 return 2;
1033 }
1034 1025
1035 ops.ooblen = oobsize; 1026 ops.mode = MTD_OOB_AUTO;
1027 ops.ooblen = cmlen;
1036 ops.oobbuf = c->oobbuf; 1028 ops.oobbuf = c->oobbuf;
1037 ops.ooboffs = 0; 1029 ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
1038 ops.datbuf = NULL; 1030 ops.datbuf = NULL;
1039 ops.mode = MTD_OOB_PLACE;
1040 1031
1041 ret = c->mtd->read_oob(c->mtd, offset, &ops); 1032 ret = c->mtd->read_oob(c->mtd, jeb->offset, &ops);
1042 if (ret) { 1033 if (ret || ops.oobretlen != ops.ooblen) {
1043 D1 (printk(KERN_WARNING "jffs2_check_nand_cleanmarker(): " 1034 printk(KERN_ERR "cannot read OOB for EB at %08x, requested %zd"
1044 "Read OOB failed %d for block at %08x\n", 1035 " bytes, read %zd bytes, error %d\n",
1045 ret, jeb->offset)); 1036 jeb->offset, ops.ooblen, ops.oobretlen, ret);
1037 if (!ret)
1038 ret = -EIO;
1046 return ret; 1039 return ret;
1047 } 1040 }
1048 1041
1049 if (ops.oobretlen < ops.ooblen) { 1042 return !!memcmp(&oob_cleanmarker, c->oobbuf, cmlen);
1050 D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): "
1051 "Read OOB return short read (%zd bytes not %d) "
1052 "for block at %08x\n", ops.oobretlen, ops.ooblen,
1053 jeb->offset));
1054 return -EIO;
1055 }
1056
1057 n.magic = cpu_to_je16 (JFFS2_MAGIC_BITMASK);
1058 n.nodetype = cpu_to_je16 (JFFS2_NODETYPE_CLEANMARKER);
1059 n.totlen = cpu_to_je32 (8);
1060 p = (unsigned char *) &n;
1061 b = c->oobbuf + c->fsdata_pos;
1062
1063 for (i = c->fsdata_len; i; i--) {
1064 if (*b++ != *p++)
1065 ret = 1;
1066 }
1067
1068 D1(if (ret == 1) {
1069 printk(KERN_WARNING "jffs2_check_nand_cleanmarker(): "
1070 "Cleanmarker node not detected in block at %08x\n",
1071 offset);
1072 printk(KERN_WARNING "OOB at %08zx was ", offset);
1073 for (i=0; i < oobsize; i++)
1074 printk("%02x ", c->oobbuf[i]);
1075 printk("\n");
1076 });
1077 return ret;
1078} 1043}
1079 1044
1080int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, 1045int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c,
1081 struct jffs2_eraseblock *jeb) 1046 struct jffs2_eraseblock *jeb)
1082{ 1047{
1083 struct jffs2_unknown_node n; 1048 int ret;
1084 int ret;
1085 struct mtd_oob_ops ops; 1049 struct mtd_oob_ops ops;
1050 int cmlen = min_t(int, c->oobavail, OOB_CM_SIZE);
1086 1051
1087 n.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); 1052 ops.mode = MTD_OOB_AUTO;
1088 n.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER); 1053 ops.ooblen = cmlen;
1089 n.totlen = cpu_to_je32(8); 1054 ops.oobbuf = (uint8_t *)&oob_cleanmarker;
1090 1055 ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
1091 ops.ooblen = c->fsdata_len;
1092 ops.oobbuf = (uint8_t *)&n;
1093 ops.ooboffs = c->fsdata_pos;
1094 ops.datbuf = NULL; 1056 ops.datbuf = NULL;
1095 ops.mode = MTD_OOB_PLACE;
1096 1057
1097 ret = c->mtd->write_oob(c->mtd, jeb->offset, &ops); 1058 ret = c->mtd->write_oob(c->mtd, jeb->offset, &ops);
1098 1059 if (ret || ops.oobretlen != ops.ooblen) {
1099 if (ret) { 1060 printk(KERN_ERR "cannot write OOB for EB at %08x, requested %zd"
1100 D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): " 1061 " bytes, read %zd bytes, error %d\n",
1101 "Write failed for block at %08x: error %d\n", 1062 jeb->offset, ops.ooblen, ops.oobretlen, ret);
1102 jeb->offset, ret)); 1063 if (!ret)
1064 ret = -EIO;
1103 return ret; 1065 return ret;
1104 } 1066 }
1105 if (ops.oobretlen != ops.ooblen) { 1067
1106 D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): "
1107 "Short write for block at %08x: %zd not %d\n",
1108 jeb->offset, ops.oobretlen, ops.ooblen));
1109 return -EIO;
1110 }
1111 return 0; 1068 return 0;
1112} 1069}
1113 1070
@@ -1140,41 +1097,24 @@ int jffs2_write_nand_badblock(struct jffs2_sb_info *c, struct jffs2_eraseblock *
1140 return 1; 1097 return 1;
1141} 1098}
1142 1099
1143static int jffs2_nand_set_oobinfo(struct jffs2_sb_info *c) 1100int jffs2_nand_flash_setup(struct jffs2_sb_info *c)
1144{ 1101{
1145 struct nand_ecclayout *oinfo = c->mtd->ecclayout; 1102 struct nand_ecclayout *oinfo = c->mtd->ecclayout;
1146 1103
1147 /* Do this only, if we have an oob buffer */
1148 if (!c->mtd->oobsize) 1104 if (!c->mtd->oobsize)
1149 return 0; 1105 return 0;
1150 1106
1151 /* Cleanmarker is out-of-band, so inline size zero */ 1107 /* Cleanmarker is out-of-band, so inline size zero */
1152 c->cleanmarker_size = 0; 1108 c->cleanmarker_size = 0;
1153 1109
1154 /* Should we use autoplacement ? */ 1110 if (!oinfo || oinfo->oobavail == 0) {
1155 if (!oinfo) { 1111 printk(KERN_ERR "inconsistent device description\n");
1156 D1(printk(KERN_DEBUG "JFFS2 on NAND. No autoplacment info found\n"));
1157 return -EINVAL; 1112 return -EINVAL;
1158 } 1113 }
1159 1114
1160 D1(printk(KERN_DEBUG "JFFS2 using autoplace on NAND\n")); 1115 D1(printk(KERN_DEBUG "JFFS2 using OOB on NAND\n"));
1161 /* Get the position of the free bytes */
1162 if (!oinfo->oobfree[0].length) {
1163 printk (KERN_WARNING "jffs2_nand_set_oobinfo(): Eeep."
1164 " Autoplacement selected and no empty space in oob\n");
1165 return -ENOSPC;
1166 }
1167 c->fsdata_pos = oinfo->oobfree[0].offset;
1168 c->fsdata_len = oinfo->oobfree[0].length;
1169 if (c->fsdata_len > 8)
1170 c->fsdata_len = 8;
1171 1116
1172 return 0; 1117 c->oobavail = oinfo->oobavail;
1173}
1174
1175int jffs2_nand_flash_setup(struct jffs2_sb_info *c)
1176{
1177 int res;
1178 1118
1179 /* Initialise write buffer */ 1119 /* Initialise write buffer */
1180 init_rwsem(&c->wbuf_sem); 1120 init_rwsem(&c->wbuf_sem);
@@ -1185,22 +1125,13 @@ int jffs2_nand_flash_setup(struct jffs2_sb_info *c)
1185 if (!c->wbuf) 1125 if (!c->wbuf)
1186 return -ENOMEM; 1126 return -ENOMEM;
1187 1127
1188 c->oobbuf = kmalloc(NR_OOB_SCAN_PAGES * c->mtd->oobsize, GFP_KERNEL); 1128 c->oobbuf = kmalloc(NR_OOB_SCAN_PAGES * c->oobavail, GFP_KERNEL);
1189 if (!c->oobbuf) 1129 if (!c->oobbuf) {
1190 return -ENOMEM;
1191
1192 res = jffs2_nand_set_oobinfo(c);
1193
1194#ifdef BREAKME
1195 if (!brokenbuf)
1196 brokenbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
1197 if (!brokenbuf) {
1198 kfree(c->wbuf); 1130 kfree(c->wbuf);
1199 return -ENOMEM; 1131 return -ENOMEM;
1200 } 1132 }
1201 memset(brokenbuf, 0xdb, c->wbuf_pagesize); 1133
1202#endif 1134 return 0;
1203 return res;
1204} 1135}
1205 1136
1206void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c) 1137void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c)
diff --git a/include/linux/mtd/bbm.h b/include/linux/mtd/bbm.h
index 1221b7c44158..fff8c53e5434 100644
--- a/include/linux/mtd/bbm.h
+++ b/include/linux/mtd/bbm.h
@@ -92,6 +92,13 @@ struct nand_bbt_descr {
92 */ 92 */
93#define ONENAND_BADBLOCK_POS 0 93#define ONENAND_BADBLOCK_POS 0
94 94
95/*
96 * Bad block scanning errors
97 */
98#define ONENAND_BBT_READ_ERROR 1
99#define ONENAND_BBT_READ_ECC_ERROR 2
100#define ONENAND_BBT_READ_FATAL_ERROR 4
101
95/** 102/**
96 * struct bbm_info - [GENERIC] Bad Block Table data structure 103 * struct bbm_info - [GENERIC] Bad Block Table data structure
97 * @bbt_erase_shift: [INTERN] number of address bits in a bbt entry 104 * @bbt_erase_shift: [INTERN] number of address bits in a bbt entry
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
index 28d461d862bd..81f3a314dd76 100644
--- a/include/linux/mtd/map.h
+++ b/include/linux/mtd/map.h
@@ -183,7 +183,7 @@ typedef union {
183struct map_info { 183struct map_info {
184 char *name; 184 char *name;
185 unsigned long size; 185 unsigned long size;
186 unsigned long phys; 186 resource_size_t phys;
187#define NO_XIP (-1UL) 187#define NO_XIP (-1UL)
188 188
189 void __iomem *virt; 189 void __iomem *virt;
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index d644e57703ad..6a8570be331b 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -85,6 +85,10 @@ typedef enum {
85 * mode = MTD_OOB_PLACE) 85 * mode = MTD_OOB_PLACE)
86 * @datbuf: data buffer - if NULL only oob data are read/written 86 * @datbuf: data buffer - if NULL only oob data are read/written
87 * @oobbuf: oob data buffer 87 * @oobbuf: oob data buffer
88 *
89 * Note, it is allowed to read more then one OOB area at one go, but not write.
90 * The interface assumes that the OOB write requests program only one page's
91 * OOB area.
88 */ 92 */
89struct mtd_oob_ops { 93struct mtd_oob_ops {
90 mtd_oob_mode_t mode; 94 mtd_oob_mode_t mode;
@@ -117,18 +121,6 @@ struct mtd_info {
117 u_int32_t writesize; 121 u_int32_t writesize;
118 122
119 u_int32_t oobsize; // Amount of OOB data per block (e.g. 16) 123 u_int32_t oobsize; // Amount of OOB data per block (e.g. 16)
120 u_int32_t ecctype;
121 u_int32_t eccsize;
122
123 /*
124 * Reuse some of the above unused fields in the case of NOR flash
125 * with configurable programming regions to avoid modifying the
126 * user visible structure layout/size. Only valid when the
127 * MTD_PROGRAM_REGIONS flag is set.
128 * (Maybe we should have an union for those?)
129 */
130#define MTD_PROGREGION_CTRLMODE_VALID(mtd) (mtd)->oobsize
131#define MTD_PROGREGION_CTRLMODE_INVALID(mtd) (mtd)->ecctype
132 124
133 // Kernel-only stuff starts here. 125 // Kernel-only stuff starts here.
134 char *name; 126 char *name;
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 2071b02f0526..97523887fe5d 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -343,6 +343,7 @@ struct nand_buffers {
343 * @options: [BOARDSPECIFIC] various chip options. They can partly be set to inform nand_scan about 343 * @options: [BOARDSPECIFIC] various chip options. They can partly be set to inform nand_scan about
344 * special functionality. See the defines for further explanation 344 * special functionality. See the defines for further explanation
345 * @badblockpos: [INTERN] position of the bad block marker in the oob area 345 * @badblockpos: [INTERN] position of the bad block marker in the oob area
346 * @cellinfo: [INTERN] MLC/multichip data from chip ident
346 * @numchips: [INTERN] number of physical chips 347 * @numchips: [INTERN] number of physical chips
347 * @chipsize: [INTERN] the size of one chip for multichip arrays 348 * @chipsize: [INTERN] the size of one chip for multichip arrays
348 * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1 349 * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
index f775a7af3890..d8af8a95e58d 100644
--- a/include/linux/mtd/onenand.h
+++ b/include/linux/mtd/onenand.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * linux/include/linux/mtd/onenand.h 2 * linux/include/linux/mtd/onenand.h
3 * 3 *
4 * Copyright (C) 2005-2006 Samsung Electronics 4 * Copyright (C) 2005-2007 Samsung Electronics
5 * Kyungmin Park <kyungmin.park@samsung.com> 5 * Kyungmin Park <kyungmin.park@samsung.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -42,14 +42,10 @@ typedef enum {
42 42
43/** 43/**
44 * struct onenand_bufferram - OneNAND BufferRAM Data 44 * struct onenand_bufferram - OneNAND BufferRAM Data
45 * @block: block address in BufferRAM 45 * @blockpage: block & page address in BufferRAM
46 * @page: page address in BufferRAM
47 * @valid: valid flag
48 */ 46 */
49struct onenand_bufferram { 47struct onenand_bufferram {
50 int block; 48 int blockpage;
51 int page;
52 int valid;
53}; 49};
54 50
55/** 51/**
@@ -63,7 +59,6 @@ struct onenand_bufferram {
63 * partly be set to inform onenand_scan about 59 * partly be set to inform onenand_scan about
64 * @erase_shift: [INTERN] number of address bits in a block 60 * @erase_shift: [INTERN] number of address bits in a block
65 * @page_shift: [INTERN] number of address bits in a page 61 * @page_shift: [INTERN] number of address bits in a page
66 * @ppb_shift: [INTERN] number of address bits in a pages per block
67 * @page_mask: [INTERN] a page per block mask 62 * @page_mask: [INTERN] a page per block mask
68 * @bufferram_index: [INTERN] BufferRAM index 63 * @bufferram_index: [INTERN] BufferRAM index
69 * @bufferram: [INTERN] BufferRAM info 64 * @bufferram: [INTERN] BufferRAM info
@@ -103,7 +98,6 @@ struct onenand_chip {
103 98
104 unsigned int erase_shift; 99 unsigned int erase_shift;
105 unsigned int page_shift; 100 unsigned int page_shift;
106 unsigned int ppb_shift; /* Pages per block shift */
107 unsigned int page_mask; 101 unsigned int page_mask;
108 102
109 unsigned int bufferram_index; 103 unsigned int bufferram_index;
@@ -150,6 +144,9 @@ struct onenand_chip {
150#define ONENAND_SET_SYS_CFG1(v, this) \ 144#define ONENAND_SET_SYS_CFG1(v, this) \
151 (this->write_word(v, this->base + ONENAND_REG_SYS_CFG1)) 145 (this->write_word(v, this->base + ONENAND_REG_SYS_CFG1))
152 146
147#define ONENAND_IS_DDP(this) \
148 (this->device_id & ONENAND_DEVICE_IS_DDP)
149
153/* Check byte access in OneNAND */ 150/* Check byte access in OneNAND */
154#define ONENAND_CHECK_BYTE_ACCESS(addr) (addr & 0x1) 151#define ONENAND_CHECK_BYTE_ACCESS(addr) (addr & 0x1)
155 152
diff --git a/include/linux/mtd/onenand_regs.h b/include/linux/mtd/onenand_regs.h
index e31c8f5d4271..af94719890e7 100644
--- a/include/linux/mtd/onenand_regs.h
+++ b/include/linux/mtd/onenand_regs.h
@@ -3,7 +3,8 @@
3 * 3 *
4 * OneNAND Register header file 4 * OneNAND Register header file
5 * 5 *
6 * Copyright (C) 2005-2006 Samsung Electronics 6 * Copyright (C) 2005-2007 Samsung Electronics
7 * Kyungmin Park <kyungmin.park@samsung.com>
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * 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 10 * it under the terms of the GNU General Public License version 2 as
@@ -80,9 +81,11 @@
80#define ONENAND_VERSION_PROCESS_SHIFT (8) 81#define ONENAND_VERSION_PROCESS_SHIFT (8)
81 82
82/* 83/*
83 * Start Address 1 F100h (R/W) 84 * Start Address 1 F100h (R/W) & Start Address 2 F101h (R/W)
84 */ 85 */
85#define ONENAND_DDP_SHIFT (15) 86#define ONENAND_DDP_SHIFT (15)
87#define ONENAND_DDP_CHIP0 (0)
88#define ONENAND_DDP_CHIP1 (1 << ONENAND_DDP_SHIFT)
86 89
87/* 90/*
88 * Start Address 8 F107h (R/W) 91 * Start Address 8 F107h (R/W)
diff --git a/include/linux/mtd/physmap.h b/include/linux/mtd/physmap.h
index 86831e3594f6..0dc07d5f3354 100644
--- a/include/linux/mtd/physmap.h
+++ b/include/linux/mtd/physmap.h
@@ -18,9 +18,10 @@
18#define __LINUX_MTD_PHYSMAP__ 18#define __LINUX_MTD_PHYSMAP__
19 19
20#include <linux/mtd/mtd.h> 20#include <linux/mtd/mtd.h>
21#include <linux/mtd/map.h>
22#include <linux/mtd/partitions.h> 21#include <linux/mtd/partitions.h>
23 22
23struct map_info;
24
24struct physmap_flash_data { 25struct physmap_flash_data {
25 unsigned int width; 26 unsigned int width;
26 void (*set_vpp)(struct map_info *, int); 27 void (*set_vpp)(struct map_info *, int);
diff --git a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h
index f913c30d7b89..8e501a75a764 100644
--- a/include/mtd/mtd-abi.h
+++ b/include/mtd/mtd-abi.h
@@ -36,12 +36,6 @@ struct mtd_oob_buf {
36#define MTD_CAP_NORFLASH (MTD_WRITEABLE | MTD_BIT_WRITEABLE) 36#define MTD_CAP_NORFLASH (MTD_WRITEABLE | MTD_BIT_WRITEABLE)
37#define MTD_CAP_NANDFLASH (MTD_WRITEABLE) 37#define MTD_CAP_NANDFLASH (MTD_WRITEABLE)
38 38
39
40// Types of automatic ECC/Checksum available
41#define MTD_ECC_NONE 0 // No automatic ECC available
42#define MTD_ECC_RS_DiskOnChip 1 // Automatic ECC on DiskOnChip
43#define MTD_ECC_SW 2 // SW ECC for Toshiba & Samsung devices
44
45/* ECC byte placement */ 39/* ECC byte placement */
46#define MTD_NANDECC_OFF 0 // Switch off ECC (Not recommended) 40#define MTD_NANDECC_OFF 0 // Switch off ECC (Not recommended)
47#define MTD_NANDECC_PLACE 1 // Use the given placement in the structure (YAFFS1 legacy mode) 41#define MTD_NANDECC_PLACE 1 // Use the given placement in the structure (YAFFS1 legacy mode)
@@ -61,6 +55,8 @@ struct mtd_info_user {
61 uint32_t erasesize; 55 uint32_t erasesize;
62 uint32_t writesize; 56 uint32_t writesize;
63 uint32_t oobsize; // Amount of OOB data per block (e.g. 16) 57 uint32_t oobsize; // Amount of OOB data per block (e.g. 16)
58 /* The below two fields are obsolete and broken, do not use them
59 * (TODO: remove at some point) */
64 uint32_t ecctype; 60 uint32_t ecctype;
65 uint32_t eccsize; 61 uint32_t eccsize;
66}; 62};