From e1fbcdf8b719b56b27a6dcc9074eaecb98b9a4b9 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Wed, 22 Aug 2007 14:30:47 -0500 Subject: [PATCH] --- yaml --- r: 68512 b: refs/heads/master c: 3feb0ff1607ab3b7dcd36b2347f00c41774464c8 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/Documentation/DocBook/mtdnand.tmpl | 5 +- trunk/drivers/mtd/Kconfig | 8 - trunk/drivers/mtd/Makefile | 1 - trunk/drivers/mtd/chips/cfi_cmdset_0001.c | 14 +- trunk/drivers/mtd/chips/cfi_cmdset_0002.c | 2 +- trunk/drivers/mtd/chips/jedec_probe.c | 37 +- trunk/drivers/mtd/devices/Kconfig | 25 +- trunk/drivers/mtd/devices/Makefile | 1 + trunk/drivers/mtd/devices/at91_dataflash26.c | 485 ++++++++++++++++++ trunk/drivers/mtd/devices/docprobe.c | 4 +- trunk/drivers/mtd/devices/m25p80.c | 271 +++------- trunk/drivers/mtd/devices/mtd_dataflash.c | 17 +- trunk/drivers/mtd/devices/pmc551.c | 27 +- trunk/drivers/mtd/inftlmount.c | 3 +- trunk/drivers/mtd/maps/Kconfig | 4 +- trunk/drivers/mtd/maps/alchemy-flash.c | 14 + trunk/drivers/mtd/maps/nettel.c | 65 ++- trunk/drivers/mtd/maps/physmap_of.c | 5 + trunk/drivers/mtd/maps/pmcmsp-flash.c | 22 +- trunk/drivers/mtd/maps/pmcmsp-ramroot.c | 1 + trunk/drivers/mtd/mtd_blkdevs.c | 7 +- trunk/drivers/mtd/mtdchar.c | 3 +- trunk/drivers/mtd/mtdconcat.c | 2 +- trunk/drivers/mtd/mtdcore.c | 2 - trunk/drivers/mtd/mtdcore.h | 11 - trunk/drivers/mtd/mtdoops.c | 376 -------------- trunk/drivers/mtd/nand/Kconfig | 6 +- trunk/drivers/mtd/nand/diskonchip.c | 2 + trunk/drivers/mtd/nand/excite_nandflash.c | 1 + trunk/drivers/mtd/nand/nand_base.c | 2 +- trunk/drivers/mtd/nand/nand_ids.c | 1 - trunk/drivers/mtd/nand/ndfc.c | 8 - trunk/drivers/mtd/onenand/Kconfig | 23 - trunk/drivers/mtd/onenand/Makefile | 3 - trunk/drivers/mtd/onenand/onenand_base.c | 139 +----- trunk/drivers/mtd/onenand/onenand_sim.c | 495 ------------------- trunk/drivers/mtd/rfd_ftl.c | 8 +- trunk/drivers/mtd/ubi/scan.c | 17 +- trunk/fs/Kconfig | 81 +-- trunk/fs/jffs2/Makefile | 1 - trunk/fs/jffs2/acl.c | 23 +- trunk/fs/jffs2/acl.h | 4 +- trunk/fs/jffs2/background.c | 4 +- trunk/fs/jffs2/compr.c | 422 +++++++--------- trunk/fs/jffs2/compr.h | 54 +- trunk/fs/jffs2/compr_lzo.c | 108 ---- trunk/fs/jffs2/compr_rtime.c | 2 +- trunk/fs/jffs2/compr_rubin.c | 4 +- trunk/fs/jffs2/compr_zlib.c | 6 +- trunk/fs/jffs2/dir.c | 37 +- trunk/fs/jffs2/erase.c | 57 +-- trunk/fs/jffs2/fs.c | 32 +- trunk/fs/jffs2/gc.c | 4 +- trunk/fs/jffs2/jffs2_fs_sb.h | 3 - trunk/fs/jffs2/nodelist.h | 2 +- trunk/fs/jffs2/nodemgmt.c | 9 +- trunk/fs/jffs2/os-linux.h | 5 +- trunk/fs/jffs2/readinode.c | 6 +- trunk/fs/jffs2/scan.c | 2 +- trunk/fs/jffs2/security.c | 6 +- trunk/fs/jffs2/summary.c | 8 +- trunk/fs/jffs2/summary.h | 6 +- trunk/fs/jffs2/wbuf.c | 81 +-- trunk/fs/jffs2/xattr.h | 2 +- trunk/fs/jffs2/xattr_user.c | 4 +- trunk/include/linux/jffs2.h | 1 - trunk/include/linux/mtd/nand.h | 1 - trunk/include/linux/mtd/onenand.h | 12 - trunk/include/linux/mtd/onenand_regs.h | 4 - 70 files changed, 1083 insertions(+), 2027 deletions(-) create mode 100644 trunk/drivers/mtd/devices/at91_dataflash26.c delete mode 100644 trunk/drivers/mtd/mtdcore.h delete mode 100644 trunk/drivers/mtd/mtdoops.c delete mode 100644 trunk/drivers/mtd/onenand/onenand_sim.c delete mode 100644 trunk/fs/jffs2/compr_lzo.c diff --git a/[refs] b/[refs] index dff5b2c1e010..3fade72c7d2f 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: ac0c955d5048c2c580fa7166a89133f0fd76c125 +refs/heads/master: 3feb0ff1607ab3b7dcd36b2347f00c41774464c8 diff --git a/trunk/Documentation/DocBook/mtdnand.tmpl b/trunk/Documentation/DocBook/mtdnand.tmpl index 6fbc41d98c1e..a8c8cce50633 100644 --- a/trunk/Documentation/DocBook/mtdnand.tmpl +++ b/trunk/Documentation/DocBook/mtdnand.tmpl @@ -275,13 +275,16 @@ int __init board_init (void) int err = 0; /* Allocate memory for MTD device structure and private data */ - board_mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); + board_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip), GFP_KERNEL); if (!board_mtd) { printk ("Unable to allocate NAND MTD device structure.\n"); err = -ENOMEM; goto out; } + /* Initialize structures */ + memset ((char *) board_mtd, 0, sizeof(struct mtd_info) + sizeof(struct nand_chip)); + /* map physical adress */ baseaddr = (unsigned long)ioremap(CHIP_PHYSICAL_ADDRESS, 1024); if(!baseaddr){ diff --git a/trunk/drivers/mtd/Kconfig b/trunk/drivers/mtd/Kconfig index 8848e8ac705d..fbec8cd55e38 100644 --- a/trunk/drivers/mtd/Kconfig +++ b/trunk/drivers/mtd/Kconfig @@ -278,14 +278,6 @@ config SSFDC This enables read only access to SmartMedia formatted NAND flash. You can mount it with FAT file system. -config MTD_OOPS - tristate "Log panic/oops to an MTD buffer" - depends on MTD - help - This enables panic and oops messages to be logged to a circular - buffer in a flash partition where it can be read back at some - later point. - source "drivers/mtd/chips/Kconfig" source "drivers/mtd/maps/Kconfig" diff --git a/trunk/drivers/mtd/Makefile b/trunk/drivers/mtd/Makefile index 7f0b04b4caa7..6d958a4566ff 100644 --- a/trunk/drivers/mtd/Makefile +++ b/trunk/drivers/mtd/Makefile @@ -22,7 +22,6 @@ obj-$(CONFIG_NFTL) += nftl.o obj-$(CONFIG_INFTL) += inftl.o obj-$(CONFIG_RFD_FTL) += rfd_ftl.o obj-$(CONFIG_SSFDC) += ssfdc.o -obj-$(CONFIG_MTD_OOPS) += mtdoops.o nftl-objs := nftlcore.o nftlmount.o inftl-objs := inftlcore.o inftlmount.o diff --git a/trunk/drivers/mtd/chips/cfi_cmdset_0001.c b/trunk/drivers/mtd/chips/cfi_cmdset_0001.c index 39eff9ff575c..2f19fa78d24a 100644 --- a/trunk/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/trunk/drivers/mtd/chips/cfi_cmdset_0001.c @@ -526,7 +526,7 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd, struct cfi_pri_intelext *extp = cfi->cmdset_priv; /* - * Probing of multi-partition flash chips. + * Probing of multi-partition flash ships. * * To support multiple partitions when available, we simply arrange * 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, return ret; } -static int cfi_intelext_erase_varsize(struct mtd_info *mtd, struct erase_info *instr) +int cfi_intelext_erase_varsize(struct mtd_info *mtd, struct erase_info *instr) { unsigned long ofs, len; int ret; @@ -1930,7 +1930,7 @@ static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len) printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n", __FUNCTION__, ofs, len); cfi_varsize_frob(mtd, do_printlockstatus_oneblock, - ofs, len, NULL); + ofs, len, 0); #endif 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) printk(KERN_DEBUG "%s: lock status after, ret=%d\n", __FUNCTION__, ret); cfi_varsize_frob(mtd, do_printlockstatus_oneblock, - ofs, len, NULL); + ofs, len, 0); #endif return ret; @@ -1954,7 +1954,7 @@ static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n", __FUNCTION__, ofs, len); cfi_varsize_frob(mtd, do_printlockstatus_oneblock, - ofs, len, NULL); + ofs, len, 0); #endif 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) printk(KERN_DEBUG "%s: lock status after, ret=%d\n", __FUNCTION__, ret); cfi_varsize_frob(mtd, do_printlockstatus_oneblock, - ofs, len, NULL); + ofs, len, 0); #endif return ret; @@ -2255,7 +2255,7 @@ static void cfi_intelext_save_locks(struct mtd_info *mtd) adr = region->offset + block * len; status = cfi_varsize_frob(mtd, - do_getlockstatus_oneblock, adr, len, NULL); + do_getlockstatus_oneblock, adr, len, 0); if (status) set_bit(block, region->lockmap); else diff --git a/trunk/drivers/mtd/chips/cfi_cmdset_0002.c b/trunk/drivers/mtd/chips/cfi_cmdset_0002.c index 389acc600f5e..1f6445840461 100644 --- a/trunk/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/trunk/drivers/mtd/chips/cfi_cmdset_0002.c @@ -1609,7 +1609,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, } -static int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr) +int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr) { unsigned long ofs, len; int ret; diff --git a/trunk/drivers/mtd/chips/jedec_probe.c b/trunk/drivers/mtd/chips/jedec_probe.c index a67b23b87fc0..58e561e87699 100644 --- a/trunk/drivers/mtd/chips/jedec_probe.c +++ b/trunk/drivers/mtd/chips/jedec_probe.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -69,7 +70,6 @@ /* Fujitsu */ #define MBM29F040C 0x00A4 -#define MBM29F800BA 0x2258 #define MBM29LV650UE 0x22D7 #define MBM29LV320TE 0x22F6 #define MBM29LV320BE 0x22F9 @@ -129,7 +129,6 @@ #define LH28F640BF 0x00b0 /* ST - www.st.com */ -#define M29F800AB 0x0058 #define M29W800DT 0x00D7 #define M29W800DB 0x005B #define M29W160DT 0x22C4 @@ -645,23 +644,6 @@ static const struct amd_flash_info jedec_table[] = { .regions = { ERASEINFO(0x10000,8) } - }, { - .mfr_id = MANUFACTURER_FUJITSU, - .dev_id = MBM29F800BA, - .name = "Fujitsu MBM29F800BA", - .uaddr = { - [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ - [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ - }, - .DevSize = SIZE_1MiB, - .CmdSet = P_ID_AMD_STD, - .NumEraseRegions= 4, - .regions = { - ERASEINFO(0x04000,1), - ERASEINFO(0x02000,2), - ERASEINFO(0x08000,1), - ERASEINFO(0x10000,15), - } }, { .mfr_id = MANUFACTURER_FUJITSU, .dev_id = MBM29LV650UE, @@ -1528,23 +1510,6 @@ static const struct amd_flash_info jedec_table[] = { ERASEINFO(0x1000,256) } - }, { - .mfr_id = MANUFACTURER_ST, - .dev_id = M29F800AB, - .name = "ST M29F800AB", - .uaddr = { - [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ - [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ - }, - .DevSize = SIZE_1MiB, - .CmdSet = P_ID_AMD_STD, - .NumEraseRegions= 4, - .regions = { - ERASEINFO(0x04000,1), - ERASEINFO(0x02000,2), - ERASEINFO(0x08000,1), - ERASEINFO(0x10000,15), - } }, { .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */ .dev_id = M29W800DT, diff --git a/trunk/drivers/mtd/devices/Kconfig b/trunk/drivers/mtd/devices/Kconfig index 811d56fd890f..ff642f8fbee7 100644 --- a/trunk/drivers/mtd/devices/Kconfig +++ b/trunk/drivers/mtd/devices/Kconfig @@ -60,22 +60,21 @@ config MTD_DATAFLASH Sometimes DataFlash chips are packaged inside MMC-format cards; at this writing, the MMC stack won't handle those. +config MTD_DATAFLASH26 + tristate "AT91RM9200 DataFlash AT26xxx" + depends on MTD && ARCH_AT91RM9200 && AT91_SPI + help + This enables access to the DataFlash chip (AT26xxx) on an + AT91RM9200-based board. + If you have such a board and such a DataFlash, say 'Y'. + config MTD_M25P80 - tristate "Support most SPI Flash chips (AT26DF, M25P, W25X, ...)" + tristate "Support for M25 SPI Flash" depends on SPI_MASTER && EXPERIMENTAL help - This enables access to most modern SPI flash chips, used for - program and data storage. Series supported include Atmel AT26DF, - Spansion S25SL, SST 25VF, ST M25P, and Winbond W25X. Other chips - are supported as well. See the driver source for the current list, - or to add other chips. - - Note that the original DataFlash chips (AT45 series, not AT26DF), - need an entirely different driver. - - Set up your spi devices with the right board-specific platform data, - if you want to specify device partitioning or to use a device which - doesn't support the JEDEC ID instruction. + This enables access to ST M25P80 and similar SPI flash chips, + used for program and data storage. Set up your spi devices + with the right board-specific platform data. config MTD_SLRAM tristate "Uncached system RAM" diff --git a/trunk/drivers/mtd/devices/Makefile b/trunk/drivers/mtd/devices/Makefile index 0f788d5c4bf8..8ab568b3f533 100644 --- a/trunk/drivers/mtd/devices/Makefile +++ b/trunk/drivers/mtd/devices/Makefile @@ -16,4 +16,5 @@ obj-$(CONFIG_MTD_MTDRAM) += mtdram.o obj-$(CONFIG_MTD_LART) += lart.o obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o +obj-$(CONFIG_MTD_DATAFLASH26) += at91_dataflash26.o obj-$(CONFIG_MTD_M25P80) += m25p80.o diff --git a/trunk/drivers/mtd/devices/at91_dataflash26.c b/trunk/drivers/mtd/devices/at91_dataflash26.c new file mode 100644 index 000000000000..64ce37f986fc --- /dev/null +++ b/trunk/drivers/mtd/devices/at91_dataflash26.c @@ -0,0 +1,485 @@ +/* + * Atmel DataFlash driver for Atmel AT91RM9200 (Thunder) + * This is a largely modified version of at91_dataflash.c that + * supports AT26xxx dataflash chips. The original driver supports + * AT45xxx chips. + * + * Note: This driver was only tested with an AT26F004. It should be + * easy to make it work with other AT26xxx dataflash devices, though. + * + * Copyright (C) 2007 Hans J. Koch + * original Copyright (C) SAN People (Pty) Ltd + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. +*/ + +#include +#include +#include +#include + +#include + +#define DATAFLASH_MAX_DEVICES 4 /* max number of dataflash devices */ + +#define MANUFACTURER_ID_ATMEL 0x1F + +/* command codes */ + +#define AT26_OP_READ_STATUS 0x05 +#define AT26_OP_READ_DEV_ID 0x9F +#define AT26_OP_ERASE_PAGE_4K 0x20 +#define AT26_OP_READ_ARRAY_FAST 0x0B +#define AT26_OP_SEQUENTIAL_WRITE 0xAF +#define AT26_OP_WRITE_ENABLE 0x06 +#define AT26_OP_WRITE_DISABLE 0x04 +#define AT26_OP_SECTOR_PROTECT 0x36 +#define AT26_OP_SECTOR_UNPROTECT 0x39 + +/* status register bits */ + +#define AT26_STATUS_BUSY 0x01 +#define AT26_STATUS_WRITE_ENABLE 0x02 + +struct dataflash_local +{ + int spi; /* SPI chip-select number */ + unsigned int page_size; /* number of bytes per page */ +}; + + +/* Detected DataFlash devices */ +static struct mtd_info* mtd_devices[DATAFLASH_MAX_DEVICES]; +static int nr_devices = 0; + +/* Allocate a single SPI transfer descriptor. We're assuming that if multiple + SPI transfers occur at the same time, spi_access_bus() will serialize them. + If this is not valid, then either (i) each dataflash 'priv' structure + needs it's own transfer descriptor, (ii) we lock this one, or (iii) use + another mechanism. */ +static struct spi_transfer_list* spi_transfer_desc; + +/* + * Perform a SPI transfer to access the DataFlash device. + */ +static int do_spi_transfer(int nr, char* tx, int tx_len, char* rx, int rx_len, + char* txnext, int txnext_len, char* rxnext, int rxnext_len) +{ + struct spi_transfer_list* list = spi_transfer_desc; + + list->tx[0] = tx; list->txlen[0] = tx_len; + list->rx[0] = rx; list->rxlen[0] = rx_len; + + list->tx[1] = txnext; list->txlen[1] = txnext_len; + list->rx[1] = rxnext; list->rxlen[1] = rxnext_len; + + list->nr_transfers = nr; + /* Note: spi_transfer() always returns 0, there are no error checks */ + return spi_transfer(list); +} + +/* + * Return the status of the DataFlash device. + */ +static unsigned char at91_dataflash26_status(void) +{ + unsigned char command[2]; + + command[0] = AT26_OP_READ_STATUS; + command[1] = 0; + + do_spi_transfer(1, command, 2, command, 2, NULL, 0, NULL, 0); + + return command[1]; +} + +/* + * Poll the DataFlash device until it is READY. + */ +static unsigned char at91_dataflash26_waitready(void) +{ + unsigned char status; + + while (1) { + status = at91_dataflash26_status(); + if (!(status & AT26_STATUS_BUSY)) + return status; + } +} + +/* + * Enable/disable write access + */ + static void at91_dataflash26_write_enable(int enable) +{ + unsigned char cmd[2]; + + DEBUG(MTD_DEBUG_LEVEL3, "write_enable: enable=%i\n", enable); + + if (enable) + cmd[0] = AT26_OP_WRITE_ENABLE; + else + cmd[0] = AT26_OP_WRITE_DISABLE; + cmd[1] = 0; + + do_spi_transfer(1, cmd, 2, cmd, 2, NULL, 0, NULL, 0); +} + +/* + * Protect/unprotect sector + */ + static void at91_dataflash26_sector_protect(loff_t addr, int protect) +{ + unsigned char cmd[4]; + + DEBUG(MTD_DEBUG_LEVEL3, "sector_protect: addr=0x%06x prot=%d\n", + addr, protect); + + if (protect) + cmd[0] = AT26_OP_SECTOR_PROTECT; + else + cmd[0] = AT26_OP_SECTOR_UNPROTECT; + cmd[1] = (addr & 0x00FF0000) >> 16; + cmd[2] = (addr & 0x0000FF00) >> 8; + cmd[3] = (addr & 0x000000FF); + + do_spi_transfer(1, cmd, 4, cmd, 4, NULL, 0, NULL, 0); +} + +/* + * Erase blocks of flash. + */ +static int at91_dataflash26_erase(struct mtd_info *mtd, + struct erase_info *instr) +{ + struct dataflash_local *priv = (struct dataflash_local *) mtd->priv; + unsigned char cmd[4]; + + DEBUG(MTD_DEBUG_LEVEL1, "dataflash_erase: addr=0x%06x len=%i\n", + instr->addr, instr->len); + + /* Sanity checks */ + if (priv->page_size != 4096) + return -EINVAL; /* Can't handle other sizes at the moment */ + + if ( ((instr->len % mtd->erasesize) != 0) + || ((instr->len % priv->page_size) != 0) + || ((instr->addr % priv->page_size) != 0) + || ((instr->addr + instr->len) > mtd->size)) + return -EINVAL; + + spi_access_bus(priv->spi); + + while (instr->len > 0) { + at91_dataflash26_write_enable(1); + at91_dataflash26_sector_protect(instr->addr, 0); + at91_dataflash26_write_enable(1); + cmd[0] = AT26_OP_ERASE_PAGE_4K; + cmd[1] = (instr->addr & 0x00FF0000) >> 16; + cmd[2] = (instr->addr & 0x0000FF00) >> 8; + cmd[3] = (instr->addr & 0x000000FF); + + DEBUG(MTD_DEBUG_LEVEL3, "ERASE: (0x%02x) 0x%02x 0x%02x" + "0x%02x\n", + cmd[0], cmd[1], cmd[2], cmd[3]); + + do_spi_transfer(1, cmd, 4, cmd, 4, NULL, 0, NULL, 0); + at91_dataflash26_waitready(); + + instr->addr += priv->page_size; /* next page */ + instr->len -= priv->page_size; + } + + at91_dataflash26_write_enable(0); + spi_release_bus(priv->spi); + + /* Inform MTD subsystem that erase is complete */ + instr->state = MTD_ERASE_DONE; + if (instr->callback) + instr->callback(instr); + + return 0; +} + +/* + * Read from the DataFlash device. + * from : Start offset in flash device + * len : Number of bytes to read + * retlen : Number of bytes actually read + * buf : Buffer that will receive data + */ +static int at91_dataflash26_read(struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf) +{ + struct dataflash_local *priv = (struct dataflash_local *) mtd->priv; + unsigned char cmd[5]; + + DEBUG(MTD_DEBUG_LEVEL1, "dataflash_read: %lli .. %lli\n", + from, from+len); + + *retlen = 0; + + /* Sanity checks */ + if (!len) + return 0; + if (from + len > mtd->size) + return -EINVAL; + + cmd[0] = AT26_OP_READ_ARRAY_FAST; + cmd[1] = (from & 0x00FF0000) >> 16; + cmd[2] = (from & 0x0000FF00) >> 8; + cmd[3] = (from & 0x000000FF); + /* cmd[4] is a "Don't care" byte */ + + DEBUG(MTD_DEBUG_LEVEL3, "READ: (0x%02x) 0x%02x 0x%02x 0x%02x\n", + cmd[0], cmd[1], cmd[2], cmd[3]); + + spi_access_bus(priv->spi); + do_spi_transfer(2, cmd, 5, cmd, 5, buf, len, buf, len); + spi_release_bus(priv->spi); + + *retlen = len; + return 0; +} + +/* + * Write to the DataFlash device. + * to : Start offset in flash device + * len : Number of bytes to write + * retlen : Number of bytes actually written + * buf : Buffer containing the data + */ +static int at91_dataflash26_write(struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf) +{ + struct dataflash_local *priv = (struct dataflash_local *) mtd->priv; + unsigned int addr, buf_index = 0; + int ret = -EIO, sector, last_sector; + unsigned char status, cmd[5]; + + DEBUG(MTD_DEBUG_LEVEL1, "dataflash_write: %lli .. %lli\n", to, to+len); + + *retlen = 0; + + /* Sanity checks */ + if (!len) + return 0; + if (to + len > mtd->size) + return -EINVAL; + + spi_access_bus(priv->spi); + + addr = to; + last_sector = -1; + + while (buf_index < len) { + sector = addr / priv->page_size; + /* Write first byte if a new sector begins */ + if (sector != last_sector) { + at91_dataflash26_write_enable(1); + at91_dataflash26_sector_protect(addr, 0); + at91_dataflash26_write_enable(1); + + /* Program first byte of a new sector */ + cmd[0] = AT26_OP_SEQUENTIAL_WRITE; + cmd[1] = (addr & 0x00FF0000) >> 16; + cmd[2] = (addr & 0x0000FF00) >> 8; + cmd[3] = (addr & 0x000000FF); + cmd[4] = buf[buf_index++]; + do_spi_transfer(1, cmd, 5, cmd, 5, NULL, 0, NULL, 0); + status = at91_dataflash26_waitready(); + addr++; + /* On write errors, the chip resets the write enable + flag. This also happens after the last byte of a + sector is successfully programmed. */ + if ( ( !(status & AT26_STATUS_WRITE_ENABLE)) + && ((addr % priv->page_size) != 0) ) { + DEBUG(MTD_DEBUG_LEVEL1, + "write error1: addr=0x%06x, " + "status=0x%02x\n", addr, status); + goto write_err; + } + (*retlen)++; + last_sector = sector; + } + + /* Write subsequent bytes in the same sector */ + cmd[0] = AT26_OP_SEQUENTIAL_WRITE; + cmd[1] = buf[buf_index++]; + do_spi_transfer(1, cmd, 2, cmd, 2, NULL, 0, NULL, 0); + status = at91_dataflash26_waitready(); + addr++; + + if ( ( !(status & AT26_STATUS_WRITE_ENABLE)) + && ((addr % priv->page_size) != 0) ) { + DEBUG(MTD_DEBUG_LEVEL1, "write error2: addr=0x%06x, " + "status=0x%02x\n", addr, status); + goto write_err; + } + + (*retlen)++; + } + + ret = 0; + at91_dataflash26_write_enable(0); +write_err: + spi_release_bus(priv->spi); + return ret; +} + +/* + * Initialize and register DataFlash device with MTD subsystem. + */ +static int __init add_dataflash(int channel, char *name, int nr_pages, + int pagesize) +{ + struct mtd_info *device; + struct dataflash_local *priv; + + if (nr_devices >= DATAFLASH_MAX_DEVICES) { + printk(KERN_ERR "at91_dataflash26: Too many devices " + "detected\n"); + return 0; + } + + device = kzalloc(sizeof(struct mtd_info) + strlen(name) + 8, + GFP_KERNEL); + if (!device) + return -ENOMEM; + + device->name = (char *)&device[1]; + sprintf(device->name, "%s.spi%d", name, channel); + device->size = nr_pages * pagesize; + device->erasesize = pagesize; + device->owner = THIS_MODULE; + device->type = MTD_DATAFLASH; + device->flags = MTD_CAP_NORFLASH; + device->erase = at91_dataflash26_erase; + device->read = at91_dataflash26_read; + device->write = at91_dataflash26_write; + + priv = (struct dataflash_local *)kzalloc(sizeof(struct dataflash_local), + GFP_KERNEL); + if (!priv) { + kfree(device); + return -ENOMEM; + } + + priv->spi = channel; + priv->page_size = pagesize; + device->priv = priv; + + mtd_devices[nr_devices] = device; + nr_devices++; + printk(KERN_INFO "at91_dataflash26: %s detected [spi%i] (%i bytes)\n", + name, channel, device->size); + + return add_mtd_device(device); +} + +/* + * Detect and initialize DataFlash device connected to specified SPI channel. + * + */ + +struct dataflash26_types { + unsigned char id0; + unsigned char id1; + char *name; + int pagesize; + int nr_pages; +}; + +struct dataflash26_types df26_types[] = { + { + .id0 = 0x04, + .id1 = 0x00, + .name = "AT26F004", + .pagesize = 4096, + .nr_pages = 128, + }, + { + .id0 = 0x45, + .id1 = 0x01, + .name = "AT26DF081A", /* Not tested ! */ + .pagesize = 4096, + .nr_pages = 256, + }, +}; + +static int __init at91_dataflash26_detect(int channel) +{ + unsigned char status, cmd[5]; + int i; + + spi_access_bus(channel); + status = at91_dataflash26_status(); + + if (status == 0 || status == 0xff) { + printk(KERN_ERR "at91_dataflash26_detect: status error %d\n", + status); + spi_release_bus(channel); + return -ENODEV; + } + + cmd[0] = AT26_OP_READ_DEV_ID; + do_spi_transfer(1, cmd, 5, cmd, 5, NULL, 0, NULL, 0); + spi_release_bus(channel); + + if (cmd[1] != MANUFACTURER_ID_ATMEL) + return -ENODEV; + + for (i = 0; i < ARRAY_SIZE(df26_types); i++) { + if ( cmd[2] == df26_types[i].id0 + && cmd[3] == df26_types[i].id1) + return add_dataflash(channel, + df26_types[i].name, + df26_types[i].nr_pages, + df26_types[i].pagesize); + } + + printk(KERN_ERR "at91_dataflash26_detect: Unsupported device " + "(0x%02x/0x%02x)\n", cmd[2], cmd[3]); + return -ENODEV; +} + +static int __init at91_dataflash26_init(void) +{ + spi_transfer_desc = kmalloc(sizeof(struct spi_transfer_list), + GFP_KERNEL); + if (!spi_transfer_desc) + return -ENOMEM; + + /* DataFlash (SPI chip select 0) */ + at91_dataflash26_detect(0); + +#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD + /* DataFlash card (SPI chip select 3) */ + at91_dataflash26_detect(3); +#endif + return 0; +} + +static void __exit at91_dataflash26_exit(void) +{ + int i; + + for (i = 0; i < DATAFLASH_MAX_DEVICES; i++) { + if (mtd_devices[i]) { + del_mtd_device(mtd_devices[i]); + kfree(mtd_devices[i]->priv); + kfree(mtd_devices[i]); + } + } + nr_devices = 0; + kfree(spi_transfer_desc); +} + +module_init(at91_dataflash26_init); +module_exit(at91_dataflash26_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Hans J. Koch"); +MODULE_DESCRIPTION("DataFlash AT26xxx driver for Atmel AT91RM9200"); diff --git a/trunk/drivers/mtd/devices/docprobe.c b/trunk/drivers/mtd/devices/docprobe.c index d8cc94ec4e50..54aa75907640 100644 --- a/trunk/drivers/mtd/devices/docprobe.c +++ b/trunk/drivers/mtd/devices/docprobe.c @@ -81,7 +81,9 @@ static unsigned long __initdata doc_locations[] = { #endif /* CONFIG_MTD_DOCPROBE_HIGH */ #elif defined(__PPC__) 0xe4000000, -#else +#elif defined(CONFIG_MOMENCO_OCELOT_G) + 0xff000000, +##else #warning Unknown architecture for DiskOnChip. No default probe locations defined #endif 0xffffffff }; diff --git a/trunk/drivers/mtd/devices/m25p80.c b/trunk/drivers/mtd/devices/m25p80.c index 98df5bcc02f3..78c2511ae9e0 100644 --- a/trunk/drivers/mtd/devices/m25p80.c +++ b/trunk/drivers/mtd/devices/m25p80.c @@ -1,5 +1,5 @@ /* - * MTD SPI driver for ST M25Pxx (and similar) serial flash chips + * MTD SPI driver for ST M25Pxx flash chips * * Author: Mike Lavender, mike@steroidmicros.com * @@ -19,32 +19,33 @@ #include #include #include -#include - +#include #include #include - #include #include +#include + + +/* NOTE: AT 25F and SST 25LF series are very similar, + * but commands for sector erase and chip id differ... + */ #define FLASH_PAGESIZE 256 /* Flash opcodes. */ -#define OPCODE_WREN 0x06 /* Write enable */ -#define OPCODE_RDSR 0x05 /* Read status register */ -#define OPCODE_READ 0x03 /* Read data bytes (low frequency) */ -#define OPCODE_FAST_READ 0x0b /* Read data bytes (high frequency) */ -#define OPCODE_PP 0x02 /* Page program (up to 256 bytes) */ -#define OPCODE_BE_4K 0x20 /* Erase 4KiB block */ -#define OPCODE_BE_32K 0x52 /* Erase 32KiB block */ -#define OPCODE_SE 0xd8 /* Sector erase (usually 64KiB) */ +#define OPCODE_WREN 6 /* Write enable */ +#define OPCODE_RDSR 5 /* Read status register */ +#define OPCODE_READ 3 /* Read data bytes */ +#define OPCODE_PP 2 /* Page program */ +#define OPCODE_SE 0xd8 /* Sector erase */ +#define OPCODE_RES 0xab /* Read Electronic Signature */ #define OPCODE_RDID 0x9f /* Read JEDEC ID */ /* Status Register bits. */ #define SR_WIP 1 /* Write in progress */ #define SR_WEL 2 /* Write enable latch */ -/* meaning of other SR_* bits may differ between vendors */ #define SR_BP0 4 /* Block protect 0 */ #define SR_BP1 8 /* Block protect 1 */ #define SR_BP2 0x10 /* Block protect 2 */ @@ -64,10 +65,9 @@ struct m25p { struct spi_device *spi; - struct mutex lock; + struct semaphore lock; struct mtd_info mtd; - unsigned partitioned:1; - u8 erase_opcode; + unsigned partitioned; u8 command[4]; }; @@ -150,9 +150,8 @@ static int wait_till_ready(struct m25p *flash) */ static int erase_sector(struct m25p *flash, u32 offset) { - DEBUG(MTD_DEBUG_LEVEL3, "%s: %s %dKiB at 0x%08x\n", - flash->spi->dev.bus_id, __FUNCTION__, - flash->mtd.erasesize / 1024, offset); + DEBUG(MTD_DEBUG_LEVEL3, "%s: %s at 0x%08x\n", flash->spi->dev.bus_id, + __FUNCTION__, offset); /* Wait until finished previous write command. */ if (wait_till_ready(flash)) @@ -162,7 +161,7 @@ static int erase_sector(struct m25p *flash, u32 offset) write_enable(flash); /* Set up command buffer. */ - flash->command[0] = flash->erase_opcode; + flash->command[0] = OPCODE_SE; flash->command[1] = offset >> 16; flash->command[2] = offset >> 8; flash->command[3] = offset; @@ -202,17 +201,13 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr) addr = instr->addr; len = instr->len; - mutex_lock(&flash->lock); - - /* REVISIT in some cases we could speed up erasing large regions - * by using OPCODE_SE instead of OPCODE_BE_4K - */ + down(&flash->lock); /* now erase those sectors */ while (len) { if (erase_sector(flash, addr)) { instr->state = MTD_ERASE_FAILED; - mutex_unlock(&flash->lock); + up(&flash->lock); return -EIO; } @@ -220,7 +215,7 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr) len -= mtd->erasesize; } - mutex_unlock(&flash->lock); + up(&flash->lock); instr->state = MTD_ERASE_DONE; mtd_erase_callback(instr); @@ -265,19 +260,16 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, if (retlen) *retlen = 0; - mutex_lock(&flash->lock); + down(&flash->lock); /* Wait till previous write/erase is done. */ if (wait_till_ready(flash)) { /* REVISIT status return?? */ - mutex_unlock(&flash->lock); + up(&flash->lock); return 1; } - /* FIXME switch to OPCODE_FAST_READ. It's required for higher - * clocks; and at this writing, every chip this driver handles - * supports that opcode. - */ + /* NOTE: OPCODE_FAST_READ (if available) is faster... */ /* Set up the write data buffer. */ flash->command[0] = OPCODE_READ; @@ -289,7 +281,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, *retlen = m.actual_length - sizeof(flash->command); - mutex_unlock(&flash->lock); + up(&flash->lock); return 0; } @@ -331,7 +323,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len, t[1].tx_buf = buf; spi_message_add_tail(&t[1], &m); - mutex_lock(&flash->lock); + down(&flash->lock); /* Wait until finished previous write command. */ if (wait_till_ready(flash)) @@ -389,10 +381,10 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len, if (retlen) *retlen += m.actual_length - sizeof(flash->command); - } - } + } + } - mutex_unlock(&flash->lock); + up(&flash->lock); return 0; } @@ -406,118 +398,24 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len, struct flash_info { char *name; - - /* JEDEC id zero means "no ID" (most older chips); otherwise it has - * a high byte of zero plus three data bytes: the manufacturer id, - * then a two byte device id. - */ - u32 jedec_id; - - /* The size listed here is what works with OPCODE_SE, which isn't - * necessarily called a "sector" by the vendor. - */ + u8 id; + u16 jedec_id; unsigned sector_size; - u16 n_sectors; - - u16 flags; -#define SECT_4K 0x01 /* OPCODE_BE_4K works uniformly */ + unsigned n_sectors; }; - -/* NOTE: double check command sets and memory organization when you add - * more flash chips. This current list focusses on newer chips, which - * have been converging on command sets which including JEDEC ID. - */ static struct flash_info __devinitdata m25p_data [] = { - - /* Atmel -- some are (confusingly) marketed as "DataFlash" */ - { "at25fs010", 0x1f6601, 32 * 1024, 4, SECT_4K, }, - { "at25fs040", 0x1f6604, 64 * 1024, 8, SECT_4K, }, - - { "at25df041a", 0x1f4401, 64 * 1024, 8, SECT_4K, }, - - { "at26f004", 0x1f0400, 64 * 1024, 8, SECT_4K, }, - { "at26df081a", 0x1f4501, 64 * 1024, 16, SECT_4K, }, - { "at26df161a", 0x1f4601, 64 * 1024, 32, SECT_4K, }, - { "at26df321", 0x1f4701, 64 * 1024, 64, SECT_4K, }, - - /* Spansion -- single (large) sector size only, at least - * for the chips listed here (without boot sectors). - */ - { "s25sl004a", 0x010212, 64 * 1024, 8, }, - { "s25sl008a", 0x010213, 64 * 1024, 16, }, - { "s25sl016a", 0x010214, 64 * 1024, 32, }, - { "s25sl032a", 0x010215, 64 * 1024, 64, }, - { "s25sl064a", 0x010216, 64 * 1024, 128, }, - - /* SST -- large erase sizes are "overlays", "sectors" are 4K */ - { "sst25vf040b", 0xbf258d, 64 * 1024, 8, SECT_4K, }, - { "sst25vf080b", 0xbf258e, 64 * 1024, 16, SECT_4K, }, - { "sst25vf016b", 0xbf2541, 64 * 1024, 32, SECT_4K, }, - { "sst25vf032b", 0xbf254a, 64 * 1024, 64, SECT_4K, }, - - /* ST Microelectronics -- newer production may have feature updates */ - { "m25p05", 0x202010, 32 * 1024, 2, }, - { "m25p10", 0x202011, 32 * 1024, 4, }, - { "m25p20", 0x202012, 64 * 1024, 4, }, - { "m25p40", 0x202013, 64 * 1024, 8, }, - { "m25p80", 0, 64 * 1024, 16, }, - { "m25p16", 0x202015, 64 * 1024, 32, }, - { "m25p32", 0x202016, 64 * 1024, 64, }, - { "m25p64", 0x202017, 64 * 1024, 128, }, - { "m25p128", 0x202018, 256 * 1024, 64, }, - - { "m45pe80", 0x204014, 64 * 1024, 16, }, - { "m45pe16", 0x204015, 64 * 1024, 32, }, - - { "m25pe80", 0x208014, 64 * 1024, 16, }, - { "m25pe16", 0x208015, 64 * 1024, 32, SECT_4K, }, - - /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ - { "w25x10", 0xef3011, 64 * 1024, 2, SECT_4K, }, - { "w25x20", 0xef3012, 64 * 1024, 4, SECT_4K, }, - { "w25x40", 0xef3013, 64 * 1024, 8, SECT_4K, }, - { "w25x80", 0xef3014, 64 * 1024, 16, SECT_4K, }, - { "w25x16", 0xef3015, 64 * 1024, 32, SECT_4K, }, - { "w25x32", 0xef3016, 64 * 1024, 64, SECT_4K, }, - { "w25x64", 0xef3017, 64 * 1024, 128, SECT_4K, }, + /* REVISIT: fill in JEDEC ids, for parts that have them */ + { "m25p05", 0x05, 0x2010, 32 * 1024, 2 }, + { "m25p10", 0x10, 0x2011, 32 * 1024, 4 }, + { "m25p20", 0x11, 0x2012, 64 * 1024, 4 }, + { "m25p40", 0x12, 0x2013, 64 * 1024, 8 }, + { "m25p80", 0x13, 0x0000, 64 * 1024, 16 }, + { "m25p16", 0x14, 0x2015, 64 * 1024, 32 }, + { "m25p32", 0x15, 0x2016, 64 * 1024, 64 }, + { "m25p64", 0x16, 0x2017, 64 * 1024, 128 }, }; -static struct flash_info *__devinit jedec_probe(struct spi_device *spi) -{ - int tmp; - u8 code = OPCODE_RDID; - u8 id[3]; - u32 jedec; - struct flash_info *info; - - /* JEDEC also defines an optional "extended device information" - * string for after vendor-specific data, after the three bytes - * we use here. Supporting some chips might require using it. - */ - tmp = spi_write_then_read(spi, &code, 1, id, 3); - if (tmp < 0) { - DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n", - spi->dev.bus_id, tmp); - return NULL; - } - jedec = id[0]; - jedec = jedec << 8; - jedec |= id[1]; - jedec = jedec << 8; - jedec |= id[2]; - - for (tmp = 0, info = m25p_data; - tmp < ARRAY_SIZE(m25p_data); - tmp++, info++) { - if (info->jedec_id == jedec) - return info; - } - dev_err(&spi->dev, "unrecognized JEDEC id %06x\n", jedec); - return NULL; -} - - /* * board specific setup should have ensured the SPI clock used here * matches what the READ command supports, at least until this driver @@ -531,51 +429,37 @@ static int __devinit m25p_probe(struct spi_device *spi) unsigned i; /* Platform data helps sort out which chip type we have, as - * well as how this board partitions it. If we don't have - * a chip ID, try the JEDEC id commands; they'll work for most - * newer chips, even if we don't recognize the particular chip. + * well as how this board partitions it. */ data = spi->dev.platform_data; - if (data && data->type) { - for (i = 0, info = m25p_data; - i < ARRAY_SIZE(m25p_data); - i++, info++) { - if (strcmp(data->type, info->name) == 0) - break; - } - - /* unrecognized chip? */ - if (i == ARRAY_SIZE(m25p_data)) { - DEBUG(MTD_DEBUG_LEVEL0, "%s: unrecognized id %s\n", - spi->dev.bus_id, data->type); - info = NULL; - - /* recognized; is that chip really what's there? */ - } else if (info->jedec_id) { - struct flash_info *chip = jedec_probe(spi); - - if (!chip || chip != info) { - dev_warn(&spi->dev, "found %s, expected %s\n", - chip ? chip->name : "UNKNOWN", - info->name); - info = NULL; - } - } - } else - info = jedec_probe(spi); + if (!data || !data->type) { + /* FIXME some chips can identify themselves with RES + * or JEDEC get-id commands. Try them ... + */ + DEBUG(MTD_DEBUG_LEVEL1, "%s: no chip id\n", + spi->dev.bus_id); + return -ENODEV; + } - if (!info) + for (i = 0, info = m25p_data; i < ARRAY_SIZE(m25p_data); i++, info++) { + if (strcmp(data->type, info->name) == 0) + break; + } + if (i == ARRAY_SIZE(m25p_data)) { + DEBUG(MTD_DEBUG_LEVEL1, "%s: unrecognized id %s\n", + spi->dev.bus_id, data->type); return -ENODEV; + } flash = kzalloc(sizeof *flash, GFP_KERNEL); if (!flash) return -ENOMEM; flash->spi = spi; - mutex_init(&flash->lock); + init_MUTEX(&flash->lock); dev_set_drvdata(&spi->dev, flash); - if (data && data->name) + if (data->name) flash->mtd.name = data->name; else flash->mtd.name = spi->dev.bus_id; @@ -584,25 +468,17 @@ static int __devinit m25p_probe(struct spi_device *spi) flash->mtd.writesize = 1; flash->mtd.flags = MTD_CAP_NORFLASH; flash->mtd.size = info->sector_size * info->n_sectors; + flash->mtd.erasesize = info->sector_size; flash->mtd.erase = m25p80_erase; flash->mtd.read = m25p80_read; flash->mtd.write = m25p80_write; - /* prefer "small sector" erase if possible */ - if (info->flags & SECT_4K) { - flash->erase_opcode = OPCODE_BE_4K; - flash->mtd.erasesize = 4096; - } else { - flash->erase_opcode = OPCODE_SE; - flash->mtd.erasesize = info->sector_size; - } - dev_info(&spi->dev, "%s (%d Kbytes)\n", info->name, flash->mtd.size / 1024); DEBUG(MTD_DEBUG_LEVEL2, - "mtd .name = %s, .size = 0x%.8x (%uMiB) " - ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n", + "mtd .name = %s, .size = 0x%.8x (%uM) " + ".erasesize = 0x%.8x (%uK) .numeraseregions = %d\n", flash->mtd.name, flash->mtd.size, flash->mtd.size / (1024*1024), flash->mtd.erasesize, flash->mtd.erasesize / 1024, @@ -612,7 +488,7 @@ static int __devinit m25p_probe(struct spi_device *spi) for (i = 0; i < flash->mtd.numeraseregions; i++) DEBUG(MTD_DEBUG_LEVEL2, "mtd.eraseregions[%d] = { .offset = 0x%.8x, " - ".erasesize = 0x%.8x (%uKiB), " + ".erasesize = 0x%.8x (%uK), " ".numblocks = %d }\n", i, flash->mtd.eraseregions[i].offset, flash->mtd.eraseregions[i].erasesize, @@ -640,14 +516,14 @@ static int __devinit m25p_probe(struct spi_device *spi) } if (nr_parts > 0) { - for (i = 0; i < nr_parts; i++) { + for (i = 0; i < data->nr_parts; i++) { DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = " "{.name = %s, .offset = 0x%.8x, " - ".size = 0x%.8x (%uKiB) }\n", - i, parts[i].name, - parts[i].offset, - parts[i].size, - parts[i].size / 1024); + ".size = 0x%.8x (%uK) }\n", + i, data->parts[i].name, + data->parts[i].offset, + data->parts[i].size, + data->parts[i].size / 1024); } flash->partitioned = 1; return add_mtd_partitions(&flash->mtd, parts, nr_parts); @@ -684,11 +560,6 @@ static struct spi_driver m25p80_driver = { }, .probe = m25p_probe, .remove = __devexit_p(m25p_remove), - - /* REVISIT: many of these chips have deep power-down modes, which - * should clearly be entered on suspend() to minimize power use. - * And also when they're otherwise idle... - */ }; diff --git a/trunk/drivers/mtd/devices/mtd_dataflash.c b/trunk/drivers/mtd/devices/mtd_dataflash.c index a5ed6d232c35..a987e917f4e0 100644 --- a/trunk/drivers/mtd/devices/mtd_dataflash.c +++ b/trunk/drivers/mtd/devices/mtd_dataflash.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include @@ -90,7 +89,7 @@ struct dataflash { unsigned short page_offset; /* offset in flash address */ unsigned int page_size; /* of bytes per page */ - struct mutex lock; + struct semaphore lock; struct spi_device *spi; struct mtd_info mtd; @@ -168,7 +167,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr) x.len = 4; spi_message_add_tail(&x, &msg); - mutex_lock(&priv->lock); + down(&priv->lock); while (instr->len > 0) { unsigned int pageaddr; int status; @@ -211,7 +210,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr) instr->len -= priv->page_size; } } - mutex_unlock(&priv->lock); + up(&priv->lock); /* Inform MTD subsystem that erase is complete */ instr->state = MTD_ERASE_DONE; @@ -267,7 +266,7 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len, x[1].len = len; spi_message_add_tail(&x[1], &msg); - mutex_lock(&priv->lock); + down(&priv->lock); /* Continuous read, max clock = f(car) which may be less than * the peak rate available. Some chips support commands with @@ -280,7 +279,7 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len, /* plus 4 "don't care" bytes */ status = spi_sync(priv->spi, &msg); - mutex_unlock(&priv->lock); + up(&priv->lock); if (status >= 0) { *retlen = msg.actual_length - 8; @@ -337,7 +336,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len, else writelen = len; - mutex_lock(&priv->lock); + down(&priv->lock); while (remaining > 0) { DEBUG(MTD_DEBUG_LEVEL3, "write @ %i:%i len=%i\n", pageaddr, offset, writelen); @@ -442,7 +441,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len, else writelen = remaining; } - mutex_unlock(&priv->lock); + up(&priv->lock); return status; } @@ -464,7 +463,7 @@ add_dataflash(struct spi_device *spi, char *name, if (!priv) return -ENOMEM; - mutex_init(&priv->lock); + init_MUTEX(&priv->lock); priv->spi = spi; priv->page_size = pagesize; priv->page_offset = pageoffset; diff --git a/trunk/drivers/mtd/devices/pmc551.c b/trunk/drivers/mtd/devices/pmc551.c index 7060a0895ce2..e8f686f7a357 100644 --- a/trunk/drivers/mtd/devices/pmc551.c +++ b/trunk/drivers/mtd/devices/pmc551.c @@ -30,8 +30,8 @@ * * Notes: * Due to what I assume is more buggy SROM, the 64M PMC551 I - * have available claims that all 4 of its DRAM banks have 64MiB - * of ram configured (making a grand total of 256MiB onboard). + * have available claims that all 4 of it's DRAM banks have 64M + * of ram configured (making a grand total of 256M onboard). * This is slightly annoying since the BAR0 size reflects the * aperture size, not the dram size, and the V370PDC supplies no * other method for memory size discovery. This problem is @@ -70,7 +70,7 @@ * made the memory unusable, added a fix to code to touch up * the DRAM some. * - * Bugs/FIXMEs: + * Bugs/FIXME's: * * MUST fix the init function to not spin on a register * waiting for it to set .. this does not safely handle busted * devices that never reset the register correctly which will @@ -562,10 +562,10 @@ static u32 fixup_pmc551(struct pci_dev *dev) /* * Some screen fun */ - printk(KERN_DEBUG "pmc551: %d%sB (0x%x) of %sprefetchable memory at " + printk(KERN_DEBUG "pmc551: %d%c (0x%x) of %sprefetchable memory at " "0x%llx\n", (size < 1024) ? size : (size < 1048576) ? size >> 10 : size >> 20, - (size < 1024) ? "" : (size < 1048576) ? "Ki" : "Mi", size, + (size < 1024) ? 'B' : (size < 1048576) ? 'K' : 'M', size, ((dcmd & (0x1 << 3)) == 0) ? "non-" : "", (unsigned long long)pci_resource_start(dev, 0)); @@ -649,10 +649,14 @@ MODULE_DESCRIPTION(PMC551_VERSION); * Stuff these outside the ifdef so as to not bust compiled in driver support */ static int msize = 0; +#if defined(CONFIG_MTD_PMC551_APERTURE_SIZE) +static int asize = CONFIG_MTD_PMC551_APERTURE_SIZE; +#else static int asize = 0; +#endif module_param(msize, int, 0); -MODULE_PARM_DESC(msize, "memory size in MiB [1 - 1024]"); +MODULE_PARM_DESC(msize, "memory size in Megabytes [1 - 1024]"); module_param(asize, int, 0); MODULE_PARM_DESC(asize, "aperture size, must be <= memsize [1-1024]"); @@ -795,7 +799,8 @@ static int __init init_pmc551(void) mtd->owner = THIS_MODULE; if (add_mtd_device(mtd)) { - printk(KERN_NOTICE "pmc551: Failed to register new device\n"); + printk(KERN_NOTICE "pmc551: Failed to register new " + "device\n"); pci_iounmap(PCI_Device, priv->start); kfree(mtd->priv); kfree(mtd); @@ -806,13 +811,13 @@ static int __init init_pmc551(void) pci_dev_get(PCI_Device); printk(KERN_NOTICE "Registered pmc551 memory device.\n"); - printk(KERN_NOTICE "Mapped %dMiB of memory from 0x%p to 0x%p\n", + printk(KERN_NOTICE "Mapped %dM of memory from 0x%p to 0x%p\n", priv->asize >> 20, priv->start, priv->start + priv->asize); - printk(KERN_NOTICE "Total memory is %d%sB\n", + printk(KERN_NOTICE "Total memory is %d%c\n", (length < 1024) ? length : (length < 1048576) ? length >> 10 : length >> 20, - (length < 1024) ? "" : (length < 1048576) ? "Ki" : "Mi"); + (length < 1024) ? 'B' : (length < 1048576) ? 'K' : 'M'); priv->nextpmc551 = pmc551list; pmc551list = mtd; found++; @@ -845,7 +850,7 @@ static void __exit cleanup_pmc551(void) pmc551list = priv->nextpmc551; if (priv->start) { - printk(KERN_DEBUG "pmc551: unmapping %dMiB starting at " + printk(KERN_DEBUG "pmc551: unmapping %dM starting at " "0x%p\n", priv->asize >> 20, priv->start); pci_iounmap(priv->dev, priv->start); } diff --git a/trunk/drivers/mtd/inftlmount.c b/trunk/drivers/mtd/inftlmount.c index b8917beeb650..ecac0e438f49 100644 --- a/trunk/drivers/mtd/inftlmount.c +++ b/trunk/drivers/mtd/inftlmount.c @@ -580,13 +580,14 @@ int INFTL_mount(struct INFTLrecord *s) logical_block = block = BLOCK_NIL; /* Temporary buffer to store ANAC numbers. */ - ANACtable = kcalloc(s->nb_blocks, sizeof(u8), GFP_KERNEL); + ANACtable = kmalloc(s->nb_blocks * sizeof(u8), GFP_KERNEL); if (!ANACtable) { printk(KERN_WARNING "INFTL: allocation of ANACtable " "failed (%zd bytes)\n", s->nb_blocks * sizeof(u8)); return -ENOMEM; } + memset(ANACtable, 0, s->nb_blocks); /* * First pass is to explore each physical unit, and construct the diff --git a/trunk/drivers/mtd/maps/Kconfig b/trunk/drivers/mtd/maps/Kconfig index cc6c73442435..3a6566adcdda 100644 --- a/trunk/drivers/mtd/maps/Kconfig +++ b/trunk/drivers/mtd/maps/Kconfig @@ -354,7 +354,7 @@ config MTD_CFI_FLAGADM config MTD_WALNUT tristate "Flash device mapped on IBM 405GP Walnut" - depends on MTD_JEDECPROBE && WALNUT + depends on MTD_JEDECPROBE && WALNUT && !PPC_MERGE help This enables access routines for the flash chips on the IBM 405GP Walnut board. If you have one of these boards and would like to @@ -370,7 +370,7 @@ config MTD_EBONY config MTD_OCOTEA tristate "Flash devices mapped on IBM 440GX Ocotea" - depends on MTD_CFI && OCOTEA + depends on MTD_CFI && OCOTEA && !PPC_MERGE help This enables access routines for the flash chips on the IBM 440GX Ocotea board. If you have one of these boards and would like to diff --git a/trunk/drivers/mtd/maps/alchemy-flash.c b/trunk/drivers/mtd/maps/alchemy-flash.c index 82811bcb0436..84fbe0e8c47e 100644 --- a/trunk/drivers/mtd/maps/alchemy-flash.c +++ b/trunk/drivers/mtd/maps/alchemy-flash.c @@ -75,6 +75,13 @@ #define BOARD_FLASH_WIDTH 2 /* 16-bits */ #endif +#ifdef CONFIG_MIPS_HYDROGEN3 +#define BOARD_MAP_NAME "Hydrogen3 Flash" +#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */ +#define BOARD_FLASH_WIDTH 4 /* 32-bits */ +#define USE_LOCAL_ACCESSORS /* why? */ +#endif + #ifdef CONFIG_MIPS_BOSPORUS #define BOARD_MAP_NAME "Bosporus Flash" #define BOARD_FLASH_SIZE 0x01000000 /* 16MB */ @@ -123,6 +130,13 @@ int __init alchemy_mtd_init(void) window_addr = 0x20000000 - BOARD_FLASH_SIZE; window_size = BOARD_FLASH_SIZE; +#ifdef CONFIG_MIPS_MIRAGE_WHY + /* Boot ROM flash bank only; no user bank */ + window_addr = 0x1C000000; + window_size = 0x04000000; + /* USERFS from 0x1C00 0000 to 0x1FC00000 */ + alchemy_partitions[0].size = 0x03C00000; +#endif /* * Static partition definition selection diff --git a/trunk/drivers/mtd/maps/nettel.c b/trunk/drivers/mtd/maps/nettel.c index 0c9b305a72e0..7b96cd02f82b 100644 --- a/trunk/drivers/mtd/maps/nettel.c +++ b/trunk/drivers/mtd/maps/nettel.c @@ -158,11 +158,68 @@ static struct notifier_block nettel_notifier_block = { nettel_reboot_notifier, NULL, 0 }; +/* + * Erase the configuration file system. + * Used to support the software reset button. + */ +static void nettel_erasecallback(struct erase_info *done) +{ + wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv; + wake_up(wait_q); +} + +static struct erase_info nettel_erase; + +int nettel_eraseconfig(void) +{ + struct mtd_info *mtd; + DECLARE_WAITQUEUE(wait, current); + wait_queue_head_t wait_q; + int ret; + + init_waitqueue_head(&wait_q); + mtd = get_mtd_device(NULL, 2); + if (!IS_ERR(mtd)) { + nettel_erase.mtd = mtd; + nettel_erase.callback = nettel_erasecallback; + nettel_erase.callback = NULL; + nettel_erase.addr = 0; + nettel_erase.len = mtd->size; + nettel_erase.priv = (u_long) &wait_q; + nettel_erase.priv = 0; + + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&wait_q, &wait); + + ret = mtd->erase(mtd, &nettel_erase); + if (ret) { + set_current_state(TASK_RUNNING); + remove_wait_queue(&wait_q, &wait); + put_mtd_device(mtd); + return(ret); + } + + schedule(); /* Wait for erase to finish. */ + remove_wait_queue(&wait_q, &wait); + + put_mtd_device(mtd); + } + + return(0); +} + +#else + +int nettel_eraseconfig(void) +{ + return(0); +} + #endif /****************************************************************************/ -static int __init nettel_init(void) +int __init nettel_init(void) { volatile unsigned long *amdpar; unsigned long amdaddr, maxsize; @@ -364,6 +421,10 @@ static int __init nettel_init(void) intel_mtd->owner = THIS_MODULE; +#ifndef CONFIG_BLK_DEV_INITRD + ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, 1); +#endif + num_intel_partitions = sizeof(nettel_intel_partitions) / sizeof(nettel_intel_partitions[0]); @@ -416,7 +477,7 @@ static int __init nettel_init(void) /****************************************************************************/ -static void __exit nettel_cleanup(void) +void __exit nettel_cleanup(void) { #ifdef CONFIG_MTD_CFI_INTELEXT unregister_reboot_notifier(&nettel_notifier_block); diff --git a/trunk/drivers/mtd/maps/physmap_of.c b/trunk/drivers/mtd/maps/physmap_of.c index fbd613968717..bbb42c35b69b 100644 --- a/trunk/drivers/mtd/maps/physmap_of.c +++ b/trunk/drivers/mtd/maps/physmap_of.c @@ -141,6 +141,7 @@ static int __devinit of_physmap_probe(struct of_device *dev, const struct of_dev err = -ENOMEM; goto err_out; } + memset(info, 0, sizeof(*info)); dev_set_drvdata(&dev->dev, info); @@ -212,6 +213,10 @@ static int __devinit of_physmap_probe(struct of_device *dev, const struct of_dev err_out: of_physmap_remove(dev); return err; + + return 0; + + } static struct of_device_id of_physmap_match[] = { diff --git a/trunk/drivers/mtd/maps/pmcmsp-flash.c b/trunk/drivers/mtd/maps/pmcmsp-flash.c index 02bde8c982ec..7e0377ec1c40 100644 --- a/trunk/drivers/mtd/maps/pmcmsp-flash.c +++ b/trunk/drivers/mtd/maps/pmcmsp-flash.c @@ -73,16 +73,13 @@ int __init init_msp_flash(void) return -ENXIO; printk(KERN_NOTICE "Found %d PMC flash devices\n", fcnt); - - msp_flash = kmalloc(fcnt * sizeof(struct map_info *), GFP_KERNEL); - msp_parts = kmalloc(fcnt * sizeof(struct mtd_partition *), GFP_KERNEL); - msp_maps = kcalloc(fcnt, sizeof(struct mtd_info), GFP_KERNEL); - if (!msp_flash || !msp_parts || !msp_maps) { - kfree(msp_maps); - kfree(msp_parts); - kfree(msp_flash); - return -ENOMEM; - } + msp_flash = (struct mtd_info **)kmalloc( + fcnt * sizeof(struct map_info *), GFP_KERNEL); + msp_parts = (struct mtd_partition **)kmalloc( + fcnt * sizeof(struct mtd_partition *), GFP_KERNEL); + msp_maps = (struct map_info *)kmalloc( + fcnt * sizeof(struct mtd_info), GFP_KERNEL); + memset(msp_maps, 0, fcnt * sizeof(struct mtd_info)); /* loop over the flash devices, initializing each */ for (i = 0; i < fcnt; i++) { @@ -98,8 +95,9 @@ int __init init_msp_flash(void) continue; } - msp_parts[i] = kcalloc(pcnt, sizeof(struct mtd_partition), - GFP_KERNEL); + msp_parts[i] = (struct mtd_partition *)kmalloc( + pcnt * sizeof(struct mtd_partition), GFP_KERNEL); + memset(msp_parts[i], 0, pcnt * sizeof(struct mtd_partition)); /* now initialize the devices proper */ flash_name[5] = '0' + i; diff --git a/trunk/drivers/mtd/maps/pmcmsp-ramroot.c b/trunk/drivers/mtd/maps/pmcmsp-ramroot.c index 30de5c0c09a9..18049bceba8d 100644 --- a/trunk/drivers/mtd/maps/pmcmsp-ramroot.c +++ b/trunk/drivers/mtd/maps/pmcmsp-ramroot.c @@ -79,6 +79,7 @@ static int __init init_rrmap(void) rr_mtd->owner = THIS_MODULE; add_mtd_device(rr_mtd); + ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, rr_mtd->index); return 0; } diff --git a/trunk/drivers/mtd/mtd_blkdevs.c b/trunk/drivers/mtd/mtd_blkdevs.c index 74d9d30edabd..ef89780eb9d6 100644 --- a/trunk/drivers/mtd/mtd_blkdevs.c +++ b/trunk/drivers/mtd/mtd_blkdevs.c @@ -24,10 +24,11 @@ #include #include -#include "mtdcore.h" - static LIST_HEAD(blktrans_majors); +extern struct mutex mtd_table_mutex; +extern struct mtd_info *mtd_table[]; + struct mtd_blkcore_priv { struct task_struct *thread; struct request_queue *rq; @@ -201,7 +202,7 @@ static int blktrans_ioctl(struct inode *inode, struct file *file, } } -static struct block_device_operations mtd_blktrans_ops = { +struct block_device_operations mtd_blktrans_ops = { .owner = THIS_MODULE, .open = blktrans_open, .release = blktrans_release, diff --git a/trunk/drivers/mtd/mtdchar.c b/trunk/drivers/mtd/mtdchar.c index 22ed96c4b7bd..d091b2430b48 100644 --- a/trunk/drivers/mtd/mtdchar.c +++ b/trunk/drivers/mtd/mtdchar.c @@ -136,8 +136,7 @@ static int mtd_close(struct inode *inode, struct file *file) DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n"); - /* Only sync if opened RW */ - if ((file->f_mode & 2) && mtd->sync) + if (mtd->sync) mtd->sync(mtd); put_mtd_device(mtd); diff --git a/trunk/drivers/mtd/mtdconcat.c b/trunk/drivers/mtd/mtdconcat.c index 96be7ef62f35..41844ea02462 100644 --- a/trunk/drivers/mtd/mtdconcat.c +++ b/trunk/drivers/mtd/mtdconcat.c @@ -178,7 +178,7 @@ concat_writev(struct mtd_info *mtd, const struct kvec *vecs, /* Check alignment */ if (mtd->writesize > 1) { - uint64_t __to = to; + loff_t __to = to; if (do_div(__to, mtd->writesize) || (total_len % mtd->writesize)) return -EINVAL; } diff --git a/trunk/drivers/mtd/mtdcore.c b/trunk/drivers/mtd/mtdcore.c index 6c2645e28371..c153b64a8300 100644 --- a/trunk/drivers/mtd/mtdcore.c +++ b/trunk/drivers/mtd/mtdcore.c @@ -22,8 +22,6 @@ #include -#include "mtdcore.h" - /* These are exported solely for the purpose of mtd_blkdevs.c. You should not use them for _anything_ else */ DEFINE_MUTEX(mtd_table_mutex); diff --git a/trunk/drivers/mtd/mtdcore.h b/trunk/drivers/mtd/mtdcore.h deleted file mode 100644 index a33251f4b872..000000000000 --- a/trunk/drivers/mtd/mtdcore.h +++ /dev/null @@ -1,11 +0,0 @@ -/* linux/drivers/mtd/mtdcore.h - * - * Header file for driver private mtdcore exports - * - */ - -/* These are exported solely for the purpose of mtd_blkdevs.c. You - should not use them for _anything_ else */ - -extern struct mutex mtd_table_mutex; -extern struct mtd_info *mtd_table[MAX_MTD_DEVICES]; diff --git a/trunk/drivers/mtd/mtdoops.c b/trunk/drivers/mtd/mtdoops.c deleted file mode 100644 index f8af627f0b98..000000000000 --- a/trunk/drivers/mtd/mtdoops.c +++ /dev/null @@ -1,376 +0,0 @@ -/* - * MTD Oops/Panic logger - * - * Copyright (C) 2007 Nokia Corporation. All rights reserved. - * - * Author: Richard Purdie - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define OOPS_PAGE_SIZE 4096 - -static struct mtdoops_context { - int mtd_index; - struct work_struct work; - struct mtd_info *mtd; - int oops_pages; - int nextpage; - int nextcount; - - void *oops_buf; - int ready; - int writecount; -} oops_cxt; - -static void mtdoops_erase_callback(struct erase_info *done) -{ - wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv; - wake_up(wait_q); -} - -static int mtdoops_erase_block(struct mtd_info *mtd, int offset) -{ - struct erase_info erase; - DECLARE_WAITQUEUE(wait, current); - wait_queue_head_t wait_q; - int ret; - - init_waitqueue_head(&wait_q); - erase.mtd = mtd; - erase.callback = mtdoops_erase_callback; - erase.addr = offset; - if (mtd->erasesize < OOPS_PAGE_SIZE) - erase.len = OOPS_PAGE_SIZE; - else - erase.len = mtd->erasesize; - erase.priv = (u_long)&wait_q; - - set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&wait_q, &wait); - - ret = mtd->erase(mtd, &erase); - if (ret) { - set_current_state(TASK_RUNNING); - remove_wait_queue(&wait_q, &wait); - printk (KERN_WARNING "mtdoops: erase of region [0x%x, 0x%x] " - "on \"%s\" failed\n", - erase.addr, erase.len, mtd->name); - return ret; - } - - schedule(); /* Wait for erase to finish. */ - remove_wait_queue(&wait_q, &wait); - - return 0; -} - -static int mtdoops_inc_counter(struct mtdoops_context *cxt) -{ - struct mtd_info *mtd = cxt->mtd; - size_t retlen; - u32 count; - int ret; - - cxt->nextpage++; - if (cxt->nextpage > cxt->oops_pages) - cxt->nextpage = 0; - cxt->nextcount++; - if (cxt->nextcount == 0xffffffff) - cxt->nextcount = 0; - - ret = mtd->read(mtd, cxt->nextpage * OOPS_PAGE_SIZE, 4, - &retlen, (u_char *) &count); - if ((retlen != 4) || (ret < 0)) { - printk(KERN_ERR "mtdoops: Read failure at %d (%td of 4 read)" - ", err %d.\n", cxt->nextpage * OOPS_PAGE_SIZE, - retlen, ret); - return 1; - } - - /* See if we need to erase the next block */ - if (count != 0xffffffff) - return 1; - - printk(KERN_DEBUG "mtdoops: Ready %d, %d (no erase)\n", - cxt->nextpage, cxt->nextcount); - cxt->ready = 1; - return 0; -} - -static void mtdoops_prepare(struct mtdoops_context *cxt) -{ - struct mtd_info *mtd = cxt->mtd; - int i = 0, j, ret, mod; - - /* We were unregistered */ - if (!mtd) - return; - - mod = (cxt->nextpage * OOPS_PAGE_SIZE) % mtd->erasesize; - if (mod != 0) { - cxt->nextpage = cxt->nextpage + ((mtd->erasesize - mod) / OOPS_PAGE_SIZE); - if (cxt->nextpage > cxt->oops_pages) - cxt->nextpage = 0; - } - - while (mtd->block_isbad && - mtd->block_isbad(mtd, cxt->nextpage * OOPS_PAGE_SIZE)) { -badblock: - printk(KERN_WARNING "mtdoops: Bad block at %08x\n", - cxt->nextpage * OOPS_PAGE_SIZE); - i++; - cxt->nextpage = cxt->nextpage + (mtd->erasesize / OOPS_PAGE_SIZE); - if (cxt->nextpage > cxt->oops_pages) - cxt->nextpage = 0; - if (i == (cxt->oops_pages / (mtd->erasesize / OOPS_PAGE_SIZE))) { - printk(KERN_ERR "mtdoops: All blocks bad!\n"); - return; - } - } - - for (j = 0, ret = -1; (j < 3) && (ret < 0); j++) - ret = mtdoops_erase_block(mtd, cxt->nextpage * OOPS_PAGE_SIZE); - - if (ret < 0) { - if (mtd->block_markbad) - mtd->block_markbad(mtd, cxt->nextpage * OOPS_PAGE_SIZE); - goto badblock; - } - - printk(KERN_DEBUG "mtdoops: Ready %d, %d \n", cxt->nextpage, cxt->nextcount); - - cxt->ready = 1; -} - -static void mtdoops_workfunc(struct work_struct *work) -{ - struct mtdoops_context *cxt = - container_of(work, struct mtdoops_context, work); - - mtdoops_prepare(cxt); -} - -static int find_next_position(struct mtdoops_context *cxt) -{ - struct mtd_info *mtd = cxt->mtd; - int page, maxpos = 0; - u32 count, maxcount = 0xffffffff; - size_t retlen; - - for (page = 0; page < cxt->oops_pages; page++) { - mtd->read(mtd, page * OOPS_PAGE_SIZE, 4, &retlen, (u_char *) &count); - if (count == 0xffffffff) - continue; - if (maxcount == 0xffffffff) { - maxcount = count; - maxpos = page; - } else if ((count < 0x40000000) && (maxcount > 0xc0000000)) { - maxcount = count; - maxpos = page; - } else if ((count > maxcount) && (count < 0xc0000000)) { - maxcount = count; - maxpos = page; - } else if ((count > maxcount) && (count > 0xc0000000) - && (maxcount > 0x80000000)) { - maxcount = count; - maxpos = page; - } - } - if (maxcount == 0xffffffff) { - cxt->nextpage = 0; - cxt->nextcount = 1; - cxt->ready = 1; - printk(KERN_DEBUG "mtdoops: Ready %d, %d (first init)\n", - cxt->nextpage, cxt->nextcount); - return 0; - } - - cxt->nextpage = maxpos; - cxt->nextcount = maxcount; - - return mtdoops_inc_counter(cxt); -} - - -static void mtdoops_notify_add(struct mtd_info *mtd) -{ - struct mtdoops_context *cxt = &oops_cxt; - int ret; - - if ((mtd->index != cxt->mtd_index) || cxt->mtd_index < 0) - return; - - if (mtd->size < (mtd->erasesize * 2)) { - printk(KERN_ERR "MTD partition %d not big enough for mtdoops\n", - mtd->index); - return; - } - - cxt->mtd = mtd; - cxt->oops_pages = mtd->size / OOPS_PAGE_SIZE; - - ret = find_next_position(cxt); - if (ret == 1) - mtdoops_prepare(cxt); - - printk(KERN_DEBUG "mtdoops: Attached to MTD device %d\n", mtd->index); -} - -static void mtdoops_notify_remove(struct mtd_info *mtd) -{ - struct mtdoops_context *cxt = &oops_cxt; - - if ((mtd->index != cxt->mtd_index) || cxt->mtd_index < 0) - return; - - cxt->mtd = NULL; - flush_scheduled_work(); -} - -static void mtdoops_console_sync(void) -{ - struct mtdoops_context *cxt = &oops_cxt; - struct mtd_info *mtd = cxt->mtd; - size_t retlen; - int ret; - - if (!cxt->ready || !mtd) - return; - - if (cxt->writecount == 0) - return; - - if (cxt->writecount < OOPS_PAGE_SIZE) - memset(cxt->oops_buf + cxt->writecount, 0xff, - OOPS_PAGE_SIZE - cxt->writecount); - - ret = mtd->write(mtd, cxt->nextpage * OOPS_PAGE_SIZE, - OOPS_PAGE_SIZE, &retlen, cxt->oops_buf); - cxt->ready = 0; - cxt->writecount = 0; - - if ((retlen != OOPS_PAGE_SIZE) || (ret < 0)) - printk(KERN_ERR "mtdoops: Write failure at %d (%td of %d written), err %d.\n", - cxt->nextpage * OOPS_PAGE_SIZE, retlen, OOPS_PAGE_SIZE, ret); - - ret = mtdoops_inc_counter(cxt); - if (ret == 1) - schedule_work(&cxt->work); -} - -static void -mtdoops_console_write(struct console *co, const char *s, unsigned int count) -{ - struct mtdoops_context *cxt = co->data; - struct mtd_info *mtd = cxt->mtd; - int i; - - if (!oops_in_progress) { - mtdoops_console_sync(); - return; - } - - if (!cxt->ready || !mtd) - return; - - if (cxt->writecount == 0) { - u32 *stamp = cxt->oops_buf; - *stamp = cxt->nextcount; - cxt->writecount = 4; - } - - if ((count + cxt->writecount) > OOPS_PAGE_SIZE) - count = OOPS_PAGE_SIZE - cxt->writecount; - - for (i = 0; i < count; i++, s++) - *((char *)(cxt->oops_buf) + cxt->writecount + i) = *s; - - cxt->writecount = cxt->writecount + count; -} - -static int __init mtdoops_console_setup(struct console *co, char *options) -{ - struct mtdoops_context *cxt = co->data; - - if (cxt->mtd_index != -1) - return -EBUSY; - if (co->index == -1) - return -EINVAL; - - cxt->mtd_index = co->index; - return 0; -} - -static struct mtd_notifier mtdoops_notifier = { - .add = mtdoops_notify_add, - .remove = mtdoops_notify_remove, -}; - -static struct console mtdoops_console = { - .name = "ttyMTD", - .write = mtdoops_console_write, - .setup = mtdoops_console_setup, - .unblank = mtdoops_console_sync, - .flags = CON_PRINTBUFFER, - .index = -1, - .data = &oops_cxt, -}; - -static int __init mtdoops_console_init(void) -{ - struct mtdoops_context *cxt = &oops_cxt; - - cxt->mtd_index = -1; - cxt->oops_buf = vmalloc(OOPS_PAGE_SIZE); - - if (!cxt->oops_buf) { - printk(KERN_ERR "Failed to allocate oops buffer workspace\n"); - return -ENOMEM; - } - - INIT_WORK(&cxt->work, mtdoops_workfunc); - - register_console(&mtdoops_console); - register_mtd_user(&mtdoops_notifier); - return 0; -} - -static void __exit mtdoops_console_exit(void) -{ - struct mtdoops_context *cxt = &oops_cxt; - - unregister_mtd_user(&mtdoops_notifier); - unregister_console(&mtdoops_console); - vfree(cxt->oops_buf); -} - - -subsys_initcall(mtdoops_console_init); -module_exit(mtdoops_console_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Richard Purdie "); -MODULE_DESCRIPTION("MTD Oops/Panic console logger/driver"); diff --git a/trunk/drivers/mtd/nand/Kconfig b/trunk/drivers/mtd/nand/Kconfig index df25cabb0481..a783d62f48f6 100644 --- a/trunk/drivers/mtd/nand/Kconfig +++ b/trunk/drivers/mtd/nand/Kconfig @@ -134,10 +134,10 @@ config MTD_NAND_S3C2410_HWECC config MTD_NAND_NDFC tristate "NDFC NanD Flash Controller" - depends on 4xx + depends on 44x && !PPC_MERGE select MTD_NAND_ECC_SMC help - NDFC Nand Flash Controllers are integrated in IBM/AMCC's 4xx SoCs + NDFC Nand Flash Controllers are integrated in EP44x SoCs config MTD_NAND_S3C2410_CLKSTOP bool "S3C2410 NAND IDLE clock stop" @@ -237,7 +237,7 @@ config MTD_NAND_CAFE select REED_SOLOMON select REED_SOLOMON_DEC16 help - Use NAND flash attached to the CAFÉ chip designed for the OLPC + Use NAND flash attached to the CAFÉ chip designed for the $100 laptop. config MTD_NAND_CS553X diff --git a/trunk/drivers/mtd/nand/diskonchip.c b/trunk/drivers/mtd/nand/diskonchip.c index ab9f5c5db38d..e96259f22cca 100644 --- a/trunk/drivers/mtd/nand/diskonchip.c +++ b/trunk/drivers/mtd/nand/diskonchip.c @@ -56,6 +56,8 @@ static unsigned long __initdata doc_locations[] = { #endif /* CONFIG_MTD_DOCPROBE_HIGH */ #elif defined(__PPC__) 0xe4000000, +#elif defined(CONFIG_MOMENCO_OCELOT_G) + 0xff000000, #else #warning Unknown architecture for DiskOnChip. No default probe locations defined #endif diff --git a/trunk/drivers/mtd/nand/excite_nandflash.c b/trunk/drivers/mtd/nand/excite_nandflash.c index bed87290decc..7e9afc4c7757 100644 --- a/trunk/drivers/mtd/nand/excite_nandflash.c +++ b/trunk/drivers/mtd/nand/excite_nandflash.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/mtd/nand/nand_base.c b/trunk/drivers/mtd/nand/nand_base.c index d5691212058d..24ac6778b1a8 100644 --- a/trunk/drivers/mtd/nand/nand_base.c +++ b/trunk/drivers/mtd/nand/nand_base.c @@ -7,7 +7,7 @@ * Basic support for AG-AND chips is provided. * * Additional technical information is available on - * http://www.linux-mtd.infradead.org/doc/nand.html + * http://www.linux-mtd.infradead.org/tech/nand.html * * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) * 2002-2006 Thomas Gleixner (tglx@linutronix.de) diff --git a/trunk/drivers/mtd/nand/nand_ids.c b/trunk/drivers/mtd/nand/nand_ids.c index a3e3ab0185d5..2fc674a190cf 100644 --- a/trunk/drivers/mtd/nand/nand_ids.c +++ b/trunk/drivers/mtd/nand/nand_ids.c @@ -141,7 +141,6 @@ struct nand_manufacturers nand_manuf_ids[] = { {NAND_MFR_STMICRO, "ST Micro"}, {NAND_MFR_HYNIX, "Hynix"}, {NAND_MFR_MICRON, "Micron"}, - {NAND_MFR_AMD, "AMD"}, {0x0, "Unknown"} }; diff --git a/trunk/drivers/mtd/nand/ndfc.c b/trunk/drivers/mtd/nand/ndfc.c index 1c0e89f00e8d..fd7a8d5ba29a 100644 --- a/trunk/drivers/mtd/nand/ndfc.c +++ b/trunk/drivers/mtd/nand/ndfc.c @@ -24,11 +24,7 @@ #include #include -#ifdef CONFIG_40x -#include -#else #include -#endif struct ndfc_nand_mtd { struct mtd_info mtd; @@ -234,11 +230,7 @@ static int ndfc_nand_probe(struct platform_device *pdev) struct ndfc_controller *ndfc = &ndfc_ctrl; unsigned long long phys = settings->ndfc_erpn | res->start; -#ifndef CONFIG_PHYS_64BIT - ndfc->ndfcbase = ioremap((phys_addr_t)phys, res->end - res->start + 1); -#else ndfc->ndfcbase = ioremap64(phys, res->end - res->start + 1); -#endif if (!ndfc->ndfcbase) { printk(KERN_ERR "NDFC: ioremap failed\n"); return -EIO; diff --git a/trunk/drivers/mtd/onenand/Kconfig b/trunk/drivers/mtd/onenand/Kconfig index cb41cbca64f7..c257d397d08a 100644 --- a/trunk/drivers/mtd/onenand/Kconfig +++ b/trunk/drivers/mtd/onenand/Kconfig @@ -40,27 +40,4 @@ config MTD_ONENAND_OTP OTP block is fully-guaranteed to be a valid block. -config MTD_ONENAND_2X_PROGRAM - bool "OneNAND 2X program support" - help - The 2X Program is an extension of Program Operation. - Since the device is equipped with two DataRAMs, and two-plane NAND - Flash memory array, these two component enables simultaneous program - of 4KiB. Plane1 has only even blocks such as block0, block2, block4 - while Plane2 has only odd blocks such as block1, block3, block5. - So MTD regards it as 4KiB page size and 256KiB block size - - Now the following chips support it. (KFXXX16Q2M) - Demux: KFG2G16Q2M, KFH4G16Q2M, KFW8G16Q2M, - Mux: KFM2G16Q2M, KFN4G16Q2M, - - And more recent chips - -config MTD_ONENAND_SIM - tristate "OneNAND simulator support" - depends on MTD_PARTITIONS - help - The simulator may simulate various OneNAND flash chips for the - OneNAND MTD layer. - endif # MTD_ONENAND diff --git a/trunk/drivers/mtd/onenand/Makefile b/trunk/drivers/mtd/onenand/Makefile index 4d2eacfd7e11..269cfe467345 100644 --- a/trunk/drivers/mtd/onenand/Makefile +++ b/trunk/drivers/mtd/onenand/Makefile @@ -8,7 +8,4 @@ obj-$(CONFIG_MTD_ONENAND) += onenand.o # Board specific. obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o -# Simulator -obj-$(CONFIG_MTD_ONENAND_SIM) += onenand_sim.o - onenand-objs = onenand_base.o onenand_bbt.o diff --git a/trunk/drivers/mtd/onenand/onenand_base.c b/trunk/drivers/mtd/onenand/onenand_base.c index 7d194cfdb873..0537fac8de74 100644 --- a/trunk/drivers/mtd/onenand/onenand_base.c +++ b/trunk/drivers/mtd/onenand/onenand_base.c @@ -206,15 +206,6 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le default: block = (int) (addr >> this->erase_shift); page = (int) (addr >> this->page_shift); - - if (ONENAND_IS_2PLANE(this)) { - /* Make the even block number */ - block &= ~1; - /* Is it the odd plane? */ - if (addr & this->writesize) - block++; - page >>= 1; - } page &= this->page_mask; break; } @@ -225,12 +216,8 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le value = onenand_bufferram_address(this, block); this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2); - if (ONENAND_IS_2PLANE(this)) - /* It is always BufferRAM0 */ - ONENAND_SET_BUFFERRAM0(this); - else - /* Switch to the next data buffer */ - ONENAND_SET_NEXT_BUFFERRAM(this); + /* Switch to the next data buffer */ + ONENAND_SET_NEXT_BUFFERRAM(this); return 0; } @@ -260,8 +247,6 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le break; default: - if (ONENAND_IS_2PLANE(this) && cmd == ONENAND_CMD_PROG) - cmd = ONENAND_CMD_2X_PROG; dataram = ONENAND_CURRENT_BUFFERRAM(this); break; } @@ -460,9 +445,8 @@ static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area) struct onenand_chip *this = mtd->priv; if (ONENAND_CURRENT_BUFFERRAM(this)) { - /* Note: the 'this->writesize' is a real page size */ if (area == ONENAND_DATARAM) - return this->writesize; + return mtd->writesize; if (area == ONENAND_SPARERAM) return mtd->oobsize; } @@ -587,30 +571,6 @@ static int onenand_write_bufferram(struct mtd_info *mtd, int area, return 0; } -/** - * onenand_get_2x_blockpage - [GENERIC] Get blockpage at 2x program mode - * @param mtd MTD data structure - * @param addr address to check - * @return blockpage address - * - * Get blockpage address at 2x program mode - */ -static int onenand_get_2x_blockpage(struct mtd_info *mtd, loff_t addr) -{ - struct onenand_chip *this = mtd->priv; - int blockpage, block, page; - - /* Calculate the even block number */ - block = (int) (addr >> this->erase_shift) & ~1; - /* Is it the odd plane? */ - if (addr & this->writesize) - block++; - page = (int) (addr >> (this->page_shift + 1)) & this->page_mask; - blockpage = (block << 7) | page; - - return blockpage; -} - /** * onenand_check_bufferram - [GENERIC] Check BufferRAM information * @param mtd MTD data structure @@ -625,10 +585,7 @@ static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr) int blockpage, found = 0; unsigned int i; - if (ONENAND_IS_2PLANE(this)) - blockpage = onenand_get_2x_blockpage(mtd, addr); - else - blockpage = (int) (addr >> this->page_shift); + blockpage = (int) (addr >> this->page_shift); /* Is there valid data? */ i = ONENAND_CURRENT_BUFFERRAM(this); @@ -668,10 +625,7 @@ static void onenand_update_bufferram(struct mtd_info *mtd, loff_t addr, int blockpage; unsigned int i; - if (ONENAND_IS_2PLANE(this)) - blockpage = onenand_get_2x_blockpage(mtd, addr); - else - blockpage = (int) (addr >> this->page_shift); + blockpage = (int) (addr >> this->page_shift); /* Invalidate another BufferRAM */ i = ONENAND_NEXT_BUFFERRAM(this); @@ -780,7 +734,6 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len, int read = 0, column; int thislen; int ret = 0, boundary = 0; - int writesize = this->writesize; DEBUG(MTD_DEBUG_LEVEL3, "onenand_read: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); @@ -801,22 +754,22 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len, /* Do first load to bufferRAM */ if (read < len) { if (!onenand_check_bufferram(mtd, from)) { - this->command(mtd, ONENAND_CMD_READ, from, writesize); + this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize); ret = this->wait(mtd, FL_READING); onenand_update_bufferram(mtd, from, !ret); } } - thislen = min_t(int, writesize, len - read); - column = from & (writesize - 1); - if (column + thislen > writesize) - thislen = writesize - column; + thislen = min_t(int, mtd->writesize, len - read); + column = from & (mtd->writesize - 1); + if (column + thislen > mtd->writesize) + thislen = mtd->writesize - column; while (!ret) { /* If there is more to load then start next load */ from += thislen; if (read + thislen < len) { - this->command(mtd, ONENAND_CMD_READ, from, writesize); + this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize); /* * Chip boundary handling in DDP * Now we issued chip 1 read and pointed chip 1 @@ -841,7 +794,7 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len, this->write_word(ONENAND_DDP_CHIP1, this->base + ONENAND_REG_START_ADDRESS2); ONENAND_SET_NEXT_BUFFERRAM(this); buf += thislen; - thislen = min_t(int, writesize, len - read); + thislen = min_t(int, mtd->writesize, len - read); column = 0; cond_resched(); /* Now wait for load */ @@ -1126,7 +1079,7 @@ int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from, /* Read more? */ if (read < len) { /* Update Page size */ - from += this->writesize; + from += mtd->writesize; column = 0; } } @@ -1182,12 +1135,12 @@ static int onenand_verify(struct mtd_info *mtd, const u_char *buf, loff_t addr, int thislen, column; while (len != 0) { - thislen = min_t(int, this->writesize, len); - column = addr & (this->writesize - 1); - if (column + thislen > this->writesize) - thislen = this->writesize - column; + thislen = min_t(int, mtd->writesize, len); + column = addr & (mtd->writesize - 1); + if (column + thislen > mtd->writesize) + thislen = mtd->writesize - column; - this->command(mtd, ONENAND_CMD_READ, addr, this->writesize); + this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize); onenand_update_bufferram(mtd, addr, 0); @@ -1283,10 +1236,6 @@ static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len, /* In partial page write we don't update bufferram */ onenand_update_bufferram(mtd, to, !ret && !subpage); - if (ONENAND_IS_2PLANE(this)) { - ONENAND_SET_BUFFERRAM1(this); - onenand_update_bufferram(mtd, to + this->writesize, !ret && !subpage); - } if (ret) { printk(KERN_ERR "onenand_write: write filaed %d\n", ret); @@ -1435,10 +1384,6 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len, this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize); onenand_update_bufferram(mtd, to, 0); - if (ONENAND_IS_2PLANE(this)) { - ONENAND_SET_BUFFERRAM1(this); - onenand_update_bufferram(mtd, to + this->writesize, 0); - } ret = this->wait(mtd, FL_WRITING); if (ret) { @@ -2162,7 +2107,6 @@ static int onenand_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, * * Check and set OneNAND features * - lock scheme - * - two plane */ static void onenand_check_features(struct mtd_info *mtd) { @@ -2174,35 +2118,19 @@ static void onenand_check_features(struct mtd_info *mtd) process = this->version_id >> ONENAND_VERSION_PROCESS_SHIFT; /* Lock scheme */ - switch (density) { - case ONENAND_DEVICE_DENSITY_4Gb: - this->options |= ONENAND_HAS_2PLANE; - - case ONENAND_DEVICE_DENSITY_2Gb: - /* 2Gb DDP don't have 2 plane */ - if (!ONENAND_IS_DDP(this)) - this->options |= ONENAND_HAS_2PLANE; - this->options |= ONENAND_HAS_UNLOCK_ALL; - - case ONENAND_DEVICE_DENSITY_1Gb: + if (density >= ONENAND_DEVICE_DENSITY_1Gb) { /* A-Die has all block unlock */ - if (process) + if (process) { + printk(KERN_DEBUG "Chip support all block unlock\n"); this->options |= ONENAND_HAS_UNLOCK_ALL; - break; - - default: - /* Some OneNAND has continuous lock scheme */ - if (!process) + } + } else { + /* Some OneNAND has continues lock scheme */ + if (!process) { + printk(KERN_DEBUG "Lock scheme is Continues Lock\n"); this->options |= ONENAND_HAS_CONT_LOCK; - break; + } } - - if (this->options & ONENAND_HAS_CONT_LOCK) - printk(KERN_DEBUG "Lock scheme is Continuous Lock\n"); - if (this->options & ONENAND_HAS_UNLOCK_ALL) - printk(KERN_DEBUG "Chip support all block unlock\n"); - if (this->options & ONENAND_HAS_2PLANE) - printk(KERN_DEBUG "Chip has 2 plane\n"); } /** @@ -2329,8 +2257,6 @@ static int onenand_probe(struct mtd_info *mtd) this->erase_shift = ffs(mtd->erasesize) - 1; this->page_shift = ffs(mtd->writesize) - 1; this->page_mask = (1 << (this->erase_shift - this->page_shift)) - 1; - /* It's real page size */ - this->writesize = mtd->writesize; /* REVIST: Multichip handling */ @@ -2339,17 +2265,6 @@ static int onenand_probe(struct mtd_info *mtd) /* Check OneNAND features */ onenand_check_features(mtd); - /* - * We emulate the 4KiB page and 256KiB erase block size - * But oobsize is still 64 bytes. - * It is only valid if you turn on 2X program support, - * Otherwise it will be ignored by compiler. - */ - if (ONENAND_IS_2PLANE(this)) { - mtd->writesize <<= 1; - mtd->erasesize <<= 1; - } - return 0; } diff --git a/trunk/drivers/mtd/onenand/onenand_sim.c b/trunk/drivers/mtd/onenand/onenand_sim.c deleted file mode 100644 index 0d89ad5776fa..000000000000 --- a/trunk/drivers/mtd/onenand/onenand_sim.c +++ /dev/null @@ -1,495 +0,0 @@ -/* - * linux/drivers/mtd/onenand/onenand_sim.c - * - * The OneNAND simulator - * - * Copyright © 2005-2007 Samsung Electronics - * Kyungmin Park - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifndef CONFIG_ONENAND_SIM_MANUFACTURER -#define CONFIG_ONENAND_SIM_MANUFACTURER 0xec -#endif -#ifndef CONFIG_ONENAND_SIM_DEVICE_ID -#define CONFIG_ONENAND_SIM_DEVICE_ID 0x04 -#endif -#ifndef CONFIG_ONENAND_SIM_VERSION_ID -#define CONFIG_ONENAND_SIM_VERSION_ID 0x1e -#endif - -static int manuf_id = CONFIG_ONENAND_SIM_MANUFACTURER; -static int device_id = CONFIG_ONENAND_SIM_DEVICE_ID; -static int version_id = CONFIG_ONENAND_SIM_VERSION_ID; - -struct onenand_flash { - void __iomem *base; - void __iomem *data; -}; - -#define ONENAND_CORE(flash) (flash->data) -#define ONENAND_CORE_SPARE(flash, this, offset) \ - ((flash->data) + (this->chipsize) + (offset >> 5)) - -#define ONENAND_MAIN_AREA(this, offset) \ - (this->base + ONENAND_DATARAM + offset) - -#define ONENAND_SPARE_AREA(this, offset) \ - (this->base + ONENAND_SPARERAM + offset) - -#define ONENAND_GET_WP_STATUS(this) \ - (readw(this->base + ONENAND_REG_WP_STATUS)) - -#define ONENAND_SET_WP_STATUS(v, this) \ - (writew(v, this->base + ONENAND_REG_WP_STATUS)) - -/* It has all 0xff chars */ -#define MAX_ONENAND_PAGESIZE (2048 + 64) -static unsigned char *ffchars; - -static struct mtd_partition os_partitions[] = { - { - .name = "OneNAND simulator partition", - .offset = 0, - .size = MTDPART_SIZ_FULL, - }, -}; - -/* - * OneNAND simulator mtd - */ -struct onenand_info { - struct mtd_info mtd; - struct mtd_partition *parts; - struct onenand_chip onenand; - struct onenand_flash flash; -}; - -static struct onenand_info *info; - -#define DPRINTK(format, args...) \ -do { \ - printk(KERN_DEBUG "%s[%d]: " format "\n", __func__, \ - __LINE__, ##args); \ -} while (0) - -/** - * onenand_lock_handle - Handle Lock scheme - * @param this OneNAND device structure - * @param cmd The command to be sent - * - * Send lock command to OneNAND device. - * The lock scheme is depends on chip type. - */ -static void onenand_lock_handle(struct onenand_chip *this, int cmd) -{ - int block_lock_scheme; - int status; - - status = ONENAND_GET_WP_STATUS(this); - block_lock_scheme = !(this->options & ONENAND_HAS_CONT_LOCK); - - switch (cmd) { - case ONENAND_CMD_UNLOCK: - if (block_lock_scheme) - ONENAND_SET_WP_STATUS(ONENAND_WP_US, this); - else - ONENAND_SET_WP_STATUS(status | ONENAND_WP_US, this); - break; - - case ONENAND_CMD_LOCK: - if (block_lock_scheme) - ONENAND_SET_WP_STATUS(ONENAND_WP_LS, this); - else - ONENAND_SET_WP_STATUS(status | ONENAND_WP_LS, this); - break; - - case ONENAND_CMD_LOCK_TIGHT: - if (block_lock_scheme) - ONENAND_SET_WP_STATUS(ONENAND_WP_LTS, this); - else - ONENAND_SET_WP_STATUS(status | ONENAND_WP_LTS, this); - break; - - default: - break; - } -} - -/** - * onenand_bootram_handle - Handle BootRAM area - * @param this OneNAND device structure - * @param cmd The command to be sent - * - * Emulate BootRAM area. It is possible to do basic operation using BootRAM. - */ -static void onenand_bootram_handle(struct onenand_chip *this, int cmd) -{ - switch (cmd) { - case ONENAND_CMD_READID: - writew(manuf_id, this->base); - writew(device_id, this->base + 2); - writew(version_id, this->base + 4); - break; - - default: - /* REVIST: Handle other commands */ - break; - } -} - -/** - * onenand_update_interrupt - Set interrupt register - * @param this OneNAND device structure - * @param cmd The command to be sent - * - * Update interrupt register. The status is depends on command. - */ -static void onenand_update_interrupt(struct onenand_chip *this, int cmd) -{ - int interrupt = ONENAND_INT_MASTER; - - switch (cmd) { - case ONENAND_CMD_READ: - case ONENAND_CMD_READOOB: - interrupt |= ONENAND_INT_READ; - break; - - case ONENAND_CMD_PROG: - case ONENAND_CMD_PROGOOB: - interrupt |= ONENAND_INT_WRITE; - break; - - case ONENAND_CMD_ERASE: - interrupt |= ONENAND_INT_ERASE; - break; - - case ONENAND_CMD_RESET: - interrupt |= ONENAND_INT_RESET; - break; - - default: - break; - } - - writew(interrupt, this->base + ONENAND_REG_INTERRUPT); -} - -/** - * onenand_check_overwrite - Check over-write if happend - * @param dest The destination pointer - * @param src The source pointer - * @param count The length to be check - * @return 0 on same, otherwise 1 - * - * Compare the source with destination - */ -static int onenand_check_overwrite(void *dest, void *src, size_t count) -{ - unsigned int *s = (unsigned int *) src; - unsigned int *d = (unsigned int *) dest; - int i; - - count >>= 2; - for (i = 0; i < count; i++) - if ((*s++ ^ *d++) != 0) - return 1; - - return 0; -} - -/** - * onenand_data_handle - Handle OneNAND Core and DataRAM - * @param this OneNAND device structure - * @param cmd The command to be sent - * @param dataram Which dataram used - * @param offset The offset to OneNAND Core - * - * Copy data from OneNAND Core to DataRAM (read) - * Copy data from DataRAM to OneNAND Core (write) - * Erase the OneNAND Core (erase) - */ -static void onenand_data_handle(struct onenand_chip *this, int cmd, - int dataram, unsigned int offset) -{ - struct mtd_info *mtd = &info->mtd; - struct onenand_flash *flash = this->priv; - int main_offset, spare_offset; - void __iomem *src; - void __iomem *dest; - unsigned int i; - - if (dataram) { - main_offset = mtd->writesize; - spare_offset = mtd->oobsize; - } else { - main_offset = 0; - spare_offset = 0; - } - - switch (cmd) { - case ONENAND_CMD_READ: - src = ONENAND_CORE(flash) + offset; - dest = ONENAND_MAIN_AREA(this, main_offset); - memcpy(dest, src, mtd->writesize); - /* Fall through */ - - case ONENAND_CMD_READOOB: - src = ONENAND_CORE_SPARE(flash, this, offset); - dest = ONENAND_SPARE_AREA(this, spare_offset); - memcpy(dest, src, mtd->oobsize); - break; - - case ONENAND_CMD_PROG: - src = ONENAND_MAIN_AREA(this, main_offset); - dest = ONENAND_CORE(flash) + offset; - /* To handle partial write */ - for (i = 0; i < (1 << mtd->subpage_sft); i++) { - int off = i * this->subpagesize; - if (!memcmp(src + off, ffchars, this->subpagesize)) - continue; - if (memcmp(dest + off, ffchars, this->subpagesize) && - onenand_check_overwrite(dest + off, src + off, this->subpagesize)) - printk(KERN_ERR "over-write happend at 0x%08x\n", offset); - memcpy(dest + off, src + off, this->subpagesize); - } - /* Fall through */ - - case ONENAND_CMD_PROGOOB: - src = ONENAND_SPARE_AREA(this, spare_offset); - /* Check all data is 0xff chars */ - if (!memcmp(src, ffchars, mtd->oobsize)) - break; - - dest = ONENAND_CORE_SPARE(flash, this, offset); - if (memcmp(dest, ffchars, mtd->oobsize) && - onenand_check_overwrite(dest, src, mtd->oobsize)) - printk(KERN_ERR "OOB: over-write happend at 0x%08x\n", - offset); - memcpy(dest, src, mtd->oobsize); - break; - - case ONENAND_CMD_ERASE: - memset(ONENAND_CORE(flash) + offset, 0xff, mtd->erasesize); - memset(ONENAND_CORE_SPARE(flash, this, offset), 0xff, - (mtd->erasesize >> 5)); - break; - - default: - break; - } -} - -/** - * onenand_command_handle - Handle command - * @param this OneNAND device structure - * @param cmd The command to be sent - * - * Emulate OneNAND command. - */ -static void onenand_command_handle(struct onenand_chip *this, int cmd) -{ - unsigned long offset = 0; - int block = -1, page = -1, bufferram = -1; - int dataram = 0; - - switch (cmd) { - case ONENAND_CMD_UNLOCK: - case ONENAND_CMD_LOCK: - case ONENAND_CMD_LOCK_TIGHT: - case ONENAND_CMD_UNLOCK_ALL: - onenand_lock_handle(this, cmd); - break; - - case ONENAND_CMD_BUFFERRAM: - /* Do nothing */ - return; - - default: - block = (int) readw(this->base + ONENAND_REG_START_ADDRESS1); - if (block & (1 << ONENAND_DDP_SHIFT)) { - block &= ~(1 << ONENAND_DDP_SHIFT); - /* The half of chip block */ - block += this->chipsize >> (this->erase_shift + 1); - } - if (cmd == ONENAND_CMD_ERASE) - break; - - page = (int) readw(this->base + ONENAND_REG_START_ADDRESS8); - page = (page >> ONENAND_FPA_SHIFT); - bufferram = (int) readw(this->base + ONENAND_REG_START_BUFFER); - bufferram >>= ONENAND_BSA_SHIFT; - bufferram &= ONENAND_BSA_DATARAM1; - dataram = (bufferram == ONENAND_BSA_DATARAM1) ? 1 : 0; - break; - } - - if (block != -1) - offset += block << this->erase_shift; - - if (page != -1) - offset += page << this->page_shift; - - onenand_data_handle(this, cmd, dataram, offset); - - onenand_update_interrupt(this, cmd); -} - -/** - * onenand_writew - [OneNAND Interface] Emulate write operation - * @param value value to write - * @param addr address to write - * - * Write OneNAND register with value - */ -static void onenand_writew(unsigned short value, void __iomem * addr) -{ - struct onenand_chip *this = info->mtd.priv; - - /* BootRAM handling */ - if (addr < this->base + ONENAND_DATARAM) { - onenand_bootram_handle(this, value); - return; - } - /* Command handling */ - if (addr == this->base + ONENAND_REG_COMMAND) - onenand_command_handle(this, value); - - writew(value, addr); -} - -/** - * flash_init - Initialize OneNAND simulator - * @param flash OneNAND simulaotr data strucutres - * - * Initialize OneNAND simulator. - */ -static int __init flash_init(struct onenand_flash *flash) -{ - int density, size; - int buffer_size; - - flash->base = kzalloc(131072, GFP_KERNEL); - if (!flash->base) { - printk(KERN_ERR "Unable to allocate base address.\n"); - return -ENOMEM; - } - - density = device_id >> ONENAND_DEVICE_DENSITY_SHIFT; - size = ((16 << 20) << density); - - ONENAND_CORE(flash) = vmalloc(size + (size >> 5)); - if (!ONENAND_CORE(flash)) { - printk(KERN_ERR "Unable to allocate nand core address.\n"); - kfree(flash->base); - return -ENOMEM; - } - - memset(ONENAND_CORE(flash), 0xff, size + (size >> 5)); - - /* Setup registers */ - writew(manuf_id, flash->base + ONENAND_REG_MANUFACTURER_ID); - writew(device_id, flash->base + ONENAND_REG_DEVICE_ID); - writew(version_id, flash->base + ONENAND_REG_VERSION_ID); - - if (density < 2) - buffer_size = 0x0400; /* 1KiB page */ - else - buffer_size = 0x0800; /* 2KiB page */ - writew(buffer_size, flash->base + ONENAND_REG_DATA_BUFFER_SIZE); - - return 0; -} - -/** - * flash_exit - Clean up OneNAND simulator - * @param flash OneNAND simulaotr data strucutres - * - * Clean up OneNAND simulator. - */ -static void flash_exit(struct onenand_flash *flash) -{ - vfree(ONENAND_CORE(flash)); - kfree(flash->base); - kfree(flash); -} - -static int __init onenand_sim_init(void) -{ - /* Allocate all 0xff chars pointer */ - ffchars = kmalloc(MAX_ONENAND_PAGESIZE, GFP_KERNEL); - if (!ffchars) { - printk(KERN_ERR "Unable to allocate ff chars.\n"); - return -ENOMEM; - } - memset(ffchars, 0xff, MAX_ONENAND_PAGESIZE); - - /* Allocate OneNAND simulator mtd pointer */ - info = kzalloc(sizeof(struct onenand_info), GFP_KERNEL); - if (!info) { - printk(KERN_ERR "Unable to allocate core structures.\n"); - kfree(ffchars); - return -ENOMEM; - } - - /* Override write_word function */ - info->onenand.write_word = onenand_writew; - - if (flash_init(&info->flash)) { - printk(KERN_ERR "Unable to allocat flash.\n"); - kfree(ffchars); - kfree(info); - return -ENOMEM; - } - - info->parts = os_partitions; - - info->onenand.base = info->flash.base; - info->onenand.priv = &info->flash; - - info->mtd.name = "OneNAND simulator"; - info->mtd.priv = &info->onenand; - info->mtd.owner = THIS_MODULE; - - if (onenand_scan(&info->mtd, 1)) { - flash_exit(&info->flash); - kfree(ffchars); - kfree(info); - return -ENXIO; - } - - add_mtd_partitions(&info->mtd, info->parts, ARRAY_SIZE(os_partitions)); - - return 0; -} - -static void __exit onenand_sim_exit(void) -{ - struct onenand_chip *this = info->mtd.priv; - struct onenand_flash *flash = this->priv; - - onenand_release(&info->mtd); - flash_exit(flash); - kfree(ffchars); - kfree(info); -} - -module_init(onenand_sim_init); -module_exit(onenand_sim_exit); - -MODULE_AUTHOR("Kyungmin Park "); -MODULE_DESCRIPTION("The OneNAND flash simulator"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/mtd/rfd_ftl.c b/trunk/drivers/mtd/rfd_ftl.c index 823fba4e6d2f..006c03aacb55 100644 --- a/trunk/drivers/mtd/rfd_ftl.c +++ b/trunk/drivers/mtd/rfd_ftl.c @@ -779,8 +779,10 @@ static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) else { if (!mtd->erasesize) { printk(KERN_WARNING PREFIX "please provide block_size"); - goto out; - } else + kfree(part); + return; + } + else part->block_size = mtd->erasesize; } @@ -802,7 +804,7 @@ static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) if (!add_mtd_blktrans_dev((void*)part)) return; } -out: + kfree(part); } diff --git a/trunk/drivers/mtd/ubi/scan.c b/trunk/drivers/mtd/ubi/scan.c index 29c41eeb09fe..94ee54934411 100644 --- a/trunk/drivers/mtd/ubi/scan.c +++ b/trunk/drivers/mtd/ubi/scan.c @@ -1314,10 +1314,11 @@ static int paranoid_check_si(const struct ubi_device *ubi, * Make sure that all the physical eraseblocks are in one of the lists * or trees. */ - buf = kzalloc(ubi->peb_count, GFP_KERNEL); + buf = kmalloc(ubi->peb_count, GFP_KERNEL); if (!buf) return -ENOMEM; + memset(buf, 1, ubi->peb_count); for (pnum = 0; pnum < ubi->peb_count; pnum++) { err = ubi_io_is_bad(ubi, pnum); if (err < 0) { @@ -1325,28 +1326,28 @@ static int paranoid_check_si(const struct ubi_device *ubi, return err; } else if (err) - buf[pnum] = 1; + buf[pnum] = 0; } ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) ubi_rb_for_each_entry(rb2, seb, &sv->root, u.rb) - buf[seb->pnum] = 1; + buf[seb->pnum] = 0; list_for_each_entry(seb, &si->free, u.list) - buf[seb->pnum] = 1; + buf[seb->pnum] = 0; list_for_each_entry(seb, &si->corr, u.list) - buf[seb->pnum] = 1; + buf[seb->pnum] = 0; list_for_each_entry(seb, &si->erase, u.list) - buf[seb->pnum] = 1; + buf[seb->pnum] = 0; list_for_each_entry(seb, &si->alien, u.list) - buf[seb->pnum] = 1; + buf[seb->pnum] = 0; err = 0; for (pnum = 0; pnum < ubi->peb_count; pnum++) - if (!buf[pnum]) { + if (buf[pnum]) { ubi_err("PEB %d is not referred", pnum); err = 1; } diff --git a/trunk/fs/Kconfig b/trunk/fs/Kconfig index 84fb8428c023..58a0650293e1 100644 --- a/trunk/fs/Kconfig +++ b/trunk/fs/Kconfig @@ -1228,14 +1228,6 @@ config JFFS2_FS_WRITEBUFFER - NOR flash with transparent ECC - DataFlash -config JFFS2_FS_WBUF_VERIFY - bool "Verify JFFS2 write-buffer reads" - depends on JFFS2_FS_WRITEBUFFER - default n - help - This causes JFFS2 to read back every page written through the - write-buffer, and check for errors. - config JFFS2_SUMMARY bool "JFFS2 summary support (EXPERIMENTAL)" depends on JFFS2_FS && EXPERIMENTAL @@ -1306,71 +1298,52 @@ config JFFS2_ZLIB select ZLIB_DEFLATE depends on JFFS2_FS default y - help - Zlib is designed to be a free, general-purpose, legally unencumbered, - lossless data-compression library for use on virtually any computer - hardware and operating system. See for - further information. - - Say 'Y' if unsure. - -config JFFS2_LZO - bool "JFFS2 LZO compression support" if JFFS2_COMPRESSION_OPTIONS - select LZO_COMPRESS - select LZO_DECOMPRESS - depends on JFFS2_FS - default n - help - minilzo-based compression. Generally works better than Zlib. + help + Zlib is designed to be a free, general-purpose, legally unencumbered, + lossless data-compression library for use on virtually any computer + hardware and operating system. See for + further information. - This feature was added in July, 2007. Say 'N' if you need - compatibility with older bootloaders or kernels. + Say 'Y' if unsure. config JFFS2_RTIME bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS depends on JFFS2_FS default y - help - Rtime does manage to recompress already-compressed data. Say 'Y' if unsure. + help + Rtime does manage to recompress already-compressed data. Say 'Y' if unsure. config JFFS2_RUBIN bool "JFFS2 RUBIN compression support" if JFFS2_COMPRESSION_OPTIONS depends on JFFS2_FS default n - help - RUBINMIPS and DYNRUBIN compressors. Say 'N' if unsure. + help + RUBINMIPS and DYNRUBIN compressors. Say 'N' if unsure. choice - prompt "JFFS2 default compression mode" if JFFS2_COMPRESSION_OPTIONS - default JFFS2_CMODE_PRIORITY - depends on JFFS2_FS - help - You can set here the default compression mode of JFFS2 from - the available compression modes. Don't touch if unsure. + prompt "JFFS2 default compression mode" if JFFS2_COMPRESSION_OPTIONS + default JFFS2_CMODE_PRIORITY + depends on JFFS2_FS + help + You can set here the default compression mode of JFFS2 from + the available compression modes. Don't touch if unsure. config JFFS2_CMODE_NONE - bool "no compression" - help - Uses no compression. + bool "no compression" + help + Uses no compression. config JFFS2_CMODE_PRIORITY - bool "priority" - help - Tries the compressors in a predefined order and chooses the first - successful one. + bool "priority" + help + Tries the compressors in a predefined order and chooses the first + successful one. config JFFS2_CMODE_SIZE - bool "size (EXPERIMENTAL)" - help - Tries all compressors and chooses the one which has the smallest - result. - -config JFFS2_CMODE_FAVOURLZO - bool "Favour LZO" - help - Tries all compressors and chooses the one which has the smallest - result but gives some preference to LZO (which has faster - decompression) at the expense of size. + bool "size (EXPERIMENTAL)" + help + Tries all compressors and chooses the one which has the smallest + result. endchoice diff --git a/trunk/fs/jffs2/Makefile b/trunk/fs/jffs2/Makefile index 60e5d49ca03e..c32b241e3d91 100644 --- a/trunk/fs/jffs2/Makefile +++ b/trunk/fs/jffs2/Makefile @@ -17,5 +17,4 @@ jffs2-$(CONFIG_JFFS2_FS_POSIX_ACL) += acl.o jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rubin.o jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o -jffs2-$(CONFIG_JFFS2_LZO) += compr_lzo.o jffs2-$(CONFIG_JFFS2_SUMMARY) += summary.o diff --git a/trunk/fs/jffs2/acl.c b/trunk/fs/jffs2/acl.c index 8ec9323e830a..65b3a1b5b88d 100644 --- a/trunk/fs/jffs2/acl.c +++ b/trunk/fs/jffs2/acl.c @@ -176,7 +176,7 @@ static void jffs2_iset_acl(struct inode *inode, struct posix_acl **i_acl, struct spin_unlock(&inode->i_lock); } -struct posix_acl *jffs2_get_acl(struct inode *inode, int type) +static struct posix_acl *jffs2_get_acl(struct inode *inode, int type) { struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); struct posix_acl *acl; @@ -247,13 +247,8 @@ static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl) if (rc < 0) return rc; if (inode->i_mode != mode) { - struct iattr attr; - - attr.ia_valid = ATTR_MODE; - attr.ia_mode = mode; - rc = jffs2_do_setattr(inode, &attr); - if (rc < 0) - return rc; + inode->i_mode = mode; + jffs2_dirty_inode(inode); } if (rc == 0) acl = NULL; @@ -312,16 +307,22 @@ int jffs2_permission(struct inode *inode, int mask, struct nameidata *nd) return generic_permission(inode, mask, jffs2_check_acl); } -int jffs2_init_acl(struct inode *inode, struct posix_acl *acl) +int jffs2_init_acl(struct inode *inode, struct inode *dir) { struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); - struct posix_acl *clone; + struct posix_acl *acl = NULL, *clone; mode_t mode; int rc = 0; f->i_acl_access = JFFS2_ACL_NOT_CACHED; f->i_acl_default = JFFS2_ACL_NOT_CACHED; - + if (!S_ISLNK(inode->i_mode)) { + acl = jffs2_get_acl(dir, ACL_TYPE_DEFAULT); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (!acl) + inode->i_mode &= ~current->fs->umask; + } if (acl) { if (S_ISDIR(inode->i_mode)) { rc = jffs2_set_acl(inode, ACL_TYPE_DEFAULT, acl); diff --git a/trunk/fs/jffs2/acl.h b/trunk/fs/jffs2/acl.h index 90a2dbf59051..c84378cee82a 100644 --- a/trunk/fs/jffs2/acl.h +++ b/trunk/fs/jffs2/acl.h @@ -28,10 +28,9 @@ struct jffs2_acl_header { #define JFFS2_ACL_NOT_CACHED ((void *)-1) -extern struct posix_acl *jffs2_get_acl(struct inode *inode, int type); extern int jffs2_permission(struct inode *, int, struct nameidata *); extern int jffs2_acl_chmod(struct inode *); -extern int jffs2_init_acl(struct inode *, struct posix_acl *); +extern int jffs2_init_acl(struct inode *, struct inode *); extern void jffs2_clear_acl(struct jffs2_inode_info *); extern struct xattr_handler jffs2_acl_access_xattr_handler; @@ -39,7 +38,6 @@ extern struct xattr_handler jffs2_acl_default_xattr_handler; #else -#define jffs2_get_acl(inode, type) (NULL) #define jffs2_permission NULL #define jffs2_acl_chmod(inode) (0) #define jffs2_init_acl(inode,dir) (0) diff --git a/trunk/fs/jffs2/background.c b/trunk/fs/jffs2/background.c index d568ae846741..504643f2e98b 100644 --- a/trunk/fs/jffs2/background.c +++ b/trunk/fs/jffs2/background.c @@ -23,8 +23,8 @@ static int jffs2_garbage_collect_thread(void *); void jffs2_garbage_collect_trigger(struct jffs2_sb_info *c) { spin_lock(&c->erase_completion_lock); - if (c->gc_task && jffs2_thread_should_wake(c)) - send_sig(SIGHUP, c->gc_task, 1); + if (c->gc_task && jffs2_thread_should_wake(c)) + send_sig(SIGHUP, c->gc_task, 1); spin_unlock(&c->erase_completion_lock); } diff --git a/trunk/fs/jffs2/compr.c b/trunk/fs/jffs2/compr.c index 86739ee53b37..485d065de41f 100644 --- a/trunk/fs/jffs2/compr.c +++ b/trunk/fs/jffs2/compr.c @@ -5,7 +5,7 @@ * Created by Arjan van de Ven * * Copyright © 2004 Ferenc Havasi , - * University of Szeged, Hungary + * University of Szeged, Hungary * * For licensing information, see the file 'LICENCE' in this directory. * @@ -24,34 +24,6 @@ static int jffs2_compression_mode = JFFS2_COMPR_MODE_PRIORITY; /* Statistics for blocks stored without compression */ static uint32_t none_stat_compr_blocks=0,none_stat_decompr_blocks=0,none_stat_compr_size=0; - -/* - * Return 1 to use this compression - */ -static int jffs2_is_best_compression(struct jffs2_compressor *this, - struct jffs2_compressor *best, uint32_t size, uint32_t bestsize) -{ - switch (jffs2_compression_mode) { - case JFFS2_COMPR_MODE_SIZE: - if (bestsize > size) - return 1; - return 0; - case JFFS2_COMPR_MODE_FAVOURLZO: - if ((this->compr == JFFS2_COMPR_LZO) && (bestsize > size)) - return 1; - if ((best->compr != JFFS2_COMPR_LZO) && (bestsize > size)) - return 1; - if ((this->compr == JFFS2_COMPR_LZO) && (bestsize > (size * FAVOUR_LZO_PERCENT / 100))) - return 1; - if ((bestsize * FAVOUR_LZO_PERCENT / 100) > size) - return 1; - - return 0; - } - /* Shouldn't happen */ - return 0; -} - /* jffs2_compress: * @data: Pointer to uncompressed data * @cdata: Pointer to returned pointer to buffer for compressed data @@ -71,124 +43,121 @@ static int jffs2_is_best_compression(struct jffs2_compressor *this, * *datalen accordingly to show the amount of data which were compressed. */ uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, - unsigned char *data_in, unsigned char **cpage_out, - uint32_t *datalen, uint32_t *cdatalen) + unsigned char *data_in, unsigned char **cpage_out, + uint32_t *datalen, uint32_t *cdatalen) { int ret = JFFS2_COMPR_NONE; - int compr_ret; - struct jffs2_compressor *this, *best=NULL; - unsigned char *output_buf = NULL, *tmp_buf; - uint32_t orig_slen, orig_dlen; - uint32_t best_slen=0, best_dlen=0; + int compr_ret; + struct jffs2_compressor *this, *best=NULL; + unsigned char *output_buf = NULL, *tmp_buf; + uint32_t orig_slen, orig_dlen; + uint32_t best_slen=0, best_dlen=0; - switch (jffs2_compression_mode) { - case JFFS2_COMPR_MODE_NONE: - break; - case JFFS2_COMPR_MODE_PRIORITY: - output_buf = kmalloc(*cdatalen,GFP_KERNEL); - if (!output_buf) { - printk(KERN_WARNING "JFFS2: No memory for compressor allocation. Compression failed.\n"); - goto out; - } - orig_slen = *datalen; - orig_dlen = *cdatalen; - spin_lock(&jffs2_compressor_list_lock); - list_for_each_entry(this, &jffs2_compressor_list, list) { - /* Skip decompress-only backwards-compatibility and disabled modules */ - if ((!this->compress)||(this->disabled)) - continue; + switch (jffs2_compression_mode) { + case JFFS2_COMPR_MODE_NONE: + break; + case JFFS2_COMPR_MODE_PRIORITY: + output_buf = kmalloc(*cdatalen,GFP_KERNEL); + if (!output_buf) { + printk(KERN_WARNING "JFFS2: No memory for compressor allocation. Compression failed.\n"); + goto out; + } + orig_slen = *datalen; + orig_dlen = *cdatalen; + spin_lock(&jffs2_compressor_list_lock); + list_for_each_entry(this, &jffs2_compressor_list, list) { + /* Skip decompress-only backwards-compatibility and disabled modules */ + if ((!this->compress)||(this->disabled)) + continue; - this->usecount++; - spin_unlock(&jffs2_compressor_list_lock); - *datalen = orig_slen; - *cdatalen = orig_dlen; - compr_ret = this->compress(data_in, output_buf, datalen, cdatalen, NULL); - spin_lock(&jffs2_compressor_list_lock); - this->usecount--; - if (!compr_ret) { - ret = this->compr; - this->stat_compr_blocks++; - this->stat_compr_orig_size += *datalen; - this->stat_compr_new_size += *cdatalen; - break; - } - } - spin_unlock(&jffs2_compressor_list_lock); - if (ret == JFFS2_COMPR_NONE) - kfree(output_buf); - break; - case JFFS2_COMPR_MODE_SIZE: - case JFFS2_COMPR_MODE_FAVOURLZO: - orig_slen = *datalen; - orig_dlen = *cdatalen; - spin_lock(&jffs2_compressor_list_lock); - list_for_each_entry(this, &jffs2_compressor_list, list) { - /* Skip decompress-only backwards-compatibility and disabled modules */ - if ((!this->compress)||(this->disabled)) - continue; - /* Allocating memory for output buffer if necessary */ - if ((this->compr_buf_size < orig_slen) && (this->compr_buf)) { - spin_unlock(&jffs2_compressor_list_lock); - kfree(this->compr_buf); - spin_lock(&jffs2_compressor_list_lock); - this->compr_buf_size=0; - this->compr_buf=NULL; - } - if (!this->compr_buf) { - spin_unlock(&jffs2_compressor_list_lock); - tmp_buf = kmalloc(orig_slen, GFP_KERNEL); - spin_lock(&jffs2_compressor_list_lock); - if (!tmp_buf) { - printk(KERN_WARNING "JFFS2: No memory for compressor allocation. (%d bytes)\n", orig_slen); - continue; - } - else { - this->compr_buf = tmp_buf; - this->compr_buf_size = orig_slen; - } - } - this->usecount++; - spin_unlock(&jffs2_compressor_list_lock); - *datalen = orig_slen; - *cdatalen = orig_dlen; - compr_ret = this->compress(data_in, this->compr_buf, datalen, cdatalen, NULL); - spin_lock(&jffs2_compressor_list_lock); - this->usecount--; - if (!compr_ret) { - if (((!best_dlen) || jffs2_is_best_compression(this, best, *cdatalen, best_dlen)) - && (*cdatalen < *datalen)) { - best_dlen = *cdatalen; - best_slen = *datalen; - best = this; - } - } - } - if (best_dlen) { - *cdatalen = best_dlen; - *datalen = best_slen; - output_buf = best->compr_buf; - best->compr_buf = NULL; - best->compr_buf_size = 0; - best->stat_compr_blocks++; - best->stat_compr_orig_size += best_slen; - best->stat_compr_new_size += best_dlen; - ret = best->compr; - } - spin_unlock(&jffs2_compressor_list_lock); - break; - default: - printk(KERN_ERR "JFFS2: unknow compression mode.\n"); - } + this->usecount++; + spin_unlock(&jffs2_compressor_list_lock); + *datalen = orig_slen; + *cdatalen = orig_dlen; + compr_ret = this->compress(data_in, output_buf, datalen, cdatalen, NULL); + spin_lock(&jffs2_compressor_list_lock); + this->usecount--; + if (!compr_ret) { + ret = this->compr; + this->stat_compr_blocks++; + this->stat_compr_orig_size += *datalen; + this->stat_compr_new_size += *cdatalen; + break; + } + } + spin_unlock(&jffs2_compressor_list_lock); + if (ret == JFFS2_COMPR_NONE) kfree(output_buf); + break; + case JFFS2_COMPR_MODE_SIZE: + orig_slen = *datalen; + orig_dlen = *cdatalen; + spin_lock(&jffs2_compressor_list_lock); + list_for_each_entry(this, &jffs2_compressor_list, list) { + /* Skip decompress-only backwards-compatibility and disabled modules */ + if ((!this->compress)||(this->disabled)) + continue; + /* Allocating memory for output buffer if necessary */ + if ((this->compr_buf_sizecompr_buf)) { + spin_unlock(&jffs2_compressor_list_lock); + kfree(this->compr_buf); + spin_lock(&jffs2_compressor_list_lock); + this->compr_buf_size=0; + this->compr_buf=NULL; + } + if (!this->compr_buf) { + spin_unlock(&jffs2_compressor_list_lock); + tmp_buf = kmalloc(orig_dlen,GFP_KERNEL); + spin_lock(&jffs2_compressor_list_lock); + if (!tmp_buf) { + printk(KERN_WARNING "JFFS2: No memory for compressor allocation. (%d bytes)\n",orig_dlen); + continue; + } + else { + this->compr_buf = tmp_buf; + this->compr_buf_size = orig_dlen; + } + } + this->usecount++; + spin_unlock(&jffs2_compressor_list_lock); + *datalen = orig_slen; + *cdatalen = orig_dlen; + compr_ret = this->compress(data_in, this->compr_buf, datalen, cdatalen, NULL); + spin_lock(&jffs2_compressor_list_lock); + this->usecount--; + if (!compr_ret) { + if ((!best_dlen)||(best_dlen>*cdatalen)) { + best_dlen = *cdatalen; + best_slen = *datalen; + best = this; + } + } + } + if (best_dlen) { + *cdatalen = best_dlen; + *datalen = best_slen; + output_buf = best->compr_buf; + best->compr_buf = NULL; + best->compr_buf_size = 0; + best->stat_compr_blocks++; + best->stat_compr_orig_size += best_slen; + best->stat_compr_new_size += best_dlen; + ret = best->compr; + } + spin_unlock(&jffs2_compressor_list_lock); + break; + default: + printk(KERN_ERR "JFFS2: unknow compression mode.\n"); + } out: - if (ret == JFFS2_COMPR_NONE) { - *cpage_out = data_in; - *datalen = *cdatalen; - none_stat_compr_blocks++; - none_stat_compr_size += *datalen; - } - else { - *cpage_out = output_buf; - } + if (ret == JFFS2_COMPR_NONE) { + *cpage_out = data_in; + *datalen = *cdatalen; + none_stat_compr_blocks++; + none_stat_compr_size += *datalen; + } + else { + *cpage_out = output_buf; + } return ret; } @@ -196,8 +165,8 @@ int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint16_t comprtype, unsigned char *cdata_in, unsigned char *data_out, uint32_t cdatalen, uint32_t datalen) { - struct jffs2_compressor *this; - int ret; + struct jffs2_compressor *this; + int ret; /* Older code had a bug where it would write non-zero 'usercompr' fields. Deal with it. */ @@ -208,32 +177,32 @@ int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, case JFFS2_COMPR_NONE: /* This should be special-cased elsewhere, but we might as well deal with it */ memcpy(data_out, cdata_in, datalen); - none_stat_decompr_blocks++; + none_stat_decompr_blocks++; break; case JFFS2_COMPR_ZERO: memset(data_out, 0, datalen); break; default: - spin_lock(&jffs2_compressor_list_lock); - list_for_each_entry(this, &jffs2_compressor_list, list) { - if (comprtype == this->compr) { - this->usecount++; - spin_unlock(&jffs2_compressor_list_lock); - ret = this->decompress(cdata_in, data_out, cdatalen, datalen, NULL); - spin_lock(&jffs2_compressor_list_lock); - if (ret) { - printk(KERN_WARNING "Decompressor \"%s\" returned %d\n", this->name, ret); - } - else { - this->stat_decompr_blocks++; - } - this->usecount--; - spin_unlock(&jffs2_compressor_list_lock); - return ret; - } - } + spin_lock(&jffs2_compressor_list_lock); + list_for_each_entry(this, &jffs2_compressor_list, list) { + if (comprtype == this->compr) { + this->usecount++; + spin_unlock(&jffs2_compressor_list_lock); + ret = this->decompress(cdata_in, data_out, cdatalen, datalen, NULL); + spin_lock(&jffs2_compressor_list_lock); + if (ret) { + printk(KERN_WARNING "Decompressor \"%s\" returned %d\n", this->name, ret); + } + else { + this->stat_decompr_blocks++; + } + this->usecount--; + spin_unlock(&jffs2_compressor_list_lock); + return ret; + } + } printk(KERN_WARNING "JFFS2 compression type 0x%02x not available.\n", comprtype); - spin_unlock(&jffs2_compressor_list_lock); + spin_unlock(&jffs2_compressor_list_lock); return -EIO; } return 0; @@ -241,119 +210,108 @@ int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, int jffs2_register_compressor(struct jffs2_compressor *comp) { - struct jffs2_compressor *this; + struct jffs2_compressor *this; - if (!comp->name) { - printk(KERN_WARNING "NULL compressor name at registering JFFS2 compressor. Failed.\n"); - return -1; - } - comp->compr_buf_size=0; - comp->compr_buf=NULL; - comp->usecount=0; - comp->stat_compr_orig_size=0; - comp->stat_compr_new_size=0; - comp->stat_compr_blocks=0; - comp->stat_decompr_blocks=0; - D1(printk(KERN_DEBUG "Registering JFFS2 compressor \"%s\"\n", comp->name)); + if (!comp->name) { + printk(KERN_WARNING "NULL compressor name at registering JFFS2 compressor. Failed.\n"); + return -1; + } + comp->compr_buf_size=0; + comp->compr_buf=NULL; + comp->usecount=0; + comp->stat_compr_orig_size=0; + comp->stat_compr_new_size=0; + comp->stat_compr_blocks=0; + comp->stat_decompr_blocks=0; + D1(printk(KERN_DEBUG "Registering JFFS2 compressor \"%s\"\n", comp->name)); - spin_lock(&jffs2_compressor_list_lock); + spin_lock(&jffs2_compressor_list_lock); - list_for_each_entry(this, &jffs2_compressor_list, list) { - if (this->priority < comp->priority) { - list_add(&comp->list, this->list.prev); - goto out; - } - } - list_add_tail(&comp->list, &jffs2_compressor_list); + list_for_each_entry(this, &jffs2_compressor_list, list) { + if (this->priority < comp->priority) { + list_add(&comp->list, this->list.prev); + goto out; + } + } + list_add_tail(&comp->list, &jffs2_compressor_list); out: - D2(list_for_each_entry(this, &jffs2_compressor_list, list) { - printk(KERN_DEBUG "Compressor \"%s\", prio %d\n", this->name, this->priority); - }) + D2(list_for_each_entry(this, &jffs2_compressor_list, list) { + printk(KERN_DEBUG "Compressor \"%s\", prio %d\n", this->name, this->priority); + }) - spin_unlock(&jffs2_compressor_list_lock); + spin_unlock(&jffs2_compressor_list_lock); - return 0; + return 0; } int jffs2_unregister_compressor(struct jffs2_compressor *comp) { - D2(struct jffs2_compressor *this;) + D2(struct jffs2_compressor *this;) - D1(printk(KERN_DEBUG "Unregistering JFFS2 compressor \"%s\"\n", comp->name)); + D1(printk(KERN_DEBUG "Unregistering JFFS2 compressor \"%s\"\n", comp->name)); - spin_lock(&jffs2_compressor_list_lock); + spin_lock(&jffs2_compressor_list_lock); - if (comp->usecount) { - spin_unlock(&jffs2_compressor_list_lock); - printk(KERN_WARNING "JFFS2: Compressor modul is in use. Unregister failed.\n"); - return -1; - } - list_del(&comp->list); + if (comp->usecount) { + spin_unlock(&jffs2_compressor_list_lock); + printk(KERN_WARNING "JFFS2: Compressor modul is in use. Unregister failed.\n"); + return -1; + } + list_del(&comp->list); - D2(list_for_each_entry(this, &jffs2_compressor_list, list) { - printk(KERN_DEBUG "Compressor \"%s\", prio %d\n", this->name, this->priority); - }) - spin_unlock(&jffs2_compressor_list_lock); - return 0; + D2(list_for_each_entry(this, &jffs2_compressor_list, list) { + printk(KERN_DEBUG "Compressor \"%s\", prio %d\n", this->name, this->priority); + }) + spin_unlock(&jffs2_compressor_list_lock); + return 0; } void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig) { - if (orig != comprbuf) - kfree(comprbuf); + if (orig != comprbuf) + kfree(comprbuf); } int __init jffs2_compressors_init(void) { /* Registering compressors */ #ifdef CONFIG_JFFS2_ZLIB - jffs2_zlib_init(); + jffs2_zlib_init(); #endif #ifdef CONFIG_JFFS2_RTIME - jffs2_rtime_init(); + jffs2_rtime_init(); #endif #ifdef CONFIG_JFFS2_RUBIN - jffs2_rubinmips_init(); - jffs2_dynrubin_init(); -#endif -#ifdef CONFIG_JFFS2_LZO - jffs2_lzo_init(); + jffs2_rubinmips_init(); + jffs2_dynrubin_init(); #endif /* Setting default compression mode */ #ifdef CONFIG_JFFS2_CMODE_NONE - jffs2_compression_mode = JFFS2_COMPR_MODE_NONE; - D1(printk(KERN_INFO "JFFS2: default compression mode: none\n");) + jffs2_compression_mode = JFFS2_COMPR_MODE_NONE; + D1(printk(KERN_INFO "JFFS2: default compression mode: none\n");) #else #ifdef CONFIG_JFFS2_CMODE_SIZE - jffs2_compression_mode = JFFS2_COMPR_MODE_SIZE; - D1(printk(KERN_INFO "JFFS2: default compression mode: size\n");) -#else -#ifdef CONFIG_JFFS2_CMODE_FAVOURLZO - jffs2_compression_mode = JFFS2_COMPR_MODE_FAVOURLZO; - D1(printk(KERN_INFO "JFFS2: default compression mode: favourlzo\n");) + jffs2_compression_mode = JFFS2_COMPR_MODE_SIZE; + D1(printk(KERN_INFO "JFFS2: default compression mode: size\n");) #else - D1(printk(KERN_INFO "JFFS2: default compression mode: priority\n");) -#endif + D1(printk(KERN_INFO "JFFS2: default compression mode: priority\n");) #endif #endif - return 0; + return 0; } int jffs2_compressors_exit(void) { /* Unregistering compressors */ -#ifdef CONFIG_JFFS2_LZO - jffs2_lzo_exit(); -#endif #ifdef CONFIG_JFFS2_RUBIN - jffs2_dynrubin_exit(); - jffs2_rubinmips_exit(); + jffs2_dynrubin_exit(); + jffs2_rubinmips_exit(); #endif #ifdef CONFIG_JFFS2_RTIME - jffs2_rtime_exit(); + jffs2_rtime_exit(); #endif #ifdef CONFIG_JFFS2_ZLIB - jffs2_zlib_exit(); + jffs2_zlib_exit(); #endif - return 0; + return 0; } diff --git a/trunk/fs/jffs2/compr.h b/trunk/fs/jffs2/compr.h index 7d1d72faa774..68cc7010dbdf 100644 --- a/trunk/fs/jffs2/compr.h +++ b/trunk/fs/jffs2/compr.h @@ -2,7 +2,7 @@ * JFFS2 -- Journalling Flash File System, Version 2. * * Copyright © 2004 Ferenc Havasi , - * University of Szeged, Hungary + * University of Szeged, Hungary * * For licensing information, see the file 'LICENCE' in this directory. * @@ -27,38 +27,34 @@ #define JFFS2_RUBINMIPS_PRIORITY 10 #define JFFS2_DYNRUBIN_PRIORITY 20 #define JFFS2_LZARI_PRIORITY 30 +#define JFFS2_LZO_PRIORITY 40 #define JFFS2_RTIME_PRIORITY 50 #define JFFS2_ZLIB_PRIORITY 60 -#define JFFS2_LZO_PRIORITY 80 - #define JFFS2_RUBINMIPS_DISABLED /* RUBINs will be used only */ -#define JFFS2_DYNRUBIN_DISABLED /* for decompression */ +#define JFFS2_DYNRUBIN_DISABLED /* for decompression */ #define JFFS2_COMPR_MODE_NONE 0 #define JFFS2_COMPR_MODE_PRIORITY 1 #define JFFS2_COMPR_MODE_SIZE 2 -#define JFFS2_COMPR_MODE_FAVOURLZO 3 - -#define FAVOUR_LZO_PERCENT 80 struct jffs2_compressor { - struct list_head list; - int priority; /* used by prirority comr. mode */ - char *name; - char compr; /* JFFS2_COMPR_XXX */ - int (*compress)(unsigned char *data_in, unsigned char *cpage_out, - uint32_t *srclen, uint32_t *destlen, void *model); - int (*decompress)(unsigned char *cdata_in, unsigned char *data_out, - uint32_t cdatalen, uint32_t datalen, void *model); - int usecount; - int disabled; /* if set the compressor won't compress */ - unsigned char *compr_buf; /* used by size compr. mode */ - uint32_t compr_buf_size; /* used by size compr. mode */ - uint32_t stat_compr_orig_size; - uint32_t stat_compr_new_size; - uint32_t stat_compr_blocks; - uint32_t stat_decompr_blocks; + struct list_head list; + int priority; /* used by prirority comr. mode */ + char *name; + char compr; /* JFFS2_COMPR_XXX */ + int (*compress)(unsigned char *data_in, unsigned char *cpage_out, + uint32_t *srclen, uint32_t *destlen, void *model); + int (*decompress)(unsigned char *cdata_in, unsigned char *data_out, + uint32_t cdatalen, uint32_t datalen, void *model); + int usecount; + int disabled; /* if seted the compressor won't compress */ + unsigned char *compr_buf; /* used by size compr. mode */ + uint32_t compr_buf_size; /* used by size compr. mode */ + uint32_t stat_compr_orig_size; + uint32_t stat_compr_new_size; + uint32_t stat_compr_blocks; + uint32_t stat_decompr_blocks; }; int jffs2_register_compressor(struct jffs2_compressor *comp); @@ -68,12 +64,12 @@ int jffs2_compressors_init(void); int jffs2_compressors_exit(void); uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, - unsigned char *data_in, unsigned char **cpage_out, - uint32_t *datalen, uint32_t *cdatalen); + unsigned char *data_in, unsigned char **cpage_out, + uint32_t *datalen, uint32_t *cdatalen); int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, - uint16_t comprtype, unsigned char *cdata_in, - unsigned char *data_out, uint32_t cdatalen, uint32_t datalen); + uint16_t comprtype, unsigned char *cdata_in, + unsigned char *data_out, uint32_t cdatalen, uint32_t datalen); void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig); @@ -94,9 +90,5 @@ void jffs2_rtime_exit(void); int jffs2_zlib_init(void); void jffs2_zlib_exit(void); #endif -#ifdef CONFIG_JFFS2_LZO -int jffs2_lzo_init(void); -void jffs2_lzo_exit(void); -#endif #endif /* __JFFS2_COMPR_H__ */ diff --git a/trunk/fs/jffs2/compr_lzo.c b/trunk/fs/jffs2/compr_lzo.c deleted file mode 100644 index 47b045797e42..000000000000 --- a/trunk/fs/jffs2/compr_lzo.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright © 2007 Nokia Corporation. All rights reserved. - * - * Created by Richard Purdie - * - * For licensing information, see the file 'LICENCE' in this directory. - * - */ - -#include -#include -#include -#include -#include -#include -#include "compr.h" - -static void *lzo_mem; -static void *lzo_compress_buf; -static DEFINE_MUTEX(deflate_mutex); - -static void free_workspace(void) -{ - vfree(lzo_mem); - vfree(lzo_compress_buf); -} - -static int __init alloc_workspace(void) -{ - lzo_mem = vmalloc(LZO1X_MEM_COMPRESS); - lzo_compress_buf = vmalloc(lzo1x_worst_compress(PAGE_SIZE)); - - if (!lzo_mem || !lzo_compress_buf) { - printk(KERN_WARNING "Failed to allocate lzo deflate workspace\n"); - free_workspace(); - return -ENOMEM; - } - - return 0; -} - -static int jffs2_lzo_compress(unsigned char *data_in, unsigned char *cpage_out, - uint32_t *sourcelen, uint32_t *dstlen, void *model) -{ - size_t compress_size; - int ret; - - mutex_lock(&deflate_mutex); - ret = lzo1x_1_compress(data_in, *sourcelen, lzo_compress_buf, &compress_size, lzo_mem); - mutex_unlock(&deflate_mutex); - - if (ret != LZO_E_OK) - return -1; - - if (compress_size > *dstlen) - return -1; - - memcpy(cpage_out, lzo_compress_buf, compress_size); - *dstlen = compress_size; - - return 0; -} - -static int jffs2_lzo_decompress(unsigned char *data_in, unsigned char *cpage_out, - uint32_t srclen, uint32_t destlen, void *model) -{ - size_t dl = destlen; - int ret; - - ret = lzo1x_decompress_safe(data_in, srclen, cpage_out, &dl); - - if (ret != LZO_E_OK || dl != destlen) - return -1; - - return 0; -} - -static struct jffs2_compressor jffs2_lzo_comp = { - .priority = JFFS2_LZO_PRIORITY, - .name = "lzo", - .compr = JFFS2_COMPR_LZO, - .compress = &jffs2_lzo_compress, - .decompress = &jffs2_lzo_decompress, - .disabled = 0, -}; - -int __init jffs2_lzo_init(void) -{ - int ret; - - ret = alloc_workspace(); - if (ret < 0) - return ret; - - ret = jffs2_register_compressor(&jffs2_lzo_comp); - if (ret) - free_workspace(); - - return ret; -} - -void jffs2_lzo_exit(void) -{ - jffs2_unregister_compressor(&jffs2_lzo_comp); - free_workspace(); -} diff --git a/trunk/fs/jffs2/compr_rtime.c b/trunk/fs/jffs2/compr_rtime.c index 546d1538d076..0d0bfd2e4e0d 100644 --- a/trunk/fs/jffs2/compr_rtime.c +++ b/trunk/fs/jffs2/compr_rtime.c @@ -104,7 +104,7 @@ static int jffs2_rtime_decompress(unsigned char *data_in, } } } - return 0; + return 0; } static struct jffs2_compressor jffs2_rtime_comp = { diff --git a/trunk/fs/jffs2/compr_rubin.c b/trunk/fs/jffs2/compr_rubin.c index c73fa89b5f8a..ea0431e047d5 100644 --- a/trunk/fs/jffs2/compr_rubin.c +++ b/trunk/fs/jffs2/compr_rubin.c @@ -384,7 +384,7 @@ static int jffs2_rubinmips_decompress(unsigned char *data_in, void *model) { rubin_do_decompress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen); - return 0; + return 0; } static int jffs2_dynrubin_decompress(unsigned char *data_in, @@ -399,7 +399,7 @@ static int jffs2_dynrubin_decompress(unsigned char *data_in, bits[c] = data_in[c]; rubin_do_decompress(256, bits, data_in+8, cpage_out, sourcelen-8, dstlen); - return 0; + return 0; } static struct jffs2_compressor jffs2_rubinmips_comp = { diff --git a/trunk/fs/jffs2/compr_zlib.c b/trunk/fs/jffs2/compr_zlib.c index cfd301a5edfc..2b87fccc1557 100644 --- a/trunk/fs/jffs2/compr_zlib.c +++ b/trunk/fs/jffs2/compr_zlib.c @@ -181,7 +181,7 @@ static int jffs2_zlib_decompress(unsigned char *data_in, } zlib_inflateEnd(&inf_strm); mutex_unlock(&inflate_mutex); - return 0; + return 0; } static struct jffs2_compressor jffs2_zlib_comp = { @@ -203,11 +203,11 @@ int __init jffs2_zlib_init(void) ret = alloc_workspaces(); if (ret) - return ret; + return ret; ret = jffs2_register_compressor(&jffs2_zlib_comp); if (ret) - free_workspaces(); + free_workspaces(); return ret; } diff --git a/trunk/fs/jffs2/dir.c b/trunk/fs/jffs2/dir.c index 8353eb9c1799..c1dfca310dd6 100644 --- a/trunk/fs/jffs2/dir.c +++ b/trunk/fs/jffs2/dir.c @@ -32,7 +32,7 @@ static int jffs2_mkdir (struct inode *,struct dentry *,int); static int jffs2_rmdir (struct inode *,struct dentry *); static int jffs2_mknod (struct inode *,struct dentry *,int,dev_t); static int jffs2_rename (struct inode *, struct dentry *, - struct inode *, struct dentry *); + struct inode *, struct dentry *); const struct file_operations jffs2_dir_operations = { @@ -182,7 +182,6 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode, struct jffs2_inode_info *f, *dir_f; struct jffs2_sb_info *c; struct inode *inode; - struct posix_acl *acl; int ret; ri = jffs2_alloc_raw_inode(); @@ -193,7 +192,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode, D1(printk(KERN_DEBUG "jffs2_create()\n")); - inode = jffs2_new_inode(dir_i, mode, ri, &acl); + inode = jffs2_new_inode(dir_i, mode, ri); if (IS_ERR(inode)) { D1(printk(KERN_DEBUG "jffs2_new_inode() failed\n")); @@ -213,12 +212,12 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode, dentry->d_name.name, dentry->d_name.len); if (ret) - goto fail_acl; + goto fail; ret = jffs2_init_security(inode, dir_i); if (ret) - goto fail_acl; - ret = jffs2_init_acl(inode, acl); + goto fail; + ret = jffs2_init_acl(inode, dir_i); if (ret) goto fail; @@ -231,8 +230,6 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode, inode->i_ino, inode->i_mode, inode->i_nlink, f->inocache->nlink, inode->i_mapping->nrpages)); return 0; - fail_acl: - posix_acl_release(acl); fail: make_bad_inode(inode); iput(inode); @@ -309,7 +306,6 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char struct jffs2_full_dirent *fd; int namelen; uint32_t alloclen; - struct posix_acl *acl; int ret, targetlen = strlen(target); /* FIXME: If you care. We'd need to use frags for the target @@ -336,7 +332,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char return ret; } - inode = jffs2_new_inode(dir_i, S_IFLNK | S_IRWXUGO, ri, &acl); + inode = jffs2_new_inode(dir_i, S_IFLNK | S_IRWXUGO, ri); if (IS_ERR(inode)) { jffs2_free_raw_inode(ri); @@ -366,7 +362,6 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char up(&f->sem); jffs2_complete_reservation(c); jffs2_clear_inode(inode); - posix_acl_release(acl); return PTR_ERR(fn); } @@ -377,7 +372,6 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char up(&f->sem); jffs2_complete_reservation(c); jffs2_clear_inode(inode); - posix_acl_release(acl); return -ENOMEM; } @@ -395,10 +389,9 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char ret = jffs2_init_security(inode, dir_i); if (ret) { jffs2_clear_inode(inode); - posix_acl_release(acl); return ret; } - ret = jffs2_init_acl(inode, acl); + ret = jffs2_init_acl(inode, dir_i); if (ret) { jffs2_clear_inode(inode); return ret; @@ -476,7 +469,6 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) struct jffs2_full_dirent *fd; int namelen; uint32_t alloclen; - struct posix_acl *acl; int ret; mode |= S_IFDIR; @@ -499,7 +491,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) return ret; } - inode = jffs2_new_inode(dir_i, mode, ri, &acl); + inode = jffs2_new_inode(dir_i, mode, ri); if (IS_ERR(inode)) { jffs2_free_raw_inode(ri); @@ -526,7 +518,6 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) up(&f->sem); jffs2_complete_reservation(c); jffs2_clear_inode(inode); - posix_acl_release(acl); return PTR_ERR(fn); } /* No data here. Only a metadata node, which will be @@ -540,10 +531,9 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) ret = jffs2_init_security(inode, dir_i); if (ret) { jffs2_clear_inode(inode); - posix_acl_release(acl); return ret; } - ret = jffs2_init_acl(inode, acl); + ret = jffs2_init_acl(inode, dir_i); if (ret) { jffs2_clear_inode(inode); return ret; @@ -639,7 +629,6 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de union jffs2_device_node dev; int devlen = 0; uint32_t alloclen; - struct posix_acl *acl; int ret; if (!new_valid_dev(rdev)) @@ -666,7 +655,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de return ret; } - inode = jffs2_new_inode(dir_i, mode, ri, &acl); + inode = jffs2_new_inode(dir_i, mode, ri); if (IS_ERR(inode)) { jffs2_free_raw_inode(ri); @@ -695,7 +684,6 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de up(&f->sem); jffs2_complete_reservation(c); jffs2_clear_inode(inode); - posix_acl_release(acl); return PTR_ERR(fn); } /* No data here. Only a metadata node, which will be @@ -709,10 +697,9 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de ret = jffs2_init_security(inode, dir_i); if (ret) { jffs2_clear_inode(inode); - posix_acl_release(acl); return ret; } - ret = jffs2_init_acl(inode, acl); + ret = jffs2_init_acl(inode, dir_i); if (ret) { jffs2_clear_inode(inode); return ret; @@ -783,7 +770,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de } static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, - struct inode *new_dir_i, struct dentry *new_dentry) + struct inode *new_dir_i, struct dentry *new_dentry) { int ret; struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb); diff --git a/trunk/fs/jffs2/erase.c b/trunk/fs/jffs2/erase.c index addd3fc0e877..66e7c2f1e644 100644 --- a/trunk/fs/jffs2/erase.c +++ b/trunk/fs/jffs2/erase.c @@ -38,8 +38,8 @@ static void jffs2_erase_block(struct jffs2_sb_info *c, #ifdef __ECOS ret = jffs2_flash_erase(c, jeb); if (!ret) { - jffs2_erase_succeeded(c, jeb); - return; + jffs2_erase_succeeded(c, jeb); + return; } bad_offset = jeb->offset; #else /* Linux */ @@ -50,14 +50,12 @@ static void jffs2_erase_block(struct jffs2_sb_info *c, instr = kmalloc(sizeof(struct erase_info) + sizeof(struct erase_priv_struct), GFP_KERNEL); if (!instr) { printk(KERN_WARNING "kmalloc for struct erase_info in jffs2_erase_block failed. Refiling block for later\n"); - down(&c->erase_free_sem); spin_lock(&c->erase_completion_lock); list_move(&jeb->list, &c->erase_pending_list); c->erasing_size -= c->sector_size; c->dirty_size += c->sector_size; jeb->dirty_size = c->sector_size; spin_unlock(&c->erase_completion_lock); - up(&c->erase_free_sem); return; } @@ -84,14 +82,12 @@ static void jffs2_erase_block(struct jffs2_sb_info *c, if (ret == -ENOMEM || ret == -EAGAIN) { /* Erase failed immediately. Refile it on the list */ D1(printk(KERN_DEBUG "Erase at 0x%08x failed: %d. Refiling on erase_pending_list\n", jeb->offset, ret)); - down(&c->erase_free_sem); spin_lock(&c->erase_completion_lock); list_move(&jeb->list, &c->erase_pending_list); c->erasing_size -= c->sector_size; c->dirty_size += c->sector_size; jeb->dirty_size = c->sector_size; spin_unlock(&c->erase_completion_lock); - up(&c->erase_free_sem); return; } @@ -118,7 +114,6 @@ void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count) jeb = list_entry(c->erase_complete_list.next, struct jffs2_eraseblock, list); list_del(&jeb->list); spin_unlock(&c->erase_completion_lock); - up(&c->erase_free_sem); jffs2_mark_erased_block(c, jeb); if (!--count) { @@ -139,7 +134,6 @@ void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count) jffs2_free_jeb_node_refs(c, jeb); list_add(&jeb->list, &c->erasing_list); spin_unlock(&c->erase_completion_lock); - up(&c->erase_free_sem); jffs2_erase_block(c, jeb); @@ -148,25 +142,23 @@ void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count) } /* Be nice */ - yield(); - down(&c->erase_free_sem); + cond_resched(); spin_lock(&c->erase_completion_lock); } spin_unlock(&c->erase_completion_lock); - up(&c->erase_free_sem); done: D1(printk(KERN_DEBUG "jffs2_erase_pending_blocks completed\n")); + + up(&c->erase_free_sem); } static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) { D1(printk(KERN_DEBUG "Erase completed successfully at 0x%08x\n", jeb->offset)); - down(&c->erase_free_sem); spin_lock(&c->erase_completion_lock); list_move_tail(&jeb->list, &c->erase_complete_list); spin_unlock(&c->erase_completion_lock); - up(&c->erase_free_sem); /* Ensure that kupdated calls us again to mark them clean */ jffs2_erase_pending_trigger(c); } @@ -180,26 +172,22 @@ static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock failed too many times. */ if (!jffs2_write_nand_badblock(c, jeb, bad_offset)) { /* We'd like to give this block another try. */ - down(&c->erase_free_sem); spin_lock(&c->erase_completion_lock); list_move(&jeb->list, &c->erase_pending_list); c->erasing_size -= c->sector_size; c->dirty_size += c->sector_size; jeb->dirty_size = c->sector_size; spin_unlock(&c->erase_completion_lock); - up(&c->erase_free_sem); return; } } - down(&c->erase_free_sem); spin_lock(&c->erase_completion_lock); c->erasing_size -= c->sector_size; c->bad_size += c->sector_size; list_move(&jeb->list, &c->bad_list); c->nr_erasing_blocks--; spin_unlock(&c->erase_completion_lock); - up(&c->erase_free_sem); wake_up(&c->erase_wait); } @@ -329,33 +317,6 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl size_t retlen; int ret = -EIO; - if (c->mtd->point) { - unsigned long *wordebuf; - - ret = c->mtd->point(c->mtd, jeb->offset, c->sector_size, &retlen, (unsigned char **)&ebuf); - if (ret) { - D1(printk(KERN_DEBUG "MTD point failed %d\n", ret)); - goto do_flash_read; - } - if (retlen < c->sector_size) { - /* Don't muck about if it won't let us point to the whole erase sector */ - D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", retlen)); - c->mtd->unpoint(c->mtd, ebuf, jeb->offset, c->sector_size); - goto do_flash_read; - } - wordebuf = ebuf-sizeof(*wordebuf); - retlen /= sizeof(*wordebuf); - do { - if (*++wordebuf != ~0) - break; - } while(--retlen); - c->mtd->unpoint(c->mtd, ebuf, jeb->offset, c->sector_size); - if (retlen) - printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08tx\n", - *wordebuf, jeb->offset + c->sector_size-retlen*sizeof(*wordebuf)); - return 0; - } - do_flash_read: ebuf = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!ebuf) { printk(KERN_WARNING "Failed to allocate page buffer for verifying erase at 0x%08x. Refiling\n", jeb->offset); @@ -401,7 +362,7 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb { size_t retlen; int ret; - uint32_t uninitialized_var(bad_offset); + uint32_t bad_offset; switch (jffs2_block_check_erase(c, jeb, &bad_offset)) { case -EAGAIN: goto refile; @@ -456,7 +417,6 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb jffs2_link_node_ref(c, jeb, jeb->offset | REF_NORMAL, c->cleanmarker_size, NULL); } - down(&c->erase_free_sem); spin_lock(&c->erase_completion_lock); c->erasing_size -= c->sector_size; c->free_size += jeb->free_size; @@ -469,28 +429,23 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb c->nr_erasing_blocks--; c->nr_free_blocks++; spin_unlock(&c->erase_completion_lock); - up(&c->erase_free_sem); wake_up(&c->erase_wait); return; filebad: - down(&c->erase_free_sem); spin_lock(&c->erase_completion_lock); /* Stick it on a list (any list) so erase_failed can take it right off again. Silly, but shouldn't happen often. */ list_add(&jeb->list, &c->erasing_list); spin_unlock(&c->erase_completion_lock); - up(&c->erase_free_sem); jffs2_erase_failed(c, jeb, bad_offset); return; refile: /* Stick it back on the list from whence it came and come back later */ jffs2_erase_pending_trigger(c); - down(&c->erase_free_sem); spin_lock(&c->erase_completion_lock); list_add(&jeb->list, &c->erase_complete_list); spin_unlock(&c->erase_completion_lock); - up(&c->erase_free_sem); return; } diff --git a/trunk/fs/jffs2/fs.c b/trunk/fs/jffs2/fs.c index dd64ddc11d43..1d3b7a9fc828 100644 --- a/trunk/fs/jffs2/fs.c +++ b/trunk/fs/jffs2/fs.c @@ -24,7 +24,7 @@ static int jffs2_flash_setup(struct jffs2_sb_info *c); -int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) +static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) { struct jffs2_full_dnode *old_metadata, *new_metadata; struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); @@ -36,8 +36,10 @@ int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) unsigned int ivalid; uint32_t alloclen; int ret; - D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino)); + ret = inode_change_ok(inode, iattr); + if (ret) + return ret; /* Special cases - we don't want more than one data node for these types on the medium at any time. So setattr @@ -181,14 +183,9 @@ int jffs2_setattr(struct dentry *dentry, struct iattr *iattr) { int rc; - rc = inode_change_ok(dentry->d_inode, iattr); - if (rc) - return rc; - rc = jffs2_do_setattr(dentry->d_inode, iattr); if (!rc && (iattr->ia_valid & ATTR_MODE)) rc = jffs2_acl_chmod(dentry->d_inode); - return rc; } @@ -402,8 +399,7 @@ void jffs2_write_super (struct super_block *sb) /* jffs2_new_inode: allocate a new inode and inocache, add it to the hash, fill in the raw_inode while you're at it. */ -struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri, - struct posix_acl **acl) +struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri) { struct inode *inode; struct super_block *sb = dir_i->i_sb; @@ -435,23 +431,7 @@ struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_i } else { ri->gid = cpu_to_je16(current->fsgid); } - - /* POSIX ACLs have to be processed now, at least partly. - The umask is only applied if there's no default ACL */ - if (!S_ISLNK(mode)) { - *acl = jffs2_get_acl(dir_i, ACL_TYPE_DEFAULT); - if (IS_ERR(*acl)) { - make_bad_inode(inode); - iput(inode); - inode = (void *)*acl; - *acl = NULL; - return inode; - } - if (!(*acl)) - mode &= ~current->fs->umask; - } else { - *acl = NULL; - } + ri->mode = cpu_to_jemode(mode); ret = jffs2_do_new_inode (c, f, mode, ri); if (ret) { make_bad_inode(inode); diff --git a/trunk/fs/jffs2/gc.c b/trunk/fs/jffs2/gc.c index eded819df235..2d99e06ab223 100644 --- a/trunk/fs/jffs2/gc.c +++ b/trunk/fs/jffs2/gc.c @@ -556,7 +556,7 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, node = kmalloc(rawlen, GFP_KERNEL); if (!node) - return -ENOMEM; + return -ENOMEM; ret = jffs2_flash_read(c, ref_offset(raw), rawlen, &retlen, (char *)node); if (!ret && retlen != rawlen) @@ -624,7 +624,7 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, if (ret || (retlen != rawlen)) { printk(KERN_NOTICE "Write of %d bytes at 0x%08x failed. returned %d, retlen %zd\n", - rawlen, phys_ofs, ret, retlen); + rawlen, phys_ofs, ret, retlen); if (retlen) { jffs2_add_physical_node_ref(c, phys_ofs | REF_OBSOLETE, rawlen, NULL); } else { diff --git a/trunk/fs/jffs2/jffs2_fs_sb.h b/trunk/fs/jffs2/jffs2_fs_sb.h index ae99cd7fd43b..b13298a824ed 100644 --- a/trunk/fs/jffs2/jffs2_fs_sb.h +++ b/trunk/fs/jffs2/jffs2_fs_sb.h @@ -106,9 +106,6 @@ struct jffs2_sb_info { uint32_t wbuf_pagesize; /* 0 for NOR and other flashes with no wbuf */ -#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY - unsigned char *wbuf_verify; /* read-back buffer for verification */ -#endif #ifdef CONFIG_JFFS2_FS_WRITEBUFFER unsigned char *wbuf; /* Write-behind buffer for NAND flash */ uint32_t wbuf_ofs; diff --git a/trunk/fs/jffs2/nodelist.h b/trunk/fs/jffs2/nodelist.h index ec1aae9e695e..bc5509fe577b 100644 --- a/trunk/fs/jffs2/nodelist.h +++ b/trunk/fs/jffs2/nodelist.h @@ -127,7 +127,7 @@ static inline struct jffs2_inode_cache *jffs2_raw_ref_to_ic(struct jffs2_raw_nod return ((struct jffs2_inode_cache *)raw); } - /* flash_offset & 3 always has to be zero, because nodes are + /* flash_offset & 3 always has to be zero, because nodes are always aligned at 4 bytes. So we have a couple of extra bits to play with, which indicate the node's status; see below: */ #define REF_UNCHECKED 0 /* We haven't yet checked the CRC or built its inode */ diff --git a/trunk/fs/jffs2/nodemgmt.c b/trunk/fs/jffs2/nodemgmt.c index 5b49bff364b4..dbc908ad622b 100644 --- a/trunk/fs/jffs2/nodemgmt.c +++ b/trunk/fs/jffs2/nodemgmt.c @@ -154,7 +154,7 @@ int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, while(ret == -EAGAIN) { ret = jffs2_do_reserve_space(c, minsize, len, sumsize); if (ret) { - D1(printk(KERN_DEBUG "jffs2_reserve_space_gc: looping, ret is %d\n", ret)); + D1(printk(KERN_DEBUG "jffs2_reserve_space_gc: looping, ret is %d\n", ret)); } } spin_unlock(&c->erase_completion_lock); @@ -423,12 +423,7 @@ struct jffs2_raw_node_ref *jffs2_add_physical_node_ref(struct jffs2_sb_info *c, even after refiling c->nextblock */ if ((c->nextblock || ((ofs & 3) != REF_OBSOLETE)) && (jeb != c->nextblock || (ofs & ~3) != jeb->offset + (c->sector_size - jeb->free_size))) { - printk(KERN_WARNING "argh. node added in wrong place at 0x%08x(%d)\n", ofs & ~3, ofs & 3); - if (c->nextblock) - printk(KERN_WARNING "nextblock 0x%08x", c->nextblock->offset); - else - printk(KERN_WARNING "No nextblock"); - printk(", expected at %08x\n", jeb->offset + (c->sector_size - jeb->free_size)); + printk(KERN_WARNING "argh. node added in wrong place\n"); return ERR_PTR(-EINVAL); } #endif diff --git a/trunk/fs/jffs2/os-linux.h b/trunk/fs/jffs2/os-linux.h index f6743a915cf3..80daea96bbc2 100644 --- a/trunk/fs/jffs2/os-linux.h +++ b/trunk/fs/jffs2/os-linux.h @@ -173,15 +173,12 @@ int jffs2_ioctl(struct inode *, struct file *, unsigned int, unsigned long); extern const struct inode_operations jffs2_symlink_inode_operations; /* fs.c */ -struct posix_acl; - int jffs2_setattr (struct dentry *, struct iattr *); -int jffs2_do_setattr (struct inode *, struct iattr *); void jffs2_read_inode (struct inode *); void jffs2_clear_inode (struct inode *); void jffs2_dirty_inode(struct inode *inode); struct inode *jffs2_new_inode (struct inode *dir_i, int mode, - struct jffs2_raw_inode *ri, struct posix_acl **acl); + struct jffs2_raw_inode *ri); int jffs2_statfs (struct dentry *, struct kstatfs *); void jffs2_write_super (struct super_block *); int jffs2_remount_fs (struct super_block *, int *, char *); diff --git a/trunk/fs/jffs2/readinode.c b/trunk/fs/jffs2/readinode.c index 8d4319c56b17..b5baa356fed2 100644 --- a/trunk/fs/jffs2/readinode.c +++ b/trunk/fs/jffs2/readinode.c @@ -211,7 +211,7 @@ static void jffs2_kill_tn(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info * * ordering. * * Returns 0 if the node was handled (including marking it obsolete) - * < 0 an if error occurred + * < 0 an if error occurred */ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, struct jffs2_readinode_info *rii, @@ -862,8 +862,8 @@ static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_re JFFS2_ERROR("REF_UNCHECKED but unknown node at %#08x\n", ref_offset(ref)); JFFS2_ERROR("Node is {%04x,%04x,%08x,%08x}. Please report this error.\n", - je16_to_cpu(un->magic), je16_to_cpu(un->nodetype), - je32_to_cpu(un->totlen), je32_to_cpu(un->hdr_crc)); + je16_to_cpu(un->magic), je16_to_cpu(un->nodetype), + je32_to_cpu(un->totlen), je32_to_cpu(un->hdr_crc)); jffs2_mark_node_obsolete(c, ref); return 0; } diff --git a/trunk/fs/jffs2/scan.c b/trunk/fs/jffs2/scan.c index 59dd408e5432..6c75cd433342 100644 --- a/trunk/fs/jffs2/scan.c +++ b/trunk/fs/jffs2/scan.c @@ -863,7 +863,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo switch (je16_to_cpu(node->nodetype) & JFFS2_COMPAT_MASK) { case JFFS2_FEATURE_ROCOMPAT: printk(KERN_NOTICE "Read-only compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs); - c->flags |= JFFS2_SB_FLAG_RO; + c->flags |= JFFS2_SB_FLAG_RO; if (!(jffs2_is_readonly(c))) return -EROFS; if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(node->totlen))))) diff --git a/trunk/fs/jffs2/security.c b/trunk/fs/jffs2/security.c index 02c39c64ecb3..bc9f6ba10823 100644 --- a/trunk/fs/jffs2/security.c +++ b/trunk/fs/jffs2/security.c @@ -38,9 +38,9 @@ int jffs2_init_security(struct inode *inode, struct inode *dir) } rc = do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY, name, value, len, 0); - kfree(name); - kfree(value); - return rc; + kfree(name); + kfree(value); + return rc; } /* ---- XATTR Handler for "security.*" ----------------- */ diff --git a/trunk/fs/jffs2/summary.c b/trunk/fs/jffs2/summary.c index 2a77d3f93029..d828b296392a 100644 --- a/trunk/fs/jffs2/summary.c +++ b/trunk/fs/jffs2/summary.c @@ -2,10 +2,10 @@ * JFFS2 -- Journalling Flash File System, Version 2. * * Copyright © 2004 Ferenc Havasi , - * Zoltan Sogor , - * Patrik Kluba , - * University of Szeged, Hungary - * 2006 KaiGai Kohei + * Zoltan Sogor , + * Patrik Kluba , + * University of Szeged, Hungary + * 2006 KaiGai Kohei * * For licensing information, see the file 'LICENCE' in this directory. * diff --git a/trunk/fs/jffs2/summary.h b/trunk/fs/jffs2/summary.h index 8bf34f2fa5ce..0c6669e21390 100644 --- a/trunk/fs/jffs2/summary.h +++ b/trunk/fs/jffs2/summary.h @@ -2,9 +2,9 @@ * JFFS2 -- Journalling Flash File System, Version 2. * * Copyright © 2004 Ferenc Havasi , - * Zoltan Sogor , - * Patrik Kluba , - * University of Szeged, Hungary + * Zoltan Sogor , + * Patrik Kluba , + * University of Szeged, Hungary * * For licensing information, see the file 'LICENCE' in this directory. * diff --git a/trunk/fs/jffs2/wbuf.c b/trunk/fs/jffs2/wbuf.c index d1d4f27464ba..91d1d0f1c66c 100644 --- a/trunk/fs/jffs2/wbuf.c +++ b/trunk/fs/jffs2/wbuf.c @@ -220,47 +220,6 @@ static struct jffs2_raw_node_ref **jffs2_incore_replace_raw(struct jffs2_sb_info return NULL; } -#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY -static int jffs2_verify_write(struct jffs2_sb_info *c, unsigned char *buf, - uint32_t ofs) -{ - int ret; - size_t retlen; - char *eccstr; - - ret = c->mtd->read(c->mtd, ofs, c->wbuf_pagesize, &retlen, c->wbuf_verify); - if (ret && ret != -EUCLEAN && ret != -EBADMSG) { - printk(KERN_WARNING "jffs2_verify_write(): Read back of page at %08x failed: %d\n", c->wbuf_ofs, ret); - return ret; - } else if (retlen != c->wbuf_pagesize) { - printk(KERN_WARNING "jffs2_verify_write(): Read back of page at %08x gave short read: %zd not %d.\n", ofs, retlen, c->wbuf_pagesize); - return -EIO; - } - if (!memcmp(buf, c->wbuf_verify, c->wbuf_pagesize)) - return 0; - - if (ret == -EUCLEAN) - eccstr = "corrected"; - else if (ret == -EBADMSG) - eccstr = "correction failed"; - else - eccstr = "OK or unused"; - - printk(KERN_WARNING "Write verify error (ECC %s) at %08x. Wrote:\n", - eccstr, c->wbuf_ofs); - print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 16, 1, - c->wbuf, c->wbuf_pagesize, 0); - - printk(KERN_WARNING "Read back:\n"); - print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 16, 1, - c->wbuf_verify, c->wbuf_pagesize, 0); - - return -EIO; -} -#else -#define jffs2_verify_write(c,b,o) (0) -#endif - /* Recover from failure to write wbuf. Recover the nodes up to the * wbuf, not the one which we were starting to try to write. */ @@ -421,7 +380,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c) ret = c->mtd->write(c->mtd, ofs, towrite, &retlen, rewrite_buf); - if (ret || retlen != towrite || jffs2_verify_write(c, rewrite_buf, ofs)) { + if (ret || retlen != towrite) { /* Argh. We tried. Really we did. */ printk(KERN_CRIT "Recovery of wbuf failed due to a second write error\n"); kfree(buf); @@ -628,16 +587,15 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad) ret = c->mtd->write(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, c->wbuf); - if (ret) { - printk(KERN_WARNING "jffs2_flush_wbuf(): Write failed with %d\n", ret); - goto wfail; - } else if (retlen != c->wbuf_pagesize) { - printk(KERN_WARNING "jffs2_flush_wbuf(): Write was short: %zd instead of %d\n", - retlen, c->wbuf_pagesize); - ret = -EIO; - goto wfail; - } else if ((ret = jffs2_verify_write(c, c->wbuf, c->wbuf_ofs))) { - wfail: + if (ret || retlen != c->wbuf_pagesize) { + if (ret) + printk(KERN_WARNING "jffs2_flush_wbuf(): Write failed with %d\n",ret); + else { + printk(KERN_WARNING "jffs2_flush_wbuf(): Write was short: %zd instead of %d\n", + retlen, c->wbuf_pagesize); + ret = -EIO; + } + jffs2_wbuf_recover(c); return ret; @@ -1008,8 +966,8 @@ int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *re #define NR_OOB_SCAN_PAGES 4 -/* For historical reasons we use only 8 bytes for OOB clean marker */ -#define OOB_CM_SIZE 8 +/* For historical reasons we use only 12 bytes for OOB clean marker */ +#define OOB_CM_SIZE 12 static const struct jffs2_unknown_node oob_cleanmarker = { @@ -1063,8 +1021,8 @@ int jffs2_check_oob_empty(struct jffs2_sb_info *c, /* * Check for a valid cleanmarker. * Returns: 0 if a valid cleanmarker was found - * 1 if no cleanmarker was found - * negative error code if an error occurred + * 1 if no cleanmarker was found + * negative error code if an error occurred */ int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) @@ -1180,22 +1138,11 @@ int jffs2_nand_flash_setup(struct jffs2_sb_info *c) return -ENOMEM; } -#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY - c->wbuf_verify = kmalloc(c->wbuf_pagesize, GFP_KERNEL); - if (!c->wbuf_verify) { - kfree(c->oobbuf); - kfree(c->wbuf); - return -ENOMEM; - } -#endif return 0; } void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c) { -#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY - kfree(c->wbuf_verify); -#endif kfree(c->wbuf); kfree(c->oobbuf); } diff --git a/trunk/fs/jffs2/xattr.h b/trunk/fs/jffs2/xattr.h index 6e3b5ddfb7ab..3b0ff2925937 100644 --- a/trunk/fs/jffs2/xattr.h +++ b/trunk/fs/jffs2/xattr.h @@ -75,7 +75,7 @@ extern void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c); extern void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c); extern struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c, - uint32_t xid, uint32_t version); + uint32_t xid, uint32_t version); extern void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic); extern void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic); diff --git a/trunk/fs/jffs2/xattr_user.c b/trunk/fs/jffs2/xattr_user.c index 8bbeab90ada1..40942bc516bb 100644 --- a/trunk/fs/jffs2/xattr_user.c +++ b/trunk/fs/jffs2/xattr_user.c @@ -17,7 +17,7 @@ #include "nodelist.h" static int jffs2_user_getxattr(struct inode *inode, const char *name, - void *buffer, size_t size) + void *buffer, size_t size) { if (!strcmp(name, "")) return -EINVAL; @@ -25,7 +25,7 @@ static int jffs2_user_getxattr(struct inode *inode, const char *name, } static int jffs2_user_setxattr(struct inode *inode, const char *name, const void *buffer, - size_t size, int flags) + size_t size, int flags) { if (!strcmp(name, "")) return -EINVAL; diff --git a/trunk/include/linux/jffs2.h b/trunk/include/linux/jffs2.h index 6b563cae23df..840631fa5ff1 100644 --- a/trunk/include/linux/jffs2.h +++ b/trunk/include/linux/jffs2.h @@ -46,7 +46,6 @@ #define JFFS2_COMPR_COPY 0x04 #define JFFS2_COMPR_DYNRUBIN 0x05 #define JFFS2_COMPR_ZLIB 0x06 -#define JFFS2_COMPR_LZO 0x07 /* Compatibility flags. */ #define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */ #define JFFS2_NODE_ACCURATE 0x2000 diff --git a/trunk/include/linux/mtd/nand.h b/trunk/include/linux/mtd/nand.h index c42bc7f533a5..d2365c8dcacc 100644 --- a/trunk/include/linux/mtd/nand.h +++ b/trunk/include/linux/mtd/nand.h @@ -432,7 +432,6 @@ struct nand_chip { #define NAND_MFR_STMICRO 0x20 #define NAND_MFR_HYNIX 0xad #define NAND_MFR_MICRON 0x2c -#define NAND_MFR_AMD 0x01 /** * struct nand_flash_dev - NAND Flash Device ID Structure diff --git a/trunk/include/linux/mtd/onenand.h b/trunk/include/linux/mtd/onenand.h index fd0a260e070b..a56d24ada505 100644 --- a/trunk/include/linux/mtd/onenand.h +++ b/trunk/include/linux/mtd/onenand.h @@ -60,7 +60,6 @@ struct onenand_bufferram { * @erase_shift: [INTERN] number of address bits in a block * @page_shift: [INTERN] number of address bits in a page * @page_mask: [INTERN] a page per block mask - * @writesize: [INTERN] a real page size * @bufferram_index: [INTERN] BufferRAM index * @bufferram: [INTERN] BufferRAM info * @readw: [REPLACEABLE] hardware specific function for read short @@ -101,7 +100,6 @@ struct onenand_chip { unsigned int erase_shift; unsigned int page_shift; unsigned int page_mask; - unsigned int writesize; unsigned int bufferram_index; struct onenand_bufferram bufferram[MAX_BUFFERRAM]; @@ -142,8 +140,6 @@ struct onenand_chip { #define ONENAND_NEXT_BUFFERRAM(this) (this->bufferram_index ^ 1) #define ONENAND_SET_NEXT_BUFFERRAM(this) (this->bufferram_index ^= 1) #define ONENAND_SET_PREV_BUFFERRAM(this) (this->bufferram_index ^= 1) -#define ONENAND_SET_BUFFERRAM0(this) (this->bufferram_index = 0) -#define ONENAND_SET_BUFFERRAM1(this) (this->bufferram_index = 1) #define ONENAND_GET_SYS_CFG1(this) \ (this->read_word(this->base + ONENAND_REG_SYS_CFG1)) @@ -153,13 +149,6 @@ struct onenand_chip { #define ONENAND_IS_DDP(this) \ (this->device_id & ONENAND_DEVICE_IS_DDP) -#ifdef CONFIG_MTD_ONENAND_2X_PROGRAM -#define ONENAND_IS_2PLANE(this) \ - (this->options & ONENAND_HAS_2PLANE) -#else -#define ONENAND_IS_2PLANE(this) (0) -#endif - /* Check byte access in OneNAND */ #define ONENAND_CHECK_BYTE_ACCESS(addr) (addr & 0x1) @@ -168,7 +157,6 @@ struct onenand_chip { */ #define ONENAND_HAS_CONT_LOCK (0x0001) #define ONENAND_HAS_UNLOCK_ALL (0x0002) -#define ONENAND_HAS_2PLANE (0x0004) #define ONENAND_PAGEBUF_ALLOC (0x1000) #define ONENAND_OOBBUF_ALLOC (0x2000) diff --git a/trunk/include/linux/mtd/onenand_regs.h b/trunk/include/linux/mtd/onenand_regs.h index c46161f4eee3..af94719890e7 100644 --- a/trunk/include/linux/mtd/onenand_regs.h +++ b/trunk/include/linux/mtd/onenand_regs.h @@ -74,8 +74,6 @@ #define ONENAND_DEVICE_DENSITY_512Mb (0x002) #define ONENAND_DEVICE_DENSITY_1Gb (0x003) -#define ONENAND_DEVICE_DENSITY_2Gb (0x004) -#define ONENAND_DEVICE_DENSITY_4Gb (0x005) /* * Version ID Register F002h (R) @@ -113,8 +111,6 @@ #define ONENAND_CMD_READOOB (0x13) #define ONENAND_CMD_PROG (0x80) #define ONENAND_CMD_PROGOOB (0x1A) -#define ONENAND_CMD_2X_PROG (0x7D) -#define ONENAND_CMD_2X_CACHE_PROG (0x7F) #define ONENAND_CMD_UNLOCK (0x23) #define ONENAND_CMD_LOCK (0x2A) #define ONENAND_CMD_LOCK_TIGHT (0x2C)