aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/DocBook/mtdnand.tmpl5
-rw-r--r--drivers/mtd/Kconfig8
-rw-r--r--drivers/mtd/Makefile1
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c14
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0002.c2
-rw-r--r--drivers/mtd/chips/jedec_probe.c37
-rw-r--r--drivers/mtd/devices/Kconfig25
-rw-r--r--drivers/mtd/devices/Makefile1
-rw-r--r--drivers/mtd/devices/at91_dataflash26.c485
-rw-r--r--drivers/mtd/devices/docprobe.c4
-rw-r--r--drivers/mtd/devices/m25p80.c271
-rw-r--r--drivers/mtd/devices/mtd_dataflash.c17
-rw-r--r--drivers/mtd/devices/pmc551.c27
-rw-r--r--drivers/mtd/inftlmount.c3
-rw-r--r--drivers/mtd/maps/alchemy-flash.c14
-rw-r--r--drivers/mtd/maps/nettel.c65
-rw-r--r--drivers/mtd/maps/physmap_of.c5
-rw-r--r--drivers/mtd/maps/pmcmsp-flash.c22
-rw-r--r--drivers/mtd/maps/pmcmsp-ramroot.c1
-rw-r--r--drivers/mtd/mtd_blkdevs.c7
-rw-r--r--drivers/mtd/mtdchar.c3
-rw-r--r--drivers/mtd/mtdconcat.c2
-rw-r--r--drivers/mtd/mtdcore.c2
-rw-r--r--drivers/mtd/mtdcore.h11
-rw-r--r--drivers/mtd/mtdoops.c376
-rw-r--r--drivers/mtd/nand/Kconfig6
-rw-r--r--drivers/mtd/nand/diskonchip.c2
-rw-r--r--drivers/mtd/nand/excite_nandflash.c1
-rw-r--r--drivers/mtd/nand/nand_base.c2
-rw-r--r--drivers/mtd/nand/nand_ids.c1
-rw-r--r--drivers/mtd/nand/ndfc.c8
-rw-r--r--drivers/mtd/onenand/Kconfig23
-rw-r--r--drivers/mtd/onenand/Makefile3
-rw-r--r--drivers/mtd/onenand/onenand_base.c139
-rw-r--r--drivers/mtd/onenand/onenand_sim.c495
-rw-r--r--drivers/mtd/rfd_ftl.c8
-rw-r--r--drivers/mtd/ubi/scan.c17
-rw-r--r--fs/Kconfig81
-rw-r--r--fs/jffs2/Makefile1
-rw-r--r--fs/jffs2/acl.c23
-rw-r--r--fs/jffs2/acl.h4
-rw-r--r--fs/jffs2/background.c4
-rw-r--r--fs/jffs2/compr.c422
-rw-r--r--fs/jffs2/compr.h54
-rw-r--r--fs/jffs2/compr_lzo.c108
-rw-r--r--fs/jffs2/compr_rtime.c2
-rw-r--r--fs/jffs2/compr_rubin.c4
-rw-r--r--fs/jffs2/compr_zlib.c6
-rw-r--r--fs/jffs2/dir.c37
-rw-r--r--fs/jffs2/erase.c57
-rw-r--r--fs/jffs2/fs.c32
-rw-r--r--fs/jffs2/gc.c4
-rw-r--r--fs/jffs2/jffs2_fs_sb.h3
-rw-r--r--fs/jffs2/nodelist.h2
-rw-r--r--fs/jffs2/nodemgmt.c9
-rw-r--r--fs/jffs2/os-linux.h5
-rw-r--r--fs/jffs2/readinode.c6
-rw-r--r--fs/jffs2/scan.c2
-rw-r--r--fs/jffs2/security.c6
-rw-r--r--fs/jffs2/summary.c8
-rw-r--r--fs/jffs2/summary.h6
-rw-r--r--fs/jffs2/wbuf.c81
-rw-r--r--fs/jffs2/xattr.h2
-rw-r--r--fs/jffs2/xattr_user.c4
-rw-r--r--include/linux/jffs2.h1
-rw-r--r--include/linux/mtd/nand.h1
-rw-r--r--include/linux/mtd/onenand.h12
-rw-r--r--include/linux/mtd/onenand_regs.h4
68 files changed, 2024 insertions, 1080 deletions
diff --git a/Documentation/DocBook/mtdnand.tmpl b/Documentation/DocBook/mtdnand.tmpl
index a8c8cce50633..6fbc41d98c1e 100644
--- a/Documentation/DocBook/mtdnand.tmpl
+++ b/Documentation/DocBook/mtdnand.tmpl
@@ -275,16 +275,13 @@ int __init board_init (void)
275 int err = 0; 275 int err = 0;
276 276
277 /* Allocate memory for MTD device structure and private data */ 277 /* Allocate memory for MTD device structure and private data */
278 board_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip), GFP_KERNEL); 278 board_mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
279 if (!board_mtd) { 279 if (!board_mtd) {
280 printk ("Unable to allocate NAND MTD device structure.\n"); 280 printk ("Unable to allocate NAND MTD device structure.\n");
281 err = -ENOMEM; 281 err = -ENOMEM;
282 goto out; 282 goto out;
283 } 283 }
284 284
285 /* Initialize structures */
286 memset ((char *) board_mtd, 0, sizeof(struct mtd_info) + sizeof(struct nand_chip));
287
288 /* map physical adress */ 285 /* map physical adress */
289 baseaddr = (unsigned long)ioremap(CHIP_PHYSICAL_ADDRESS, 1024); 286 baseaddr = (unsigned long)ioremap(CHIP_PHYSICAL_ADDRESS, 1024);
290 if(!baseaddr){ 287 if(!baseaddr){
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index fbec8cd55e38..8848e8ac705d 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -278,6 +278,14 @@ config SSFDC
278 This enables read only access to SmartMedia formatted NAND 278 This enables read only access to SmartMedia formatted NAND
279 flash. You can mount it with FAT file system. 279 flash. You can mount it with FAT file system.
280 280
281config MTD_OOPS
282 tristate "Log panic/oops to an MTD buffer"
283 depends on MTD
284 help
285 This enables panic and oops messages to be logged to a circular
286 buffer in a flash partition where it can be read back at some
287 later point.
288
281source "drivers/mtd/chips/Kconfig" 289source "drivers/mtd/chips/Kconfig"
282 290
283source "drivers/mtd/maps/Kconfig" 291source "drivers/mtd/maps/Kconfig"
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index 6d958a4566ff..7f0b04b4caa7 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_NFTL) += nftl.o
22obj-$(CONFIG_INFTL) += inftl.o 22obj-$(CONFIG_INFTL) += inftl.o
23obj-$(CONFIG_RFD_FTL) += rfd_ftl.o 23obj-$(CONFIG_RFD_FTL) += rfd_ftl.o
24obj-$(CONFIG_SSFDC) += ssfdc.o 24obj-$(CONFIG_SSFDC) += ssfdc.o
25obj-$(CONFIG_MTD_OOPS) += mtdoops.o
25 26
26nftl-objs := nftlcore.o nftlmount.o 27nftl-objs := nftlcore.o nftlmount.o
27inftl-objs := inftlcore.o inftlmount.o 28inftl-objs := inftlcore.o inftlmount.o
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 2f19fa78d24a..39eff9ff575c 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -526,7 +526,7 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
526 struct cfi_pri_intelext *extp = cfi->cmdset_priv; 526 struct cfi_pri_intelext *extp = cfi->cmdset_priv;
527 527
528 /* 528 /*
529 * Probing of multi-partition flash ships. 529 * Probing of multi-partition flash chips.
530 * 530 *
531 * To support multiple partitions when available, we simply arrange 531 * To support multiple partitions when available, we simply arrange
532 * for each of them to have their own flchip structure even if they 532 * for each of them to have their own flchip structure even if they
@@ -1780,7 +1780,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
1780 return ret; 1780 return ret;
1781} 1781}
1782 1782
1783int cfi_intelext_erase_varsize(struct mtd_info *mtd, struct erase_info *instr) 1783static int cfi_intelext_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
1784{ 1784{
1785 unsigned long ofs, len; 1785 unsigned long ofs, len;
1786 int ret; 1786 int ret;
@@ -1930,7 +1930,7 @@ static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
1930 printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n", 1930 printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n",
1931 __FUNCTION__, ofs, len); 1931 __FUNCTION__, ofs, len);
1932 cfi_varsize_frob(mtd, do_printlockstatus_oneblock, 1932 cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
1933 ofs, len, 0); 1933 ofs, len, NULL);
1934#endif 1934#endif
1935 1935
1936 ret = cfi_varsize_frob(mtd, do_xxlock_oneblock, 1936 ret = cfi_varsize_frob(mtd, do_xxlock_oneblock,
@@ -1940,7 +1940,7 @@ static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
1940 printk(KERN_DEBUG "%s: lock status after, ret=%d\n", 1940 printk(KERN_DEBUG "%s: lock status after, ret=%d\n",
1941 __FUNCTION__, ret); 1941 __FUNCTION__, ret);
1942 cfi_varsize_frob(mtd, do_printlockstatus_oneblock, 1942 cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
1943 ofs, len, 0); 1943 ofs, len, NULL);
1944#endif 1944#endif
1945 1945
1946 return ret; 1946 return ret;
@@ -1954,7 +1954,7 @@ static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1954 printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n", 1954 printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n",
1955 __FUNCTION__, ofs, len); 1955 __FUNCTION__, ofs, len);
1956 cfi_varsize_frob(mtd, do_printlockstatus_oneblock, 1956 cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
1957 ofs, len, 0); 1957 ofs, len, NULL);
1958#endif 1958#endif
1959 1959
1960 ret = cfi_varsize_frob(mtd, do_xxlock_oneblock, 1960 ret = cfi_varsize_frob(mtd, do_xxlock_oneblock,
@@ -1964,7 +1964,7 @@ static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1964 printk(KERN_DEBUG "%s: lock status after, ret=%d\n", 1964 printk(KERN_DEBUG "%s: lock status after, ret=%d\n",
1965 __FUNCTION__, ret); 1965 __FUNCTION__, ret);
1966 cfi_varsize_frob(mtd, do_printlockstatus_oneblock, 1966 cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
1967 ofs, len, 0); 1967 ofs, len, NULL);
1968#endif 1968#endif
1969 1969
1970 return ret; 1970 return ret;
@@ -2255,7 +2255,7 @@ static void cfi_intelext_save_locks(struct mtd_info *mtd)
2255 adr = region->offset + block * len; 2255 adr = region->offset + block * len;
2256 2256
2257 status = cfi_varsize_frob(mtd, 2257 status = cfi_varsize_frob(mtd,
2258 do_getlockstatus_oneblock, adr, len, 0); 2258 do_getlockstatus_oneblock, adr, len, NULL);
2259 if (status) 2259 if (status)
2260 set_bit(block, region->lockmap); 2260 set_bit(block, region->lockmap);
2261 else 2261 else
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 1f6445840461..389acc600f5e 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -1609,7 +1609,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
1609} 1609}
1610 1610
1611 1611
1612int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr) 1612static int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
1613{ 1613{
1614 unsigned long ofs, len; 1614 unsigned long ofs, len;
1615 int ret; 1615 int ret;
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c
index 58e561e87699..a67b23b87fc0 100644
--- a/drivers/mtd/chips/jedec_probe.c
+++ b/drivers/mtd/chips/jedec_probe.c
@@ -17,7 +17,6 @@
17#include <linux/errno.h> 17#include <linux/errno.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/init.h>
21 20
22#include <linux/mtd/mtd.h> 21#include <linux/mtd/mtd.h>
23#include <linux/mtd/map.h> 22#include <linux/mtd/map.h>
@@ -70,6 +69,7 @@
70 69
71/* Fujitsu */ 70/* Fujitsu */
72#define MBM29F040C 0x00A4 71#define MBM29F040C 0x00A4
72#define MBM29F800BA 0x2258
73#define MBM29LV650UE 0x22D7 73#define MBM29LV650UE 0x22D7
74#define MBM29LV320TE 0x22F6 74#define MBM29LV320TE 0x22F6
75#define MBM29LV320BE 0x22F9 75#define MBM29LV320BE 0x22F9
@@ -129,6 +129,7 @@
129#define LH28F640BF 0x00b0 129#define LH28F640BF 0x00b0
130 130
131/* ST - www.st.com */ 131/* ST - www.st.com */
132#define M29F800AB 0x0058
132#define M29W800DT 0x00D7 133#define M29W800DT 0x00D7
133#define M29W800DB 0x005B 134#define M29W800DB 0x005B
134#define M29W160DT 0x22C4 135#define M29W160DT 0x22C4
@@ -646,6 +647,23 @@ static const struct amd_flash_info jedec_table[] = {
646 } 647 }
647 }, { 648 }, {
648 .mfr_id = MANUFACTURER_FUJITSU, 649 .mfr_id = MANUFACTURER_FUJITSU,
650 .dev_id = MBM29F800BA,
651 .name = "Fujitsu MBM29F800BA",
652 .uaddr = {
653 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
654 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
655 },
656 .DevSize = SIZE_1MiB,
657 .CmdSet = P_ID_AMD_STD,
658 .NumEraseRegions= 4,
659 .regions = {
660 ERASEINFO(0x04000,1),
661 ERASEINFO(0x02000,2),
662 ERASEINFO(0x08000,1),
663 ERASEINFO(0x10000,15),
664 }
665 }, {
666 .mfr_id = MANUFACTURER_FUJITSU,
649 .dev_id = MBM29LV650UE, 667 .dev_id = MBM29LV650UE,
650 .name = "Fujitsu MBM29LV650UE", 668 .name = "Fujitsu MBM29LV650UE",
651 .uaddr = { 669 .uaddr = {
@@ -1510,6 +1528,23 @@ static const struct amd_flash_info jedec_table[] = {
1510 ERASEINFO(0x1000,256) 1528 ERASEINFO(0x1000,256)
1511 } 1529 }
1512 1530
1531 }, {
1532 .mfr_id = MANUFACTURER_ST,
1533 .dev_id = M29F800AB,
1534 .name = "ST M29F800AB",
1535 .uaddr = {
1536 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1537 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
1538 },
1539 .DevSize = SIZE_1MiB,
1540 .CmdSet = P_ID_AMD_STD,
1541 .NumEraseRegions= 4,
1542 .regions = {
1543 ERASEINFO(0x04000,1),
1544 ERASEINFO(0x02000,2),
1545 ERASEINFO(0x08000,1),
1546 ERASEINFO(0x10000,15),
1547 }
1513 }, { 1548 }, {
1514 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */ 1549 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
1515 .dev_id = M29W800DT, 1550 .dev_id = M29W800DT,
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index ff642f8fbee7..811d56fd890f 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -60,21 +60,22 @@ config MTD_DATAFLASH
60 Sometimes DataFlash chips are packaged inside MMC-format 60 Sometimes DataFlash chips are packaged inside MMC-format
61 cards; at this writing, the MMC stack won't handle those. 61 cards; at this writing, the MMC stack won't handle those.
62 62
63config MTD_DATAFLASH26
64 tristate "AT91RM9200 DataFlash AT26xxx"
65 depends on MTD && ARCH_AT91RM9200 && AT91_SPI
66 help
67 This enables access to the DataFlash chip (AT26xxx) on an
68 AT91RM9200-based board.
69 If you have such a board and such a DataFlash, say 'Y'.
70
71config MTD_M25P80 63config MTD_M25P80
72 tristate "Support for M25 SPI Flash" 64 tristate "Support most SPI Flash chips (AT26DF, M25P, W25X, ...)"
73 depends on SPI_MASTER && EXPERIMENTAL 65 depends on SPI_MASTER && EXPERIMENTAL
74 help 66 help
75 This enables access to ST M25P80 and similar SPI flash chips, 67 This enables access to most modern SPI flash chips, used for
76 used for program and data storage. Set up your spi devices 68 program and data storage. Series supported include Atmel AT26DF,
77 with the right board-specific platform data. 69 Spansion S25SL, SST 25VF, ST M25P, and Winbond W25X. Other chips
70 are supported as well. See the driver source for the current list,
71 or to add other chips.
72
73 Note that the original DataFlash chips (AT45 series, not AT26DF),
74 need an entirely different driver.
75
76 Set up your spi devices with the right board-specific platform data,
77 if you want to specify device partitioning or to use a device which
78 doesn't support the JEDEC ID instruction.
78 79
79config MTD_SLRAM 80config MTD_SLRAM
80 tristate "Uncached system RAM" 81 tristate "Uncached system RAM"
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
index 8ab568b3f533..0f788d5c4bf8 100644
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -16,5 +16,4 @@ obj-$(CONFIG_MTD_MTDRAM) += mtdram.o
16obj-$(CONFIG_MTD_LART) += lart.o 16obj-$(CONFIG_MTD_LART) += lart.o
17obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o 17obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o
18obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o 18obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o
19obj-$(CONFIG_MTD_DATAFLASH26) += at91_dataflash26.o
20obj-$(CONFIG_MTD_M25P80) += m25p80.o 19obj-$(CONFIG_MTD_M25P80) += m25p80.o
diff --git a/drivers/mtd/devices/at91_dataflash26.c b/drivers/mtd/devices/at91_dataflash26.c
deleted file mode 100644
index 64ce37f986fc..000000000000
--- a/drivers/mtd/devices/at91_dataflash26.c
+++ /dev/null
@@ -1,485 +0,0 @@
1/*
2 * Atmel DataFlash driver for Atmel AT91RM9200 (Thunder)
3 * This is a largely modified version of at91_dataflash.c that
4 * supports AT26xxx dataflash chips. The original driver supports
5 * AT45xxx chips.
6 *
7 * Note: This driver was only tested with an AT26F004. It should be
8 * easy to make it work with other AT26xxx dataflash devices, though.
9 *
10 * Copyright (C) 2007 Hans J. Koch <hjk@linutronix.de>
11 * original Copyright (C) SAN People (Pty) Ltd
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * version 2 as published by the Free Software Foundation.
16*/
17
18#include <linux/config.h>
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/mtd/mtd.h>
22
23#include <asm/arch/at91_spi.h>
24
25#define DATAFLASH_MAX_DEVICES 4 /* max number of dataflash devices */
26
27#define MANUFACTURER_ID_ATMEL 0x1F
28
29/* command codes */
30
31#define AT26_OP_READ_STATUS 0x05
32#define AT26_OP_READ_DEV_ID 0x9F
33#define AT26_OP_ERASE_PAGE_4K 0x20
34#define AT26_OP_READ_ARRAY_FAST 0x0B
35#define AT26_OP_SEQUENTIAL_WRITE 0xAF
36#define AT26_OP_WRITE_ENABLE 0x06
37#define AT26_OP_WRITE_DISABLE 0x04
38#define AT26_OP_SECTOR_PROTECT 0x36
39#define AT26_OP_SECTOR_UNPROTECT 0x39
40
41/* status register bits */
42
43#define AT26_STATUS_BUSY 0x01
44#define AT26_STATUS_WRITE_ENABLE 0x02
45
46struct dataflash_local
47{
48 int spi; /* SPI chip-select number */
49 unsigned int page_size; /* number of bytes per page */
50};
51
52
53/* Detected DataFlash devices */
54static struct mtd_info* mtd_devices[DATAFLASH_MAX_DEVICES];
55static int nr_devices = 0;
56
57/* Allocate a single SPI transfer descriptor. We're assuming that if multiple
58 SPI transfers occur at the same time, spi_access_bus() will serialize them.
59 If this is not valid, then either (i) each dataflash 'priv' structure
60 needs it's own transfer descriptor, (ii) we lock this one, or (iii) use
61 another mechanism. */
62static struct spi_transfer_list* spi_transfer_desc;
63
64/*
65 * Perform a SPI transfer to access the DataFlash device.
66 */
67static int do_spi_transfer(int nr, char* tx, int tx_len, char* rx, int rx_len,
68 char* txnext, int txnext_len, char* rxnext, int rxnext_len)
69{
70 struct spi_transfer_list* list = spi_transfer_desc;
71
72 list->tx[0] = tx; list->txlen[0] = tx_len;
73 list->rx[0] = rx; list->rxlen[0] = rx_len;
74
75 list->tx[1] = txnext; list->txlen[1] = txnext_len;
76 list->rx[1] = rxnext; list->rxlen[1] = rxnext_len;
77
78 list->nr_transfers = nr;
79 /* Note: spi_transfer() always returns 0, there are no error checks */
80 return spi_transfer(list);
81}
82
83/*
84 * Return the status of the DataFlash device.
85 */
86static unsigned char at91_dataflash26_status(void)
87{
88 unsigned char command[2];
89
90 command[0] = AT26_OP_READ_STATUS;
91 command[1] = 0;
92
93 do_spi_transfer(1, command, 2, command, 2, NULL, 0, NULL, 0);
94
95 return command[1];
96}
97
98/*
99 * Poll the DataFlash device until it is READY.
100 */
101static unsigned char at91_dataflash26_waitready(void)
102{
103 unsigned char status;
104
105 while (1) {
106 status = at91_dataflash26_status();
107 if (!(status & AT26_STATUS_BUSY))
108 return status;
109 }
110}
111
112/*
113 * Enable/disable write access
114 */
115 static void at91_dataflash26_write_enable(int enable)
116{
117 unsigned char cmd[2];
118
119 DEBUG(MTD_DEBUG_LEVEL3, "write_enable: enable=%i\n", enable);
120
121 if (enable)
122 cmd[0] = AT26_OP_WRITE_ENABLE;
123 else
124 cmd[0] = AT26_OP_WRITE_DISABLE;
125 cmd[1] = 0;
126
127 do_spi_transfer(1, cmd, 2, cmd, 2, NULL, 0, NULL, 0);
128}
129
130/*
131 * Protect/unprotect sector
132 */
133 static void at91_dataflash26_sector_protect(loff_t addr, int protect)
134{
135 unsigned char cmd[4];
136
137 DEBUG(MTD_DEBUG_LEVEL3, "sector_protect: addr=0x%06x prot=%d\n",
138 addr, protect);
139
140 if (protect)
141 cmd[0] = AT26_OP_SECTOR_PROTECT;
142 else
143 cmd[0] = AT26_OP_SECTOR_UNPROTECT;
144 cmd[1] = (addr & 0x00FF0000) >> 16;
145 cmd[2] = (addr & 0x0000FF00) >> 8;
146 cmd[3] = (addr & 0x000000FF);
147
148 do_spi_transfer(1, cmd, 4, cmd, 4, NULL, 0, NULL, 0);
149}
150
151/*
152 * Erase blocks of flash.
153 */
154static int at91_dataflash26_erase(struct mtd_info *mtd,
155 struct erase_info *instr)
156{
157 struct dataflash_local *priv = (struct dataflash_local *) mtd->priv;
158 unsigned char cmd[4];
159
160 DEBUG(MTD_DEBUG_LEVEL1, "dataflash_erase: addr=0x%06x len=%i\n",
161 instr->addr, instr->len);
162
163 /* Sanity checks */
164 if (priv->page_size != 4096)
165 return -EINVAL; /* Can't handle other sizes at the moment */
166
167 if ( ((instr->len % mtd->erasesize) != 0)
168 || ((instr->len % priv->page_size) != 0)
169 || ((instr->addr % priv->page_size) != 0)
170 || ((instr->addr + instr->len) > mtd->size))
171 return -EINVAL;
172
173 spi_access_bus(priv->spi);
174
175 while (instr->len > 0) {
176 at91_dataflash26_write_enable(1);
177 at91_dataflash26_sector_protect(instr->addr, 0);
178 at91_dataflash26_write_enable(1);
179 cmd[0] = AT26_OP_ERASE_PAGE_4K;
180 cmd[1] = (instr->addr & 0x00FF0000) >> 16;
181 cmd[2] = (instr->addr & 0x0000FF00) >> 8;
182 cmd[3] = (instr->addr & 0x000000FF);
183
184 DEBUG(MTD_DEBUG_LEVEL3, "ERASE: (0x%02x) 0x%02x 0x%02x"
185 "0x%02x\n",
186 cmd[0], cmd[1], cmd[2], cmd[3]);
187
188 do_spi_transfer(1, cmd, 4, cmd, 4, NULL, 0, NULL, 0);
189 at91_dataflash26_waitready();
190
191 instr->addr += priv->page_size; /* next page */
192 instr->len -= priv->page_size;
193 }
194
195 at91_dataflash26_write_enable(0);
196 spi_release_bus(priv->spi);
197
198 /* Inform MTD subsystem that erase is complete */
199 instr->state = MTD_ERASE_DONE;
200 if (instr->callback)
201 instr->callback(instr);
202
203 return 0;
204}
205
206/*
207 * Read from the DataFlash device.
208 * from : Start offset in flash device
209 * len : Number of bytes to read
210 * retlen : Number of bytes actually read
211 * buf : Buffer that will receive data
212 */
213static int at91_dataflash26_read(struct mtd_info *mtd, loff_t from, size_t len,
214 size_t *retlen, u_char *buf)
215{
216 struct dataflash_local *priv = (struct dataflash_local *) mtd->priv;
217 unsigned char cmd[5];
218
219 DEBUG(MTD_DEBUG_LEVEL1, "dataflash_read: %lli .. %lli\n",
220 from, from+len);
221
222 *retlen = 0;
223
224 /* Sanity checks */
225 if (!len)
226 return 0;
227 if (from + len > mtd->size)
228 return -EINVAL;
229
230 cmd[0] = AT26_OP_READ_ARRAY_FAST;
231 cmd[1] = (from & 0x00FF0000) >> 16;
232 cmd[2] = (from & 0x0000FF00) >> 8;
233 cmd[3] = (from & 0x000000FF);
234 /* cmd[4] is a "Don't care" byte */
235
236 DEBUG(MTD_DEBUG_LEVEL3, "READ: (0x%02x) 0x%02x 0x%02x 0x%02x\n",
237 cmd[0], cmd[1], cmd[2], cmd[3]);
238
239 spi_access_bus(priv->spi);
240 do_spi_transfer(2, cmd, 5, cmd, 5, buf, len, buf, len);
241 spi_release_bus(priv->spi);
242
243 *retlen = len;
244 return 0;
245}
246
247/*
248 * Write to the DataFlash device.
249 * to : Start offset in flash device
250 * len : Number of bytes to write
251 * retlen : Number of bytes actually written
252 * buf : Buffer containing the data
253 */
254static int at91_dataflash26_write(struct mtd_info *mtd, loff_t to, size_t len,
255 size_t *retlen, const u_char *buf)
256{
257 struct dataflash_local *priv = (struct dataflash_local *) mtd->priv;
258 unsigned int addr, buf_index = 0;
259 int ret = -EIO, sector, last_sector;
260 unsigned char status, cmd[5];
261
262 DEBUG(MTD_DEBUG_LEVEL1, "dataflash_write: %lli .. %lli\n", to, to+len);
263
264 *retlen = 0;
265
266 /* Sanity checks */
267 if (!len)
268 return 0;
269 if (to + len > mtd->size)
270 return -EINVAL;
271
272 spi_access_bus(priv->spi);
273
274 addr = to;
275 last_sector = -1;
276
277 while (buf_index < len) {
278 sector = addr / priv->page_size;
279 /* Write first byte if a new sector begins */
280 if (sector != last_sector) {
281 at91_dataflash26_write_enable(1);
282 at91_dataflash26_sector_protect(addr, 0);
283 at91_dataflash26_write_enable(1);
284
285 /* Program first byte of a new sector */
286 cmd[0] = AT26_OP_SEQUENTIAL_WRITE;
287 cmd[1] = (addr & 0x00FF0000) >> 16;
288 cmd[2] = (addr & 0x0000FF00) >> 8;
289 cmd[3] = (addr & 0x000000FF);
290 cmd[4] = buf[buf_index++];
291 do_spi_transfer(1, cmd, 5, cmd, 5, NULL, 0, NULL, 0);
292 status = at91_dataflash26_waitready();
293 addr++;
294 /* On write errors, the chip resets the write enable
295 flag. This also happens after the last byte of a
296 sector is successfully programmed. */
297 if ( ( !(status & AT26_STATUS_WRITE_ENABLE))
298 && ((addr % priv->page_size) != 0) ) {
299 DEBUG(MTD_DEBUG_LEVEL1,
300 "write error1: addr=0x%06x, "
301 "status=0x%02x\n", addr, status);
302 goto write_err;
303 }
304 (*retlen)++;
305 last_sector = sector;
306 }
307
308 /* Write subsequent bytes in the same sector */
309 cmd[0] = AT26_OP_SEQUENTIAL_WRITE;
310 cmd[1] = buf[buf_index++];
311 do_spi_transfer(1, cmd, 2, cmd, 2, NULL, 0, NULL, 0);
312 status = at91_dataflash26_waitready();
313 addr++;
314
315 if ( ( !(status & AT26_STATUS_WRITE_ENABLE))
316 && ((addr % priv->page_size) != 0) ) {
317 DEBUG(MTD_DEBUG_LEVEL1, "write error2: addr=0x%06x, "
318 "status=0x%02x\n", addr, status);
319 goto write_err;
320 }
321
322 (*retlen)++;
323 }
324
325 ret = 0;
326 at91_dataflash26_write_enable(0);
327write_err:
328 spi_release_bus(priv->spi);
329 return ret;
330}
331
332/*
333 * Initialize and register DataFlash device with MTD subsystem.
334 */
335static int __init add_dataflash(int channel, char *name, int nr_pages,
336 int pagesize)
337{
338 struct mtd_info *device;
339 struct dataflash_local *priv;
340
341 if (nr_devices >= DATAFLASH_MAX_DEVICES) {
342 printk(KERN_ERR "at91_dataflash26: Too many devices "
343 "detected\n");
344 return 0;
345 }
346
347 device = kzalloc(sizeof(struct mtd_info) + strlen(name) + 8,
348 GFP_KERNEL);
349 if (!device)
350 return -ENOMEM;
351
352 device->name = (char *)&device[1];
353 sprintf(device->name, "%s.spi%d", name, channel);
354 device->size = nr_pages * pagesize;
355 device->erasesize = pagesize;
356 device->owner = THIS_MODULE;
357 device->type = MTD_DATAFLASH;
358 device->flags = MTD_CAP_NORFLASH;
359 device->erase = at91_dataflash26_erase;
360 device->read = at91_dataflash26_read;
361 device->write = at91_dataflash26_write;
362
363 priv = (struct dataflash_local *)kzalloc(sizeof(struct dataflash_local),
364 GFP_KERNEL);
365 if (!priv) {
366 kfree(device);
367 return -ENOMEM;
368 }
369
370 priv->spi = channel;
371 priv->page_size = pagesize;
372 device->priv = priv;
373
374 mtd_devices[nr_devices] = device;
375 nr_devices++;
376 printk(KERN_INFO "at91_dataflash26: %s detected [spi%i] (%i bytes)\n",
377 name, channel, device->size);
378
379 return add_mtd_device(device);
380}
381
382/*
383 * Detect and initialize DataFlash device connected to specified SPI channel.
384 *
385 */
386
387struct dataflash26_types {
388 unsigned char id0;
389 unsigned char id1;
390 char *name;
391 int pagesize;
392 int nr_pages;
393};
394
395struct dataflash26_types df26_types[] = {
396 {
397 .id0 = 0x04,
398 .id1 = 0x00,
399 .name = "AT26F004",
400 .pagesize = 4096,
401 .nr_pages = 128,
402 },
403 {
404 .id0 = 0x45,
405 .id1 = 0x01,
406 .name = "AT26DF081A", /* Not tested ! */
407 .pagesize = 4096,
408 .nr_pages = 256,
409 },
410};
411
412static int __init at91_dataflash26_detect(int channel)
413{
414 unsigned char status, cmd[5];
415 int i;
416
417 spi_access_bus(channel);
418 status = at91_dataflash26_status();
419
420 if (status == 0 || status == 0xff) {
421 printk(KERN_ERR "at91_dataflash26_detect: status error %d\n",
422 status);
423 spi_release_bus(channel);
424 return -ENODEV;
425 }
426
427 cmd[0] = AT26_OP_READ_DEV_ID;
428 do_spi_transfer(1, cmd, 5, cmd, 5, NULL, 0, NULL, 0);
429 spi_release_bus(channel);
430
431 if (cmd[1] != MANUFACTURER_ID_ATMEL)
432 return -ENODEV;
433
434 for (i = 0; i < ARRAY_SIZE(df26_types); i++) {
435 if ( cmd[2] == df26_types[i].id0
436 && cmd[3] == df26_types[i].id1)
437 return add_dataflash(channel,
438 df26_types[i].name,
439 df26_types[i].nr_pages,
440 df26_types[i].pagesize);
441 }
442
443 printk(KERN_ERR "at91_dataflash26_detect: Unsupported device "
444 "(0x%02x/0x%02x)\n", cmd[2], cmd[3]);
445 return -ENODEV;
446}
447
448static int __init at91_dataflash26_init(void)
449{
450 spi_transfer_desc = kmalloc(sizeof(struct spi_transfer_list),
451 GFP_KERNEL);
452 if (!spi_transfer_desc)
453 return -ENOMEM;
454
455 /* DataFlash (SPI chip select 0) */
456 at91_dataflash26_detect(0);
457
458#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
459 /* DataFlash card (SPI chip select 3) */
460 at91_dataflash26_detect(3);
461#endif
462 return 0;
463}
464
465static void __exit at91_dataflash26_exit(void)
466{
467 int i;
468
469 for (i = 0; i < DATAFLASH_MAX_DEVICES; i++) {
470 if (mtd_devices[i]) {
471 del_mtd_device(mtd_devices[i]);
472 kfree(mtd_devices[i]->priv);
473 kfree(mtd_devices[i]);
474 }
475 }
476 nr_devices = 0;
477 kfree(spi_transfer_desc);
478}
479
480module_init(at91_dataflash26_init);
481module_exit(at91_dataflash26_exit);
482
483MODULE_LICENSE("GPL");
484MODULE_AUTHOR("Hans J. Koch");
485MODULE_DESCRIPTION("DataFlash AT26xxx driver for Atmel AT91RM9200");
diff --git a/drivers/mtd/devices/docprobe.c b/drivers/mtd/devices/docprobe.c
index 54aa75907640..d8cc94ec4e50 100644
--- a/drivers/mtd/devices/docprobe.c
+++ b/drivers/mtd/devices/docprobe.c
@@ -81,9 +81,7 @@ static unsigned long __initdata doc_locations[] = {
81#endif /* CONFIG_MTD_DOCPROBE_HIGH */ 81#endif /* CONFIG_MTD_DOCPROBE_HIGH */
82#elif defined(__PPC__) 82#elif defined(__PPC__)
83 0xe4000000, 83 0xe4000000,
84#elif defined(CONFIG_MOMENCO_OCELOT_G) 84#else
85 0xff000000,
86##else
87#warning Unknown architecture for DiskOnChip. No default probe locations defined 85#warning Unknown architecture for DiskOnChip. No default probe locations defined
88#endif 86#endif
89 0xffffffff }; 87 0xffffffff };
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 78c2511ae9e0..98df5bcc02f3 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * MTD SPI driver for ST M25Pxx flash chips 2 * MTD SPI driver for ST M25Pxx (and similar) serial flash chips
3 * 3 *
4 * Author: Mike Lavender, mike@steroidmicros.com 4 * Author: Mike Lavender, mike@steroidmicros.com
5 * 5 *
@@ -19,33 +19,32 @@
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/device.h> 20#include <linux/device.h>
21#include <linux/interrupt.h> 21#include <linux/interrupt.h>
22#include <linux/interrupt.h> 22#include <linux/mutex.h>
23
23#include <linux/mtd/mtd.h> 24#include <linux/mtd/mtd.h>
24#include <linux/mtd/partitions.h> 25#include <linux/mtd/partitions.h>
26
25#include <linux/spi/spi.h> 27#include <linux/spi/spi.h>
26#include <linux/spi/flash.h> 28#include <linux/spi/flash.h>
27 29
28#include <asm/semaphore.h>
29
30
31/* NOTE: AT 25F and SST 25LF series are very similar,
32 * but commands for sector erase and chip id differ...
33 */
34 30
35#define FLASH_PAGESIZE 256 31#define FLASH_PAGESIZE 256
36 32
37/* Flash opcodes. */ 33/* Flash opcodes. */
38#define OPCODE_WREN 6 /* Write enable */ 34#define OPCODE_WREN 0x06 /* Write enable */
39#define OPCODE_RDSR 5 /* Read status register */ 35#define OPCODE_RDSR 0x05 /* Read status register */
40#define OPCODE_READ 3 /* Read data bytes */ 36#define OPCODE_READ 0x03 /* Read data bytes (low frequency) */
41#define OPCODE_PP 2 /* Page program */ 37#define OPCODE_FAST_READ 0x0b /* Read data bytes (high frequency) */
42#define OPCODE_SE 0xd8 /* Sector erase */ 38#define OPCODE_PP 0x02 /* Page program (up to 256 bytes) */
43#define OPCODE_RES 0xab /* Read Electronic Signature */ 39#define OPCODE_BE_4K 0x20 /* Erase 4KiB block */
40#define OPCODE_BE_32K 0x52 /* Erase 32KiB block */
41#define OPCODE_SE 0xd8 /* Sector erase (usually 64KiB) */
44#define OPCODE_RDID 0x9f /* Read JEDEC ID */ 42#define OPCODE_RDID 0x9f /* Read JEDEC ID */
45 43
46/* Status Register bits. */ 44/* Status Register bits. */
47#define SR_WIP 1 /* Write in progress */ 45#define SR_WIP 1 /* Write in progress */
48#define SR_WEL 2 /* Write enable latch */ 46#define SR_WEL 2 /* Write enable latch */
47/* meaning of other SR_* bits may differ between vendors */
49#define SR_BP0 4 /* Block protect 0 */ 48#define SR_BP0 4 /* Block protect 0 */
50#define SR_BP1 8 /* Block protect 1 */ 49#define SR_BP1 8 /* Block protect 1 */
51#define SR_BP2 0x10 /* Block protect 2 */ 50#define SR_BP2 0x10 /* Block protect 2 */
@@ -65,9 +64,10 @@
65 64
66struct m25p { 65struct m25p {
67 struct spi_device *spi; 66 struct spi_device *spi;
68 struct semaphore lock; 67 struct mutex lock;
69 struct mtd_info mtd; 68 struct mtd_info mtd;
70 unsigned partitioned; 69 unsigned partitioned:1;
70 u8 erase_opcode;
71 u8 command[4]; 71 u8 command[4];
72}; 72};
73 73
@@ -150,8 +150,9 @@ static int wait_till_ready(struct m25p *flash)
150 */ 150 */
151static int erase_sector(struct m25p *flash, u32 offset) 151static int erase_sector(struct m25p *flash, u32 offset)
152{ 152{
153 DEBUG(MTD_DEBUG_LEVEL3, "%s: %s at 0x%08x\n", flash->spi->dev.bus_id, 153 DEBUG(MTD_DEBUG_LEVEL3, "%s: %s %dKiB at 0x%08x\n",
154 __FUNCTION__, offset); 154 flash->spi->dev.bus_id, __FUNCTION__,
155 flash->mtd.erasesize / 1024, offset);
155 156
156 /* Wait until finished previous write command. */ 157 /* Wait until finished previous write command. */
157 if (wait_till_ready(flash)) 158 if (wait_till_ready(flash))
@@ -161,7 +162,7 @@ static int erase_sector(struct m25p *flash, u32 offset)
161 write_enable(flash); 162 write_enable(flash);
162 163
163 /* Set up command buffer. */ 164 /* Set up command buffer. */
164 flash->command[0] = OPCODE_SE; 165 flash->command[0] = flash->erase_opcode;
165 flash->command[1] = offset >> 16; 166 flash->command[1] = offset >> 16;
166 flash->command[2] = offset >> 8; 167 flash->command[2] = offset >> 8;
167 flash->command[3] = offset; 168 flash->command[3] = offset;
@@ -201,13 +202,17 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
201 addr = instr->addr; 202 addr = instr->addr;
202 len = instr->len; 203 len = instr->len;
203 204
204 down(&flash->lock); 205 mutex_lock(&flash->lock);
206
207 /* REVISIT in some cases we could speed up erasing large regions
208 * by using OPCODE_SE instead of OPCODE_BE_4K
209 */
205 210
206 /* now erase those sectors */ 211 /* now erase those sectors */
207 while (len) { 212 while (len) {
208 if (erase_sector(flash, addr)) { 213 if (erase_sector(flash, addr)) {
209 instr->state = MTD_ERASE_FAILED; 214 instr->state = MTD_ERASE_FAILED;
210 up(&flash->lock); 215 mutex_unlock(&flash->lock);
211 return -EIO; 216 return -EIO;
212 } 217 }
213 218
@@ -215,7 +220,7 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
215 len -= mtd->erasesize; 220 len -= mtd->erasesize;
216 } 221 }
217 222
218 up(&flash->lock); 223 mutex_unlock(&flash->lock);
219 224
220 instr->state = MTD_ERASE_DONE; 225 instr->state = MTD_ERASE_DONE;
221 mtd_erase_callback(instr); 226 mtd_erase_callback(instr);
@@ -260,16 +265,19 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
260 if (retlen) 265 if (retlen)
261 *retlen = 0; 266 *retlen = 0;
262 267
263 down(&flash->lock); 268 mutex_lock(&flash->lock);
264 269
265 /* Wait till previous write/erase is done. */ 270 /* Wait till previous write/erase is done. */
266 if (wait_till_ready(flash)) { 271 if (wait_till_ready(flash)) {
267 /* REVISIT status return?? */ 272 /* REVISIT status return?? */
268 up(&flash->lock); 273 mutex_unlock(&flash->lock);
269 return 1; 274 return 1;
270 } 275 }
271 276
272 /* NOTE: OPCODE_FAST_READ (if available) is faster... */ 277 /* FIXME switch to OPCODE_FAST_READ. It's required for higher
278 * clocks; and at this writing, every chip this driver handles
279 * supports that opcode.
280 */
273 281
274 /* Set up the write data buffer. */ 282 /* Set up the write data buffer. */
275 flash->command[0] = OPCODE_READ; 283 flash->command[0] = OPCODE_READ;
@@ -281,7 +289,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
281 289
282 *retlen = m.actual_length - sizeof(flash->command); 290 *retlen = m.actual_length - sizeof(flash->command);
283 291
284 up(&flash->lock); 292 mutex_unlock(&flash->lock);
285 293
286 return 0; 294 return 0;
287} 295}
@@ -323,7 +331,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
323 t[1].tx_buf = buf; 331 t[1].tx_buf = buf;
324 spi_message_add_tail(&t[1], &m); 332 spi_message_add_tail(&t[1], &m);
325 333
326 down(&flash->lock); 334 mutex_lock(&flash->lock);
327 335
328 /* Wait until finished previous write command. */ 336 /* Wait until finished previous write command. */
329 if (wait_till_ready(flash)) 337 if (wait_till_ready(flash))
@@ -381,10 +389,10 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
381 if (retlen) 389 if (retlen)
382 *retlen += m.actual_length 390 *retlen += m.actual_length
383 - sizeof(flash->command); 391 - sizeof(flash->command);
384 } 392 }
385 } 393 }
386 394
387 up(&flash->lock); 395 mutex_unlock(&flash->lock);
388 396
389 return 0; 397 return 0;
390} 398}
@@ -398,24 +406,118 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
398 406
399struct flash_info { 407struct flash_info {
400 char *name; 408 char *name;
401 u8 id; 409
402 u16 jedec_id; 410 /* JEDEC id zero means "no ID" (most older chips); otherwise it has
411 * a high byte of zero plus three data bytes: the manufacturer id,
412 * then a two byte device id.
413 */
414 u32 jedec_id;
415
416 /* The size listed here is what works with OPCODE_SE, which isn't
417 * necessarily called a "sector" by the vendor.
418 */
403 unsigned sector_size; 419 unsigned sector_size;
404 unsigned n_sectors; 420 u16 n_sectors;
421
422 u16 flags;
423#define SECT_4K 0x01 /* OPCODE_BE_4K works uniformly */
405}; 424};
406 425
426
427/* NOTE: double check command sets and memory organization when you add
428 * more flash chips. This current list focusses on newer chips, which
429 * have been converging on command sets which including JEDEC ID.
430 */
407static struct flash_info __devinitdata m25p_data [] = { 431static struct flash_info __devinitdata m25p_data [] = {
408 /* REVISIT: fill in JEDEC ids, for parts that have them */ 432
409 { "m25p05", 0x05, 0x2010, 32 * 1024, 2 }, 433 /* Atmel -- some are (confusingly) marketed as "DataFlash" */
410 { "m25p10", 0x10, 0x2011, 32 * 1024, 4 }, 434 { "at25fs010", 0x1f6601, 32 * 1024, 4, SECT_4K, },
411 { "m25p20", 0x11, 0x2012, 64 * 1024, 4 }, 435 { "at25fs040", 0x1f6604, 64 * 1024, 8, SECT_4K, },
412 { "m25p40", 0x12, 0x2013, 64 * 1024, 8 }, 436
413 { "m25p80", 0x13, 0x0000, 64 * 1024, 16 }, 437 { "at25df041a", 0x1f4401, 64 * 1024, 8, SECT_4K, },
414 { "m25p16", 0x14, 0x2015, 64 * 1024, 32 }, 438
415 { "m25p32", 0x15, 0x2016, 64 * 1024, 64 }, 439 { "at26f004", 0x1f0400, 64 * 1024, 8, SECT_4K, },
416 { "m25p64", 0x16, 0x2017, 64 * 1024, 128 }, 440 { "at26df081a", 0x1f4501, 64 * 1024, 16, SECT_4K, },
441 { "at26df161a", 0x1f4601, 64 * 1024, 32, SECT_4K, },
442 { "at26df321", 0x1f4701, 64 * 1024, 64, SECT_4K, },
443
444 /* Spansion -- single (large) sector size only, at least
445 * for the chips listed here (without boot sectors).
446 */
447 { "s25sl004a", 0x010212, 64 * 1024, 8, },
448 { "s25sl008a", 0x010213, 64 * 1024, 16, },
449 { "s25sl016a", 0x010214, 64 * 1024, 32, },
450 { "s25sl032a", 0x010215, 64 * 1024, 64, },
451 { "s25sl064a", 0x010216, 64 * 1024, 128, },
452
453 /* SST -- large erase sizes are "overlays", "sectors" are 4K */
454 { "sst25vf040b", 0xbf258d, 64 * 1024, 8, SECT_4K, },
455 { "sst25vf080b", 0xbf258e, 64 * 1024, 16, SECT_4K, },
456 { "sst25vf016b", 0xbf2541, 64 * 1024, 32, SECT_4K, },
457 { "sst25vf032b", 0xbf254a, 64 * 1024, 64, SECT_4K, },
458
459 /* ST Microelectronics -- newer production may have feature updates */
460 { "m25p05", 0x202010, 32 * 1024, 2, },
461 { "m25p10", 0x202011, 32 * 1024, 4, },
462 { "m25p20", 0x202012, 64 * 1024, 4, },
463 { "m25p40", 0x202013, 64 * 1024, 8, },
464 { "m25p80", 0, 64 * 1024, 16, },
465 { "m25p16", 0x202015, 64 * 1024, 32, },
466 { "m25p32", 0x202016, 64 * 1024, 64, },
467 { "m25p64", 0x202017, 64 * 1024, 128, },
468 { "m25p128", 0x202018, 256 * 1024, 64, },
469
470 { "m45pe80", 0x204014, 64 * 1024, 16, },
471 { "m45pe16", 0x204015, 64 * 1024, 32, },
472
473 { "m25pe80", 0x208014, 64 * 1024, 16, },
474 { "m25pe16", 0x208015, 64 * 1024, 32, SECT_4K, },
475
476 /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
477 { "w25x10", 0xef3011, 64 * 1024, 2, SECT_4K, },
478 { "w25x20", 0xef3012, 64 * 1024, 4, SECT_4K, },
479 { "w25x40", 0xef3013, 64 * 1024, 8, SECT_4K, },
480 { "w25x80", 0xef3014, 64 * 1024, 16, SECT_4K, },
481 { "w25x16", 0xef3015, 64 * 1024, 32, SECT_4K, },
482 { "w25x32", 0xef3016, 64 * 1024, 64, SECT_4K, },
483 { "w25x64", 0xef3017, 64 * 1024, 128, SECT_4K, },
417}; 484};
418 485
486static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
487{
488 int tmp;
489 u8 code = OPCODE_RDID;
490 u8 id[3];
491 u32 jedec;
492 struct flash_info *info;
493
494 /* JEDEC also defines an optional "extended device information"
495 * string for after vendor-specific data, after the three bytes
496 * we use here. Supporting some chips might require using it.
497 */
498 tmp = spi_write_then_read(spi, &code, 1, id, 3);
499 if (tmp < 0) {
500 DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n",
501 spi->dev.bus_id, tmp);
502 return NULL;
503 }
504 jedec = id[0];
505 jedec = jedec << 8;
506 jedec |= id[1];
507 jedec = jedec << 8;
508 jedec |= id[2];
509
510 for (tmp = 0, info = m25p_data;
511 tmp < ARRAY_SIZE(m25p_data);
512 tmp++, info++) {
513 if (info->jedec_id == jedec)
514 return info;
515 }
516 dev_err(&spi->dev, "unrecognized JEDEC id %06x\n", jedec);
517 return NULL;
518}
519
520
419/* 521/*
420 * board specific setup should have ensured the SPI clock used here 522 * board specific setup should have ensured the SPI clock used here
421 * matches what the READ command supports, at least until this driver 523 * matches what the READ command supports, at least until this driver
@@ -429,37 +531,51 @@ static int __devinit m25p_probe(struct spi_device *spi)
429 unsigned i; 531 unsigned i;
430 532
431 /* Platform data helps sort out which chip type we have, as 533 /* Platform data helps sort out which chip type we have, as
432 * well as how this board partitions it. 534 * well as how this board partitions it. If we don't have
535 * a chip ID, try the JEDEC id commands; they'll work for most
536 * newer chips, even if we don't recognize the particular chip.
433 */ 537 */
434 data = spi->dev.platform_data; 538 data = spi->dev.platform_data;
435 if (!data || !data->type) { 539 if (data && data->type) {
436 /* FIXME some chips can identify themselves with RES 540 for (i = 0, info = m25p_data;
437 * or JEDEC get-id commands. Try them ... 541 i < ARRAY_SIZE(m25p_data);
438 */ 542 i++, info++) {
439 DEBUG(MTD_DEBUG_LEVEL1, "%s: no chip id\n", 543 if (strcmp(data->type, info->name) == 0)
440 spi->dev.bus_id); 544 break;
441 return -ENODEV; 545 }
442 }
443 546
444 for (i = 0, info = m25p_data; i < ARRAY_SIZE(m25p_data); i++, info++) { 547 /* unrecognized chip? */
445 if (strcmp(data->type, info->name) == 0) 548 if (i == ARRAY_SIZE(m25p_data)) {
446 break; 549 DEBUG(MTD_DEBUG_LEVEL0, "%s: unrecognized id %s\n",
447 } 550 spi->dev.bus_id, data->type);
448 if (i == ARRAY_SIZE(m25p_data)) { 551 info = NULL;
449 DEBUG(MTD_DEBUG_LEVEL1, "%s: unrecognized id %s\n", 552
450 spi->dev.bus_id, data->type); 553 /* recognized; is that chip really what's there? */
554 } else if (info->jedec_id) {
555 struct flash_info *chip = jedec_probe(spi);
556
557 if (!chip || chip != info) {
558 dev_warn(&spi->dev, "found %s, expected %s\n",
559 chip ? chip->name : "UNKNOWN",
560 info->name);
561 info = NULL;
562 }
563 }
564 } else
565 info = jedec_probe(spi);
566
567 if (!info)
451 return -ENODEV; 568 return -ENODEV;
452 }
453 569
454 flash = kzalloc(sizeof *flash, GFP_KERNEL); 570 flash = kzalloc(sizeof *flash, GFP_KERNEL);
455 if (!flash) 571 if (!flash)
456 return -ENOMEM; 572 return -ENOMEM;
457 573
458 flash->spi = spi; 574 flash->spi = spi;
459 init_MUTEX(&flash->lock); 575 mutex_init(&flash->lock);
460 dev_set_drvdata(&spi->dev, flash); 576 dev_set_drvdata(&spi->dev, flash);
461 577
462 if (data->name) 578 if (data && data->name)
463 flash->mtd.name = data->name; 579 flash->mtd.name = data->name;
464 else 580 else
465 flash->mtd.name = spi->dev.bus_id; 581 flash->mtd.name = spi->dev.bus_id;
@@ -468,17 +584,25 @@ static int __devinit m25p_probe(struct spi_device *spi)
468 flash->mtd.writesize = 1; 584 flash->mtd.writesize = 1;
469 flash->mtd.flags = MTD_CAP_NORFLASH; 585 flash->mtd.flags = MTD_CAP_NORFLASH;
470 flash->mtd.size = info->sector_size * info->n_sectors; 586 flash->mtd.size = info->sector_size * info->n_sectors;
471 flash->mtd.erasesize = info->sector_size;
472 flash->mtd.erase = m25p80_erase; 587 flash->mtd.erase = m25p80_erase;
473 flash->mtd.read = m25p80_read; 588 flash->mtd.read = m25p80_read;
474 flash->mtd.write = m25p80_write; 589 flash->mtd.write = m25p80_write;
475 590
591 /* prefer "small sector" erase if possible */
592 if (info->flags & SECT_4K) {
593 flash->erase_opcode = OPCODE_BE_4K;
594 flash->mtd.erasesize = 4096;
595 } else {
596 flash->erase_opcode = OPCODE_SE;
597 flash->mtd.erasesize = info->sector_size;
598 }
599
476 dev_info(&spi->dev, "%s (%d Kbytes)\n", info->name, 600 dev_info(&spi->dev, "%s (%d Kbytes)\n", info->name,
477 flash->mtd.size / 1024); 601 flash->mtd.size / 1024);
478 602
479 DEBUG(MTD_DEBUG_LEVEL2, 603 DEBUG(MTD_DEBUG_LEVEL2,
480 "mtd .name = %s, .size = 0x%.8x (%uM) " 604 "mtd .name = %s, .size = 0x%.8x (%uMiB) "
481 ".erasesize = 0x%.8x (%uK) .numeraseregions = %d\n", 605 ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n",
482 flash->mtd.name, 606 flash->mtd.name,
483 flash->mtd.size, flash->mtd.size / (1024*1024), 607 flash->mtd.size, flash->mtd.size / (1024*1024),
484 flash->mtd.erasesize, flash->mtd.erasesize / 1024, 608 flash->mtd.erasesize, flash->mtd.erasesize / 1024,
@@ -488,7 +612,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
488 for (i = 0; i < flash->mtd.numeraseregions; i++) 612 for (i = 0; i < flash->mtd.numeraseregions; i++)
489 DEBUG(MTD_DEBUG_LEVEL2, 613 DEBUG(MTD_DEBUG_LEVEL2,
490 "mtd.eraseregions[%d] = { .offset = 0x%.8x, " 614 "mtd.eraseregions[%d] = { .offset = 0x%.8x, "
491 ".erasesize = 0x%.8x (%uK), " 615 ".erasesize = 0x%.8x (%uKiB), "
492 ".numblocks = %d }\n", 616 ".numblocks = %d }\n",
493 i, flash->mtd.eraseregions[i].offset, 617 i, flash->mtd.eraseregions[i].offset,
494 flash->mtd.eraseregions[i].erasesize, 618 flash->mtd.eraseregions[i].erasesize,
@@ -516,14 +640,14 @@ static int __devinit m25p_probe(struct spi_device *spi)
516 } 640 }
517 641
518 if (nr_parts > 0) { 642 if (nr_parts > 0) {
519 for (i = 0; i < data->nr_parts; i++) { 643 for (i = 0; i < nr_parts; i++) {
520 DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = " 644 DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = "
521 "{.name = %s, .offset = 0x%.8x, " 645 "{.name = %s, .offset = 0x%.8x, "
522 ".size = 0x%.8x (%uK) }\n", 646 ".size = 0x%.8x (%uKiB) }\n",
523 i, data->parts[i].name, 647 i, parts[i].name,
524 data->parts[i].offset, 648 parts[i].offset,
525 data->parts[i].size, 649 parts[i].size,
526 data->parts[i].size / 1024); 650 parts[i].size / 1024);
527 } 651 }
528 flash->partitioned = 1; 652 flash->partitioned = 1;
529 return add_mtd_partitions(&flash->mtd, parts, nr_parts); 653 return add_mtd_partitions(&flash->mtd, parts, nr_parts);
@@ -560,6 +684,11 @@ static struct spi_driver m25p80_driver = {
560 }, 684 },
561 .probe = m25p_probe, 685 .probe = m25p_probe,
562 .remove = __devexit_p(m25p_remove), 686 .remove = __devexit_p(m25p_remove),
687
688 /* REVISIT: many of these chips have deep power-down modes, which
689 * should clearly be entered on suspend() to minimize power use.
690 * And also when they're otherwise idle...
691 */
563}; 692};
564 693
565 694
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
index a987e917f4e0..a5ed6d232c35 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -14,6 +14,7 @@
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/mutex.h>
17#include <linux/spi/spi.h> 18#include <linux/spi/spi.h>
18#include <linux/spi/flash.h> 19#include <linux/spi/flash.h>
19 20
@@ -89,7 +90,7 @@ struct dataflash {
89 unsigned short page_offset; /* offset in flash address */ 90 unsigned short page_offset; /* offset in flash address */
90 unsigned int page_size; /* of bytes per page */ 91 unsigned int page_size; /* of bytes per page */
91 92
92 struct semaphore lock; 93 struct mutex lock;
93 struct spi_device *spi; 94 struct spi_device *spi;
94 95
95 struct mtd_info mtd; 96 struct mtd_info mtd;
@@ -167,7 +168,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
167 x.len = 4; 168 x.len = 4;
168 spi_message_add_tail(&x, &msg); 169 spi_message_add_tail(&x, &msg);
169 170
170 down(&priv->lock); 171 mutex_lock(&priv->lock);
171 while (instr->len > 0) { 172 while (instr->len > 0) {
172 unsigned int pageaddr; 173 unsigned int pageaddr;
173 int status; 174 int status;
@@ -210,7 +211,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
210 instr->len -= priv->page_size; 211 instr->len -= priv->page_size;
211 } 212 }
212 } 213 }
213 up(&priv->lock); 214 mutex_unlock(&priv->lock);
214 215
215 /* Inform MTD subsystem that erase is complete */ 216 /* Inform MTD subsystem that erase is complete */
216 instr->state = MTD_ERASE_DONE; 217 instr->state = MTD_ERASE_DONE;
@@ -266,7 +267,7 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len,
266 x[1].len = len; 267 x[1].len = len;
267 spi_message_add_tail(&x[1], &msg); 268 spi_message_add_tail(&x[1], &msg);
268 269
269 down(&priv->lock); 270 mutex_lock(&priv->lock);
270 271
271 /* Continuous read, max clock = f(car) which may be less than 272 /* Continuous read, max clock = f(car) which may be less than
272 * the peak rate available. Some chips support commands with 273 * the peak rate available. Some chips support commands with
@@ -279,7 +280,7 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len,
279 /* plus 4 "don't care" bytes */ 280 /* plus 4 "don't care" bytes */
280 281
281 status = spi_sync(priv->spi, &msg); 282 status = spi_sync(priv->spi, &msg);
282 up(&priv->lock); 283 mutex_unlock(&priv->lock);
283 284
284 if (status >= 0) { 285 if (status >= 0) {
285 *retlen = msg.actual_length - 8; 286 *retlen = msg.actual_length - 8;
@@ -336,7 +337,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
336 else 337 else
337 writelen = len; 338 writelen = len;
338 339
339 down(&priv->lock); 340 mutex_lock(&priv->lock);
340 while (remaining > 0) { 341 while (remaining > 0) {
341 DEBUG(MTD_DEBUG_LEVEL3, "write @ %i:%i len=%i\n", 342 DEBUG(MTD_DEBUG_LEVEL3, "write @ %i:%i len=%i\n",
342 pageaddr, offset, writelen); 343 pageaddr, offset, writelen);
@@ -441,7 +442,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
441 else 442 else
442 writelen = remaining; 443 writelen = remaining;
443 } 444 }
444 up(&priv->lock); 445 mutex_unlock(&priv->lock);
445 446
446 return status; 447 return status;
447} 448}
@@ -463,7 +464,7 @@ add_dataflash(struct spi_device *spi, char *name,
463 if (!priv) 464 if (!priv)
464 return -ENOMEM; 465 return -ENOMEM;
465 466
466 init_MUTEX(&priv->lock); 467 mutex_init(&priv->lock);
467 priv->spi = spi; 468 priv->spi = spi;
468 priv->page_size = pagesize; 469 priv->page_size = pagesize;
469 priv->page_offset = pageoffset; 470 priv->page_offset = pageoffset;
diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c
index e8f686f7a357..7060a0895ce2 100644
--- a/drivers/mtd/devices/pmc551.c
+++ b/drivers/mtd/devices/pmc551.c
@@ -30,8 +30,8 @@
30 * 30 *
31 * Notes: 31 * Notes:
32 * Due to what I assume is more buggy SROM, the 64M PMC551 I 32 * Due to what I assume is more buggy SROM, the 64M PMC551 I
33 * have available claims that all 4 of it's DRAM banks have 64M 33 * have available claims that all 4 of its DRAM banks have 64MiB
34 * of ram configured (making a grand total of 256M onboard). 34 * of ram configured (making a grand total of 256MiB onboard).
35 * This is slightly annoying since the BAR0 size reflects the 35 * This is slightly annoying since the BAR0 size reflects the
36 * aperture size, not the dram size, and the V370PDC supplies no 36 * aperture size, not the dram size, and the V370PDC supplies no
37 * other method for memory size discovery. This problem is 37 * other method for memory size discovery. This problem is
@@ -70,7 +70,7 @@
70 * made the memory unusable, added a fix to code to touch up 70 * made the memory unusable, added a fix to code to touch up
71 * the DRAM some. 71 * the DRAM some.
72 * 72 *
73 * Bugs/FIXME's: 73 * Bugs/FIXMEs:
74 * * MUST fix the init function to not spin on a register 74 * * MUST fix the init function to not spin on a register
75 * waiting for it to set .. this does not safely handle busted 75 * waiting for it to set .. this does not safely handle busted
76 * devices that never reset the register correctly which will 76 * devices that never reset the register correctly which will
@@ -562,10 +562,10 @@ static u32 fixup_pmc551(struct pci_dev *dev)
562 /* 562 /*
563 * Some screen fun 563 * Some screen fun
564 */ 564 */
565 printk(KERN_DEBUG "pmc551: %d%c (0x%x) of %sprefetchable memory at " 565 printk(KERN_DEBUG "pmc551: %d%sB (0x%x) of %sprefetchable memory at "
566 "0x%llx\n", (size < 1024) ? size : (size < 1048576) ? 566 "0x%llx\n", (size < 1024) ? size : (size < 1048576) ?
567 size >> 10 : size >> 20, 567 size >> 10 : size >> 20,
568 (size < 1024) ? 'B' : (size < 1048576) ? 'K' : 'M', size, 568 (size < 1024) ? "" : (size < 1048576) ? "Ki" : "Mi", size,
569 ((dcmd & (0x1 << 3)) == 0) ? "non-" : "", 569 ((dcmd & (0x1 << 3)) == 0) ? "non-" : "",
570 (unsigned long long)pci_resource_start(dev, 0)); 570 (unsigned long long)pci_resource_start(dev, 0));
571 571
@@ -649,14 +649,10 @@ MODULE_DESCRIPTION(PMC551_VERSION);
649 * Stuff these outside the ifdef so as to not bust compiled in driver support 649 * Stuff these outside the ifdef so as to not bust compiled in driver support
650 */ 650 */
651static int msize = 0; 651static int msize = 0;
652#if defined(CONFIG_MTD_PMC551_APERTURE_SIZE)
653static int asize = CONFIG_MTD_PMC551_APERTURE_SIZE;
654#else
655static int asize = 0; 652static int asize = 0;
656#endif
657 653
658module_param(msize, int, 0); 654module_param(msize, int, 0);
659MODULE_PARM_DESC(msize, "memory size in Megabytes [1 - 1024]"); 655MODULE_PARM_DESC(msize, "memory size in MiB [1 - 1024]");
660module_param(asize, int, 0); 656module_param(asize, int, 0);
661MODULE_PARM_DESC(asize, "aperture size, must be <= memsize [1-1024]"); 657MODULE_PARM_DESC(asize, "aperture size, must be <= memsize [1-1024]");
662 658
@@ -799,8 +795,7 @@ static int __init init_pmc551(void)
799 mtd->owner = THIS_MODULE; 795 mtd->owner = THIS_MODULE;
800 796
801 if (add_mtd_device(mtd)) { 797 if (add_mtd_device(mtd)) {
802 printk(KERN_NOTICE "pmc551: Failed to register new " 798 printk(KERN_NOTICE "pmc551: Failed to register new device\n");
803 "device\n");
804 pci_iounmap(PCI_Device, priv->start); 799 pci_iounmap(PCI_Device, priv->start);
805 kfree(mtd->priv); 800 kfree(mtd->priv);
806 kfree(mtd); 801 kfree(mtd);
@@ -811,13 +806,13 @@ static int __init init_pmc551(void)
811 pci_dev_get(PCI_Device); 806 pci_dev_get(PCI_Device);
812 807
813 printk(KERN_NOTICE "Registered pmc551 memory device.\n"); 808 printk(KERN_NOTICE "Registered pmc551 memory device.\n");
814 printk(KERN_NOTICE "Mapped %dM of memory from 0x%p to 0x%p\n", 809 printk(KERN_NOTICE "Mapped %dMiB of memory from 0x%p to 0x%p\n",
815 priv->asize >> 20, 810 priv->asize >> 20,
816 priv->start, priv->start + priv->asize); 811 priv->start, priv->start + priv->asize);
817 printk(KERN_NOTICE "Total memory is %d%c\n", 812 printk(KERN_NOTICE "Total memory is %d%sB\n",
818 (length < 1024) ? length : 813 (length < 1024) ? length :
819 (length < 1048576) ? length >> 10 : length >> 20, 814 (length < 1048576) ? length >> 10 : length >> 20,
820 (length < 1024) ? 'B' : (length < 1048576) ? 'K' : 'M'); 815 (length < 1024) ? "" : (length < 1048576) ? "Ki" : "Mi");
821 priv->nextpmc551 = pmc551list; 816 priv->nextpmc551 = pmc551list;
822 pmc551list = mtd; 817 pmc551list = mtd;
823 found++; 818 found++;
@@ -850,7 +845,7 @@ static void __exit cleanup_pmc551(void)
850 pmc551list = priv->nextpmc551; 845 pmc551list = priv->nextpmc551;
851 846
852 if (priv->start) { 847 if (priv->start) {
853 printk(KERN_DEBUG "pmc551: unmapping %dM starting at " 848 printk(KERN_DEBUG "pmc551: unmapping %dMiB starting at "
854 "0x%p\n", priv->asize >> 20, priv->start); 849 "0x%p\n", priv->asize >> 20, priv->start);
855 pci_iounmap(priv->dev, priv->start); 850 pci_iounmap(priv->dev, priv->start);
856 } 851 }
diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c
index ecac0e438f49..b8917beeb650 100644
--- a/drivers/mtd/inftlmount.c
+++ b/drivers/mtd/inftlmount.c
@@ -580,14 +580,13 @@ int INFTL_mount(struct INFTLrecord *s)
580 logical_block = block = BLOCK_NIL; 580 logical_block = block = BLOCK_NIL;
581 581
582 /* Temporary buffer to store ANAC numbers. */ 582 /* Temporary buffer to store ANAC numbers. */
583 ANACtable = kmalloc(s->nb_blocks * sizeof(u8), GFP_KERNEL); 583 ANACtable = kcalloc(s->nb_blocks, sizeof(u8), GFP_KERNEL);
584 if (!ANACtable) { 584 if (!ANACtable) {
585 printk(KERN_WARNING "INFTL: allocation of ANACtable " 585 printk(KERN_WARNING "INFTL: allocation of ANACtable "
586 "failed (%zd bytes)\n", 586 "failed (%zd bytes)\n",
587 s->nb_blocks * sizeof(u8)); 587 s->nb_blocks * sizeof(u8));
588 return -ENOMEM; 588 return -ENOMEM;
589 } 589 }
590 memset(ANACtable, 0, s->nb_blocks);
591 590
592 /* 591 /*
593 * First pass is to explore each physical unit, and construct the 592 * First pass is to explore each physical unit, and construct the
diff --git a/drivers/mtd/maps/alchemy-flash.c b/drivers/mtd/maps/alchemy-flash.c
index 84fbe0e8c47e..82811bcb0436 100644
--- a/drivers/mtd/maps/alchemy-flash.c
+++ b/drivers/mtd/maps/alchemy-flash.c
@@ -75,13 +75,6 @@
75#define BOARD_FLASH_WIDTH 2 /* 16-bits */ 75#define BOARD_FLASH_WIDTH 2 /* 16-bits */
76#endif 76#endif
77 77
78#ifdef CONFIG_MIPS_HYDROGEN3
79#define BOARD_MAP_NAME "Hydrogen3 Flash"
80#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
81#define BOARD_FLASH_WIDTH 4 /* 32-bits */
82#define USE_LOCAL_ACCESSORS /* why? */
83#endif
84
85#ifdef CONFIG_MIPS_BOSPORUS 78#ifdef CONFIG_MIPS_BOSPORUS
86#define BOARD_MAP_NAME "Bosporus Flash" 79#define BOARD_MAP_NAME "Bosporus Flash"
87#define BOARD_FLASH_SIZE 0x01000000 /* 16MB */ 80#define BOARD_FLASH_SIZE 0x01000000 /* 16MB */
@@ -130,13 +123,6 @@ int __init alchemy_mtd_init(void)
130 123
131 window_addr = 0x20000000 - BOARD_FLASH_SIZE; 124 window_addr = 0x20000000 - BOARD_FLASH_SIZE;
132 window_size = BOARD_FLASH_SIZE; 125 window_size = BOARD_FLASH_SIZE;
133#ifdef CONFIG_MIPS_MIRAGE_WHY
134 /* Boot ROM flash bank only; no user bank */
135 window_addr = 0x1C000000;
136 window_size = 0x04000000;
137 /* USERFS from 0x1C00 0000 to 0x1FC00000 */
138 alchemy_partitions[0].size = 0x03C00000;
139#endif
140 126
141 /* 127 /*
142 * Static partition definition selection 128 * Static partition definition selection
diff --git a/drivers/mtd/maps/nettel.c b/drivers/mtd/maps/nettel.c
index 7b96cd02f82b..0c9b305a72e0 100644
--- a/drivers/mtd/maps/nettel.c
+++ b/drivers/mtd/maps/nettel.c
@@ -158,68 +158,11 @@ static struct notifier_block nettel_notifier_block = {
158 nettel_reboot_notifier, NULL, 0 158 nettel_reboot_notifier, NULL, 0
159}; 159};
160 160
161/*
162 * Erase the configuration file system.
163 * Used to support the software reset button.
164 */
165static void nettel_erasecallback(struct erase_info *done)
166{
167 wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv;
168 wake_up(wait_q);
169}
170
171static struct erase_info nettel_erase;
172
173int nettel_eraseconfig(void)
174{
175 struct mtd_info *mtd;
176 DECLARE_WAITQUEUE(wait, current);
177 wait_queue_head_t wait_q;
178 int ret;
179
180 init_waitqueue_head(&wait_q);
181 mtd = get_mtd_device(NULL, 2);
182 if (!IS_ERR(mtd)) {
183 nettel_erase.mtd = mtd;
184 nettel_erase.callback = nettel_erasecallback;
185 nettel_erase.callback = NULL;
186 nettel_erase.addr = 0;
187 nettel_erase.len = mtd->size;
188 nettel_erase.priv = (u_long) &wait_q;
189 nettel_erase.priv = 0;
190
191 set_current_state(TASK_INTERRUPTIBLE);
192 add_wait_queue(&wait_q, &wait);
193
194 ret = mtd->erase(mtd, &nettel_erase);
195 if (ret) {
196 set_current_state(TASK_RUNNING);
197 remove_wait_queue(&wait_q, &wait);
198 put_mtd_device(mtd);
199 return(ret);
200 }
201
202 schedule(); /* Wait for erase to finish. */
203 remove_wait_queue(&wait_q, &wait);
204
205 put_mtd_device(mtd);
206 }
207
208 return(0);
209}
210
211#else
212
213int nettel_eraseconfig(void)
214{
215 return(0);
216}
217
218#endif 161#endif
219 162
220/****************************************************************************/ 163/****************************************************************************/
221 164
222int __init nettel_init(void) 165static int __init nettel_init(void)
223{ 166{
224 volatile unsigned long *amdpar; 167 volatile unsigned long *amdpar;
225 unsigned long amdaddr, maxsize; 168 unsigned long amdaddr, maxsize;
@@ -421,10 +364,6 @@ int __init nettel_init(void)
421 364
422 intel_mtd->owner = THIS_MODULE; 365 intel_mtd->owner = THIS_MODULE;
423 366
424#ifndef CONFIG_BLK_DEV_INITRD
425 ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, 1);
426#endif
427
428 num_intel_partitions = sizeof(nettel_intel_partitions) / 367 num_intel_partitions = sizeof(nettel_intel_partitions) /
429 sizeof(nettel_intel_partitions[0]); 368 sizeof(nettel_intel_partitions[0]);
430 369
@@ -477,7 +416,7 @@ out_unmap2:
477 416
478/****************************************************************************/ 417/****************************************************************************/
479 418
480void __exit nettel_cleanup(void) 419static void __exit nettel_cleanup(void)
481{ 420{
482#ifdef CONFIG_MTD_CFI_INTELEXT 421#ifdef CONFIG_MTD_CFI_INTELEXT
483 unregister_reboot_notifier(&nettel_notifier_block); 422 unregister_reboot_notifier(&nettel_notifier_block);
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c
index bbb42c35b69b..fbd613968717 100644
--- a/drivers/mtd/maps/physmap_of.c
+++ b/drivers/mtd/maps/physmap_of.c
@@ -141,7 +141,6 @@ static int __devinit of_physmap_probe(struct of_device *dev, const struct of_dev
141 err = -ENOMEM; 141 err = -ENOMEM;
142 goto err_out; 142 goto err_out;
143 } 143 }
144 memset(info, 0, sizeof(*info));
145 144
146 dev_set_drvdata(&dev->dev, info); 145 dev_set_drvdata(&dev->dev, info);
147 146
@@ -213,10 +212,6 @@ static int __devinit of_physmap_probe(struct of_device *dev, const struct of_dev
213err_out: 212err_out:
214 of_physmap_remove(dev); 213 of_physmap_remove(dev);
215 return err; 214 return err;
216
217 return 0;
218
219
220} 215}
221 216
222static struct of_device_id of_physmap_match[] = { 217static struct of_device_id of_physmap_match[] = {
diff --git a/drivers/mtd/maps/pmcmsp-flash.c b/drivers/mtd/maps/pmcmsp-flash.c
index 7e0377ec1c40..02bde8c982ec 100644
--- a/drivers/mtd/maps/pmcmsp-flash.c
+++ b/drivers/mtd/maps/pmcmsp-flash.c
@@ -73,13 +73,16 @@ int __init init_msp_flash(void)
73 return -ENXIO; 73 return -ENXIO;
74 74
75 printk(KERN_NOTICE "Found %d PMC flash devices\n", fcnt); 75 printk(KERN_NOTICE "Found %d PMC flash devices\n", fcnt);
76 msp_flash = (struct mtd_info **)kmalloc( 76
77 fcnt * sizeof(struct map_info *), GFP_KERNEL); 77 msp_flash = kmalloc(fcnt * sizeof(struct map_info *), GFP_KERNEL);
78 msp_parts = (struct mtd_partition **)kmalloc( 78 msp_parts = kmalloc(fcnt * sizeof(struct mtd_partition *), GFP_KERNEL);
79 fcnt * sizeof(struct mtd_partition *), GFP_KERNEL); 79 msp_maps = kcalloc(fcnt, sizeof(struct mtd_info), GFP_KERNEL);
80 msp_maps = (struct map_info *)kmalloc( 80 if (!msp_flash || !msp_parts || !msp_maps) {
81 fcnt * sizeof(struct mtd_info), GFP_KERNEL); 81 kfree(msp_maps);
82 memset(msp_maps, 0, fcnt * sizeof(struct mtd_info)); 82 kfree(msp_parts);
83 kfree(msp_flash);
84 return -ENOMEM;
85 }
83 86
84 /* loop over the flash devices, initializing each */ 87 /* loop over the flash devices, initializing each */
85 for (i = 0; i < fcnt; i++) { 88 for (i = 0; i < fcnt; i++) {
@@ -95,9 +98,8 @@ int __init init_msp_flash(void)
95 continue; 98 continue;
96 } 99 }
97 100
98 msp_parts[i] = (struct mtd_partition *)kmalloc( 101 msp_parts[i] = kcalloc(pcnt, sizeof(struct mtd_partition),
99 pcnt * sizeof(struct mtd_partition), GFP_KERNEL); 102 GFP_KERNEL);
100 memset(msp_parts[i], 0, pcnt * sizeof(struct mtd_partition));
101 103
102 /* now initialize the devices proper */ 104 /* now initialize the devices proper */
103 flash_name[5] = '0' + i; 105 flash_name[5] = '0' + i;
diff --git a/drivers/mtd/maps/pmcmsp-ramroot.c b/drivers/mtd/maps/pmcmsp-ramroot.c
index 18049bceba8d..30de5c0c09a9 100644
--- a/drivers/mtd/maps/pmcmsp-ramroot.c
+++ b/drivers/mtd/maps/pmcmsp-ramroot.c
@@ -79,7 +79,6 @@ static int __init init_rrmap(void)
79 rr_mtd->owner = THIS_MODULE; 79 rr_mtd->owner = THIS_MODULE;
80 80
81 add_mtd_device(rr_mtd); 81 add_mtd_device(rr_mtd);
82 ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, rr_mtd->index);
83 82
84 return 0; 83 return 0;
85 } 84 }
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index ef89780eb9d6..74d9d30edabd 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -24,10 +24,9 @@
24#include <linux/kthread.h> 24#include <linux/kthread.h>
25#include <asm/uaccess.h> 25#include <asm/uaccess.h>
26 26
27static LIST_HEAD(blktrans_majors); 27#include "mtdcore.h"
28 28
29extern struct mutex mtd_table_mutex; 29static LIST_HEAD(blktrans_majors);
30extern struct mtd_info *mtd_table[];
31 30
32struct mtd_blkcore_priv { 31struct mtd_blkcore_priv {
33 struct task_struct *thread; 32 struct task_struct *thread;
@@ -202,7 +201,7 @@ static int blktrans_ioctl(struct inode *inode, struct file *file,
202 } 201 }
203} 202}
204 203
205struct block_device_operations mtd_blktrans_ops = { 204static struct block_device_operations mtd_blktrans_ops = {
206 .owner = THIS_MODULE, 205 .owner = THIS_MODULE,
207 .open = blktrans_open, 206 .open = blktrans_open,
208 .release = blktrans_release, 207 .release = blktrans_release,
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index d091b2430b48..22ed96c4b7bd 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -136,7 +136,8 @@ static int mtd_close(struct inode *inode, struct file *file)
136 136
137 DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n"); 137 DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n");
138 138
139 if (mtd->sync) 139 /* Only sync if opened RW */
140 if ((file->f_mode & 2) && mtd->sync)
140 mtd->sync(mtd); 141 mtd->sync(mtd);
141 142
142 put_mtd_device(mtd); 143 put_mtd_device(mtd);
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 41844ea02462..96be7ef62f35 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -178,7 +178,7 @@ concat_writev(struct mtd_info *mtd, const struct kvec *vecs,
178 178
179 /* Check alignment */ 179 /* Check alignment */
180 if (mtd->writesize > 1) { 180 if (mtd->writesize > 1) {
181 loff_t __to = to; 181 uint64_t __to = to;
182 if (do_div(__to, mtd->writesize) || (total_len % mtd->writesize)) 182 if (do_div(__to, mtd->writesize) || (total_len % mtd->writesize))
183 return -EINVAL; 183 return -EINVAL;
184 } 184 }
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index c153b64a8300..6c2645e28371 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -22,6 +22,8 @@
22 22
23#include <linux/mtd/mtd.h> 23#include <linux/mtd/mtd.h>
24 24
25#include "mtdcore.h"
26
25/* These are exported solely for the purpose of mtd_blkdevs.c. You 27/* These are exported solely for the purpose of mtd_blkdevs.c. You
26 should not use them for _anything_ else */ 28 should not use them for _anything_ else */
27DEFINE_MUTEX(mtd_table_mutex); 29DEFINE_MUTEX(mtd_table_mutex);
diff --git a/drivers/mtd/mtdcore.h b/drivers/mtd/mtdcore.h
new file mode 100644
index 000000000000..a33251f4b872
--- /dev/null
+++ b/drivers/mtd/mtdcore.h
@@ -0,0 +1,11 @@
1/* linux/drivers/mtd/mtdcore.h
2 *
3 * Header file for driver private mtdcore exports
4 *
5 */
6
7/* These are exported solely for the purpose of mtd_blkdevs.c. You
8 should not use them for _anything_ else */
9
10extern struct mutex mtd_table_mutex;
11extern struct mtd_info *mtd_table[MAX_MTD_DEVICES];
diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c
new file mode 100644
index 000000000000..f8af627f0b98
--- /dev/null
+++ b/drivers/mtd/mtdoops.c
@@ -0,0 +1,376 @@
1/*
2 * MTD Oops/Panic logger
3 *
4 * Copyright (C) 2007 Nokia Corporation. All rights reserved.
5 *
6 * Author: Richard Purdie <rpurdie@openedhand.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/console.h>
27#include <linux/vmalloc.h>
28#include <linux/workqueue.h>
29#include <linux/sched.h>
30#include <linux/wait.h>
31#include <linux/mtd/mtd.h>
32
33#define OOPS_PAGE_SIZE 4096
34
35static struct mtdoops_context {
36 int mtd_index;
37 struct work_struct work;
38 struct mtd_info *mtd;
39 int oops_pages;
40 int nextpage;
41 int nextcount;
42
43 void *oops_buf;
44 int ready;
45 int writecount;
46} oops_cxt;
47
48static void mtdoops_erase_callback(struct erase_info *done)
49{
50 wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv;
51 wake_up(wait_q);
52}
53
54static int mtdoops_erase_block(struct mtd_info *mtd, int offset)
55{
56 struct erase_info erase;
57 DECLARE_WAITQUEUE(wait, current);
58 wait_queue_head_t wait_q;
59 int ret;
60
61 init_waitqueue_head(&wait_q);
62 erase.mtd = mtd;
63 erase.callback = mtdoops_erase_callback;
64 erase.addr = offset;
65 if (mtd->erasesize < OOPS_PAGE_SIZE)
66 erase.len = OOPS_PAGE_SIZE;
67 else
68 erase.len = mtd->erasesize;
69 erase.priv = (u_long)&wait_q;
70
71 set_current_state(TASK_INTERRUPTIBLE);
72 add_wait_queue(&wait_q, &wait);
73
74 ret = mtd->erase(mtd, &erase);
75 if (ret) {
76 set_current_state(TASK_RUNNING);
77 remove_wait_queue(&wait_q, &wait);
78 printk (KERN_WARNING "mtdoops: erase of region [0x%x, 0x%x] "
79 "on \"%s\" failed\n",
80 erase.addr, erase.len, mtd->name);
81 return ret;
82 }
83
84 schedule(); /* Wait for erase to finish. */
85 remove_wait_queue(&wait_q, &wait);
86
87 return 0;
88}
89
90static int mtdoops_inc_counter(struct mtdoops_context *cxt)
91{
92 struct mtd_info *mtd = cxt->mtd;
93 size_t retlen;
94 u32 count;
95 int ret;
96
97 cxt->nextpage++;
98 if (cxt->nextpage > cxt->oops_pages)
99 cxt->nextpage = 0;
100 cxt->nextcount++;
101 if (cxt->nextcount == 0xffffffff)
102 cxt->nextcount = 0;
103
104 ret = mtd->read(mtd, cxt->nextpage * OOPS_PAGE_SIZE, 4,
105 &retlen, (u_char *) &count);
106 if ((retlen != 4) || (ret < 0)) {
107 printk(KERN_ERR "mtdoops: Read failure at %d (%td of 4 read)"
108 ", err %d.\n", cxt->nextpage * OOPS_PAGE_SIZE,
109 retlen, ret);
110 return 1;
111 }
112
113 /* See if we need to erase the next block */
114 if (count != 0xffffffff)
115 return 1;
116
117 printk(KERN_DEBUG "mtdoops: Ready %d, %d (no erase)\n",
118 cxt->nextpage, cxt->nextcount);
119 cxt->ready = 1;
120 return 0;
121}
122
123static void mtdoops_prepare(struct mtdoops_context *cxt)
124{
125 struct mtd_info *mtd = cxt->mtd;
126 int i = 0, j, ret, mod;
127
128 /* We were unregistered */
129 if (!mtd)
130 return;
131
132 mod = (cxt->nextpage * OOPS_PAGE_SIZE) % mtd->erasesize;
133 if (mod != 0) {
134 cxt->nextpage = cxt->nextpage + ((mtd->erasesize - mod) / OOPS_PAGE_SIZE);
135 if (cxt->nextpage > cxt->oops_pages)
136 cxt->nextpage = 0;
137 }
138
139 while (mtd->block_isbad &&
140 mtd->block_isbad(mtd, cxt->nextpage * OOPS_PAGE_SIZE)) {
141badblock:
142 printk(KERN_WARNING "mtdoops: Bad block at %08x\n",
143 cxt->nextpage * OOPS_PAGE_SIZE);
144 i++;
145 cxt->nextpage = cxt->nextpage + (mtd->erasesize / OOPS_PAGE_SIZE);
146 if (cxt->nextpage > cxt->oops_pages)
147 cxt->nextpage = 0;
148 if (i == (cxt->oops_pages / (mtd->erasesize / OOPS_PAGE_SIZE))) {
149 printk(KERN_ERR "mtdoops: All blocks bad!\n");
150 return;
151 }
152 }
153
154 for (j = 0, ret = -1; (j < 3) && (ret < 0); j++)
155 ret = mtdoops_erase_block(mtd, cxt->nextpage * OOPS_PAGE_SIZE);
156
157 if (ret < 0) {
158 if (mtd->block_markbad)
159 mtd->block_markbad(mtd, cxt->nextpage * OOPS_PAGE_SIZE);
160 goto badblock;
161 }
162
163 printk(KERN_DEBUG "mtdoops: Ready %d, %d \n", cxt->nextpage, cxt->nextcount);
164
165 cxt->ready = 1;
166}
167
168static void mtdoops_workfunc(struct work_struct *work)
169{
170 struct mtdoops_context *cxt =
171 container_of(work, struct mtdoops_context, work);
172
173 mtdoops_prepare(cxt);
174}
175
176static int find_next_position(struct mtdoops_context *cxt)
177{
178 struct mtd_info *mtd = cxt->mtd;
179 int page, maxpos = 0;
180 u32 count, maxcount = 0xffffffff;
181 size_t retlen;
182
183 for (page = 0; page < cxt->oops_pages; page++) {
184 mtd->read(mtd, page * OOPS_PAGE_SIZE, 4, &retlen, (u_char *) &count);
185 if (count == 0xffffffff)
186 continue;
187 if (maxcount == 0xffffffff) {
188 maxcount = count;
189 maxpos = page;
190 } else if ((count < 0x40000000) && (maxcount > 0xc0000000)) {
191 maxcount = count;
192 maxpos = page;
193 } else if ((count > maxcount) && (count < 0xc0000000)) {
194 maxcount = count;
195 maxpos = page;
196 } else if ((count > maxcount) && (count > 0xc0000000)
197 && (maxcount > 0x80000000)) {
198 maxcount = count;
199 maxpos = page;
200 }
201 }
202 if (maxcount == 0xffffffff) {
203 cxt->nextpage = 0;
204 cxt->nextcount = 1;
205 cxt->ready = 1;
206 printk(KERN_DEBUG "mtdoops: Ready %d, %d (first init)\n",
207 cxt->nextpage, cxt->nextcount);
208 return 0;
209 }
210
211 cxt->nextpage = maxpos;
212 cxt->nextcount = maxcount;
213
214 return mtdoops_inc_counter(cxt);
215}
216
217
218static void mtdoops_notify_add(struct mtd_info *mtd)
219{
220 struct mtdoops_context *cxt = &oops_cxt;
221 int ret;
222
223 if ((mtd->index != cxt->mtd_index) || cxt->mtd_index < 0)
224 return;
225
226 if (mtd->size < (mtd->erasesize * 2)) {
227 printk(KERN_ERR "MTD partition %d not big enough for mtdoops\n",
228 mtd->index);
229 return;
230 }
231
232 cxt->mtd = mtd;
233 cxt->oops_pages = mtd->size / OOPS_PAGE_SIZE;
234
235 ret = find_next_position(cxt);
236 if (ret == 1)
237 mtdoops_prepare(cxt);
238
239 printk(KERN_DEBUG "mtdoops: Attached to MTD device %d\n", mtd->index);
240}
241
242static void mtdoops_notify_remove(struct mtd_info *mtd)
243{
244 struct mtdoops_context *cxt = &oops_cxt;
245
246 if ((mtd->index != cxt->mtd_index) || cxt->mtd_index < 0)
247 return;
248
249 cxt->mtd = NULL;
250 flush_scheduled_work();
251}
252
253static void mtdoops_console_sync(void)
254{
255 struct mtdoops_context *cxt = &oops_cxt;
256 struct mtd_info *mtd = cxt->mtd;
257 size_t retlen;
258 int ret;
259
260 if (!cxt->ready || !mtd)
261 return;
262
263 if (cxt->writecount == 0)
264 return;
265
266 if (cxt->writecount < OOPS_PAGE_SIZE)
267 memset(cxt->oops_buf + cxt->writecount, 0xff,
268 OOPS_PAGE_SIZE - cxt->writecount);
269
270 ret = mtd->write(mtd, cxt->nextpage * OOPS_PAGE_SIZE,
271 OOPS_PAGE_SIZE, &retlen, cxt->oops_buf);
272 cxt->ready = 0;
273 cxt->writecount = 0;
274
275 if ((retlen != OOPS_PAGE_SIZE) || (ret < 0))
276 printk(KERN_ERR "mtdoops: Write failure at %d (%td of %d written), err %d.\n",
277 cxt->nextpage * OOPS_PAGE_SIZE, retlen, OOPS_PAGE_SIZE, ret);
278
279 ret = mtdoops_inc_counter(cxt);
280 if (ret == 1)
281 schedule_work(&cxt->work);
282}
283
284static void
285mtdoops_console_write(struct console *co, const char *s, unsigned int count)
286{
287 struct mtdoops_context *cxt = co->data;
288 struct mtd_info *mtd = cxt->mtd;
289 int i;
290
291 if (!oops_in_progress) {
292 mtdoops_console_sync();
293 return;
294 }
295
296 if (!cxt->ready || !mtd)
297 return;
298
299 if (cxt->writecount == 0) {
300 u32 *stamp = cxt->oops_buf;
301 *stamp = cxt->nextcount;
302 cxt->writecount = 4;
303 }
304
305 if ((count + cxt->writecount) > OOPS_PAGE_SIZE)
306 count = OOPS_PAGE_SIZE - cxt->writecount;
307
308 for (i = 0; i < count; i++, s++)
309 *((char *)(cxt->oops_buf) + cxt->writecount + i) = *s;
310
311 cxt->writecount = cxt->writecount + count;
312}
313
314static int __init mtdoops_console_setup(struct console *co, char *options)
315{
316 struct mtdoops_context *cxt = co->data;
317
318 if (cxt->mtd_index != -1)
319 return -EBUSY;
320 if (co->index == -1)
321 return -EINVAL;
322
323 cxt->mtd_index = co->index;
324 return 0;
325}
326
327static struct mtd_notifier mtdoops_notifier = {
328 .add = mtdoops_notify_add,
329 .remove = mtdoops_notify_remove,
330};
331
332static struct console mtdoops_console = {
333 .name = "ttyMTD",
334 .write = mtdoops_console_write,
335 .setup = mtdoops_console_setup,
336 .unblank = mtdoops_console_sync,
337 .flags = CON_PRINTBUFFER,
338 .index = -1,
339 .data = &oops_cxt,
340};
341
342static int __init mtdoops_console_init(void)
343{
344 struct mtdoops_context *cxt = &oops_cxt;
345
346 cxt->mtd_index = -1;
347 cxt->oops_buf = vmalloc(OOPS_PAGE_SIZE);
348
349 if (!cxt->oops_buf) {
350 printk(KERN_ERR "Failed to allocate oops buffer workspace\n");
351 return -ENOMEM;
352 }
353
354 INIT_WORK(&cxt->work, mtdoops_workfunc);
355
356 register_console(&mtdoops_console);
357 register_mtd_user(&mtdoops_notifier);
358 return 0;
359}
360
361static void __exit mtdoops_console_exit(void)
362{
363 struct mtdoops_context *cxt = &oops_cxt;
364
365 unregister_mtd_user(&mtdoops_notifier);
366 unregister_console(&mtdoops_console);
367 vfree(cxt->oops_buf);
368}
369
370
371subsys_initcall(mtdoops_console_init);
372module_exit(mtdoops_console_exit);
373
374MODULE_LICENSE("GPL");
375MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>");
376MODULE_DESCRIPTION("MTD Oops/Panic console logger/driver");
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index a783d62f48f6..511448ff0ce2 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -134,10 +134,10 @@ config MTD_NAND_S3C2410_HWECC
134 134
135config MTD_NAND_NDFC 135config MTD_NAND_NDFC
136 tristate "NDFC NanD Flash Controller" 136 tristate "NDFC NanD Flash Controller"
137 depends on 44x && !PPC_MERGE 137 depends on 4xx && !PPC_MERGE
138 select MTD_NAND_ECC_SMC 138 select MTD_NAND_ECC_SMC
139 help 139 help
140 NDFC Nand Flash Controllers are integrated in EP44x SoCs 140 NDFC Nand Flash Controllers are integrated in IBM/AMCC's 4xx SoCs
141 141
142config MTD_NAND_S3C2410_CLKSTOP 142config MTD_NAND_S3C2410_CLKSTOP
143 bool "S3C2410 NAND IDLE clock stop" 143 bool "S3C2410 NAND IDLE clock stop"
@@ -237,7 +237,7 @@ config MTD_NAND_CAFE
237 select REED_SOLOMON 237 select REED_SOLOMON
238 select REED_SOLOMON_DEC16 238 select REED_SOLOMON_DEC16
239 help 239 help
240 Use NAND flash attached to the CAFÉ chip designed for the $100 240 Use NAND flash attached to the CAFÉ chip designed for the OLPC
241 laptop. 241 laptop.
242 242
243config MTD_NAND_CS553X 243config MTD_NAND_CS553X
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index e96259f22cca..ab9f5c5db38d 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -56,8 +56,6 @@ static unsigned long __initdata doc_locations[] = {
56#endif /* CONFIG_MTD_DOCPROBE_HIGH */ 56#endif /* CONFIG_MTD_DOCPROBE_HIGH */
57#elif defined(__PPC__) 57#elif defined(__PPC__)
58 0xe4000000, 58 0xe4000000,
59#elif defined(CONFIG_MOMENCO_OCELOT_G)
60 0xff000000,
61#else 59#else
62#warning Unknown architecture for DiskOnChip. No default probe locations defined 60#warning Unknown architecture for DiskOnChip. No default probe locations defined
63#endif 61#endif
diff --git a/drivers/mtd/nand/excite_nandflash.c b/drivers/mtd/nand/excite_nandflash.c
index 7e9afc4c7757..bed87290decc 100644
--- a/drivers/mtd/nand/excite_nandflash.c
+++ b/drivers/mtd/nand/excite_nandflash.c
@@ -27,7 +27,6 @@
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/err.h> 29#include <linux/err.h>
30#include <linux/kernel.h>
31 30
32#include <linux/mtd/mtd.h> 31#include <linux/mtd/mtd.h>
33#include <linux/mtd/nand.h> 32#include <linux/mtd/nand.h>
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 24ac6778b1a8..d5691212058d 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -7,7 +7,7 @@
7 * Basic support for AG-AND chips is provided. 7 * Basic support for AG-AND chips is provided.
8 * 8 *
9 * Additional technical information is available on 9 * Additional technical information is available on
10 * http://www.linux-mtd.infradead.org/tech/nand.html 10 * http://www.linux-mtd.infradead.org/doc/nand.html
11 * 11 *
12 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) 12 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
13 * 2002-2006 Thomas Gleixner (tglx@linutronix.de) 13 * 2002-2006 Thomas Gleixner (tglx@linutronix.de)
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c
index 2fc674a190cf..a3e3ab0185d5 100644
--- a/drivers/mtd/nand/nand_ids.c
+++ b/drivers/mtd/nand/nand_ids.c
@@ -141,6 +141,7 @@ struct nand_manufacturers nand_manuf_ids[] = {
141 {NAND_MFR_STMICRO, "ST Micro"}, 141 {NAND_MFR_STMICRO, "ST Micro"},
142 {NAND_MFR_HYNIX, "Hynix"}, 142 {NAND_MFR_HYNIX, "Hynix"},
143 {NAND_MFR_MICRON, "Micron"}, 143 {NAND_MFR_MICRON, "Micron"},
144 {NAND_MFR_AMD, "AMD"},
144 {0x0, "Unknown"} 145 {0x0, "Unknown"}
145}; 146};
146 147
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
index fd7a8d5ba29a..1c0e89f00e8d 100644
--- a/drivers/mtd/nand/ndfc.c
+++ b/drivers/mtd/nand/ndfc.c
@@ -24,7 +24,11 @@
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25 25
26#include <asm/io.h> 26#include <asm/io.h>
27#ifdef CONFIG_40x
28#include <asm/ibm405.h>
29#else
27#include <asm/ibm44x.h> 30#include <asm/ibm44x.h>
31#endif
28 32
29struct ndfc_nand_mtd { 33struct ndfc_nand_mtd {
30 struct mtd_info mtd; 34 struct mtd_info mtd;
@@ -230,7 +234,11 @@ static int ndfc_nand_probe(struct platform_device *pdev)
230 struct ndfc_controller *ndfc = &ndfc_ctrl; 234 struct ndfc_controller *ndfc = &ndfc_ctrl;
231 unsigned long long phys = settings->ndfc_erpn | res->start; 235 unsigned long long phys = settings->ndfc_erpn | res->start;
232 236
237#ifndef CONFIG_PHYS_64BIT
238 ndfc->ndfcbase = ioremap((phys_addr_t)phys, res->end - res->start + 1);
239#else
233 ndfc->ndfcbase = ioremap64(phys, res->end - res->start + 1); 240 ndfc->ndfcbase = ioremap64(phys, res->end - res->start + 1);
241#endif
234 if (!ndfc->ndfcbase) { 242 if (!ndfc->ndfcbase) {
235 printk(KERN_ERR "NDFC: ioremap failed\n"); 243 printk(KERN_ERR "NDFC: ioremap failed\n");
236 return -EIO; 244 return -EIO;
diff --git a/drivers/mtd/onenand/Kconfig b/drivers/mtd/onenand/Kconfig
index c257d397d08a..cb41cbca64f7 100644
--- a/drivers/mtd/onenand/Kconfig
+++ b/drivers/mtd/onenand/Kconfig
@@ -40,4 +40,27 @@ config MTD_ONENAND_OTP
40 40
41 OTP block is fully-guaranteed to be a valid block. 41 OTP block is fully-guaranteed to be a valid block.
42 42
43config MTD_ONENAND_2X_PROGRAM
44 bool "OneNAND 2X program support"
45 help
46 The 2X Program is an extension of Program Operation.
47 Since the device is equipped with two DataRAMs, and two-plane NAND
48 Flash memory array, these two component enables simultaneous program
49 of 4KiB. Plane1 has only even blocks such as block0, block2, block4
50 while Plane2 has only odd blocks such as block1, block3, block5.
51 So MTD regards it as 4KiB page size and 256KiB block size
52
53 Now the following chips support it. (KFXXX16Q2M)
54 Demux: KFG2G16Q2M, KFH4G16Q2M, KFW8G16Q2M,
55 Mux: KFM2G16Q2M, KFN4G16Q2M,
56
57 And more recent chips
58
59config MTD_ONENAND_SIM
60 tristate "OneNAND simulator support"
61 depends on MTD_PARTITIONS
62 help
63 The simulator may simulate various OneNAND flash chips for the
64 OneNAND MTD layer.
65
43endif # MTD_ONENAND 66endif # MTD_ONENAND
diff --git a/drivers/mtd/onenand/Makefile b/drivers/mtd/onenand/Makefile
index 269cfe467345..4d2eacfd7e11 100644
--- a/drivers/mtd/onenand/Makefile
+++ b/drivers/mtd/onenand/Makefile
@@ -8,4 +8,7 @@ obj-$(CONFIG_MTD_ONENAND) += onenand.o
8# Board specific. 8# Board specific.
9obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o 9obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o
10 10
11# Simulator
12obj-$(CONFIG_MTD_ONENAND_SIM) += onenand_sim.o
13
11onenand-objs = onenand_base.o onenand_bbt.o 14onenand-objs = onenand_base.o onenand_bbt.o
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 0537fac8de74..7d194cfdb873 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -206,6 +206,15 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
206 default: 206 default:
207 block = (int) (addr >> this->erase_shift); 207 block = (int) (addr >> this->erase_shift);
208 page = (int) (addr >> this->page_shift); 208 page = (int) (addr >> this->page_shift);
209
210 if (ONENAND_IS_2PLANE(this)) {
211 /* Make the even block number */
212 block &= ~1;
213 /* Is it the odd plane? */
214 if (addr & this->writesize)
215 block++;
216 page >>= 1;
217 }
209 page &= this->page_mask; 218 page &= this->page_mask;
210 break; 219 break;
211 } 220 }
@@ -216,8 +225,12 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
216 value = onenand_bufferram_address(this, block); 225 value = onenand_bufferram_address(this, block);
217 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2); 226 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
218 227
219 /* Switch to the next data buffer */ 228 if (ONENAND_IS_2PLANE(this))
220 ONENAND_SET_NEXT_BUFFERRAM(this); 229 /* It is always BufferRAM0 */
230 ONENAND_SET_BUFFERRAM0(this);
231 else
232 /* Switch to the next data buffer */
233 ONENAND_SET_NEXT_BUFFERRAM(this);
221 234
222 return 0; 235 return 0;
223 } 236 }
@@ -247,6 +260,8 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
247 break; 260 break;
248 261
249 default: 262 default:
263 if (ONENAND_IS_2PLANE(this) && cmd == ONENAND_CMD_PROG)
264 cmd = ONENAND_CMD_2X_PROG;
250 dataram = ONENAND_CURRENT_BUFFERRAM(this); 265 dataram = ONENAND_CURRENT_BUFFERRAM(this);
251 break; 266 break;
252 } 267 }
@@ -445,8 +460,9 @@ static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area)
445 struct onenand_chip *this = mtd->priv; 460 struct onenand_chip *this = mtd->priv;
446 461
447 if (ONENAND_CURRENT_BUFFERRAM(this)) { 462 if (ONENAND_CURRENT_BUFFERRAM(this)) {
463 /* Note: the 'this->writesize' is a real page size */
448 if (area == ONENAND_DATARAM) 464 if (area == ONENAND_DATARAM)
449 return mtd->writesize; 465 return this->writesize;
450 if (area == ONENAND_SPARERAM) 466 if (area == ONENAND_SPARERAM)
451 return mtd->oobsize; 467 return mtd->oobsize;
452 } 468 }
@@ -572,6 +588,30 @@ static int onenand_write_bufferram(struct mtd_info *mtd, int area,
572} 588}
573 589
574/** 590/**
591 * onenand_get_2x_blockpage - [GENERIC] Get blockpage at 2x program mode
592 * @param mtd MTD data structure
593 * @param addr address to check
594 * @return blockpage address
595 *
596 * Get blockpage address at 2x program mode
597 */
598static int onenand_get_2x_blockpage(struct mtd_info *mtd, loff_t addr)
599{
600 struct onenand_chip *this = mtd->priv;
601 int blockpage, block, page;
602
603 /* Calculate the even block number */
604 block = (int) (addr >> this->erase_shift) & ~1;
605 /* Is it the odd plane? */
606 if (addr & this->writesize)
607 block++;
608 page = (int) (addr >> (this->page_shift + 1)) & this->page_mask;
609 blockpage = (block << 7) | page;
610
611 return blockpage;
612}
613
614/**
575 * onenand_check_bufferram - [GENERIC] Check BufferRAM information 615 * onenand_check_bufferram - [GENERIC] Check BufferRAM information
576 * @param mtd MTD data structure 616 * @param mtd MTD data structure
577 * @param addr address to check 617 * @param addr address to check
@@ -585,7 +625,10 @@ static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
585 int blockpage, found = 0; 625 int blockpage, found = 0;
586 unsigned int i; 626 unsigned int i;
587 627
588 blockpage = (int) (addr >> this->page_shift); 628 if (ONENAND_IS_2PLANE(this))
629 blockpage = onenand_get_2x_blockpage(mtd, addr);
630 else
631 blockpage = (int) (addr >> this->page_shift);
589 632
590 /* Is there valid data? */ 633 /* Is there valid data? */
591 i = ONENAND_CURRENT_BUFFERRAM(this); 634 i = ONENAND_CURRENT_BUFFERRAM(this);
@@ -625,7 +668,10 @@ static void onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,
625 int blockpage; 668 int blockpage;
626 unsigned int i; 669 unsigned int i;
627 670
628 blockpage = (int) (addr >> this->page_shift); 671 if (ONENAND_IS_2PLANE(this))
672 blockpage = onenand_get_2x_blockpage(mtd, addr);
673 else
674 blockpage = (int) (addr >> this->page_shift);
629 675
630 /* Invalidate another BufferRAM */ 676 /* Invalidate another BufferRAM */
631 i = ONENAND_NEXT_BUFFERRAM(this); 677 i = ONENAND_NEXT_BUFFERRAM(this);
@@ -734,6 +780,7 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
734 int read = 0, column; 780 int read = 0, column;
735 int thislen; 781 int thislen;
736 int ret = 0, boundary = 0; 782 int ret = 0, boundary = 0;
783 int writesize = this->writesize;
737 784
738 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); 785 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
739 786
@@ -754,22 +801,22 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
754 /* Do first load to bufferRAM */ 801 /* Do first load to bufferRAM */
755 if (read < len) { 802 if (read < len) {
756 if (!onenand_check_bufferram(mtd, from)) { 803 if (!onenand_check_bufferram(mtd, from)) {
757 this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize); 804 this->command(mtd, ONENAND_CMD_READ, from, writesize);
758 ret = this->wait(mtd, FL_READING); 805 ret = this->wait(mtd, FL_READING);
759 onenand_update_bufferram(mtd, from, !ret); 806 onenand_update_bufferram(mtd, from, !ret);
760 } 807 }
761 } 808 }
762 809
763 thislen = min_t(int, mtd->writesize, len - read); 810 thislen = min_t(int, writesize, len - read);
764 column = from & (mtd->writesize - 1); 811 column = from & (writesize - 1);
765 if (column + thislen > mtd->writesize) 812 if (column + thislen > writesize)
766 thislen = mtd->writesize - column; 813 thislen = writesize - column;
767 814
768 while (!ret) { 815 while (!ret) {
769 /* If there is more to load then start next load */ 816 /* If there is more to load then start next load */
770 from += thislen; 817 from += thislen;
771 if (read + thislen < len) { 818 if (read + thislen < len) {
772 this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize); 819 this->command(mtd, ONENAND_CMD_READ, from, writesize);
773 /* 820 /*
774 * Chip boundary handling in DDP 821 * Chip boundary handling in DDP
775 * Now we issued chip 1 read and pointed chip 1 822 * Now we issued chip 1 read and pointed chip 1
@@ -794,7 +841,7 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
794 this->write_word(ONENAND_DDP_CHIP1, this->base + ONENAND_REG_START_ADDRESS2); 841 this->write_word(ONENAND_DDP_CHIP1, this->base + ONENAND_REG_START_ADDRESS2);
795 ONENAND_SET_NEXT_BUFFERRAM(this); 842 ONENAND_SET_NEXT_BUFFERRAM(this);
796 buf += thislen; 843 buf += thislen;
797 thislen = min_t(int, mtd->writesize, len - read); 844 thislen = min_t(int, writesize, len - read);
798 column = 0; 845 column = 0;
799 cond_resched(); 846 cond_resched();
800 /* Now wait for load */ 847 /* Now wait for load */
@@ -1079,7 +1126,7 @@ int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
1079 /* Read more? */ 1126 /* Read more? */
1080 if (read < len) { 1127 if (read < len) {
1081 /* Update Page size */ 1128 /* Update Page size */
1082 from += mtd->writesize; 1129 from += this->writesize;
1083 column = 0; 1130 column = 0;
1084 } 1131 }
1085 } 1132 }
@@ -1135,12 +1182,12 @@ static int onenand_verify(struct mtd_info *mtd, const u_char *buf, loff_t addr,
1135 int thislen, column; 1182 int thislen, column;
1136 1183
1137 while (len != 0) { 1184 while (len != 0) {
1138 thislen = min_t(int, mtd->writesize, len); 1185 thislen = min_t(int, this->writesize, len);
1139 column = addr & (mtd->writesize - 1); 1186 column = addr & (this->writesize - 1);
1140 if (column + thislen > mtd->writesize) 1187 if (column + thislen > this->writesize)
1141 thislen = mtd->writesize - column; 1188 thislen = this->writesize - column;
1142 1189
1143 this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize); 1190 this->command(mtd, ONENAND_CMD_READ, addr, this->writesize);
1144 1191
1145 onenand_update_bufferram(mtd, addr, 0); 1192 onenand_update_bufferram(mtd, addr, 0);
1146 1193
@@ -1236,6 +1283,10 @@ static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
1236 1283
1237 /* In partial page write we don't update bufferram */ 1284 /* In partial page write we don't update bufferram */
1238 onenand_update_bufferram(mtd, to, !ret && !subpage); 1285 onenand_update_bufferram(mtd, to, !ret && !subpage);
1286 if (ONENAND_IS_2PLANE(this)) {
1287 ONENAND_SET_BUFFERRAM1(this);
1288 onenand_update_bufferram(mtd, to + this->writesize, !ret && !subpage);
1289 }
1239 1290
1240 if (ret) { 1291 if (ret) {
1241 printk(KERN_ERR "onenand_write: write filaed %d\n", ret); 1292 printk(KERN_ERR "onenand_write: write filaed %d\n", ret);
@@ -1384,6 +1435,10 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
1384 this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize); 1435 this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
1385 1436
1386 onenand_update_bufferram(mtd, to, 0); 1437 onenand_update_bufferram(mtd, to, 0);
1438 if (ONENAND_IS_2PLANE(this)) {
1439 ONENAND_SET_BUFFERRAM1(this);
1440 onenand_update_bufferram(mtd, to + this->writesize, 0);
1441 }
1387 1442
1388 ret = this->wait(mtd, FL_WRITING); 1443 ret = this->wait(mtd, FL_WRITING);
1389 if (ret) { 1444 if (ret) {
@@ -2107,6 +2162,7 @@ static int onenand_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
2107 * 2162 *
2108 * Check and set OneNAND features 2163 * Check and set OneNAND features
2109 * - lock scheme 2164 * - lock scheme
2165 * - two plane
2110 */ 2166 */
2111static void onenand_check_features(struct mtd_info *mtd) 2167static void onenand_check_features(struct mtd_info *mtd)
2112{ 2168{
@@ -2118,19 +2174,35 @@ static void onenand_check_features(struct mtd_info *mtd)
2118 process = this->version_id >> ONENAND_VERSION_PROCESS_SHIFT; 2174 process = this->version_id >> ONENAND_VERSION_PROCESS_SHIFT;
2119 2175
2120 /* Lock scheme */ 2176 /* Lock scheme */
2121 if (density >= ONENAND_DEVICE_DENSITY_1Gb) { 2177 switch (density) {
2178 case ONENAND_DEVICE_DENSITY_4Gb:
2179 this->options |= ONENAND_HAS_2PLANE;
2180
2181 case ONENAND_DEVICE_DENSITY_2Gb:
2182 /* 2Gb DDP don't have 2 plane */
2183 if (!ONENAND_IS_DDP(this))
2184 this->options |= ONENAND_HAS_2PLANE;
2185 this->options |= ONENAND_HAS_UNLOCK_ALL;
2186
2187 case ONENAND_DEVICE_DENSITY_1Gb:
2122 /* A-Die has all block unlock */ 2188 /* A-Die has all block unlock */
2123 if (process) { 2189 if (process)
2124 printk(KERN_DEBUG "Chip support all block unlock\n");
2125 this->options |= ONENAND_HAS_UNLOCK_ALL; 2190 this->options |= ONENAND_HAS_UNLOCK_ALL;
2126 } 2191 break;
2127 } else { 2192
2128 /* Some OneNAND has continues lock scheme */ 2193 default:
2129 if (!process) { 2194 /* Some OneNAND has continuous lock scheme */
2130 printk(KERN_DEBUG "Lock scheme is Continues Lock\n"); 2195 if (!process)
2131 this->options |= ONENAND_HAS_CONT_LOCK; 2196 this->options |= ONENAND_HAS_CONT_LOCK;
2132 } 2197 break;
2133 } 2198 }
2199
2200 if (this->options & ONENAND_HAS_CONT_LOCK)
2201 printk(KERN_DEBUG "Lock scheme is Continuous Lock\n");
2202 if (this->options & ONENAND_HAS_UNLOCK_ALL)
2203 printk(KERN_DEBUG "Chip support all block unlock\n");
2204 if (this->options & ONENAND_HAS_2PLANE)
2205 printk(KERN_DEBUG "Chip has 2 plane\n");
2134} 2206}
2135 2207
2136/** 2208/**
@@ -2257,6 +2329,8 @@ static int onenand_probe(struct mtd_info *mtd)
2257 this->erase_shift = ffs(mtd->erasesize) - 1; 2329 this->erase_shift = ffs(mtd->erasesize) - 1;
2258 this->page_shift = ffs(mtd->writesize) - 1; 2330 this->page_shift = ffs(mtd->writesize) - 1;
2259 this->page_mask = (1 << (this->erase_shift - this->page_shift)) - 1; 2331 this->page_mask = (1 << (this->erase_shift - this->page_shift)) - 1;
2332 /* It's real page size */
2333 this->writesize = mtd->writesize;
2260 2334
2261 /* REVIST: Multichip handling */ 2335 /* REVIST: Multichip handling */
2262 2336
@@ -2265,6 +2339,17 @@ static int onenand_probe(struct mtd_info *mtd)
2265 /* Check OneNAND features */ 2339 /* Check OneNAND features */
2266 onenand_check_features(mtd); 2340 onenand_check_features(mtd);
2267 2341
2342 /*
2343 * We emulate the 4KiB page and 256KiB erase block size
2344 * But oobsize is still 64 bytes.
2345 * It is only valid if you turn on 2X program support,
2346 * Otherwise it will be ignored by compiler.
2347 */
2348 if (ONENAND_IS_2PLANE(this)) {
2349 mtd->writesize <<= 1;
2350 mtd->erasesize <<= 1;
2351 }
2352
2268 return 0; 2353 return 0;
2269} 2354}
2270 2355
diff --git a/drivers/mtd/onenand/onenand_sim.c b/drivers/mtd/onenand/onenand_sim.c
new file mode 100644
index 000000000000..0d89ad5776fa
--- /dev/null
+++ b/drivers/mtd/onenand/onenand_sim.c
@@ -0,0 +1,495 @@
1/*
2 * linux/drivers/mtd/onenand/onenand_sim.c
3 *
4 * The OneNAND simulator
5 *
6 * Copyright © 2005-2007 Samsung Electronics
7 * Kyungmin Park <kyungmin.park@samsung.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/vmalloc.h>
18#include <linux/mtd/mtd.h>
19#include <linux/mtd/partitions.h>
20#include <linux/mtd/onenand.h>
21
22#include <linux/io.h>
23
24#ifndef CONFIG_ONENAND_SIM_MANUFACTURER
25#define CONFIG_ONENAND_SIM_MANUFACTURER 0xec
26#endif
27#ifndef CONFIG_ONENAND_SIM_DEVICE_ID
28#define CONFIG_ONENAND_SIM_DEVICE_ID 0x04
29#endif
30#ifndef CONFIG_ONENAND_SIM_VERSION_ID
31#define CONFIG_ONENAND_SIM_VERSION_ID 0x1e
32#endif
33
34static int manuf_id = CONFIG_ONENAND_SIM_MANUFACTURER;
35static int device_id = CONFIG_ONENAND_SIM_DEVICE_ID;
36static int version_id = CONFIG_ONENAND_SIM_VERSION_ID;
37
38struct onenand_flash {
39 void __iomem *base;
40 void __iomem *data;
41};
42
43#define ONENAND_CORE(flash) (flash->data)
44#define ONENAND_CORE_SPARE(flash, this, offset) \
45 ((flash->data) + (this->chipsize) + (offset >> 5))
46
47#define ONENAND_MAIN_AREA(this, offset) \
48 (this->base + ONENAND_DATARAM + offset)
49
50#define ONENAND_SPARE_AREA(this, offset) \
51 (this->base + ONENAND_SPARERAM + offset)
52
53#define ONENAND_GET_WP_STATUS(this) \
54 (readw(this->base + ONENAND_REG_WP_STATUS))
55
56#define ONENAND_SET_WP_STATUS(v, this) \
57 (writew(v, this->base + ONENAND_REG_WP_STATUS))
58
59/* It has all 0xff chars */
60#define MAX_ONENAND_PAGESIZE (2048 + 64)
61static unsigned char *ffchars;
62
63static struct mtd_partition os_partitions[] = {
64 {
65 .name = "OneNAND simulator partition",
66 .offset = 0,
67 .size = MTDPART_SIZ_FULL,
68 },
69};
70
71/*
72 * OneNAND simulator mtd
73 */
74struct onenand_info {
75 struct mtd_info mtd;
76 struct mtd_partition *parts;
77 struct onenand_chip onenand;
78 struct onenand_flash flash;
79};
80
81static struct onenand_info *info;
82
83#define DPRINTK(format, args...) \
84do { \
85 printk(KERN_DEBUG "%s[%d]: " format "\n", __func__, \
86 __LINE__, ##args); \
87} while (0)
88
89/**
90 * onenand_lock_handle - Handle Lock scheme
91 * @param this OneNAND device structure
92 * @param cmd The command to be sent
93 *
94 * Send lock command to OneNAND device.
95 * The lock scheme is depends on chip type.
96 */
97static void onenand_lock_handle(struct onenand_chip *this, int cmd)
98{
99 int block_lock_scheme;
100 int status;
101
102 status = ONENAND_GET_WP_STATUS(this);
103 block_lock_scheme = !(this->options & ONENAND_HAS_CONT_LOCK);
104
105 switch (cmd) {
106 case ONENAND_CMD_UNLOCK:
107 if (block_lock_scheme)
108 ONENAND_SET_WP_STATUS(ONENAND_WP_US, this);
109 else
110 ONENAND_SET_WP_STATUS(status | ONENAND_WP_US, this);
111 break;
112
113 case ONENAND_CMD_LOCK:
114 if (block_lock_scheme)
115 ONENAND_SET_WP_STATUS(ONENAND_WP_LS, this);
116 else
117 ONENAND_SET_WP_STATUS(status | ONENAND_WP_LS, this);
118 break;
119
120 case ONENAND_CMD_LOCK_TIGHT:
121 if (block_lock_scheme)
122 ONENAND_SET_WP_STATUS(ONENAND_WP_LTS, this);
123 else
124 ONENAND_SET_WP_STATUS(status | ONENAND_WP_LTS, this);
125 break;
126
127 default:
128 break;
129 }
130}
131
132/**
133 * onenand_bootram_handle - Handle BootRAM area
134 * @param this OneNAND device structure
135 * @param cmd The command to be sent
136 *
137 * Emulate BootRAM area. It is possible to do basic operation using BootRAM.
138 */
139static void onenand_bootram_handle(struct onenand_chip *this, int cmd)
140{
141 switch (cmd) {
142 case ONENAND_CMD_READID:
143 writew(manuf_id, this->base);
144 writew(device_id, this->base + 2);
145 writew(version_id, this->base + 4);
146 break;
147
148 default:
149 /* REVIST: Handle other commands */
150 break;
151 }
152}
153
154/**
155 * onenand_update_interrupt - Set interrupt register
156 * @param this OneNAND device structure
157 * @param cmd The command to be sent
158 *
159 * Update interrupt register. The status is depends on command.
160 */
161static void onenand_update_interrupt(struct onenand_chip *this, int cmd)
162{
163 int interrupt = ONENAND_INT_MASTER;
164
165 switch (cmd) {
166 case ONENAND_CMD_READ:
167 case ONENAND_CMD_READOOB:
168 interrupt |= ONENAND_INT_READ;
169 break;
170
171 case ONENAND_CMD_PROG:
172 case ONENAND_CMD_PROGOOB:
173 interrupt |= ONENAND_INT_WRITE;
174 break;
175
176 case ONENAND_CMD_ERASE:
177 interrupt |= ONENAND_INT_ERASE;
178 break;
179
180 case ONENAND_CMD_RESET:
181 interrupt |= ONENAND_INT_RESET;
182 break;
183
184 default:
185 break;
186 }
187
188 writew(interrupt, this->base + ONENAND_REG_INTERRUPT);
189}
190
191/**
192 * onenand_check_overwrite - Check over-write if happend
193 * @param dest The destination pointer
194 * @param src The source pointer
195 * @param count The length to be check
196 * @return 0 on same, otherwise 1
197 *
198 * Compare the source with destination
199 */
200static int onenand_check_overwrite(void *dest, void *src, size_t count)
201{
202 unsigned int *s = (unsigned int *) src;
203 unsigned int *d = (unsigned int *) dest;
204 int i;
205
206 count >>= 2;
207 for (i = 0; i < count; i++)
208 if ((*s++ ^ *d++) != 0)
209 return 1;
210
211 return 0;
212}
213
214/**
215 * onenand_data_handle - Handle OneNAND Core and DataRAM
216 * @param this OneNAND device structure
217 * @param cmd The command to be sent
218 * @param dataram Which dataram used
219 * @param offset The offset to OneNAND Core
220 *
221 * Copy data from OneNAND Core to DataRAM (read)
222 * Copy data from DataRAM to OneNAND Core (write)
223 * Erase the OneNAND Core (erase)
224 */
225static void onenand_data_handle(struct onenand_chip *this, int cmd,
226 int dataram, unsigned int offset)
227{
228 struct mtd_info *mtd = &info->mtd;
229 struct onenand_flash *flash = this->priv;
230 int main_offset, spare_offset;
231 void __iomem *src;
232 void __iomem *dest;
233 unsigned int i;
234
235 if (dataram) {
236 main_offset = mtd->writesize;
237 spare_offset = mtd->oobsize;
238 } else {
239 main_offset = 0;
240 spare_offset = 0;
241 }
242
243 switch (cmd) {
244 case ONENAND_CMD_READ:
245 src = ONENAND_CORE(flash) + offset;
246 dest = ONENAND_MAIN_AREA(this, main_offset);
247 memcpy(dest, src, mtd->writesize);
248 /* Fall through */
249
250 case ONENAND_CMD_READOOB:
251 src = ONENAND_CORE_SPARE(flash, this, offset);
252 dest = ONENAND_SPARE_AREA(this, spare_offset);
253 memcpy(dest, src, mtd->oobsize);
254 break;
255
256 case ONENAND_CMD_PROG:
257 src = ONENAND_MAIN_AREA(this, main_offset);
258 dest = ONENAND_CORE(flash) + offset;
259 /* To handle partial write */
260 for (i = 0; i < (1 << mtd->subpage_sft); i++) {
261 int off = i * this->subpagesize;
262 if (!memcmp(src + off, ffchars, this->subpagesize))
263 continue;
264 if (memcmp(dest + off, ffchars, this->subpagesize) &&
265 onenand_check_overwrite(dest + off, src + off, this->subpagesize))
266 printk(KERN_ERR "over-write happend at 0x%08x\n", offset);
267 memcpy(dest + off, src + off, this->subpagesize);
268 }
269 /* Fall through */
270
271 case ONENAND_CMD_PROGOOB:
272 src = ONENAND_SPARE_AREA(this, spare_offset);
273 /* Check all data is 0xff chars */
274 if (!memcmp(src, ffchars, mtd->oobsize))
275 break;
276
277 dest = ONENAND_CORE_SPARE(flash, this, offset);
278 if (memcmp(dest, ffchars, mtd->oobsize) &&
279 onenand_check_overwrite(dest, src, mtd->oobsize))
280 printk(KERN_ERR "OOB: over-write happend at 0x%08x\n",
281 offset);
282 memcpy(dest, src, mtd->oobsize);
283 break;
284
285 case ONENAND_CMD_ERASE:
286 memset(ONENAND_CORE(flash) + offset, 0xff, mtd->erasesize);
287 memset(ONENAND_CORE_SPARE(flash, this, offset), 0xff,
288 (mtd->erasesize >> 5));
289 break;
290
291 default:
292 break;
293 }
294}
295
296/**
297 * onenand_command_handle - Handle command
298 * @param this OneNAND device structure
299 * @param cmd The command to be sent
300 *
301 * Emulate OneNAND command.
302 */
303static void onenand_command_handle(struct onenand_chip *this, int cmd)
304{
305 unsigned long offset = 0;
306 int block = -1, page = -1, bufferram = -1;
307 int dataram = 0;
308
309 switch (cmd) {
310 case ONENAND_CMD_UNLOCK:
311 case ONENAND_CMD_LOCK:
312 case ONENAND_CMD_LOCK_TIGHT:
313 case ONENAND_CMD_UNLOCK_ALL:
314 onenand_lock_handle(this, cmd);
315 break;
316
317 case ONENAND_CMD_BUFFERRAM:
318 /* Do nothing */
319 return;
320
321 default:
322 block = (int) readw(this->base + ONENAND_REG_START_ADDRESS1);
323 if (block & (1 << ONENAND_DDP_SHIFT)) {
324 block &= ~(1 << ONENAND_DDP_SHIFT);
325 /* The half of chip block */
326 block += this->chipsize >> (this->erase_shift + 1);
327 }
328 if (cmd == ONENAND_CMD_ERASE)
329 break;
330
331 page = (int) readw(this->base + ONENAND_REG_START_ADDRESS8);
332 page = (page >> ONENAND_FPA_SHIFT);
333 bufferram = (int) readw(this->base + ONENAND_REG_START_BUFFER);
334 bufferram >>= ONENAND_BSA_SHIFT;
335 bufferram &= ONENAND_BSA_DATARAM1;
336 dataram = (bufferram == ONENAND_BSA_DATARAM1) ? 1 : 0;
337 break;
338 }
339
340 if (block != -1)
341 offset += block << this->erase_shift;
342
343 if (page != -1)
344 offset += page << this->page_shift;
345
346 onenand_data_handle(this, cmd, dataram, offset);
347
348 onenand_update_interrupt(this, cmd);
349}
350
351/**
352 * onenand_writew - [OneNAND Interface] Emulate write operation
353 * @param value value to write
354 * @param addr address to write
355 *
356 * Write OneNAND register with value
357 */
358static void onenand_writew(unsigned short value, void __iomem * addr)
359{
360 struct onenand_chip *this = info->mtd.priv;
361
362 /* BootRAM handling */
363 if (addr < this->base + ONENAND_DATARAM) {
364 onenand_bootram_handle(this, value);
365 return;
366 }
367 /* Command handling */
368 if (addr == this->base + ONENAND_REG_COMMAND)
369 onenand_command_handle(this, value);
370
371 writew(value, addr);
372}
373
374/**
375 * flash_init - Initialize OneNAND simulator
376 * @param flash OneNAND simulaotr data strucutres
377 *
378 * Initialize OneNAND simulator.
379 */
380static int __init flash_init(struct onenand_flash *flash)
381{
382 int density, size;
383 int buffer_size;
384
385 flash->base = kzalloc(131072, GFP_KERNEL);
386 if (!flash->base) {
387 printk(KERN_ERR "Unable to allocate base address.\n");
388 return -ENOMEM;
389 }
390
391 density = device_id >> ONENAND_DEVICE_DENSITY_SHIFT;
392 size = ((16 << 20) << density);
393
394 ONENAND_CORE(flash) = vmalloc(size + (size >> 5));
395 if (!ONENAND_CORE(flash)) {
396 printk(KERN_ERR "Unable to allocate nand core address.\n");
397 kfree(flash->base);
398 return -ENOMEM;
399 }
400
401 memset(ONENAND_CORE(flash), 0xff, size + (size >> 5));
402
403 /* Setup registers */
404 writew(manuf_id, flash->base + ONENAND_REG_MANUFACTURER_ID);
405 writew(device_id, flash->base + ONENAND_REG_DEVICE_ID);
406 writew(version_id, flash->base + ONENAND_REG_VERSION_ID);
407
408 if (density < 2)
409 buffer_size = 0x0400; /* 1KiB page */
410 else
411 buffer_size = 0x0800; /* 2KiB page */
412 writew(buffer_size, flash->base + ONENAND_REG_DATA_BUFFER_SIZE);
413
414 return 0;
415}
416
417/**
418 * flash_exit - Clean up OneNAND simulator
419 * @param flash OneNAND simulaotr data strucutres
420 *
421 * Clean up OneNAND simulator.
422 */
423static void flash_exit(struct onenand_flash *flash)
424{
425 vfree(ONENAND_CORE(flash));
426 kfree(flash->base);
427 kfree(flash);
428}
429
430static int __init onenand_sim_init(void)
431{
432 /* Allocate all 0xff chars pointer */
433 ffchars = kmalloc(MAX_ONENAND_PAGESIZE, GFP_KERNEL);
434 if (!ffchars) {
435 printk(KERN_ERR "Unable to allocate ff chars.\n");
436 return -ENOMEM;
437 }
438 memset(ffchars, 0xff, MAX_ONENAND_PAGESIZE);
439
440 /* Allocate OneNAND simulator mtd pointer */
441 info = kzalloc(sizeof(struct onenand_info), GFP_KERNEL);
442 if (!info) {
443 printk(KERN_ERR "Unable to allocate core structures.\n");
444 kfree(ffchars);
445 return -ENOMEM;
446 }
447
448 /* Override write_word function */
449 info->onenand.write_word = onenand_writew;
450
451 if (flash_init(&info->flash)) {
452 printk(KERN_ERR "Unable to allocat flash.\n");
453 kfree(ffchars);
454 kfree(info);
455 return -ENOMEM;
456 }
457
458 info->parts = os_partitions;
459
460 info->onenand.base = info->flash.base;
461 info->onenand.priv = &info->flash;
462
463 info->mtd.name = "OneNAND simulator";
464 info->mtd.priv = &info->onenand;
465 info->mtd.owner = THIS_MODULE;
466
467 if (onenand_scan(&info->mtd, 1)) {
468 flash_exit(&info->flash);
469 kfree(ffchars);
470 kfree(info);
471 return -ENXIO;
472 }
473
474 add_mtd_partitions(&info->mtd, info->parts, ARRAY_SIZE(os_partitions));
475
476 return 0;
477}
478
479static void __exit onenand_sim_exit(void)
480{
481 struct onenand_chip *this = info->mtd.priv;
482 struct onenand_flash *flash = this->priv;
483
484 onenand_release(&info->mtd);
485 flash_exit(flash);
486 kfree(ffchars);
487 kfree(info);
488}
489
490module_init(onenand_sim_init);
491module_exit(onenand_sim_exit);
492
493MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
494MODULE_DESCRIPTION("The OneNAND flash simulator");
495MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c
index 006c03aacb55..823fba4e6d2f 100644
--- a/drivers/mtd/rfd_ftl.c
+++ b/drivers/mtd/rfd_ftl.c
@@ -779,10 +779,8 @@ static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
779 else { 779 else {
780 if (!mtd->erasesize) { 780 if (!mtd->erasesize) {
781 printk(KERN_WARNING PREFIX "please provide block_size"); 781 printk(KERN_WARNING PREFIX "please provide block_size");
782 kfree(part); 782 goto out;
783 return; 783 } else
784 }
785 else
786 part->block_size = mtd->erasesize; 784 part->block_size = mtd->erasesize;
787 } 785 }
788 786
@@ -804,7 +802,7 @@ static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
804 if (!add_mtd_blktrans_dev((void*)part)) 802 if (!add_mtd_blktrans_dev((void*)part))
805 return; 803 return;
806 } 804 }
807 805out:
808 kfree(part); 806 kfree(part);
809} 807}
810 808
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c
index 94ee54934411..29c41eeb09fe 100644
--- a/drivers/mtd/ubi/scan.c
+++ b/drivers/mtd/ubi/scan.c
@@ -1314,11 +1314,10 @@ static int paranoid_check_si(const struct ubi_device *ubi,
1314 * Make sure that all the physical eraseblocks are in one of the lists 1314 * Make sure that all the physical eraseblocks are in one of the lists
1315 * or trees. 1315 * or trees.
1316 */ 1316 */
1317 buf = kmalloc(ubi->peb_count, GFP_KERNEL); 1317 buf = kzalloc(ubi->peb_count, GFP_KERNEL);
1318 if (!buf) 1318 if (!buf)
1319 return -ENOMEM; 1319 return -ENOMEM;
1320 1320
1321 memset(buf, 1, ubi->peb_count);
1322 for (pnum = 0; pnum < ubi->peb_count; pnum++) { 1321 for (pnum = 0; pnum < ubi->peb_count; pnum++) {
1323 err = ubi_io_is_bad(ubi, pnum); 1322 err = ubi_io_is_bad(ubi, pnum);
1324 if (err < 0) { 1323 if (err < 0) {
@@ -1326,28 +1325,28 @@ static int paranoid_check_si(const struct ubi_device *ubi,
1326 return err; 1325 return err;
1327 } 1326 }
1328 else if (err) 1327 else if (err)
1329 buf[pnum] = 0; 1328 buf[pnum] = 1;
1330 } 1329 }
1331 1330
1332 ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) 1331 ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb)
1333 ubi_rb_for_each_entry(rb2, seb, &sv->root, u.rb) 1332 ubi_rb_for_each_entry(rb2, seb, &sv->root, u.rb)
1334 buf[seb->pnum] = 0; 1333 buf[seb->pnum] = 1;
1335 1334
1336 list_for_each_entry(seb, &si->free, u.list) 1335 list_for_each_entry(seb, &si->free, u.list)
1337 buf[seb->pnum] = 0; 1336 buf[seb->pnum] = 1;
1338 1337
1339 list_for_each_entry(seb, &si->corr, u.list) 1338 list_for_each_entry(seb, &si->corr, u.list)
1340 buf[seb->pnum] = 0; 1339 buf[seb->pnum] = 1;
1341 1340
1342 list_for_each_entry(seb, &si->erase, u.list) 1341 list_for_each_entry(seb, &si->erase, u.list)
1343 buf[seb->pnum] = 0; 1342 buf[seb->pnum] = 1;
1344 1343
1345 list_for_each_entry(seb, &si->alien, u.list) 1344 list_for_each_entry(seb, &si->alien, u.list)
1346 buf[seb->pnum] = 0; 1345 buf[seb->pnum] = 1;
1347 1346
1348 err = 0; 1347 err = 0;
1349 for (pnum = 0; pnum < ubi->peb_count; pnum++) 1348 for (pnum = 0; pnum < ubi->peb_count; pnum++)
1350 if (buf[pnum]) { 1349 if (!buf[pnum]) {
1351 ubi_err("PEB %d is not referred", pnum); 1350 ubi_err("PEB %d is not referred", pnum);
1352 err = 1; 1351 err = 1;
1353 } 1352 }
diff --git a/fs/Kconfig b/fs/Kconfig
index 58a0650293e1..84fb8428c023 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -1228,6 +1228,14 @@ config JFFS2_FS_WRITEBUFFER
1228 - NOR flash with transparent ECC 1228 - NOR flash with transparent ECC
1229 - DataFlash 1229 - DataFlash
1230 1230
1231config JFFS2_FS_WBUF_VERIFY
1232 bool "Verify JFFS2 write-buffer reads"
1233 depends on JFFS2_FS_WRITEBUFFER
1234 default n
1235 help
1236 This causes JFFS2 to read back every page written through the
1237 write-buffer, and check for errors.
1238
1231config JFFS2_SUMMARY 1239config JFFS2_SUMMARY
1232 bool "JFFS2 summary support (EXPERIMENTAL)" 1240 bool "JFFS2 summary support (EXPERIMENTAL)"
1233 depends on JFFS2_FS && EXPERIMENTAL 1241 depends on JFFS2_FS && EXPERIMENTAL
@@ -1298,52 +1306,71 @@ config JFFS2_ZLIB
1298 select ZLIB_DEFLATE 1306 select ZLIB_DEFLATE
1299 depends on JFFS2_FS 1307 depends on JFFS2_FS
1300 default y 1308 default y
1301 help 1309 help
1302 Zlib is designed to be a free, general-purpose, legally unencumbered, 1310 Zlib is designed to be a free, general-purpose, legally unencumbered,
1303 lossless data-compression library for use on virtually any computer 1311 lossless data-compression library for use on virtually any computer
1304 hardware and operating system. See <http://www.gzip.org/zlib/> for 1312 hardware and operating system. See <http://www.gzip.org/zlib/> for
1305 further information. 1313 further information.
1306 1314
1307 Say 'Y' if unsure. 1315 Say 'Y' if unsure.
1316
1317config JFFS2_LZO
1318 bool "JFFS2 LZO compression support" if JFFS2_COMPRESSION_OPTIONS
1319 select LZO_COMPRESS
1320 select LZO_DECOMPRESS
1321 depends on JFFS2_FS
1322 default n
1323 help
1324 minilzo-based compression. Generally works better than Zlib.
1325
1326 This feature was added in July, 2007. Say 'N' if you need
1327 compatibility with older bootloaders or kernels.
1308 1328
1309config JFFS2_RTIME 1329config JFFS2_RTIME
1310 bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS 1330 bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS
1311 depends on JFFS2_FS 1331 depends on JFFS2_FS
1312 default y 1332 default y
1313 help 1333 help
1314 Rtime does manage to recompress already-compressed data. Say 'Y' if unsure. 1334 Rtime does manage to recompress already-compressed data. Say 'Y' if unsure.
1315 1335
1316config JFFS2_RUBIN 1336config JFFS2_RUBIN
1317 bool "JFFS2 RUBIN compression support" if JFFS2_COMPRESSION_OPTIONS 1337 bool "JFFS2 RUBIN compression support" if JFFS2_COMPRESSION_OPTIONS
1318 depends on JFFS2_FS 1338 depends on JFFS2_FS
1319 default n 1339 default n
1320 help 1340 help
1321 RUBINMIPS and DYNRUBIN compressors. Say 'N' if unsure. 1341 RUBINMIPS and DYNRUBIN compressors. Say 'N' if unsure.
1322 1342
1323choice 1343choice
1324 prompt "JFFS2 default compression mode" if JFFS2_COMPRESSION_OPTIONS 1344 prompt "JFFS2 default compression mode" if JFFS2_COMPRESSION_OPTIONS
1325 default JFFS2_CMODE_PRIORITY 1345 default JFFS2_CMODE_PRIORITY
1326 depends on JFFS2_FS 1346 depends on JFFS2_FS
1327 help 1347 help
1328 You can set here the default compression mode of JFFS2 from 1348 You can set here the default compression mode of JFFS2 from
1329 the available compression modes. Don't touch if unsure. 1349 the available compression modes. Don't touch if unsure.
1330 1350
1331config JFFS2_CMODE_NONE 1351config JFFS2_CMODE_NONE
1332 bool "no compression" 1352 bool "no compression"
1333 help 1353 help
1334 Uses no compression. 1354 Uses no compression.
1335 1355
1336config JFFS2_CMODE_PRIORITY 1356config JFFS2_CMODE_PRIORITY
1337 bool "priority" 1357 bool "priority"
1338 help 1358 help
1339 Tries the compressors in a predefined order and chooses the first 1359 Tries the compressors in a predefined order and chooses the first
1340 successful one. 1360 successful one.
1341 1361
1342config JFFS2_CMODE_SIZE 1362config JFFS2_CMODE_SIZE
1343 bool "size (EXPERIMENTAL)" 1363 bool "size (EXPERIMENTAL)"
1344 help 1364 help
1345 Tries all compressors and chooses the one which has the smallest 1365 Tries all compressors and chooses the one which has the smallest
1346 result. 1366 result.
1367
1368config JFFS2_CMODE_FAVOURLZO
1369 bool "Favour LZO"
1370 help
1371 Tries all compressors and chooses the one which has the smallest
1372 result but gives some preference to LZO (which has faster
1373 decompression) at the expense of size.
1347 1374
1348endchoice 1375endchoice
1349 1376
diff --git a/fs/jffs2/Makefile b/fs/jffs2/Makefile
index c32b241e3d91..60e5d49ca03e 100644
--- a/fs/jffs2/Makefile
+++ b/fs/jffs2/Makefile
@@ -17,4 +17,5 @@ jffs2-$(CONFIG_JFFS2_FS_POSIX_ACL) += acl.o
17jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rubin.o 17jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rubin.o
18jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o 18jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o
19jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o 19jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o
20jffs2-$(CONFIG_JFFS2_LZO) += compr_lzo.o
20jffs2-$(CONFIG_JFFS2_SUMMARY) += summary.o 21jffs2-$(CONFIG_JFFS2_SUMMARY) += summary.o
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c
index 65b3a1b5b88d..8ec9323e830a 100644
--- a/fs/jffs2/acl.c
+++ b/fs/jffs2/acl.c
@@ -176,7 +176,7 @@ static void jffs2_iset_acl(struct inode *inode, struct posix_acl **i_acl, struct
176 spin_unlock(&inode->i_lock); 176 spin_unlock(&inode->i_lock);
177} 177}
178 178
179static struct posix_acl *jffs2_get_acl(struct inode *inode, int type) 179struct posix_acl *jffs2_get_acl(struct inode *inode, int type)
180{ 180{
181 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); 181 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
182 struct posix_acl *acl; 182 struct posix_acl *acl;
@@ -247,8 +247,13 @@ static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
247 if (rc < 0) 247 if (rc < 0)
248 return rc; 248 return rc;
249 if (inode->i_mode != mode) { 249 if (inode->i_mode != mode) {
250 inode->i_mode = mode; 250 struct iattr attr;
251 jffs2_dirty_inode(inode); 251
252 attr.ia_valid = ATTR_MODE;
253 attr.ia_mode = mode;
254 rc = jffs2_do_setattr(inode, &attr);
255 if (rc < 0)
256 return rc;
252 } 257 }
253 if (rc == 0) 258 if (rc == 0)
254 acl = NULL; 259 acl = NULL;
@@ -307,22 +312,16 @@ int jffs2_permission(struct inode *inode, int mask, struct nameidata *nd)
307 return generic_permission(inode, mask, jffs2_check_acl); 312 return generic_permission(inode, mask, jffs2_check_acl);
308} 313}
309 314
310int jffs2_init_acl(struct inode *inode, struct inode *dir) 315int jffs2_init_acl(struct inode *inode, struct posix_acl *acl)
311{ 316{
312 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); 317 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
313 struct posix_acl *acl = NULL, *clone; 318 struct posix_acl *clone;
314 mode_t mode; 319 mode_t mode;
315 int rc = 0; 320 int rc = 0;
316 321
317 f->i_acl_access = JFFS2_ACL_NOT_CACHED; 322 f->i_acl_access = JFFS2_ACL_NOT_CACHED;
318 f->i_acl_default = JFFS2_ACL_NOT_CACHED; 323 f->i_acl_default = JFFS2_ACL_NOT_CACHED;
319 if (!S_ISLNK(inode->i_mode)) { 324
320 acl = jffs2_get_acl(dir, ACL_TYPE_DEFAULT);
321 if (IS_ERR(acl))
322 return PTR_ERR(acl);
323 if (!acl)
324 inode->i_mode &= ~current->fs->umask;
325 }
326 if (acl) { 325 if (acl) {
327 if (S_ISDIR(inode->i_mode)) { 326 if (S_ISDIR(inode->i_mode)) {
328 rc = jffs2_set_acl(inode, ACL_TYPE_DEFAULT, acl); 327 rc = jffs2_set_acl(inode, ACL_TYPE_DEFAULT, acl);
diff --git a/fs/jffs2/acl.h b/fs/jffs2/acl.h
index c84378cee82a..90a2dbf59051 100644
--- a/fs/jffs2/acl.h
+++ b/fs/jffs2/acl.h
@@ -28,9 +28,10 @@ struct jffs2_acl_header {
28 28
29#define JFFS2_ACL_NOT_CACHED ((void *)-1) 29#define JFFS2_ACL_NOT_CACHED ((void *)-1)
30 30
31extern struct posix_acl *jffs2_get_acl(struct inode *inode, int type);
31extern int jffs2_permission(struct inode *, int, struct nameidata *); 32extern int jffs2_permission(struct inode *, int, struct nameidata *);
32extern int jffs2_acl_chmod(struct inode *); 33extern int jffs2_acl_chmod(struct inode *);
33extern int jffs2_init_acl(struct inode *, struct inode *); 34extern int jffs2_init_acl(struct inode *, struct posix_acl *);
34extern void jffs2_clear_acl(struct jffs2_inode_info *); 35extern void jffs2_clear_acl(struct jffs2_inode_info *);
35 36
36extern struct xattr_handler jffs2_acl_access_xattr_handler; 37extern struct xattr_handler jffs2_acl_access_xattr_handler;
@@ -38,6 +39,7 @@ extern struct xattr_handler jffs2_acl_default_xattr_handler;
38 39
39#else 40#else
40 41
42#define jffs2_get_acl(inode, type) (NULL)
41#define jffs2_permission NULL 43#define jffs2_permission NULL
42#define jffs2_acl_chmod(inode) (0) 44#define jffs2_acl_chmod(inode) (0)
43#define jffs2_init_acl(inode,dir) (0) 45#define jffs2_init_acl(inode,dir) (0)
diff --git a/fs/jffs2/background.c b/fs/jffs2/background.c
index 504643f2e98b..d568ae846741 100644
--- a/fs/jffs2/background.c
+++ b/fs/jffs2/background.c
@@ -23,8 +23,8 @@ static int jffs2_garbage_collect_thread(void *);
23void jffs2_garbage_collect_trigger(struct jffs2_sb_info *c) 23void jffs2_garbage_collect_trigger(struct jffs2_sb_info *c)
24{ 24{
25 spin_lock(&c->erase_completion_lock); 25 spin_lock(&c->erase_completion_lock);
26 if (c->gc_task && jffs2_thread_should_wake(c)) 26 if (c->gc_task && jffs2_thread_should_wake(c))
27 send_sig(SIGHUP, c->gc_task, 1); 27 send_sig(SIGHUP, c->gc_task, 1);
28 spin_unlock(&c->erase_completion_lock); 28 spin_unlock(&c->erase_completion_lock);
29} 29}
30 30
diff --git a/fs/jffs2/compr.c b/fs/jffs2/compr.c
index 485d065de41f..86739ee53b37 100644
--- a/fs/jffs2/compr.c
+++ b/fs/jffs2/compr.c
@@ -5,7 +5,7 @@
5 * Created by Arjan van de Ven <arjanv@redhat.com> 5 * Created by Arjan van de Ven <arjanv@redhat.com>
6 * 6 *
7 * Copyright © 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>, 7 * Copyright © 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>,
8 * University of Szeged, Hungary 8 * University of Szeged, Hungary
9 * 9 *
10 * For licensing information, see the file 'LICENCE' in this directory. 10 * For licensing information, see the file 'LICENCE' in this directory.
11 * 11 *
@@ -24,6 +24,34 @@ static int jffs2_compression_mode = JFFS2_COMPR_MODE_PRIORITY;
24/* Statistics for blocks stored without compression */ 24/* Statistics for blocks stored without compression */
25static uint32_t none_stat_compr_blocks=0,none_stat_decompr_blocks=0,none_stat_compr_size=0; 25static uint32_t none_stat_compr_blocks=0,none_stat_decompr_blocks=0,none_stat_compr_size=0;
26 26
27
28/*
29 * Return 1 to use this compression
30 */
31static int jffs2_is_best_compression(struct jffs2_compressor *this,
32 struct jffs2_compressor *best, uint32_t size, uint32_t bestsize)
33{
34 switch (jffs2_compression_mode) {
35 case JFFS2_COMPR_MODE_SIZE:
36 if (bestsize > size)
37 return 1;
38 return 0;
39 case JFFS2_COMPR_MODE_FAVOURLZO:
40 if ((this->compr == JFFS2_COMPR_LZO) && (bestsize > size))
41 return 1;
42 if ((best->compr != JFFS2_COMPR_LZO) && (bestsize > size))
43 return 1;
44 if ((this->compr == JFFS2_COMPR_LZO) && (bestsize > (size * FAVOUR_LZO_PERCENT / 100)))
45 return 1;
46 if ((bestsize * FAVOUR_LZO_PERCENT / 100) > size)
47 return 1;
48
49 return 0;
50 }
51 /* Shouldn't happen */
52 return 0;
53}
54
27/* jffs2_compress: 55/* jffs2_compress:
28 * @data: Pointer to uncompressed data 56 * @data: Pointer to uncompressed data
29 * @cdata: Pointer to returned pointer to buffer for compressed data 57 * @cdata: Pointer to returned pointer to buffer for compressed data
@@ -43,121 +71,124 @@ static uint32_t none_stat_compr_blocks=0,none_stat_decompr_blocks=0,none_stat_co
43 * *datalen accordingly to show the amount of data which were compressed. 71 * *datalen accordingly to show the amount of data which were compressed.
44 */ 72 */
45uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 73uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
46 unsigned char *data_in, unsigned char **cpage_out, 74 unsigned char *data_in, unsigned char **cpage_out,
47 uint32_t *datalen, uint32_t *cdatalen) 75 uint32_t *datalen, uint32_t *cdatalen)
48{ 76{
49 int ret = JFFS2_COMPR_NONE; 77 int ret = JFFS2_COMPR_NONE;
50 int compr_ret; 78 int compr_ret;
51 struct jffs2_compressor *this, *best=NULL; 79 struct jffs2_compressor *this, *best=NULL;
52 unsigned char *output_buf = NULL, *tmp_buf; 80 unsigned char *output_buf = NULL, *tmp_buf;
53 uint32_t orig_slen, orig_dlen; 81 uint32_t orig_slen, orig_dlen;
54 uint32_t best_slen=0, best_dlen=0; 82 uint32_t best_slen=0, best_dlen=0;
55 83
56 switch (jffs2_compression_mode) { 84 switch (jffs2_compression_mode) {
57 case JFFS2_COMPR_MODE_NONE: 85 case JFFS2_COMPR_MODE_NONE:
58 break; 86 break;
59 case JFFS2_COMPR_MODE_PRIORITY: 87 case JFFS2_COMPR_MODE_PRIORITY:
60 output_buf = kmalloc(*cdatalen,GFP_KERNEL); 88 output_buf = kmalloc(*cdatalen,GFP_KERNEL);
61 if (!output_buf) { 89 if (!output_buf) {
62 printk(KERN_WARNING "JFFS2: No memory for compressor allocation. Compression failed.\n"); 90 printk(KERN_WARNING "JFFS2: No memory for compressor allocation. Compression failed.\n");
63 goto out; 91 goto out;
64 } 92 }
65 orig_slen = *datalen; 93 orig_slen = *datalen;
66 orig_dlen = *cdatalen; 94 orig_dlen = *cdatalen;
67 spin_lock(&jffs2_compressor_list_lock); 95 spin_lock(&jffs2_compressor_list_lock);
68 list_for_each_entry(this, &jffs2_compressor_list, list) { 96 list_for_each_entry(this, &jffs2_compressor_list, list) {
69 /* Skip decompress-only backwards-compatibility and disabled modules */ 97 /* Skip decompress-only backwards-compatibility and disabled modules */
70 if ((!this->compress)||(this->disabled)) 98 if ((!this->compress)||(this->disabled))
71 continue; 99 continue;
72 100
73 this->usecount++; 101 this->usecount++;
74 spin_unlock(&jffs2_compressor_list_lock); 102 spin_unlock(&jffs2_compressor_list_lock);
75 *datalen = orig_slen; 103 *datalen = orig_slen;
76 *cdatalen = orig_dlen; 104 *cdatalen = orig_dlen;
77 compr_ret = this->compress(data_in, output_buf, datalen, cdatalen, NULL); 105 compr_ret = this->compress(data_in, output_buf, datalen, cdatalen, NULL);
78 spin_lock(&jffs2_compressor_list_lock); 106 spin_lock(&jffs2_compressor_list_lock);
79 this->usecount--; 107 this->usecount--;
80 if (!compr_ret) { 108 if (!compr_ret) {
81 ret = this->compr; 109 ret = this->compr;
82 this->stat_compr_blocks++; 110 this->stat_compr_blocks++;
83 this->stat_compr_orig_size += *datalen; 111 this->stat_compr_orig_size += *datalen;
84 this->stat_compr_new_size += *cdatalen; 112 this->stat_compr_new_size += *cdatalen;
85 break; 113 break;
86 } 114 }
87 } 115 }
88 spin_unlock(&jffs2_compressor_list_lock); 116 spin_unlock(&jffs2_compressor_list_lock);
89 if (ret == JFFS2_COMPR_NONE) kfree(output_buf); 117 if (ret == JFFS2_COMPR_NONE)
90 break; 118 kfree(output_buf);
91 case JFFS2_COMPR_MODE_SIZE: 119 break;
92 orig_slen = *datalen; 120 case JFFS2_COMPR_MODE_SIZE:
93 orig_dlen = *cdatalen; 121 case JFFS2_COMPR_MODE_FAVOURLZO:
94 spin_lock(&jffs2_compressor_list_lock); 122 orig_slen = *datalen;
95 list_for_each_entry(this, &jffs2_compressor_list, list) { 123 orig_dlen = *cdatalen;
96 /* Skip decompress-only backwards-compatibility and disabled modules */ 124 spin_lock(&jffs2_compressor_list_lock);
97 if ((!this->compress)||(this->disabled)) 125 list_for_each_entry(this, &jffs2_compressor_list, list) {
98 continue; 126 /* Skip decompress-only backwards-compatibility and disabled modules */
99 /* Allocating memory for output buffer if necessary */ 127 if ((!this->compress)||(this->disabled))
100 if ((this->compr_buf_size<orig_dlen)&&(this->compr_buf)) { 128 continue;
101 spin_unlock(&jffs2_compressor_list_lock); 129 /* Allocating memory for output buffer if necessary */
102 kfree(this->compr_buf); 130 if ((this->compr_buf_size < orig_slen) && (this->compr_buf)) {
103 spin_lock(&jffs2_compressor_list_lock); 131 spin_unlock(&jffs2_compressor_list_lock);
104 this->compr_buf_size=0; 132 kfree(this->compr_buf);
105 this->compr_buf=NULL; 133 spin_lock(&jffs2_compressor_list_lock);
106 } 134 this->compr_buf_size=0;
107 if (!this->compr_buf) { 135 this->compr_buf=NULL;
108 spin_unlock(&jffs2_compressor_list_lock); 136 }
109 tmp_buf = kmalloc(orig_dlen,GFP_KERNEL); 137 if (!this->compr_buf) {
110 spin_lock(&jffs2_compressor_list_lock); 138 spin_unlock(&jffs2_compressor_list_lock);
111 if (!tmp_buf) { 139 tmp_buf = kmalloc(orig_slen, GFP_KERNEL);
112 printk(KERN_WARNING "JFFS2: No memory for compressor allocation. (%d bytes)\n",orig_dlen); 140 spin_lock(&jffs2_compressor_list_lock);
113 continue; 141 if (!tmp_buf) {
114 } 142 printk(KERN_WARNING "JFFS2: No memory for compressor allocation. (%d bytes)\n", orig_slen);
115 else { 143 continue;
116 this->compr_buf = tmp_buf; 144 }
117 this->compr_buf_size = orig_dlen; 145 else {
118 } 146 this->compr_buf = tmp_buf;
119 } 147 this->compr_buf_size = orig_slen;
120 this->usecount++; 148 }
121 spin_unlock(&jffs2_compressor_list_lock); 149 }
122 *datalen = orig_slen; 150 this->usecount++;
123 *cdatalen = orig_dlen; 151 spin_unlock(&jffs2_compressor_list_lock);
124 compr_ret = this->compress(data_in, this->compr_buf, datalen, cdatalen, NULL); 152 *datalen = orig_slen;
125 spin_lock(&jffs2_compressor_list_lock); 153 *cdatalen = orig_dlen;
126 this->usecount--; 154 compr_ret = this->compress(data_in, this->compr_buf, datalen, cdatalen, NULL);
127 if (!compr_ret) { 155 spin_lock(&jffs2_compressor_list_lock);
128 if ((!best_dlen)||(best_dlen>*cdatalen)) { 156 this->usecount--;
129 best_dlen = *cdatalen; 157 if (!compr_ret) {
130 best_slen = *datalen; 158 if (((!best_dlen) || jffs2_is_best_compression(this, best, *cdatalen, best_dlen))
131 best = this; 159 && (*cdatalen < *datalen)) {
132 } 160 best_dlen = *cdatalen;
133 } 161 best_slen = *datalen;
134 } 162 best = this;
135 if (best_dlen) { 163 }
136 *cdatalen = best_dlen; 164 }
137 *datalen = best_slen; 165 }
138 output_buf = best->compr_buf; 166 if (best_dlen) {
139 best->compr_buf = NULL; 167 *cdatalen = best_dlen;
140 best->compr_buf_size = 0; 168 *datalen = best_slen;
141 best->stat_compr_blocks++; 169 output_buf = best->compr_buf;
142 best->stat_compr_orig_size += best_slen; 170 best->compr_buf = NULL;
143 best->stat_compr_new_size += best_dlen; 171 best->compr_buf_size = 0;
144 ret = best->compr; 172 best->stat_compr_blocks++;
145 } 173 best->stat_compr_orig_size += best_slen;
146 spin_unlock(&jffs2_compressor_list_lock); 174 best->stat_compr_new_size += best_dlen;
147 break; 175 ret = best->compr;
148 default: 176 }
149 printk(KERN_ERR "JFFS2: unknow compression mode.\n"); 177 spin_unlock(&jffs2_compressor_list_lock);
150 } 178 break;
179 default:
180 printk(KERN_ERR "JFFS2: unknow compression mode.\n");
181 }
151 out: 182 out:
152 if (ret == JFFS2_COMPR_NONE) { 183 if (ret == JFFS2_COMPR_NONE) {
153 *cpage_out = data_in; 184 *cpage_out = data_in;
154 *datalen = *cdatalen; 185 *datalen = *cdatalen;
155 none_stat_compr_blocks++; 186 none_stat_compr_blocks++;
156 none_stat_compr_size += *datalen; 187 none_stat_compr_size += *datalen;
157 } 188 }
158 else { 189 else {
159 *cpage_out = output_buf; 190 *cpage_out = output_buf;
160 } 191 }
161 return ret; 192 return ret;
162} 193}
163 194
@@ -165,8 +196,8 @@ int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
165 uint16_t comprtype, unsigned char *cdata_in, 196 uint16_t comprtype, unsigned char *cdata_in,
166 unsigned char *data_out, uint32_t cdatalen, uint32_t datalen) 197 unsigned char *data_out, uint32_t cdatalen, uint32_t datalen)
167{ 198{
168 struct jffs2_compressor *this; 199 struct jffs2_compressor *this;
169 int ret; 200 int ret;
170 201
171 /* Older code had a bug where it would write non-zero 'usercompr' 202 /* Older code had a bug where it would write non-zero 'usercompr'
172 fields. Deal with it. */ 203 fields. Deal with it. */
@@ -177,32 +208,32 @@ int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
177 case JFFS2_COMPR_NONE: 208 case JFFS2_COMPR_NONE:
178 /* This should be special-cased elsewhere, but we might as well deal with it */ 209 /* This should be special-cased elsewhere, but we might as well deal with it */
179 memcpy(data_out, cdata_in, datalen); 210 memcpy(data_out, cdata_in, datalen);
180 none_stat_decompr_blocks++; 211 none_stat_decompr_blocks++;
181 break; 212 break;
182 case JFFS2_COMPR_ZERO: 213 case JFFS2_COMPR_ZERO:
183 memset(data_out, 0, datalen); 214 memset(data_out, 0, datalen);
184 break; 215 break;
185 default: 216 default:
186 spin_lock(&jffs2_compressor_list_lock); 217 spin_lock(&jffs2_compressor_list_lock);
187 list_for_each_entry(this, &jffs2_compressor_list, list) { 218 list_for_each_entry(this, &jffs2_compressor_list, list) {
188 if (comprtype == this->compr) { 219 if (comprtype == this->compr) {
189 this->usecount++; 220 this->usecount++;
190 spin_unlock(&jffs2_compressor_list_lock); 221 spin_unlock(&jffs2_compressor_list_lock);
191 ret = this->decompress(cdata_in, data_out, cdatalen, datalen, NULL); 222 ret = this->decompress(cdata_in, data_out, cdatalen, datalen, NULL);
192 spin_lock(&jffs2_compressor_list_lock); 223 spin_lock(&jffs2_compressor_list_lock);
193 if (ret) { 224 if (ret) {
194 printk(KERN_WARNING "Decompressor \"%s\" returned %d\n", this->name, ret); 225 printk(KERN_WARNING "Decompressor \"%s\" returned %d\n", this->name, ret);
195 } 226 }
196 else { 227 else {
197 this->stat_decompr_blocks++; 228 this->stat_decompr_blocks++;
198 } 229 }
199 this->usecount--; 230 this->usecount--;
200 spin_unlock(&jffs2_compressor_list_lock); 231 spin_unlock(&jffs2_compressor_list_lock);
201 return ret; 232 return ret;
202 } 233 }
203 } 234 }
204 printk(KERN_WARNING "JFFS2 compression type 0x%02x not available.\n", comprtype); 235 printk(KERN_WARNING "JFFS2 compression type 0x%02x not available.\n", comprtype);
205 spin_unlock(&jffs2_compressor_list_lock); 236 spin_unlock(&jffs2_compressor_list_lock);
206 return -EIO; 237 return -EIO;
207 } 238 }
208 return 0; 239 return 0;
@@ -210,108 +241,119 @@ int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
210 241
211int jffs2_register_compressor(struct jffs2_compressor *comp) 242int jffs2_register_compressor(struct jffs2_compressor *comp)
212{ 243{
213 struct jffs2_compressor *this; 244 struct jffs2_compressor *this;
214 245
215 if (!comp->name) { 246 if (!comp->name) {
216 printk(KERN_WARNING "NULL compressor name at registering JFFS2 compressor. Failed.\n"); 247 printk(KERN_WARNING "NULL compressor name at registering JFFS2 compressor. Failed.\n");
217 return -1; 248 return -1;
218 } 249 }
219 comp->compr_buf_size=0; 250 comp->compr_buf_size=0;
220 comp->compr_buf=NULL; 251 comp->compr_buf=NULL;
221 comp->usecount=0; 252 comp->usecount=0;
222 comp->stat_compr_orig_size=0; 253 comp->stat_compr_orig_size=0;
223 comp->stat_compr_new_size=0; 254 comp->stat_compr_new_size=0;
224 comp->stat_compr_blocks=0; 255 comp->stat_compr_blocks=0;
225 comp->stat_decompr_blocks=0; 256 comp->stat_decompr_blocks=0;
226 D1(printk(KERN_DEBUG "Registering JFFS2 compressor \"%s\"\n", comp->name)); 257 D1(printk(KERN_DEBUG "Registering JFFS2 compressor \"%s\"\n", comp->name));
227 258
228 spin_lock(&jffs2_compressor_list_lock); 259 spin_lock(&jffs2_compressor_list_lock);
229 260
230 list_for_each_entry(this, &jffs2_compressor_list, list) { 261 list_for_each_entry(this, &jffs2_compressor_list, list) {
231 if (this->priority < comp->priority) { 262 if (this->priority < comp->priority) {
232 list_add(&comp->list, this->list.prev); 263 list_add(&comp->list, this->list.prev);
233 goto out; 264 goto out;
234 } 265 }
235 } 266 }
236 list_add_tail(&comp->list, &jffs2_compressor_list); 267 list_add_tail(&comp->list, &jffs2_compressor_list);
237out: 268out:
238 D2(list_for_each_entry(this, &jffs2_compressor_list, list) { 269 D2(list_for_each_entry(this, &jffs2_compressor_list, list) {
239 printk(KERN_DEBUG "Compressor \"%s\", prio %d\n", this->name, this->priority); 270 printk(KERN_DEBUG "Compressor \"%s\", prio %d\n", this->name, this->priority);
240 }) 271 })
241 272
242 spin_unlock(&jffs2_compressor_list_lock); 273 spin_unlock(&jffs2_compressor_list_lock);
243 274
244 return 0; 275 return 0;
245} 276}
246 277
247int jffs2_unregister_compressor(struct jffs2_compressor *comp) 278int jffs2_unregister_compressor(struct jffs2_compressor *comp)
248{ 279{
249 D2(struct jffs2_compressor *this;) 280 D2(struct jffs2_compressor *this;)
250 281
251 D1(printk(KERN_DEBUG "Unregistering JFFS2 compressor \"%s\"\n", comp->name)); 282 D1(printk(KERN_DEBUG "Unregistering JFFS2 compressor \"%s\"\n", comp->name));
252 283
253 spin_lock(&jffs2_compressor_list_lock); 284 spin_lock(&jffs2_compressor_list_lock);
254 285
255 if (comp->usecount) { 286 if (comp->usecount) {
256 spin_unlock(&jffs2_compressor_list_lock); 287 spin_unlock(&jffs2_compressor_list_lock);
257 printk(KERN_WARNING "JFFS2: Compressor modul is in use. Unregister failed.\n"); 288 printk(KERN_WARNING "JFFS2: Compressor modul is in use. Unregister failed.\n");
258 return -1; 289 return -1;
259 } 290 }
260 list_del(&comp->list); 291 list_del(&comp->list);
261 292
262 D2(list_for_each_entry(this, &jffs2_compressor_list, list) { 293 D2(list_for_each_entry(this, &jffs2_compressor_list, list) {
263 printk(KERN_DEBUG "Compressor \"%s\", prio %d\n", this->name, this->priority); 294 printk(KERN_DEBUG "Compressor \"%s\", prio %d\n", this->name, this->priority);
264 }) 295 })
265 spin_unlock(&jffs2_compressor_list_lock); 296 spin_unlock(&jffs2_compressor_list_lock);
266 return 0; 297 return 0;
267} 298}
268 299
269void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig) 300void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig)
270{ 301{
271 if (orig != comprbuf) 302 if (orig != comprbuf)
272 kfree(comprbuf); 303 kfree(comprbuf);
273} 304}
274 305
275int __init jffs2_compressors_init(void) 306int __init jffs2_compressors_init(void)
276{ 307{
277/* Registering compressors */ 308/* Registering compressors */
278#ifdef CONFIG_JFFS2_ZLIB 309#ifdef CONFIG_JFFS2_ZLIB
279 jffs2_zlib_init(); 310 jffs2_zlib_init();
280#endif 311#endif
281#ifdef CONFIG_JFFS2_RTIME 312#ifdef CONFIG_JFFS2_RTIME
282 jffs2_rtime_init(); 313 jffs2_rtime_init();
283#endif 314#endif
284#ifdef CONFIG_JFFS2_RUBIN 315#ifdef CONFIG_JFFS2_RUBIN
285 jffs2_rubinmips_init(); 316 jffs2_rubinmips_init();
286 jffs2_dynrubin_init(); 317 jffs2_dynrubin_init();
318#endif
319#ifdef CONFIG_JFFS2_LZO
320 jffs2_lzo_init();
287#endif 321#endif
288/* Setting default compression mode */ 322/* Setting default compression mode */
289#ifdef CONFIG_JFFS2_CMODE_NONE 323#ifdef CONFIG_JFFS2_CMODE_NONE
290 jffs2_compression_mode = JFFS2_COMPR_MODE_NONE; 324 jffs2_compression_mode = JFFS2_COMPR_MODE_NONE;
291 D1(printk(KERN_INFO "JFFS2: default compression mode: none\n");) 325 D1(printk(KERN_INFO "JFFS2: default compression mode: none\n");)
292#else 326#else
293#ifdef CONFIG_JFFS2_CMODE_SIZE 327#ifdef CONFIG_JFFS2_CMODE_SIZE
294 jffs2_compression_mode = JFFS2_COMPR_MODE_SIZE; 328 jffs2_compression_mode = JFFS2_COMPR_MODE_SIZE;
295 D1(printk(KERN_INFO "JFFS2: default compression mode: size\n");) 329 D1(printk(KERN_INFO "JFFS2: default compression mode: size\n");)
330#else
331#ifdef CONFIG_JFFS2_CMODE_FAVOURLZO
332 jffs2_compression_mode = JFFS2_COMPR_MODE_FAVOURLZO;
333 D1(printk(KERN_INFO "JFFS2: default compression mode: favourlzo\n");)
296#else 334#else
297 D1(printk(KERN_INFO "JFFS2: default compression mode: priority\n");) 335 D1(printk(KERN_INFO "JFFS2: default compression mode: priority\n");)
336#endif
298#endif 337#endif
299#endif 338#endif
300 return 0; 339 return 0;
301} 340}
302 341
303int jffs2_compressors_exit(void) 342int jffs2_compressors_exit(void)
304{ 343{
305/* Unregistering compressors */ 344/* Unregistering compressors */
345#ifdef CONFIG_JFFS2_LZO
346 jffs2_lzo_exit();
347#endif
306#ifdef CONFIG_JFFS2_RUBIN 348#ifdef CONFIG_JFFS2_RUBIN
307 jffs2_dynrubin_exit(); 349 jffs2_dynrubin_exit();
308 jffs2_rubinmips_exit(); 350 jffs2_rubinmips_exit();
309#endif 351#endif
310#ifdef CONFIG_JFFS2_RTIME 352#ifdef CONFIG_JFFS2_RTIME
311 jffs2_rtime_exit(); 353 jffs2_rtime_exit();
312#endif 354#endif
313#ifdef CONFIG_JFFS2_ZLIB 355#ifdef CONFIG_JFFS2_ZLIB
314 jffs2_zlib_exit(); 356 jffs2_zlib_exit();
315#endif 357#endif
316 return 0; 358 return 0;
317} 359}
diff --git a/fs/jffs2/compr.h b/fs/jffs2/compr.h
index 68cc7010dbdf..7d1d72faa774 100644
--- a/fs/jffs2/compr.h
+++ b/fs/jffs2/compr.h
@@ -2,7 +2,7 @@
2 * JFFS2 -- Journalling Flash File System, Version 2. 2 * JFFS2 -- Journalling Flash File System, Version 2.
3 * 3 *
4 * Copyright © 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>, 4 * Copyright © 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>,
5 * University of Szeged, Hungary 5 * University of Szeged, Hungary
6 * 6 *
7 * For licensing information, see the file 'LICENCE' in this directory. 7 * For licensing information, see the file 'LICENCE' in this directory.
8 * 8 *
@@ -27,34 +27,38 @@
27#define JFFS2_RUBINMIPS_PRIORITY 10 27#define JFFS2_RUBINMIPS_PRIORITY 10
28#define JFFS2_DYNRUBIN_PRIORITY 20 28#define JFFS2_DYNRUBIN_PRIORITY 20
29#define JFFS2_LZARI_PRIORITY 30 29#define JFFS2_LZARI_PRIORITY 30
30#define JFFS2_LZO_PRIORITY 40
31#define JFFS2_RTIME_PRIORITY 50 30#define JFFS2_RTIME_PRIORITY 50
32#define JFFS2_ZLIB_PRIORITY 60 31#define JFFS2_ZLIB_PRIORITY 60
32#define JFFS2_LZO_PRIORITY 80
33
33 34
34#define JFFS2_RUBINMIPS_DISABLED /* RUBINs will be used only */ 35#define JFFS2_RUBINMIPS_DISABLED /* RUBINs will be used only */
35#define JFFS2_DYNRUBIN_DISABLED /* for decompression */ 36#define JFFS2_DYNRUBIN_DISABLED /* for decompression */
36 37
37#define JFFS2_COMPR_MODE_NONE 0 38#define JFFS2_COMPR_MODE_NONE 0
38#define JFFS2_COMPR_MODE_PRIORITY 1 39#define JFFS2_COMPR_MODE_PRIORITY 1
39#define JFFS2_COMPR_MODE_SIZE 2 40#define JFFS2_COMPR_MODE_SIZE 2
41#define JFFS2_COMPR_MODE_FAVOURLZO 3
42
43#define FAVOUR_LZO_PERCENT 80
40 44
41struct jffs2_compressor { 45struct jffs2_compressor {
42 struct list_head list; 46 struct list_head list;
43 int priority; /* used by prirority comr. mode */ 47 int priority; /* used by prirority comr. mode */
44 char *name; 48 char *name;
45 char compr; /* JFFS2_COMPR_XXX */ 49 char compr; /* JFFS2_COMPR_XXX */
46 int (*compress)(unsigned char *data_in, unsigned char *cpage_out, 50 int (*compress)(unsigned char *data_in, unsigned char *cpage_out,
47 uint32_t *srclen, uint32_t *destlen, void *model); 51 uint32_t *srclen, uint32_t *destlen, void *model);
48 int (*decompress)(unsigned char *cdata_in, unsigned char *data_out, 52 int (*decompress)(unsigned char *cdata_in, unsigned char *data_out,
49 uint32_t cdatalen, uint32_t datalen, void *model); 53 uint32_t cdatalen, uint32_t datalen, void *model);
50 int usecount; 54 int usecount;
51 int disabled; /* if seted the compressor won't compress */ 55 int disabled; /* if set the compressor won't compress */
52 unsigned char *compr_buf; /* used by size compr. mode */ 56 unsigned char *compr_buf; /* used by size compr. mode */
53 uint32_t compr_buf_size; /* used by size compr. mode */ 57 uint32_t compr_buf_size; /* used by size compr. mode */
54 uint32_t stat_compr_orig_size; 58 uint32_t stat_compr_orig_size;
55 uint32_t stat_compr_new_size; 59 uint32_t stat_compr_new_size;
56 uint32_t stat_compr_blocks; 60 uint32_t stat_compr_blocks;
57 uint32_t stat_decompr_blocks; 61 uint32_t stat_decompr_blocks;
58}; 62};
59 63
60int jffs2_register_compressor(struct jffs2_compressor *comp); 64int jffs2_register_compressor(struct jffs2_compressor *comp);
@@ -64,12 +68,12 @@ int jffs2_compressors_init(void);
64int jffs2_compressors_exit(void); 68int jffs2_compressors_exit(void);
65 69
66uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 70uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
67 unsigned char *data_in, unsigned char **cpage_out, 71 unsigned char *data_in, unsigned char **cpage_out,
68 uint32_t *datalen, uint32_t *cdatalen); 72 uint32_t *datalen, uint32_t *cdatalen);
69 73
70int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 74int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
71 uint16_t comprtype, unsigned char *cdata_in, 75 uint16_t comprtype, unsigned char *cdata_in,
72 unsigned char *data_out, uint32_t cdatalen, uint32_t datalen); 76 unsigned char *data_out, uint32_t cdatalen, uint32_t datalen);
73 77
74void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig); 78void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig);
75 79
@@ -90,5 +94,9 @@ void jffs2_rtime_exit(void);
90int jffs2_zlib_init(void); 94int jffs2_zlib_init(void);
91void jffs2_zlib_exit(void); 95void jffs2_zlib_exit(void);
92#endif 96#endif
97#ifdef CONFIG_JFFS2_LZO
98int jffs2_lzo_init(void);
99void jffs2_lzo_exit(void);
100#endif
93 101
94#endif /* __JFFS2_COMPR_H__ */ 102#endif /* __JFFS2_COMPR_H__ */
diff --git a/fs/jffs2/compr_lzo.c b/fs/jffs2/compr_lzo.c
new file mode 100644
index 000000000000..47b045797e42
--- /dev/null
+++ b/fs/jffs2/compr_lzo.c
@@ -0,0 +1,108 @@
1/*
2 * JFFS2 -- Journalling Flash File System, Version 2.
3 *
4 * Copyright © 2007 Nokia Corporation. All rights reserved.
5 *
6 * Created by Richard Purdie <rpurdie@openedhand.com>
7 *
8 * For licensing information, see the file 'LICENCE' in this directory.
9 *
10 */
11
12#include <linux/kernel.h>
13#include <linux/sched.h>
14#include <linux/slab.h>
15#include <linux/vmalloc.h>
16#include <linux/init.h>
17#include <linux/lzo.h>
18#include "compr.h"
19
20static void *lzo_mem;
21static void *lzo_compress_buf;
22static DEFINE_MUTEX(deflate_mutex);
23
24static void free_workspace(void)
25{
26 vfree(lzo_mem);
27 vfree(lzo_compress_buf);
28}
29
30static int __init alloc_workspace(void)
31{
32 lzo_mem = vmalloc(LZO1X_MEM_COMPRESS);
33 lzo_compress_buf = vmalloc(lzo1x_worst_compress(PAGE_SIZE));
34
35 if (!lzo_mem || !lzo_compress_buf) {
36 printk(KERN_WARNING "Failed to allocate lzo deflate workspace\n");
37 free_workspace();
38 return -ENOMEM;
39 }
40
41 return 0;
42}
43
44static int jffs2_lzo_compress(unsigned char *data_in, unsigned char *cpage_out,
45 uint32_t *sourcelen, uint32_t *dstlen, void *model)
46{
47 size_t compress_size;
48 int ret;
49
50 mutex_lock(&deflate_mutex);
51 ret = lzo1x_1_compress(data_in, *sourcelen, lzo_compress_buf, &compress_size, lzo_mem);
52 mutex_unlock(&deflate_mutex);
53
54 if (ret != LZO_E_OK)
55 return -1;
56
57 if (compress_size > *dstlen)
58 return -1;
59
60 memcpy(cpage_out, lzo_compress_buf, compress_size);
61 *dstlen = compress_size;
62
63 return 0;
64}
65
66static int jffs2_lzo_decompress(unsigned char *data_in, unsigned char *cpage_out,
67 uint32_t srclen, uint32_t destlen, void *model)
68{
69 size_t dl = destlen;
70 int ret;
71
72 ret = lzo1x_decompress_safe(data_in, srclen, cpage_out, &dl);
73
74 if (ret != LZO_E_OK || dl != destlen)
75 return -1;
76
77 return 0;
78}
79
80static struct jffs2_compressor jffs2_lzo_comp = {
81 .priority = JFFS2_LZO_PRIORITY,
82 .name = "lzo",
83 .compr = JFFS2_COMPR_LZO,
84 .compress = &jffs2_lzo_compress,
85 .decompress = &jffs2_lzo_decompress,
86 .disabled = 0,
87};
88
89int __init jffs2_lzo_init(void)
90{
91 int ret;
92
93 ret = alloc_workspace();
94 if (ret < 0)
95 return ret;
96
97 ret = jffs2_register_compressor(&jffs2_lzo_comp);
98 if (ret)
99 free_workspace();
100
101 return ret;
102}
103
104void jffs2_lzo_exit(void)
105{
106 jffs2_unregister_compressor(&jffs2_lzo_comp);
107 free_workspace();
108}
diff --git a/fs/jffs2/compr_rtime.c b/fs/jffs2/compr_rtime.c
index 0d0bfd2e4e0d..546d1538d076 100644
--- a/fs/jffs2/compr_rtime.c
+++ b/fs/jffs2/compr_rtime.c
@@ -104,7 +104,7 @@ static int jffs2_rtime_decompress(unsigned char *data_in,
104 } 104 }
105 } 105 }
106 } 106 }
107 return 0; 107 return 0;
108} 108}
109 109
110static struct jffs2_compressor jffs2_rtime_comp = { 110static struct jffs2_compressor jffs2_rtime_comp = {
diff --git a/fs/jffs2/compr_rubin.c b/fs/jffs2/compr_rubin.c
index ea0431e047d5..c73fa89b5f8a 100644
--- a/fs/jffs2/compr_rubin.c
+++ b/fs/jffs2/compr_rubin.c
@@ -384,7 +384,7 @@ static int jffs2_rubinmips_decompress(unsigned char *data_in,
384 void *model) 384 void *model)
385{ 385{
386 rubin_do_decompress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen); 386 rubin_do_decompress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen);
387 return 0; 387 return 0;
388} 388}
389 389
390static int jffs2_dynrubin_decompress(unsigned char *data_in, 390static int jffs2_dynrubin_decompress(unsigned char *data_in,
@@ -399,7 +399,7 @@ static int jffs2_dynrubin_decompress(unsigned char *data_in,
399 bits[c] = data_in[c]; 399 bits[c] = data_in[c];
400 400
401 rubin_do_decompress(256, bits, data_in+8, cpage_out, sourcelen-8, dstlen); 401 rubin_do_decompress(256, bits, data_in+8, cpage_out, sourcelen-8, dstlen);
402 return 0; 402 return 0;
403} 403}
404 404
405static struct jffs2_compressor jffs2_rubinmips_comp = { 405static struct jffs2_compressor jffs2_rubinmips_comp = {
diff --git a/fs/jffs2/compr_zlib.c b/fs/jffs2/compr_zlib.c
index 2b87fccc1557..cfd301a5edfc 100644
--- a/fs/jffs2/compr_zlib.c
+++ b/fs/jffs2/compr_zlib.c
@@ -181,7 +181,7 @@ static int jffs2_zlib_decompress(unsigned char *data_in,
181 } 181 }
182 zlib_inflateEnd(&inf_strm); 182 zlib_inflateEnd(&inf_strm);
183 mutex_unlock(&inflate_mutex); 183 mutex_unlock(&inflate_mutex);
184 return 0; 184 return 0;
185} 185}
186 186
187static struct jffs2_compressor jffs2_zlib_comp = { 187static struct jffs2_compressor jffs2_zlib_comp = {
@@ -203,11 +203,11 @@ int __init jffs2_zlib_init(void)
203 203
204 ret = alloc_workspaces(); 204 ret = alloc_workspaces();
205 if (ret) 205 if (ret)
206 return ret; 206 return ret;
207 207
208 ret = jffs2_register_compressor(&jffs2_zlib_comp); 208 ret = jffs2_register_compressor(&jffs2_zlib_comp);
209 if (ret) 209 if (ret)
210 free_workspaces(); 210 free_workspaces();
211 211
212 return ret; 212 return ret;
213} 213}
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index c1dfca310dd6..8353eb9c1799 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -32,7 +32,7 @@ static int jffs2_mkdir (struct inode *,struct dentry *,int);
32static int jffs2_rmdir (struct inode *,struct dentry *); 32static int jffs2_rmdir (struct inode *,struct dentry *);
33static int jffs2_mknod (struct inode *,struct dentry *,int,dev_t); 33static int jffs2_mknod (struct inode *,struct dentry *,int,dev_t);
34static int jffs2_rename (struct inode *, struct dentry *, 34static int jffs2_rename (struct inode *, struct dentry *,
35 struct inode *, struct dentry *); 35 struct inode *, struct dentry *);
36 36
37const struct file_operations jffs2_dir_operations = 37const struct file_operations jffs2_dir_operations =
38{ 38{
@@ -182,6 +182,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode,
182 struct jffs2_inode_info *f, *dir_f; 182 struct jffs2_inode_info *f, *dir_f;
183 struct jffs2_sb_info *c; 183 struct jffs2_sb_info *c;
184 struct inode *inode; 184 struct inode *inode;
185 struct posix_acl *acl;
185 int ret; 186 int ret;
186 187
187 ri = jffs2_alloc_raw_inode(); 188 ri = jffs2_alloc_raw_inode();
@@ -192,7 +193,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode,
192 193
193 D1(printk(KERN_DEBUG "jffs2_create()\n")); 194 D1(printk(KERN_DEBUG "jffs2_create()\n"));
194 195
195 inode = jffs2_new_inode(dir_i, mode, ri); 196 inode = jffs2_new_inode(dir_i, mode, ri, &acl);
196 197
197 if (IS_ERR(inode)) { 198 if (IS_ERR(inode)) {
198 D1(printk(KERN_DEBUG "jffs2_new_inode() failed\n")); 199 D1(printk(KERN_DEBUG "jffs2_new_inode() failed\n"));
@@ -212,12 +213,12 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode,
212 dentry->d_name.name, dentry->d_name.len); 213 dentry->d_name.name, dentry->d_name.len);
213 214
214 if (ret) 215 if (ret)
215 goto fail; 216 goto fail_acl;
216 217
217 ret = jffs2_init_security(inode, dir_i); 218 ret = jffs2_init_security(inode, dir_i);
218 if (ret) 219 if (ret)
219 goto fail; 220 goto fail_acl;
220 ret = jffs2_init_acl(inode, dir_i); 221 ret = jffs2_init_acl(inode, acl);
221 if (ret) 222 if (ret)
222 goto fail; 223 goto fail;
223 224
@@ -230,6 +231,8 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode,
230 inode->i_ino, inode->i_mode, inode->i_nlink, f->inocache->nlink, inode->i_mapping->nrpages)); 231 inode->i_ino, inode->i_mode, inode->i_nlink, f->inocache->nlink, inode->i_mapping->nrpages));
231 return 0; 232 return 0;
232 233
234 fail_acl:
235 posix_acl_release(acl);
233 fail: 236 fail:
234 make_bad_inode(inode); 237 make_bad_inode(inode);
235 iput(inode); 238 iput(inode);
@@ -306,6 +309,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
306 struct jffs2_full_dirent *fd; 309 struct jffs2_full_dirent *fd;
307 int namelen; 310 int namelen;
308 uint32_t alloclen; 311 uint32_t alloclen;
312 struct posix_acl *acl;
309 int ret, targetlen = strlen(target); 313 int ret, targetlen = strlen(target);
310 314
311 /* FIXME: If you care. We'd need to use frags for the target 315 /* FIXME: If you care. We'd need to use frags for the target
@@ -332,7 +336,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
332 return ret; 336 return ret;
333 } 337 }
334 338
335 inode = jffs2_new_inode(dir_i, S_IFLNK | S_IRWXUGO, ri); 339 inode = jffs2_new_inode(dir_i, S_IFLNK | S_IRWXUGO, ri, &acl);
336 340
337 if (IS_ERR(inode)) { 341 if (IS_ERR(inode)) {
338 jffs2_free_raw_inode(ri); 342 jffs2_free_raw_inode(ri);
@@ -362,6 +366,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
362 up(&f->sem); 366 up(&f->sem);
363 jffs2_complete_reservation(c); 367 jffs2_complete_reservation(c);
364 jffs2_clear_inode(inode); 368 jffs2_clear_inode(inode);
369 posix_acl_release(acl);
365 return PTR_ERR(fn); 370 return PTR_ERR(fn);
366 } 371 }
367 372
@@ -372,6 +377,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
372 up(&f->sem); 377 up(&f->sem);
373 jffs2_complete_reservation(c); 378 jffs2_complete_reservation(c);
374 jffs2_clear_inode(inode); 379 jffs2_clear_inode(inode);
380 posix_acl_release(acl);
375 return -ENOMEM; 381 return -ENOMEM;
376 } 382 }
377 383
@@ -389,9 +395,10 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
389 ret = jffs2_init_security(inode, dir_i); 395 ret = jffs2_init_security(inode, dir_i);
390 if (ret) { 396 if (ret) {
391 jffs2_clear_inode(inode); 397 jffs2_clear_inode(inode);
398 posix_acl_release(acl);
392 return ret; 399 return ret;
393 } 400 }
394 ret = jffs2_init_acl(inode, dir_i); 401 ret = jffs2_init_acl(inode, acl);
395 if (ret) { 402 if (ret) {
396 jffs2_clear_inode(inode); 403 jffs2_clear_inode(inode);
397 return ret; 404 return ret;
@@ -469,6 +476,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
469 struct jffs2_full_dirent *fd; 476 struct jffs2_full_dirent *fd;
470 int namelen; 477 int namelen;
471 uint32_t alloclen; 478 uint32_t alloclen;
479 struct posix_acl *acl;
472 int ret; 480 int ret;
473 481
474 mode |= S_IFDIR; 482 mode |= S_IFDIR;
@@ -491,7 +499,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
491 return ret; 499 return ret;
492 } 500 }
493 501
494 inode = jffs2_new_inode(dir_i, mode, ri); 502 inode = jffs2_new_inode(dir_i, mode, ri, &acl);
495 503
496 if (IS_ERR(inode)) { 504 if (IS_ERR(inode)) {
497 jffs2_free_raw_inode(ri); 505 jffs2_free_raw_inode(ri);
@@ -518,6 +526,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
518 up(&f->sem); 526 up(&f->sem);
519 jffs2_complete_reservation(c); 527 jffs2_complete_reservation(c);
520 jffs2_clear_inode(inode); 528 jffs2_clear_inode(inode);
529 posix_acl_release(acl);
521 return PTR_ERR(fn); 530 return PTR_ERR(fn);
522 } 531 }
523 /* No data here. Only a metadata node, which will be 532 /* No data here. Only a metadata node, which will be
@@ -531,9 +540,10 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
531 ret = jffs2_init_security(inode, dir_i); 540 ret = jffs2_init_security(inode, dir_i);
532 if (ret) { 541 if (ret) {
533 jffs2_clear_inode(inode); 542 jffs2_clear_inode(inode);
543 posix_acl_release(acl);
534 return ret; 544 return ret;
535 } 545 }
536 ret = jffs2_init_acl(inode, dir_i); 546 ret = jffs2_init_acl(inode, acl);
537 if (ret) { 547 if (ret) {
538 jffs2_clear_inode(inode); 548 jffs2_clear_inode(inode);
539 return ret; 549 return ret;
@@ -629,6 +639,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
629 union jffs2_device_node dev; 639 union jffs2_device_node dev;
630 int devlen = 0; 640 int devlen = 0;
631 uint32_t alloclen; 641 uint32_t alloclen;
642 struct posix_acl *acl;
632 int ret; 643 int ret;
633 644
634 if (!new_valid_dev(rdev)) 645 if (!new_valid_dev(rdev))
@@ -655,7 +666,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
655 return ret; 666 return ret;
656 } 667 }
657 668
658 inode = jffs2_new_inode(dir_i, mode, ri); 669 inode = jffs2_new_inode(dir_i, mode, ri, &acl);
659 670
660 if (IS_ERR(inode)) { 671 if (IS_ERR(inode)) {
661 jffs2_free_raw_inode(ri); 672 jffs2_free_raw_inode(ri);
@@ -684,6 +695,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
684 up(&f->sem); 695 up(&f->sem);
685 jffs2_complete_reservation(c); 696 jffs2_complete_reservation(c);
686 jffs2_clear_inode(inode); 697 jffs2_clear_inode(inode);
698 posix_acl_release(acl);
687 return PTR_ERR(fn); 699 return PTR_ERR(fn);
688 } 700 }
689 /* No data here. Only a metadata node, which will be 701 /* No data here. Only a metadata node, which will be
@@ -697,9 +709,10 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
697 ret = jffs2_init_security(inode, dir_i); 709 ret = jffs2_init_security(inode, dir_i);
698 if (ret) { 710 if (ret) {
699 jffs2_clear_inode(inode); 711 jffs2_clear_inode(inode);
712 posix_acl_release(acl);
700 return ret; 713 return ret;
701 } 714 }
702 ret = jffs2_init_acl(inode, dir_i); 715 ret = jffs2_init_acl(inode, acl);
703 if (ret) { 716 if (ret) {
704 jffs2_clear_inode(inode); 717 jffs2_clear_inode(inode);
705 return ret; 718 return ret;
@@ -770,7 +783,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
770} 783}
771 784
772static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, 785static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
773 struct inode *new_dir_i, struct dentry *new_dentry) 786 struct inode *new_dir_i, struct dentry *new_dentry)
774{ 787{
775 int ret; 788 int ret;
776 struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb); 789 struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb);
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
index 66e7c2f1e644..addd3fc0e877 100644
--- a/fs/jffs2/erase.c
+++ b/fs/jffs2/erase.c
@@ -38,8 +38,8 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,
38#ifdef __ECOS 38#ifdef __ECOS
39 ret = jffs2_flash_erase(c, jeb); 39 ret = jffs2_flash_erase(c, jeb);
40 if (!ret) { 40 if (!ret) {
41 jffs2_erase_succeeded(c, jeb); 41 jffs2_erase_succeeded(c, jeb);
42 return; 42 return;
43 } 43 }
44 bad_offset = jeb->offset; 44 bad_offset = jeb->offset;
45#else /* Linux */ 45#else /* Linux */
@@ -50,12 +50,14 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,
50 instr = kmalloc(sizeof(struct erase_info) + sizeof(struct erase_priv_struct), GFP_KERNEL); 50 instr = kmalloc(sizeof(struct erase_info) + sizeof(struct erase_priv_struct), GFP_KERNEL);
51 if (!instr) { 51 if (!instr) {
52 printk(KERN_WARNING "kmalloc for struct erase_info in jffs2_erase_block failed. Refiling block for later\n"); 52 printk(KERN_WARNING "kmalloc for struct erase_info in jffs2_erase_block failed. Refiling block for later\n");
53 down(&c->erase_free_sem);
53 spin_lock(&c->erase_completion_lock); 54 spin_lock(&c->erase_completion_lock);
54 list_move(&jeb->list, &c->erase_pending_list); 55 list_move(&jeb->list, &c->erase_pending_list);
55 c->erasing_size -= c->sector_size; 56 c->erasing_size -= c->sector_size;
56 c->dirty_size += c->sector_size; 57 c->dirty_size += c->sector_size;
57 jeb->dirty_size = c->sector_size; 58 jeb->dirty_size = c->sector_size;
58 spin_unlock(&c->erase_completion_lock); 59 spin_unlock(&c->erase_completion_lock);
60 up(&c->erase_free_sem);
59 return; 61 return;
60 } 62 }
61 63
@@ -82,12 +84,14 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,
82 if (ret == -ENOMEM || ret == -EAGAIN) { 84 if (ret == -ENOMEM || ret == -EAGAIN) {
83 /* Erase failed immediately. Refile it on the list */ 85 /* Erase failed immediately. Refile it on the list */
84 D1(printk(KERN_DEBUG "Erase at 0x%08x failed: %d. Refiling on erase_pending_list\n", jeb->offset, ret)); 86 D1(printk(KERN_DEBUG "Erase at 0x%08x failed: %d. Refiling on erase_pending_list\n", jeb->offset, ret));
87 down(&c->erase_free_sem);
85 spin_lock(&c->erase_completion_lock); 88 spin_lock(&c->erase_completion_lock);
86 list_move(&jeb->list, &c->erase_pending_list); 89 list_move(&jeb->list, &c->erase_pending_list);
87 c->erasing_size -= c->sector_size; 90 c->erasing_size -= c->sector_size;
88 c->dirty_size += c->sector_size; 91 c->dirty_size += c->sector_size;
89 jeb->dirty_size = c->sector_size; 92 jeb->dirty_size = c->sector_size;
90 spin_unlock(&c->erase_completion_lock); 93 spin_unlock(&c->erase_completion_lock);
94 up(&c->erase_free_sem);
91 return; 95 return;
92 } 96 }
93 97
@@ -114,6 +118,7 @@ void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count)
114 jeb = list_entry(c->erase_complete_list.next, struct jffs2_eraseblock, list); 118 jeb = list_entry(c->erase_complete_list.next, struct jffs2_eraseblock, list);
115 list_del(&jeb->list); 119 list_del(&jeb->list);
116 spin_unlock(&c->erase_completion_lock); 120 spin_unlock(&c->erase_completion_lock);
121 up(&c->erase_free_sem);
117 jffs2_mark_erased_block(c, jeb); 122 jffs2_mark_erased_block(c, jeb);
118 123
119 if (!--count) { 124 if (!--count) {
@@ -134,6 +139,7 @@ void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count)
134 jffs2_free_jeb_node_refs(c, jeb); 139 jffs2_free_jeb_node_refs(c, jeb);
135 list_add(&jeb->list, &c->erasing_list); 140 list_add(&jeb->list, &c->erasing_list);
136 spin_unlock(&c->erase_completion_lock); 141 spin_unlock(&c->erase_completion_lock);
142 up(&c->erase_free_sem);
137 143
138 jffs2_erase_block(c, jeb); 144 jffs2_erase_block(c, jeb);
139 145
@@ -142,23 +148,25 @@ void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count)
142 } 148 }
143 149
144 /* Be nice */ 150 /* Be nice */
145 cond_resched(); 151 yield();
152 down(&c->erase_free_sem);
146 spin_lock(&c->erase_completion_lock); 153 spin_lock(&c->erase_completion_lock);
147 } 154 }
148 155
149 spin_unlock(&c->erase_completion_lock); 156 spin_unlock(&c->erase_completion_lock);
157 up(&c->erase_free_sem);
150 done: 158 done:
151 D1(printk(KERN_DEBUG "jffs2_erase_pending_blocks completed\n")); 159 D1(printk(KERN_DEBUG "jffs2_erase_pending_blocks completed\n"));
152
153 up(&c->erase_free_sem);
154} 160}
155 161
156static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) 162static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
157{ 163{
158 D1(printk(KERN_DEBUG "Erase completed successfully at 0x%08x\n", jeb->offset)); 164 D1(printk(KERN_DEBUG "Erase completed successfully at 0x%08x\n", jeb->offset));
165 down(&c->erase_free_sem);
159 spin_lock(&c->erase_completion_lock); 166 spin_lock(&c->erase_completion_lock);
160 list_move_tail(&jeb->list, &c->erase_complete_list); 167 list_move_tail(&jeb->list, &c->erase_complete_list);
161 spin_unlock(&c->erase_completion_lock); 168 spin_unlock(&c->erase_completion_lock);
169 up(&c->erase_free_sem);
162 /* Ensure that kupdated calls us again to mark them clean */ 170 /* Ensure that kupdated calls us again to mark them clean */
163 jffs2_erase_pending_trigger(c); 171 jffs2_erase_pending_trigger(c);
164} 172}
@@ -172,22 +180,26 @@ static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock
172 failed too many times. */ 180 failed too many times. */
173 if (!jffs2_write_nand_badblock(c, jeb, bad_offset)) { 181 if (!jffs2_write_nand_badblock(c, jeb, bad_offset)) {
174 /* We'd like to give this block another try. */ 182 /* We'd like to give this block another try. */
183 down(&c->erase_free_sem);
175 spin_lock(&c->erase_completion_lock); 184 spin_lock(&c->erase_completion_lock);
176 list_move(&jeb->list, &c->erase_pending_list); 185 list_move(&jeb->list, &c->erase_pending_list);
177 c->erasing_size -= c->sector_size; 186 c->erasing_size -= c->sector_size;
178 c->dirty_size += c->sector_size; 187 c->dirty_size += c->sector_size;
179 jeb->dirty_size = c->sector_size; 188 jeb->dirty_size = c->sector_size;
180 spin_unlock(&c->erase_completion_lock); 189 spin_unlock(&c->erase_completion_lock);
190 up(&c->erase_free_sem);
181 return; 191 return;
182 } 192 }
183 } 193 }
184 194
195 down(&c->erase_free_sem);
185 spin_lock(&c->erase_completion_lock); 196 spin_lock(&c->erase_completion_lock);
186 c->erasing_size -= c->sector_size; 197 c->erasing_size -= c->sector_size;
187 c->bad_size += c->sector_size; 198 c->bad_size += c->sector_size;
188 list_move(&jeb->list, &c->bad_list); 199 list_move(&jeb->list, &c->bad_list);
189 c->nr_erasing_blocks--; 200 c->nr_erasing_blocks--;
190 spin_unlock(&c->erase_completion_lock); 201 spin_unlock(&c->erase_completion_lock);
202 up(&c->erase_free_sem);
191 wake_up(&c->erase_wait); 203 wake_up(&c->erase_wait);
192} 204}
193 205
@@ -317,6 +329,33 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl
317 size_t retlen; 329 size_t retlen;
318 int ret = -EIO; 330 int ret = -EIO;
319 331
332 if (c->mtd->point) {
333 unsigned long *wordebuf;
334
335 ret = c->mtd->point(c->mtd, jeb->offset, c->sector_size, &retlen, (unsigned char **)&ebuf);
336 if (ret) {
337 D1(printk(KERN_DEBUG "MTD point failed %d\n", ret));
338 goto do_flash_read;
339 }
340 if (retlen < c->sector_size) {
341 /* Don't muck about if it won't let us point to the whole erase sector */
342 D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", retlen));
343 c->mtd->unpoint(c->mtd, ebuf, jeb->offset, c->sector_size);
344 goto do_flash_read;
345 }
346 wordebuf = ebuf-sizeof(*wordebuf);
347 retlen /= sizeof(*wordebuf);
348 do {
349 if (*++wordebuf != ~0)
350 break;
351 } while(--retlen);
352 c->mtd->unpoint(c->mtd, ebuf, jeb->offset, c->sector_size);
353 if (retlen)
354 printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08tx\n",
355 *wordebuf, jeb->offset + c->sector_size-retlen*sizeof(*wordebuf));
356 return 0;
357 }
358 do_flash_read:
320 ebuf = kmalloc(PAGE_SIZE, GFP_KERNEL); 359 ebuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
321 if (!ebuf) { 360 if (!ebuf) {
322 printk(KERN_WARNING "Failed to allocate page buffer for verifying erase at 0x%08x. Refiling\n", jeb->offset); 361 printk(KERN_WARNING "Failed to allocate page buffer for verifying erase at 0x%08x. Refiling\n", jeb->offset);
@@ -362,7 +401,7 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
362{ 401{
363 size_t retlen; 402 size_t retlen;
364 int ret; 403 int ret;
365 uint32_t bad_offset; 404 uint32_t uninitialized_var(bad_offset);
366 405
367 switch (jffs2_block_check_erase(c, jeb, &bad_offset)) { 406 switch (jffs2_block_check_erase(c, jeb, &bad_offset)) {
368 case -EAGAIN: goto refile; 407 case -EAGAIN: goto refile;
@@ -417,6 +456,7 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
417 jffs2_link_node_ref(c, jeb, jeb->offset | REF_NORMAL, c->cleanmarker_size, NULL); 456 jffs2_link_node_ref(c, jeb, jeb->offset | REF_NORMAL, c->cleanmarker_size, NULL);
418 } 457 }
419 458
459 down(&c->erase_free_sem);
420 spin_lock(&c->erase_completion_lock); 460 spin_lock(&c->erase_completion_lock);
421 c->erasing_size -= c->sector_size; 461 c->erasing_size -= c->sector_size;
422 c->free_size += jeb->free_size; 462 c->free_size += jeb->free_size;
@@ -429,23 +469,28 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
429 c->nr_erasing_blocks--; 469 c->nr_erasing_blocks--;
430 c->nr_free_blocks++; 470 c->nr_free_blocks++;
431 spin_unlock(&c->erase_completion_lock); 471 spin_unlock(&c->erase_completion_lock);
472 up(&c->erase_free_sem);
432 wake_up(&c->erase_wait); 473 wake_up(&c->erase_wait);
433 return; 474 return;
434 475
435filebad: 476filebad:
477 down(&c->erase_free_sem);
436 spin_lock(&c->erase_completion_lock); 478 spin_lock(&c->erase_completion_lock);
437 /* Stick it on a list (any list) so erase_failed can take it 479 /* Stick it on a list (any list) so erase_failed can take it
438 right off again. Silly, but shouldn't happen often. */ 480 right off again. Silly, but shouldn't happen often. */
439 list_add(&jeb->list, &c->erasing_list); 481 list_add(&jeb->list, &c->erasing_list);
440 spin_unlock(&c->erase_completion_lock); 482 spin_unlock(&c->erase_completion_lock);
483 up(&c->erase_free_sem);
441 jffs2_erase_failed(c, jeb, bad_offset); 484 jffs2_erase_failed(c, jeb, bad_offset);
442 return; 485 return;
443 486
444refile: 487refile:
445 /* Stick it back on the list from whence it came and come back later */ 488 /* Stick it back on the list from whence it came and come back later */
446 jffs2_erase_pending_trigger(c); 489 jffs2_erase_pending_trigger(c);
490 down(&c->erase_free_sem);
447 spin_lock(&c->erase_completion_lock); 491 spin_lock(&c->erase_completion_lock);
448 list_add(&jeb->list, &c->erase_complete_list); 492 list_add(&jeb->list, &c->erase_complete_list);
449 spin_unlock(&c->erase_completion_lock); 493 spin_unlock(&c->erase_completion_lock);
494 up(&c->erase_free_sem);
450 return; 495 return;
451} 496}
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 1d3b7a9fc828..dd64ddc11d43 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -24,7 +24,7 @@
24 24
25static int jffs2_flash_setup(struct jffs2_sb_info *c); 25static int jffs2_flash_setup(struct jffs2_sb_info *c);
26 26
27static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) 27int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
28{ 28{
29 struct jffs2_full_dnode *old_metadata, *new_metadata; 29 struct jffs2_full_dnode *old_metadata, *new_metadata;
30 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); 30 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
@@ -36,10 +36,8 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
36 unsigned int ivalid; 36 unsigned int ivalid;
37 uint32_t alloclen; 37 uint32_t alloclen;
38 int ret; 38 int ret;
39
39 D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino)); 40 D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino));
40 ret = inode_change_ok(inode, iattr);
41 if (ret)
42 return ret;
43 41
44 /* Special cases - we don't want more than one data node 42 /* Special cases - we don't want more than one data node
45 for these types on the medium at any time. So setattr 43 for these types on the medium at any time. So setattr
@@ -183,9 +181,14 @@ int jffs2_setattr(struct dentry *dentry, struct iattr *iattr)
183{ 181{
184 int rc; 182 int rc;
185 183
184 rc = inode_change_ok(dentry->d_inode, iattr);
185 if (rc)
186 return rc;
187
186 rc = jffs2_do_setattr(dentry->d_inode, iattr); 188 rc = jffs2_do_setattr(dentry->d_inode, iattr);
187 if (!rc && (iattr->ia_valid & ATTR_MODE)) 189 if (!rc && (iattr->ia_valid & ATTR_MODE))
188 rc = jffs2_acl_chmod(dentry->d_inode); 190 rc = jffs2_acl_chmod(dentry->d_inode);
191
189 return rc; 192 return rc;
190} 193}
191 194
@@ -399,7 +402,8 @@ void jffs2_write_super (struct super_block *sb)
399 402
400/* jffs2_new_inode: allocate a new inode and inocache, add it to the hash, 403/* jffs2_new_inode: allocate a new inode and inocache, add it to the hash,
401 fill in the raw_inode while you're at it. */ 404 fill in the raw_inode while you're at it. */
402struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri) 405struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri,
406 struct posix_acl **acl)
403{ 407{
404 struct inode *inode; 408 struct inode *inode;
405 struct super_block *sb = dir_i->i_sb; 409 struct super_block *sb = dir_i->i_sb;
@@ -431,7 +435,23 @@ struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_i
431 } else { 435 } else {
432 ri->gid = cpu_to_je16(current->fsgid); 436 ri->gid = cpu_to_je16(current->fsgid);
433 } 437 }
434 ri->mode = cpu_to_jemode(mode); 438
439 /* POSIX ACLs have to be processed now, at least partly.
440 The umask is only applied if there's no default ACL */
441 if (!S_ISLNK(mode)) {
442 *acl = jffs2_get_acl(dir_i, ACL_TYPE_DEFAULT);
443 if (IS_ERR(*acl)) {
444 make_bad_inode(inode);
445 iput(inode);
446 inode = (void *)*acl;
447 *acl = NULL;
448 return inode;
449 }
450 if (!(*acl))
451 mode &= ~current->fs->umask;
452 } else {
453 *acl = NULL;
454 }
435 ret = jffs2_do_new_inode (c, f, mode, ri); 455 ret = jffs2_do_new_inode (c, f, mode, ri);
436 if (ret) { 456 if (ret) {
437 make_bad_inode(inode); 457 make_bad_inode(inode);
diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c
index 2d99e06ab223..eded819df235 100644
--- a/fs/jffs2/gc.c
+++ b/fs/jffs2/gc.c
@@ -556,7 +556,7 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
556 556
557 node = kmalloc(rawlen, GFP_KERNEL); 557 node = kmalloc(rawlen, GFP_KERNEL);
558 if (!node) 558 if (!node)
559 return -ENOMEM; 559 return -ENOMEM;
560 560
561 ret = jffs2_flash_read(c, ref_offset(raw), rawlen, &retlen, (char *)node); 561 ret = jffs2_flash_read(c, ref_offset(raw), rawlen, &retlen, (char *)node);
562 if (!ret && retlen != rawlen) 562 if (!ret && retlen != rawlen)
@@ -624,7 +624,7 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
624 624
625 if (ret || (retlen != rawlen)) { 625 if (ret || (retlen != rawlen)) {
626 printk(KERN_NOTICE "Write of %d bytes at 0x%08x failed. returned %d, retlen %zd\n", 626 printk(KERN_NOTICE "Write of %d bytes at 0x%08x failed. returned %d, retlen %zd\n",
627 rawlen, phys_ofs, ret, retlen); 627 rawlen, phys_ofs, ret, retlen);
628 if (retlen) { 628 if (retlen) {
629 jffs2_add_physical_node_ref(c, phys_ofs | REF_OBSOLETE, rawlen, NULL); 629 jffs2_add_physical_node_ref(c, phys_ofs | REF_OBSOLETE, rawlen, NULL);
630 } else { 630 } else {
diff --git a/fs/jffs2/jffs2_fs_sb.h b/fs/jffs2/jffs2_fs_sb.h
index b13298a824ed..ae99cd7fd43b 100644
--- a/fs/jffs2/jffs2_fs_sb.h
+++ b/fs/jffs2/jffs2_fs_sb.h
@@ -106,6 +106,9 @@ struct jffs2_sb_info {
106 106
107 uint32_t wbuf_pagesize; /* 0 for NOR and other flashes with no wbuf */ 107 uint32_t wbuf_pagesize; /* 0 for NOR and other flashes with no wbuf */
108 108
109#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
110 unsigned char *wbuf_verify; /* read-back buffer for verification */
111#endif
109#ifdef CONFIG_JFFS2_FS_WRITEBUFFER 112#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
110 unsigned char *wbuf; /* Write-behind buffer for NAND flash */ 113 unsigned char *wbuf; /* Write-behind buffer for NAND flash */
111 uint32_t wbuf_ofs; 114 uint32_t wbuf_ofs;
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h
index bc5509fe577b..ec1aae9e695e 100644
--- a/fs/jffs2/nodelist.h
+++ b/fs/jffs2/nodelist.h
@@ -127,7 +127,7 @@ static inline struct jffs2_inode_cache *jffs2_raw_ref_to_ic(struct jffs2_raw_nod
127 return ((struct jffs2_inode_cache *)raw); 127 return ((struct jffs2_inode_cache *)raw);
128} 128}
129 129
130 /* flash_offset & 3 always has to be zero, because nodes are 130 /* flash_offset & 3 always has to be zero, because nodes are
131 always aligned at 4 bytes. So we have a couple of extra bits 131 always aligned at 4 bytes. So we have a couple of extra bits
132 to play with, which indicate the node's status; see below: */ 132 to play with, which indicate the node's status; see below: */
133#define REF_UNCHECKED 0 /* We haven't yet checked the CRC or built its inode */ 133#define REF_UNCHECKED 0 /* We haven't yet checked the CRC or built its inode */
diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c
index dbc908ad622b..5b49bff364b4 100644
--- a/fs/jffs2/nodemgmt.c
+++ b/fs/jffs2/nodemgmt.c
@@ -154,7 +154,7 @@ int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize,
154 while(ret == -EAGAIN) { 154 while(ret == -EAGAIN) {
155 ret = jffs2_do_reserve_space(c, minsize, len, sumsize); 155 ret = jffs2_do_reserve_space(c, minsize, len, sumsize);
156 if (ret) { 156 if (ret) {
157 D1(printk(KERN_DEBUG "jffs2_reserve_space_gc: looping, ret is %d\n", ret)); 157 D1(printk(KERN_DEBUG "jffs2_reserve_space_gc: looping, ret is %d\n", ret));
158 } 158 }
159 } 159 }
160 spin_unlock(&c->erase_completion_lock); 160 spin_unlock(&c->erase_completion_lock);
@@ -423,7 +423,12 @@ struct jffs2_raw_node_ref *jffs2_add_physical_node_ref(struct jffs2_sb_info *c,
423 even after refiling c->nextblock */ 423 even after refiling c->nextblock */
424 if ((c->nextblock || ((ofs & 3) != REF_OBSOLETE)) 424 if ((c->nextblock || ((ofs & 3) != REF_OBSOLETE))
425 && (jeb != c->nextblock || (ofs & ~3) != jeb->offset + (c->sector_size - jeb->free_size))) { 425 && (jeb != c->nextblock || (ofs & ~3) != jeb->offset + (c->sector_size - jeb->free_size))) {
426 printk(KERN_WARNING "argh. node added in wrong place\n"); 426 printk(KERN_WARNING "argh. node added in wrong place at 0x%08x(%d)\n", ofs & ~3, ofs & 3);
427 if (c->nextblock)
428 printk(KERN_WARNING "nextblock 0x%08x", c->nextblock->offset);
429 else
430 printk(KERN_WARNING "No nextblock");
431 printk(", expected at %08x\n", jeb->offset + (c->sector_size - jeb->free_size));
427 return ERR_PTR(-EINVAL); 432 return ERR_PTR(-EINVAL);
428 } 433 }
429#endif 434#endif
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
index 80daea96bbc2..f6743a915cf3 100644
--- a/fs/jffs2/os-linux.h
+++ b/fs/jffs2/os-linux.h
@@ -173,12 +173,15 @@ int jffs2_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
173extern const struct inode_operations jffs2_symlink_inode_operations; 173extern const struct inode_operations jffs2_symlink_inode_operations;
174 174
175/* fs.c */ 175/* fs.c */
176struct posix_acl;
177
176int jffs2_setattr (struct dentry *, struct iattr *); 178int jffs2_setattr (struct dentry *, struct iattr *);
179int jffs2_do_setattr (struct inode *, struct iattr *);
177void jffs2_read_inode (struct inode *); 180void jffs2_read_inode (struct inode *);
178void jffs2_clear_inode (struct inode *); 181void jffs2_clear_inode (struct inode *);
179void jffs2_dirty_inode(struct inode *inode); 182void jffs2_dirty_inode(struct inode *inode);
180struct inode *jffs2_new_inode (struct inode *dir_i, int mode, 183struct inode *jffs2_new_inode (struct inode *dir_i, int mode,
181 struct jffs2_raw_inode *ri); 184 struct jffs2_raw_inode *ri, struct posix_acl **acl);
182int jffs2_statfs (struct dentry *, struct kstatfs *); 185int jffs2_statfs (struct dentry *, struct kstatfs *);
183void jffs2_write_super (struct super_block *); 186void jffs2_write_super (struct super_block *);
184int jffs2_remount_fs (struct super_block *, int *, char *); 187int jffs2_remount_fs (struct super_block *, int *, char *);
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index b5baa356fed2..8d4319c56b17 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -211,7 +211,7 @@ static void jffs2_kill_tn(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info *
211 * ordering. 211 * ordering.
212 * 212 *
213 * Returns 0 if the node was handled (including marking it obsolete) 213 * Returns 0 if the node was handled (including marking it obsolete)
214 * < 0 an if error occurred 214 * < 0 an if error occurred
215 */ 215 */
216static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, 216static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c,
217 struct jffs2_readinode_info *rii, 217 struct jffs2_readinode_info *rii,
@@ -862,8 +862,8 @@ static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_re
862 JFFS2_ERROR("REF_UNCHECKED but unknown node at %#08x\n", 862 JFFS2_ERROR("REF_UNCHECKED but unknown node at %#08x\n",
863 ref_offset(ref)); 863 ref_offset(ref));
864 JFFS2_ERROR("Node is {%04x,%04x,%08x,%08x}. Please report this error.\n", 864 JFFS2_ERROR("Node is {%04x,%04x,%08x,%08x}. Please report this error.\n",
865 je16_to_cpu(un->magic), je16_to_cpu(un->nodetype), 865 je16_to_cpu(un->magic), je16_to_cpu(un->nodetype),
866 je32_to_cpu(un->totlen), je32_to_cpu(un->hdr_crc)); 866 je32_to_cpu(un->totlen), je32_to_cpu(un->hdr_crc));
867 jffs2_mark_node_obsolete(c, ref); 867 jffs2_mark_node_obsolete(c, ref);
868 return 0; 868 return 0;
869 } 869 }
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
index 6c75cd433342..59dd408e5432 100644
--- a/fs/jffs2/scan.c
+++ b/fs/jffs2/scan.c
@@ -863,7 +863,7 @@ scan_more:
863 switch (je16_to_cpu(node->nodetype) & JFFS2_COMPAT_MASK) { 863 switch (je16_to_cpu(node->nodetype) & JFFS2_COMPAT_MASK) {
864 case JFFS2_FEATURE_ROCOMPAT: 864 case JFFS2_FEATURE_ROCOMPAT:
865 printk(KERN_NOTICE "Read-only compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs); 865 printk(KERN_NOTICE "Read-only compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs);
866 c->flags |= JFFS2_SB_FLAG_RO; 866 c->flags |= JFFS2_SB_FLAG_RO;
867 if (!(jffs2_is_readonly(c))) 867 if (!(jffs2_is_readonly(c)))
868 return -EROFS; 868 return -EROFS;
869 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(node->totlen))))) 869 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(node->totlen)))))
diff --git a/fs/jffs2/security.c b/fs/jffs2/security.c
index bc9f6ba10823..02c39c64ecb3 100644
--- a/fs/jffs2/security.c
+++ b/fs/jffs2/security.c
@@ -38,9 +38,9 @@ int jffs2_init_security(struct inode *inode, struct inode *dir)
38 } 38 }
39 rc = do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY, name, value, len, 0); 39 rc = do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY, name, value, len, 0);
40 40
41 kfree(name); 41 kfree(name);
42 kfree(value); 42 kfree(value);
43 return rc; 43 return rc;
44} 44}
45 45
46/* ---- XATTR Handler for "security.*" ----------------- */ 46/* ---- XATTR Handler for "security.*" ----------------- */
diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c
index d828b296392a..2a77d3f93029 100644
--- a/fs/jffs2/summary.c
+++ b/fs/jffs2/summary.c
@@ -2,10 +2,10 @@
2 * JFFS2 -- Journalling Flash File System, Version 2. 2 * JFFS2 -- Journalling Flash File System, Version 2.
3 * 3 *
4 * Copyright © 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>, 4 * Copyright © 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>,
5 * Zoltan Sogor <weth@inf.u-szeged.hu>, 5 * Zoltan Sogor <weth@inf.u-szeged.hu>,
6 * Patrik Kluba <pajko@halom.u-szeged.hu>, 6 * Patrik Kluba <pajko@halom.u-szeged.hu>,
7 * University of Szeged, Hungary 7 * University of Szeged, Hungary
8 * 2006 KaiGai Kohei <kaigai@ak.jp.nec.com> 8 * 2006 KaiGai Kohei <kaigai@ak.jp.nec.com>
9 * 9 *
10 * For licensing information, see the file 'LICENCE' in this directory. 10 * For licensing information, see the file 'LICENCE' in this directory.
11 * 11 *
diff --git a/fs/jffs2/summary.h b/fs/jffs2/summary.h
index 0c6669e21390..8bf34f2fa5ce 100644
--- a/fs/jffs2/summary.h
+++ b/fs/jffs2/summary.h
@@ -2,9 +2,9 @@
2 * JFFS2 -- Journalling Flash File System, Version 2. 2 * JFFS2 -- Journalling Flash File System, Version 2.
3 * 3 *
4 * Copyright © 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>, 4 * Copyright © 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>,
5 * Zoltan Sogor <weth@inf.u-szeged.hu>, 5 * Zoltan Sogor <weth@inf.u-szeged.hu>,
6 * Patrik Kluba <pajko@halom.u-szeged.hu>, 6 * Patrik Kluba <pajko@halom.u-szeged.hu>,
7 * University of Szeged, Hungary 7 * University of Szeged, Hungary
8 * 8 *
9 * For licensing information, see the file 'LICENCE' in this directory. 9 * For licensing information, see the file 'LICENCE' in this directory.
10 * 10 *
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index 91d1d0f1c66c..d1d4f27464ba 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -220,6 +220,47 @@ static struct jffs2_raw_node_ref **jffs2_incore_replace_raw(struct jffs2_sb_info
220 return NULL; 220 return NULL;
221} 221}
222 222
223#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
224static int jffs2_verify_write(struct jffs2_sb_info *c, unsigned char *buf,
225 uint32_t ofs)
226{
227 int ret;
228 size_t retlen;
229 char *eccstr;
230
231 ret = c->mtd->read(c->mtd, ofs, c->wbuf_pagesize, &retlen, c->wbuf_verify);
232 if (ret && ret != -EUCLEAN && ret != -EBADMSG) {
233 printk(KERN_WARNING "jffs2_verify_write(): Read back of page at %08x failed: %d\n", c->wbuf_ofs, ret);
234 return ret;
235 } else if (retlen != c->wbuf_pagesize) {
236 printk(KERN_WARNING "jffs2_verify_write(): Read back of page at %08x gave short read: %zd not %d.\n", ofs, retlen, c->wbuf_pagesize);
237 return -EIO;
238 }
239 if (!memcmp(buf, c->wbuf_verify, c->wbuf_pagesize))
240 return 0;
241
242 if (ret == -EUCLEAN)
243 eccstr = "corrected";
244 else if (ret == -EBADMSG)
245 eccstr = "correction failed";
246 else
247 eccstr = "OK or unused";
248
249 printk(KERN_WARNING "Write verify error (ECC %s) at %08x. Wrote:\n",
250 eccstr, c->wbuf_ofs);
251 print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 16, 1,
252 c->wbuf, c->wbuf_pagesize, 0);
253
254 printk(KERN_WARNING "Read back:\n");
255 print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 16, 1,
256 c->wbuf_verify, c->wbuf_pagesize, 0);
257
258 return -EIO;
259}
260#else
261#define jffs2_verify_write(c,b,o) (0)
262#endif
263
223/* Recover from failure to write wbuf. Recover the nodes up to the 264/* Recover from failure to write wbuf. Recover the nodes up to the
224 * wbuf, not the one which we were starting to try to write. */ 265 * wbuf, not the one which we were starting to try to write. */
225 266
@@ -380,7 +421,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
380 ret = c->mtd->write(c->mtd, ofs, towrite, &retlen, 421 ret = c->mtd->write(c->mtd, ofs, towrite, &retlen,
381 rewrite_buf); 422 rewrite_buf);
382 423
383 if (ret || retlen != towrite) { 424 if (ret || retlen != towrite || jffs2_verify_write(c, rewrite_buf, ofs)) {
384 /* Argh. We tried. Really we did. */ 425 /* Argh. We tried. Really we did. */
385 printk(KERN_CRIT "Recovery of wbuf failed due to a second write error\n"); 426 printk(KERN_CRIT "Recovery of wbuf failed due to a second write error\n");
386 kfree(buf); 427 kfree(buf);
@@ -587,15 +628,16 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
587 628
588 ret = c->mtd->write(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, c->wbuf); 629 ret = c->mtd->write(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, c->wbuf);
589 630
590 if (ret || retlen != c->wbuf_pagesize) { 631 if (ret) {
591 if (ret) 632 printk(KERN_WARNING "jffs2_flush_wbuf(): Write failed with %d\n", ret);
592 printk(KERN_WARNING "jffs2_flush_wbuf(): Write failed with %d\n",ret); 633 goto wfail;
593 else { 634 } else if (retlen != c->wbuf_pagesize) {
594 printk(KERN_WARNING "jffs2_flush_wbuf(): Write was short: %zd instead of %d\n", 635 printk(KERN_WARNING "jffs2_flush_wbuf(): Write was short: %zd instead of %d\n",
595 retlen, c->wbuf_pagesize); 636 retlen, c->wbuf_pagesize);
596 ret = -EIO; 637 ret = -EIO;
597 } 638 goto wfail;
598 639 } else if ((ret = jffs2_verify_write(c, c->wbuf, c->wbuf_ofs))) {
640 wfail:
599 jffs2_wbuf_recover(c); 641 jffs2_wbuf_recover(c);
600 642
601 return ret; 643 return ret;
@@ -966,8 +1008,8 @@ exit:
966 1008
967#define NR_OOB_SCAN_PAGES 4 1009#define NR_OOB_SCAN_PAGES 4
968 1010
969/* For historical reasons we use only 12 bytes for OOB clean marker */ 1011/* For historical reasons we use only 8 bytes for OOB clean marker */
970#define OOB_CM_SIZE 12 1012#define OOB_CM_SIZE 8
971 1013
972static const struct jffs2_unknown_node oob_cleanmarker = 1014static const struct jffs2_unknown_node oob_cleanmarker =
973{ 1015{
@@ -1021,8 +1063,8 @@ int jffs2_check_oob_empty(struct jffs2_sb_info *c,
1021/* 1063/*
1022 * Check for a valid cleanmarker. 1064 * Check for a valid cleanmarker.
1023 * Returns: 0 if a valid cleanmarker was found 1065 * Returns: 0 if a valid cleanmarker was found
1024 * 1 if no cleanmarker was found 1066 * 1 if no cleanmarker was found
1025 * negative error code if an error occurred 1067 * negative error code if an error occurred
1026 */ 1068 */
1027int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c, 1069int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c,
1028 struct jffs2_eraseblock *jeb) 1070 struct jffs2_eraseblock *jeb)
@@ -1138,11 +1180,22 @@ int jffs2_nand_flash_setup(struct jffs2_sb_info *c)
1138 return -ENOMEM; 1180 return -ENOMEM;
1139 } 1181 }
1140 1182
1183#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
1184 c->wbuf_verify = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
1185 if (!c->wbuf_verify) {
1186 kfree(c->oobbuf);
1187 kfree(c->wbuf);
1188 return -ENOMEM;
1189 }
1190#endif
1141 return 0; 1191 return 0;
1142} 1192}
1143 1193
1144void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c) 1194void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c)
1145{ 1195{
1196#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
1197 kfree(c->wbuf_verify);
1198#endif
1146 kfree(c->wbuf); 1199 kfree(c->wbuf);
1147 kfree(c->oobbuf); 1200 kfree(c->oobbuf);
1148} 1201}
diff --git a/fs/jffs2/xattr.h b/fs/jffs2/xattr.h
index 3b0ff2925937..6e3b5ddfb7ab 100644
--- a/fs/jffs2/xattr.h
+++ b/fs/jffs2/xattr.h
@@ -75,7 +75,7 @@ extern void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c);
75extern void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c); 75extern void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c);
76 76
77extern struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c, 77extern struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c,
78 uint32_t xid, uint32_t version); 78 uint32_t xid, uint32_t version);
79 79
80extern void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic); 80extern void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic);
81extern void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic); 81extern void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic);
diff --git a/fs/jffs2/xattr_user.c b/fs/jffs2/xattr_user.c
index 40942bc516bb..8bbeab90ada1 100644
--- a/fs/jffs2/xattr_user.c
+++ b/fs/jffs2/xattr_user.c
@@ -17,7 +17,7 @@
17#include "nodelist.h" 17#include "nodelist.h"
18 18
19static int jffs2_user_getxattr(struct inode *inode, const char *name, 19static int jffs2_user_getxattr(struct inode *inode, const char *name,
20 void *buffer, size_t size) 20 void *buffer, size_t size)
21{ 21{
22 if (!strcmp(name, "")) 22 if (!strcmp(name, ""))
23 return -EINVAL; 23 return -EINVAL;
@@ -25,7 +25,7 @@ static int jffs2_user_getxattr(struct inode *inode, const char *name,
25} 25}
26 26
27static int jffs2_user_setxattr(struct inode *inode, const char *name, const void *buffer, 27static int jffs2_user_setxattr(struct inode *inode, const char *name, const void *buffer,
28 size_t size, int flags) 28 size_t size, int flags)
29{ 29{
30 if (!strcmp(name, "")) 30 if (!strcmp(name, ""))
31 return -EINVAL; 31 return -EINVAL;
diff --git a/include/linux/jffs2.h b/include/linux/jffs2.h
index 840631fa5ff1..6b563cae23df 100644
--- a/include/linux/jffs2.h
+++ b/include/linux/jffs2.h
@@ -46,6 +46,7 @@
46#define JFFS2_COMPR_COPY 0x04 46#define JFFS2_COMPR_COPY 0x04
47#define JFFS2_COMPR_DYNRUBIN 0x05 47#define JFFS2_COMPR_DYNRUBIN 0x05
48#define JFFS2_COMPR_ZLIB 0x06 48#define JFFS2_COMPR_ZLIB 0x06
49#define JFFS2_COMPR_LZO 0x07
49/* Compatibility flags. */ 50/* Compatibility flags. */
50#define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */ 51#define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */
51#define JFFS2_NODE_ACCURATE 0x2000 52#define JFFS2_NODE_ACCURATE 0x2000
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index d2365c8dcacc..c42bc7f533a5 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -432,6 +432,7 @@ struct nand_chip {
432#define NAND_MFR_STMICRO 0x20 432#define NAND_MFR_STMICRO 0x20
433#define NAND_MFR_HYNIX 0xad 433#define NAND_MFR_HYNIX 0xad
434#define NAND_MFR_MICRON 0x2c 434#define NAND_MFR_MICRON 0x2c
435#define NAND_MFR_AMD 0x01
435 436
436/** 437/**
437 * struct nand_flash_dev - NAND Flash Device ID Structure 438 * struct nand_flash_dev - NAND Flash Device ID Structure
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
index a56d24ada505..fd0a260e070b 100644
--- a/include/linux/mtd/onenand.h
+++ b/include/linux/mtd/onenand.h
@@ -60,6 +60,7 @@ struct onenand_bufferram {
60 * @erase_shift: [INTERN] number of address bits in a block 60 * @erase_shift: [INTERN] number of address bits in a block
61 * @page_shift: [INTERN] number of address bits in a page 61 * @page_shift: [INTERN] number of address bits in a page
62 * @page_mask: [INTERN] a page per block mask 62 * @page_mask: [INTERN] a page per block mask
63 * @writesize: [INTERN] a real page size
63 * @bufferram_index: [INTERN] BufferRAM index 64 * @bufferram_index: [INTERN] BufferRAM index
64 * @bufferram: [INTERN] BufferRAM info 65 * @bufferram: [INTERN] BufferRAM info
65 * @readw: [REPLACEABLE] hardware specific function for read short 66 * @readw: [REPLACEABLE] hardware specific function for read short
@@ -100,6 +101,7 @@ struct onenand_chip {
100 unsigned int erase_shift; 101 unsigned int erase_shift;
101 unsigned int page_shift; 102 unsigned int page_shift;
102 unsigned int page_mask; 103 unsigned int page_mask;
104 unsigned int writesize;
103 105
104 unsigned int bufferram_index; 106 unsigned int bufferram_index;
105 struct onenand_bufferram bufferram[MAX_BUFFERRAM]; 107 struct onenand_bufferram bufferram[MAX_BUFFERRAM];
@@ -140,6 +142,8 @@ struct onenand_chip {
140#define ONENAND_NEXT_BUFFERRAM(this) (this->bufferram_index ^ 1) 142#define ONENAND_NEXT_BUFFERRAM(this) (this->bufferram_index ^ 1)
141#define ONENAND_SET_NEXT_BUFFERRAM(this) (this->bufferram_index ^= 1) 143#define ONENAND_SET_NEXT_BUFFERRAM(this) (this->bufferram_index ^= 1)
142#define ONENAND_SET_PREV_BUFFERRAM(this) (this->bufferram_index ^= 1) 144#define ONENAND_SET_PREV_BUFFERRAM(this) (this->bufferram_index ^= 1)
145#define ONENAND_SET_BUFFERRAM0(this) (this->bufferram_index = 0)
146#define ONENAND_SET_BUFFERRAM1(this) (this->bufferram_index = 1)
143 147
144#define ONENAND_GET_SYS_CFG1(this) \ 148#define ONENAND_GET_SYS_CFG1(this) \
145 (this->read_word(this->base + ONENAND_REG_SYS_CFG1)) 149 (this->read_word(this->base + ONENAND_REG_SYS_CFG1))
@@ -149,6 +153,13 @@ struct onenand_chip {
149#define ONENAND_IS_DDP(this) \ 153#define ONENAND_IS_DDP(this) \
150 (this->device_id & ONENAND_DEVICE_IS_DDP) 154 (this->device_id & ONENAND_DEVICE_IS_DDP)
151 155
156#ifdef CONFIG_MTD_ONENAND_2X_PROGRAM
157#define ONENAND_IS_2PLANE(this) \
158 (this->options & ONENAND_HAS_2PLANE)
159#else
160#define ONENAND_IS_2PLANE(this) (0)
161#endif
162
152/* Check byte access in OneNAND */ 163/* Check byte access in OneNAND */
153#define ONENAND_CHECK_BYTE_ACCESS(addr) (addr & 0x1) 164#define ONENAND_CHECK_BYTE_ACCESS(addr) (addr & 0x1)
154 165
@@ -157,6 +168,7 @@ struct onenand_chip {
157 */ 168 */
158#define ONENAND_HAS_CONT_LOCK (0x0001) 169#define ONENAND_HAS_CONT_LOCK (0x0001)
159#define ONENAND_HAS_UNLOCK_ALL (0x0002) 170#define ONENAND_HAS_UNLOCK_ALL (0x0002)
171#define ONENAND_HAS_2PLANE (0x0004)
160#define ONENAND_PAGEBUF_ALLOC (0x1000) 172#define ONENAND_PAGEBUF_ALLOC (0x1000)
161#define ONENAND_OOBBUF_ALLOC (0x2000) 173#define ONENAND_OOBBUF_ALLOC (0x2000)
162 174
diff --git a/include/linux/mtd/onenand_regs.h b/include/linux/mtd/onenand_regs.h
index af94719890e7..c46161f4eee3 100644
--- a/include/linux/mtd/onenand_regs.h
+++ b/include/linux/mtd/onenand_regs.h
@@ -74,6 +74,8 @@
74 74
75#define ONENAND_DEVICE_DENSITY_512Mb (0x002) 75#define ONENAND_DEVICE_DENSITY_512Mb (0x002)
76#define ONENAND_DEVICE_DENSITY_1Gb (0x003) 76#define ONENAND_DEVICE_DENSITY_1Gb (0x003)
77#define ONENAND_DEVICE_DENSITY_2Gb (0x004)
78#define ONENAND_DEVICE_DENSITY_4Gb (0x005)
77 79
78/* 80/*
79 * Version ID Register F002h (R) 81 * Version ID Register F002h (R)
@@ -111,6 +113,8 @@
111#define ONENAND_CMD_READOOB (0x13) 113#define ONENAND_CMD_READOOB (0x13)
112#define ONENAND_CMD_PROG (0x80) 114#define ONENAND_CMD_PROG (0x80)
113#define ONENAND_CMD_PROGOOB (0x1A) 115#define ONENAND_CMD_PROGOOB (0x1A)
116#define ONENAND_CMD_2X_PROG (0x7D)
117#define ONENAND_CMD_2X_CACHE_PROG (0x7F)
114#define ONENAND_CMD_UNLOCK (0x23) 118#define ONENAND_CMD_UNLOCK (0x23)
115#define ONENAND_CMD_LOCK (0x2A) 119#define ONENAND_CMD_LOCK (0x2A)
116#define ONENAND_CMD_LOCK_TIGHT (0x2C) 120#define ONENAND_CMD_LOCK_TIGHT (0x2C)