aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/Kconfig40
-rw-r--r--drivers/mtd/Makefile5
-rw-r--r--drivers/mtd/afs.c16
-rw-r--r--drivers/mtd/chips/Kconfig22
-rw-r--r--drivers/mtd/chips/Makefile4
-rw-r--r--drivers/mtd/chips/amd_flash.c80
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c484
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0002.c156
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0020.c183
-rw-r--r--drivers/mtd/chips/cfi_probe.c98
-rw-r--r--drivers/mtd/chips/cfi_util.c25
-rw-r--r--drivers/mtd/chips/chipreg.c6
-rw-r--r--drivers/mtd/chips/fwh_lock.h6
-rw-r--r--drivers/mtd/chips/gen_probe.c33
-rw-r--r--drivers/mtd/chips/jedec.c206
-rw-r--r--drivers/mtd/chips/jedec_probe.c48
-rw-r--r--drivers/mtd/chips/map_absent.c8
-rw-r--r--drivers/mtd/chips/sharp.c23
-rw-r--r--drivers/mtd/cmdlinepart.c56
-rw-r--r--drivers/mtd/devices/Kconfig8
-rw-r--r--drivers/mtd/devices/blkmtd.c10
-rw-r--r--drivers/mtd/devices/block2mtd.c8
-rw-r--r--drivers/mtd/devices/doc2000.c42
-rw-r--r--drivers/mtd/devices/doc2001.c24
-rw-r--r--drivers/mtd/devices/doc2001plus.c20
-rw-r--r--drivers/mtd/devices/docecc.c40
-rw-r--r--drivers/mtd/devices/docprobe.c84
-rw-r--r--drivers/mtd/devices/lart.c8
-rw-r--r--drivers/mtd/devices/phram.c14
-rw-r--r--drivers/mtd/devices/pmc551.c24
-rw-r--r--drivers/mtd/devices/slram.c30
-rw-r--r--drivers/mtd/ftl.c128
-rw-r--r--drivers/mtd/inftlcore.c48
-rw-r--r--drivers/mtd/inftlmount.c20
-rw-r--r--drivers/mtd/maps/Kconfig115
-rw-r--r--drivers/mtd/maps/Makefile7
-rw-r--r--drivers/mtd/maps/alchemy-flash.c12
-rw-r--r--drivers/mtd/maps/amd76xrom.c16
-rw-r--r--drivers/mtd/maps/arctic-mtd.c6
-rw-r--r--drivers/mtd/maps/autcpu12-nvram.c18
-rw-r--r--drivers/mtd/maps/bast-flash.c19
-rw-r--r--drivers/mtd/maps/beech-mtd.c6
-rw-r--r--drivers/mtd/maps/cdb89712.c34
-rw-r--r--drivers/mtd/maps/cfi_flagadm.c12
-rw-r--r--drivers/mtd/maps/cstm_mips_ixx.c24
-rw-r--r--drivers/mtd/maps/dbox2-flash.c38
-rw-r--r--drivers/mtd/maps/dc21285.c34
-rw-r--r--drivers/mtd/maps/dilnetpc.c32
-rw-r--r--drivers/mtd/maps/dmv182.c8
-rw-r--r--drivers/mtd/maps/ebony.c6
-rw-r--r--drivers/mtd/maps/edb7312.c10
-rw-r--r--drivers/mtd/maps/epxa10db-flash.c12
-rw-r--r--drivers/mtd/maps/fortunet.c4
-rw-r--r--drivers/mtd/maps/h720x-flash.c16
-rw-r--r--drivers/mtd/maps/ichxrom.c16
-rw-r--r--drivers/mtd/maps/impa7.c16
-rw-r--r--drivers/mtd/maps/integrator-flash.c14
-rw-r--r--drivers/mtd/maps/ipaq-flash.c34
-rw-r--r--drivers/mtd/maps/iq80310.c4
-rw-r--r--drivers/mtd/maps/ixp2000.c32
-rw-r--r--drivers/mtd/maps/ixp4xx.c53
-rw-r--r--drivers/mtd/maps/l440gx.c18
-rw-r--r--drivers/mtd/maps/lubbock-flash.c14
-rw-r--r--drivers/mtd/maps/mainstone-flash.c22
-rw-r--r--drivers/mtd/maps/mbx860.c6
-rw-r--r--drivers/mtd/maps/mtx-1_flash.c96
-rw-r--r--drivers/mtd/maps/netsc520.c32
-rw-r--r--drivers/mtd/maps/nettel.c8
-rw-r--r--drivers/mtd/maps/ocelot.c10
-rw-r--r--drivers/mtd/maps/octagon-5066.c36
-rw-r--r--drivers/mtd/maps/omap-toto-flash.c20
-rw-r--r--drivers/mtd/maps/omap_nor.c2
-rw-r--r--drivers/mtd/maps/pci.c6
-rw-r--r--drivers/mtd/maps/pcmciamtd.c30
-rw-r--r--drivers/mtd/maps/physmap.c8
-rw-r--r--drivers/mtd/maps/plat-ram.c13
-rw-r--r--drivers/mtd/maps/pnc2000.c8
-rw-r--r--drivers/mtd/maps/pq2fads.c88
-rw-r--r--drivers/mtd/maps/redwood.c4
-rw-r--r--drivers/mtd/maps/sa1100-flash.c6
-rw-r--r--drivers/mtd/maps/sbc8240.c4
-rw-r--r--drivers/mtd/maps/sbc_gxx.c46
-rw-r--r--drivers/mtd/maps/sc520cdp.c6
-rw-r--r--drivers/mtd/maps/scx200_docflash.c46
-rw-r--r--drivers/mtd/maps/sharpsl-flash.c12
-rw-r--r--drivers/mtd/maps/solutionengine.c4
-rw-r--r--drivers/mtd/maps/sun_uflash.c12
-rw-r--r--drivers/mtd/maps/tqm834x.c291
-rw-r--r--drivers/mtd/maps/tqm8xxl.c20
-rw-r--r--drivers/mtd/maps/ts5500_flash.c44
-rw-r--r--drivers/mtd/maps/tsunami_flash.c6
-rw-r--r--drivers/mtd/maps/uclinux.c4
-rw-r--r--drivers/mtd/maps/vmax301.c24
-rw-r--r--drivers/mtd/maps/walnut.c16
-rw-r--r--drivers/mtd/maps/wr_sbc82xx_flash.c6
-rw-r--r--drivers/mtd/mtd_blkdevs.c44
-rw-r--r--drivers/mtd/mtdblock.c53
-rw-r--r--drivers/mtd/mtdchar.c86
-rw-r--r--drivers/mtd/mtdconcat.c13
-rw-r--r--drivers/mtd/mtdcore.c62
-rw-r--r--drivers/mtd/mtdpart.c99
-rw-r--r--drivers/mtd/nand/Kconfig26
-rw-r--r--drivers/mtd/nand/au1550nd.c165
-rw-r--r--drivers/mtd/nand/autcpu12.c22
-rw-r--r--drivers/mtd/nand/diskonchip.c100
-rw-r--r--drivers/mtd/nand/edb7312.c48
-rw-r--r--drivers/mtd/nand/h1910.c48
-rw-r--r--drivers/mtd/nand/nand_base.c529
-rw-r--r--drivers/mtd/nand/nand_bbt.c248
-rw-r--r--drivers/mtd/nand/nand_ecc.c44
-rw-r--r--drivers/mtd/nand/nand_ids.c30
-rw-r--r--drivers/mtd/nand/nandsim.c162
-rw-r--r--drivers/mtd/nand/ppchameleonevb.c6
-rw-r--r--drivers/mtd/nand/rtc_from4.c58
-rw-r--r--drivers/mtd/nand/s3c2410.c61
-rw-r--r--drivers/mtd/nand/sharpsl.c41
-rw-r--r--drivers/mtd/nand/spia.c6
-rw-r--r--drivers/mtd/nand/toto.c20
-rw-r--r--drivers/mtd/nftlcore.c80
-rw-r--r--drivers/mtd/nftlmount.c56
-rw-r--r--drivers/mtd/onenand/Kconfig38
-rw-r--r--drivers/mtd/onenand/Makefile11
-rw-r--r--drivers/mtd/onenand/generic.c147
-rw-r--r--drivers/mtd/onenand/onenand_base.c1588
-rw-r--r--drivers/mtd/onenand/onenand_bbt.c246
-rw-r--r--drivers/mtd/redboot.c4
-rw-r--r--drivers/mtd/rfd_ftl.c855
-rw-r--r--fs/Kconfig23
-rw-r--r--fs/jffs2/Makefile5
-rw-r--r--fs/jffs2/TODO38
-rw-r--r--fs/jffs2/background.c4
-rw-r--r--fs/jffs2/build.c171
-rw-r--r--fs/jffs2/compr.c40
-rw-r--r--fs/jffs2/compr.h12
-rw-r--r--fs/jffs2/compr_rtime.c32
-rw-r--r--fs/jffs2/compr_rubin.c37
-rw-r--r--fs/jffs2/compr_rubin.h6
-rw-r--r--fs/jffs2/compr_zlib.c14
-rw-r--r--fs/jffs2/comprtest.c30
-rw-r--r--fs/jffs2/debug.c705
-rw-r--r--fs/jffs2/debug.h279
-rw-r--r--fs/jffs2/dir.c121
-rw-r--r--fs/jffs2/erase.c37
-rw-r--r--fs/jffs2/file.c29
-rw-r--r--fs/jffs2/fs.c104
-rw-r--r--fs/jffs2/gc.c156
-rw-r--r--fs/jffs2/histo.h2
-rw-r--r--fs/jffs2/histo_mips.h2
-rw-r--r--fs/jffs2/ioctl.c6
-rw-r--r--fs/jffs2/malloc.c84
-rw-r--r--fs/jffs2/nodelist.c1226
-rw-r--r--fs/jffs2/nodelist.h163
-rw-r--r--fs/jffs2/nodemgmt.c471
-rw-r--r--fs/jffs2/os-linux.h47
-rw-r--r--fs/jffs2/read.c17
-rw-r--r--fs/jffs2/readinode.c1151
-rw-r--r--fs/jffs2/scan.c300
-rw-r--r--fs/jffs2/summary.c730
-rw-r--r--fs/jffs2/summary.h183
-rw-r--r--fs/jffs2/super.c24
-rw-r--r--fs/jffs2/symlink.c32
-rw-r--r--fs/jffs2/wbuf.c212
-rw-r--r--fs/jffs2/write.c157
-rw-r--r--fs/jffs2/writev.c35
-rw-r--r--include/linux/jffs2.h41
-rw-r--r--include/linux/jffs2_fs_i.h7
-rw-r--r--include/linux/jffs2_fs_sb.h19
-rw-r--r--include/linux/mtd/bbm.h122
-rw-r--r--include/linux/mtd/blktrans.h4
-rw-r--r--include/linux/mtd/cfi.h33
-rw-r--r--include/linux/mtd/doc2000.h18
-rw-r--r--include/linux/mtd/flashchip.h14
-rw-r--r--include/linux/mtd/ftl.h6
-rw-r--r--include/linux/mtd/gen_probe.h4
-rw-r--r--include/linux/mtd/jedec.h20
-rw-r--r--include/linux/mtd/map.h14
-rw-r--r--include/linux/mtd/mtd.h36
-rw-r--r--include/linux/mtd/nand.h57
-rw-r--r--include/linux/mtd/onenand.h155
-rw-r--r--include/linux/mtd/onenand_regs.h180
-rw-r--r--include/linux/mtd/partitions.h20
-rw-r--r--include/linux/mtd/physmap.h12
-rw-r--r--include/linux/mtd/pmc551.h12
-rw-r--r--include/linux/mtd/xip.h20
-rw-r--r--include/linux/rslib.h28
-rw-r--r--include/mtd/inftl-user.h4
-rw-r--r--include/mtd/mtd-abi.h7
-rw-r--r--include/mtd/nftl-user.h4
-rw-r--r--lib/reed_solomon/Makefile2
-rw-r--r--lib/reed_solomon/decode_rs.c36
-rw-r--r--lib/reed_solomon/encode_rs.c14
-rw-r--r--lib/reed_solomon/reed_solomon.c64
192 files changed, 11317 insertions, 4890 deletions
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 027054dea032..f6b775e63ac8 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -1,4 +1,4 @@
1# $Id: Kconfig,v 1.7 2004/11/22 11:33:56 ijc Exp $ 1# $Id: Kconfig,v 1.11 2005/11/07 11:14:19 gleixner Exp $
2 2
3menu "Memory Technology Devices (MTD)" 3menu "Memory Technology Devices (MTD)"
4 4
@@ -10,7 +10,7 @@ config MTD
10 will provide the generic support for MTD drivers to register 10 will provide the generic support for MTD drivers to register
11 themselves with the kernel and for potential users of MTD devices 11 themselves with the kernel and for potential users of MTD devices
12 to enumerate the devices which are present and obtain a handle on 12 to enumerate the devices which are present and obtain a handle on
13 them. It will also allow you to select individual drivers for 13 them. It will also allow you to select individual drivers for
14 particular hardware and users of MTD devices. If unsure, say N. 14 particular hardware and users of MTD devices. If unsure, say N.
15 15
16config MTD_DEBUG 16config MTD_DEBUG
@@ -61,11 +61,11 @@ config MTD_REDBOOT_PARTS
61 61
62 If you need code which can detect and parse this table, and register 62 If you need code which can detect and parse this table, and register
63 MTD 'partitions' corresponding to each image in the table, enable 63 MTD 'partitions' corresponding to each image in the table, enable
64 this option. 64 this option.
65 65
66 You will still need the parsing functions to be called by the driver 66 You will still need the parsing functions to be called by the driver
67 for your particular device. It won't happen automatically. The 67 for your particular device. It won't happen automatically. The
68 SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for 68 SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for
69 example. 69 example.
70 70
71config MTD_REDBOOT_DIRECTORY_BLOCK 71config MTD_REDBOOT_DIRECTORY_BLOCK
@@ -81,10 +81,10 @@ config MTD_REDBOOT_DIRECTORY_BLOCK
81 partition table. A zero or positive value gives an absolete 81 partition table. A zero or positive value gives an absolete
82 erase block number. A negative value specifies a number of 82 erase block number. A negative value specifies a number of
83 sectors before the end of the device. 83 sectors before the end of the device.
84 84
85 For example "2" means block number 2, "-1" means the last 85 For example "2" means block number 2, "-1" means the last
86 block and "-2" means the penultimate block. 86 block and "-2" means the penultimate block.
87 87
88config MTD_REDBOOT_PARTS_UNALLOCATED 88config MTD_REDBOOT_PARTS_UNALLOCATED
89 bool " Include unallocated flash regions" 89 bool " Include unallocated flash regions"
90 depends on MTD_REDBOOT_PARTS 90 depends on MTD_REDBOOT_PARTS
@@ -105,11 +105,11 @@ config MTD_CMDLINE_PARTS
105 ---help--- 105 ---help---
106 Allow generic configuration of the MTD paritition tables via the kernel 106 Allow generic configuration of the MTD paritition tables via the kernel
107 command line. Multiple flash resources are supported for hardware where 107 command line. Multiple flash resources are supported for hardware where
108 different kinds of flash memory are available. 108 different kinds of flash memory are available.
109 109
110 You will still need the parsing functions to be called by the driver 110 You will still need the parsing functions to be called by the driver
111 for your particular device. It won't happen automatically. The 111 for your particular device. It won't happen automatically. The
112 SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for 112 SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for
113 example. 113 example.
114 114
115 The format for the command line is as follows: 115 The format for the command line is as follows:
@@ -118,12 +118,12 @@ config MTD_CMDLINE_PARTS
118 <mtddef> := <mtd-id>:<partdef>[,<partdef>] 118 <mtddef> := <mtd-id>:<partdef>[,<partdef>]
119 <partdef> := <size>[@offset][<name>][ro] 119 <partdef> := <size>[@offset][<name>][ro]
120 <mtd-id> := unique id used in mapping driver/device 120 <mtd-id> := unique id used in mapping driver/device
121 <size> := standard linux memsize OR "-" to denote all 121 <size> := standard linux memsize OR "-" to denote all
122 remaining space 122 remaining space
123 <name> := (NAME) 123 <name> := (NAME)
124 124
125 Due to the way Linux handles the command line, no spaces are 125 Due to the way Linux handles the command line, no spaces are
126 allowed in the partition definition, including mtd id's and partition 126 allowed in the partition definition, including mtd id's and partition
127 names. 127 names.
128 128
129 Examples: 129 Examples:
@@ -240,7 +240,7 @@ config INFTL
240 tristate "INFTL (Inverse NAND Flash Translation Layer) support" 240 tristate "INFTL (Inverse NAND Flash Translation Layer) support"
241 depends on MTD 241 depends on MTD
242 ---help--- 242 ---help---
243 This provides support for the Inverse NAND Flash Translation 243 This provides support for the Inverse NAND Flash Translation
244 Layer which is used on M-Systems' newer DiskOnChip devices. It 244 Layer which is used on M-Systems' newer DiskOnChip devices. It
245 uses a kind of pseudo-file system on a flash device to emulate 245 uses a kind of pseudo-file system on a flash device to emulate
246 a block device with 512-byte sectors, on top of which you put 246 a block device with 512-byte sectors, on top of which you put
@@ -253,6 +253,16 @@ config INFTL
253 permitted to copy, modify and distribute the code as you wish. Just 253 permitted to copy, modify and distribute the code as you wish. Just
254 not use it. 254 not use it.
255 255
256config RFD_FTL
257 tristate "Resident Flash Disk (Flash Translation Layer) support"
258 depends on MTD
259 ---help---
260 This provides support for the flash translation layer known
261 as the Resident Flash Disk (RFD), as used by the Embedded BIOS
262 of General Software. There is a blurb at:
263
264 http://www.gensw.com/pages/prod/bios/rfd.htm
265
256source "drivers/mtd/chips/Kconfig" 266source "drivers/mtd/chips/Kconfig"
257 267
258source "drivers/mtd/maps/Kconfig" 268source "drivers/mtd/maps/Kconfig"
@@ -261,5 +271,7 @@ source "drivers/mtd/devices/Kconfig"
261 271
262source "drivers/mtd/nand/Kconfig" 272source "drivers/mtd/nand/Kconfig"
263 273
274source "drivers/mtd/onenand/Kconfig"
275
264endmenu 276endmenu
265 277
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index e4ad588327f7..fc9374407c2b 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -1,7 +1,7 @@
1# 1#
2# Makefile for the memory technology device drivers. 2# Makefile for the memory technology device drivers.
3# 3#
4# $Id: Makefile.common,v 1.5 2004/08/10 20:51:49 dwmw2 Exp $ 4# $Id: Makefile.common,v 1.7 2005/07/11 10:39:27 gleixner Exp $
5 5
6# Core functionality. 6# Core functionality.
7mtd-y := mtdcore.o 7mtd-y := mtdcore.o
@@ -20,8 +20,9 @@ obj-$(CONFIG_MTD_BLOCK_RO) += mtdblock_ro.o mtd_blkdevs.o
20obj-$(CONFIG_FTL) += ftl.o mtd_blkdevs.o 20obj-$(CONFIG_FTL) += ftl.o mtd_blkdevs.o
21obj-$(CONFIG_NFTL) += nftl.o mtd_blkdevs.o 21obj-$(CONFIG_NFTL) += nftl.o mtd_blkdevs.o
22obj-$(CONFIG_INFTL) += inftl.o mtd_blkdevs.o 22obj-$(CONFIG_INFTL) += inftl.o mtd_blkdevs.o
23obj-$(CONFIG_RFD_FTL) += rfd_ftl.o mtd_blkdevs.o
23 24
24nftl-objs := nftlcore.o nftlmount.o 25nftl-objs := nftlcore.o nftlmount.o
25inftl-objs := inftlcore.o inftlmount.o 26inftl-objs := inftlcore.o inftlmount.o
26 27
27obj-y += chips/ maps/ devices/ nand/ 28obj-y += chips/ maps/ devices/ nand/ onenand/
diff --git a/drivers/mtd/afs.c b/drivers/mtd/afs.c
index 7363e101eb0f..6a45be04564b 100644
--- a/drivers/mtd/afs.c
+++ b/drivers/mtd/afs.c
@@ -1,27 +1,27 @@
1/*====================================================================== 1/*======================================================================
2 2
3 drivers/mtd/afs.c: ARM Flash Layout/Partitioning 3 drivers/mtd/afs.c: ARM Flash Layout/Partitioning
4 4
5 Copyright (C) 2000 ARM Limited 5 Copyright (C) 2000 ARM Limited
6 6
7 This program is free software; you can redistribute it and/or modify 7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or 9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version. 10 (at your option) any later version.
11 11
12 This program is distributed in the hope that it will be useful, 12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details. 15 GNU General Public License for more details.
16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 20
21 This is access code for flashes using ARM's flash partitioning 21 This is access code for flashes using ARM's flash partitioning
22 standards. 22 standards.
23 23
24 $Id: afs.c,v 1.13 2004/02/27 22:09:59 rmk Exp $ 24 $Id: afs.c,v 1.15 2005/11/07 11:14:19 gleixner Exp $
25 25
26======================================================================*/ 26======================================================================*/
27 27
@@ -163,7 +163,7 @@ afs_read_iis(struct mtd_info *mtd, struct image_info_struct *iis, u_int ptr)
163 return ret; 163 return ret;
164} 164}
165 165
166static int parse_afs_partitions(struct mtd_info *mtd, 166static int parse_afs_partitions(struct mtd_info *mtd,
167 struct mtd_partition **pparts, 167 struct mtd_partition **pparts,
168 unsigned long origin) 168 unsigned long origin)
169{ 169{
diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig
index df95d2158b16..eafa23f5cbd6 100644
--- a/drivers/mtd/chips/Kconfig
+++ b/drivers/mtd/chips/Kconfig
@@ -1,5 +1,5 @@
1# drivers/mtd/chips/Kconfig 1# drivers/mtd/chips/Kconfig
2# $Id: Kconfig,v 1.15 2005/06/06 23:04:35 tpoynor Exp $ 2# $Id: Kconfig,v 1.18 2005/11/07 11:14:22 gleixner Exp $
3 3
4menu "RAM/ROM/Flash chip drivers" 4menu "RAM/ROM/Flash chip drivers"
5 depends on MTD!=n 5 depends on MTD!=n
@@ -39,7 +39,7 @@ config MTD_CFI_ADV_OPTIONS
39 If you need to specify a specific endianness for access to flash 39 If you need to specify a specific endianness for access to flash
40 chips, or if you wish to reduce the size of the kernel by including 40 chips, or if you wish to reduce the size of the kernel by including
41 support for only specific arrangements of flash chips, say 'Y'. This 41 support for only specific arrangements of flash chips, say 'Y'. This
42 option does not directly affect the code, but will enable other 42 option does not directly affect the code, but will enable other
43 configuration options which allow you to do so. 43 configuration options which allow you to do so.
44 44
45 If unsure, say 'N'. 45 If unsure, say 'N'.
@@ -56,7 +56,7 @@ config MTD_CFI_NOSWAP
56 data bits when writing the 'magic' commands to the chips. Saying 56 data bits when writing the 'magic' commands to the chips. Saying
57 'NO', which is the default when CONFIG_MTD_CFI_ADV_OPTIONS isn't 57 'NO', which is the default when CONFIG_MTD_CFI_ADV_OPTIONS isn't
58 enabled, means that the CPU will not do any swapping; the chips 58 enabled, means that the CPU will not do any swapping; the chips
59 are expected to be wired to the CPU in 'host-endian' form. 59 are expected to be wired to the CPU in 'host-endian' form.
60 Specific arrangements are possible with the BIG_ENDIAN_BYTE and 60 Specific arrangements are possible with the BIG_ENDIAN_BYTE and
61 LITTLE_ENDIAN_BYTE, if the bytes are reversed. 61 LITTLE_ENDIAN_BYTE, if the bytes are reversed.
62 62
@@ -79,10 +79,10 @@ config MTD_CFI_GEOMETRY
79 bool "Specific CFI Flash geometry selection" 79 bool "Specific CFI Flash geometry selection"
80 depends on MTD_CFI_ADV_OPTIONS 80 depends on MTD_CFI_ADV_OPTIONS
81 help 81 help
82 This option does not affect the code directly, but will enable 82 This option does not affect the code directly, but will enable
83 some other configuration options which would allow you to reduce 83 some other configuration options which would allow you to reduce
84 the size of the kernel by including support for only certain 84 the size of the kernel by including support for only certain
85 arrangements of CFI chips. If unsure, say 'N' and all options 85 arrangements of CFI chips. If unsure, say 'N' and all options
86 which are supported by the current code will be enabled. 86 which are supported by the current code will be enabled.
87 87
88config MTD_MAP_BANK_WIDTH_1 88config MTD_MAP_BANK_WIDTH_1
@@ -197,7 +197,7 @@ config MTD_CFI_AMDSTD
197 help 197 help
198 The Common Flash Interface defines a number of different command 198 The Common Flash Interface defines a number of different command
199 sets which a CFI-compliant chip may claim to implement. This code 199 sets which a CFI-compliant chip may claim to implement. This code
200 provides support for one of those command sets, used on chips 200 provides support for one of those command sets, used on chips
201 including the AMD Am29LV320. 201 including the AMD Am29LV320.
202 202
203config MTD_CFI_AMDSTD_RETRY 203config MTD_CFI_AMDSTD_RETRY
@@ -237,14 +237,14 @@ config MTD_RAM
237 tristate "Support for RAM chips in bus mapping" 237 tristate "Support for RAM chips in bus mapping"
238 depends on MTD 238 depends on MTD
239 help 239 help
240 This option enables basic support for RAM chips accessed through 240 This option enables basic support for RAM chips accessed through
241 a bus mapping driver. 241 a bus mapping driver.
242 242
243config MTD_ROM 243config MTD_ROM
244 tristate "Support for ROM chips in bus mapping" 244 tristate "Support for ROM chips in bus mapping"
245 depends on MTD 245 depends on MTD
246 help 246 help
247 This option enables basic support for ROM chips accessed through 247 This option enables basic support for ROM chips accessed through
248 a bus mapping driver. 248 a bus mapping driver.
249 249
250config MTD_ABSENT 250config MTD_ABSENT
@@ -275,7 +275,7 @@ config MTD_AMDSTD
275 depends on MTD && MTD_OBSOLETE_CHIPS 275 depends on MTD && MTD_OBSOLETE_CHIPS
276 help 276 help
277 This option enables support for flash chips using AMD-compatible 277 This option enables support for flash chips using AMD-compatible
278 commands, including some which are not CFI-compatible and hence 278 commands, including some which are not CFI-compatible and hence
279 cannot be used with the CONFIG_MTD_CFI_AMDSTD option. 279 cannot be used with the CONFIG_MTD_CFI_AMDSTD option.
280 280
281 It also works on AMD compatible chips that do conform to CFI. 281 It also works on AMD compatible chips that do conform to CFI.
@@ -285,7 +285,7 @@ config MTD_SHARP
285 depends on MTD && MTD_OBSOLETE_CHIPS 285 depends on MTD && MTD_OBSOLETE_CHIPS
286 help 286 help
287 This option enables support for flash chips using Sharp-compatible 287 This option enables support for flash chips using Sharp-compatible
288 commands, including some which are not CFI-compatible and hence 288 commands, including some which are not CFI-compatible and hence
289 cannot be used with the CONFIG_MTD_CFI_INTELxxx options. 289 cannot be used with the CONFIG_MTD_CFI_INTELxxx options.
290 290
291config MTD_JEDEC 291config MTD_JEDEC
diff --git a/drivers/mtd/chips/Makefile b/drivers/mtd/chips/Makefile
index 6830489828c6..8afe3092c4e3 100644
--- a/drivers/mtd/chips/Makefile
+++ b/drivers/mtd/chips/Makefile
@@ -1,7 +1,7 @@
1# 1#
2# linux/drivers/chips/Makefile 2# linux/drivers/chips/Makefile
3# 3#
4# $Id: Makefile.common,v 1.4 2004/07/12 16:07:30 dwmw2 Exp $ 4# $Id: Makefile.common,v 1.5 2005/11/07 11:14:22 gleixner Exp $
5 5
6# *** BIG UGLY NOTE *** 6# *** BIG UGLY NOTE ***
7# 7#
@@ -11,7 +11,7 @@
11# the CFI command set drivers are linked before gen_probe.o 11# the CFI command set drivers are linked before gen_probe.o
12 12
13obj-$(CONFIG_MTD) += chipreg.o 13obj-$(CONFIG_MTD) += chipreg.o
14obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o 14obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o
15obj-$(CONFIG_MTD_CFI) += cfi_probe.o 15obj-$(CONFIG_MTD_CFI) += cfi_probe.o
16obj-$(CONFIG_MTD_CFI_UTIL) += cfi_util.o 16obj-$(CONFIG_MTD_CFI_UTIL) += cfi_util.o
17obj-$(CONFIG_MTD_CFI_STAA) += cfi_cmdset_0020.o 17obj-$(CONFIG_MTD_CFI_STAA) += cfi_cmdset_0020.o
diff --git a/drivers/mtd/chips/amd_flash.c b/drivers/mtd/chips/amd_flash.c
index 2dafeba3f3d5..fdb91b6f1d97 100644
--- a/drivers/mtd/chips/amd_flash.c
+++ b/drivers/mtd/chips/amd_flash.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Author: Jonas Holmberg <jonas.holmberg@axis.com> 4 * Author: Jonas Holmberg <jonas.holmberg@axis.com>
5 * 5 *
6 * $Id: amd_flash.c,v 1.27 2005/02/04 07:43:09 jonashg Exp $ 6 * $Id: amd_flash.c,v 1.28 2005/11/07 11:14:22 gleixner Exp $
7 * 7 *
8 * Copyright (c) 2001 Axis Communications AB 8 * Copyright (c) 2001 Axis Communications AB
9 * 9 *
@@ -93,9 +93,9 @@
93#define D6_MASK 0x40 93#define D6_MASK 0x40
94 94
95struct amd_flash_private { 95struct amd_flash_private {
96 int device_type; 96 int device_type;
97 int interleave; 97 int interleave;
98 int numchips; 98 int numchips;
99 unsigned long chipshift; 99 unsigned long chipshift;
100// const char *im_name; 100// const char *im_name;
101 struct flchip chips[0]; 101 struct flchip chips[0];
@@ -253,7 +253,7 @@ static int amd_flash_do_unlock(struct mtd_info *mtd, loff_t ofs, size_t len,
253 int i; 253 int i;
254 int retval = 0; 254 int retval = 0;
255 int lock_status; 255 int lock_status;
256 256
257 map = mtd->priv; 257 map = mtd->priv;
258 258
259 /* Pass the whole chip through sector by sector and check for each 259 /* Pass the whole chip through sector by sector and check for each
@@ -273,7 +273,7 @@ static int amd_flash_do_unlock(struct mtd_info *mtd, loff_t ofs, size_t len,
273 unlock_sector(map, eraseoffset, is_unlock); 273 unlock_sector(map, eraseoffset, is_unlock);
274 274
275 lock_status = is_sector_locked(map, eraseoffset); 275 lock_status = is_sector_locked(map, eraseoffset);
276 276
277 if (is_unlock && lock_status) { 277 if (is_unlock && lock_status) {
278 printk("Cannot unlock sector at address %x length %xx\n", 278 printk("Cannot unlock sector at address %x length %xx\n",
279 eraseoffset, merip->erasesize); 279 eraseoffset, merip->erasesize);
@@ -305,7 +305,7 @@ static int amd_flash_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
305/* 305/*
306 * Reads JEDEC manufacturer ID and device ID and returns the index of the first 306 * Reads JEDEC manufacturer ID and device ID and returns the index of the first
307 * matching table entry (-1 if not found or alias for already found chip). 307 * matching table entry (-1 if not found or alias for already found chip).
308 */ 308 */
309static int probe_new_chip(struct mtd_info *mtd, __u32 base, 309static int probe_new_chip(struct mtd_info *mtd, __u32 base,
310 struct flchip *chips, 310 struct flchip *chips,
311 struct amd_flash_private *private, 311 struct amd_flash_private *private,
@@ -636,7 +636,7 @@ static struct mtd_info *amd_flash_probe(struct map_info *map)
636 { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 }, 636 { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 },
637 { .offset = 0x1F0000, .erasesize = 0x02000, .numblocks = 8 } 637 { .offset = 0x1F0000, .erasesize = 0x02000, .numblocks = 8 }
638 } 638 }
639 } 639 }
640 }; 640 };
641 641
642 struct mtd_info *mtd; 642 struct mtd_info *mtd;
@@ -701,7 +701,7 @@ static struct mtd_info *amd_flash_probe(struct map_info *map)
701 701
702 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) * 702 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) *
703 mtd->numeraseregions, GFP_KERNEL); 703 mtd->numeraseregions, GFP_KERNEL);
704 if (!mtd->eraseregions) { 704 if (!mtd->eraseregions) {
705 printk(KERN_WARNING "%s: Failed to allocate " 705 printk(KERN_WARNING "%s: Failed to allocate "
706 "memory for MTD erase region info\n", map->name); 706 "memory for MTD erase region info\n", map->name);
707 kfree(mtd); 707 kfree(mtd);
@@ -739,12 +739,12 @@ static struct mtd_info *amd_flash_probe(struct map_info *map)
739 mtd->type = MTD_NORFLASH; 739 mtd->type = MTD_NORFLASH;
740 mtd->flags = MTD_CAP_NORFLASH; 740 mtd->flags = MTD_CAP_NORFLASH;
741 mtd->name = map->name; 741 mtd->name = map->name;
742 mtd->erase = amd_flash_erase; 742 mtd->erase = amd_flash_erase;
743 mtd->read = amd_flash_read; 743 mtd->read = amd_flash_read;
744 mtd->write = amd_flash_write; 744 mtd->write = amd_flash_write;
745 mtd->sync = amd_flash_sync; 745 mtd->sync = amd_flash_sync;
746 mtd->suspend = amd_flash_suspend; 746 mtd->suspend = amd_flash_suspend;
747 mtd->resume = amd_flash_resume; 747 mtd->resume = amd_flash_resume;
748 mtd->lock = amd_flash_lock; 748 mtd->lock = amd_flash_lock;
749 mtd->unlock = amd_flash_unlock; 749 mtd->unlock = amd_flash_unlock;
750 750
@@ -789,7 +789,7 @@ retry:
789 map->name, chip->state); 789 map->name, chip->state);
790 set_current_state(TASK_UNINTERRUPTIBLE); 790 set_current_state(TASK_UNINTERRUPTIBLE);
791 add_wait_queue(&chip->wq, &wait); 791 add_wait_queue(&chip->wq, &wait);
792 792
793 spin_unlock_bh(chip->mutex); 793 spin_unlock_bh(chip->mutex);
794 794
795 schedule(); 795 schedule();
@@ -802,7 +802,7 @@ retry:
802 timeo = jiffies + HZ; 802 timeo = jiffies + HZ;
803 803
804 goto retry; 804 goto retry;
805 } 805 }
806 806
807 adr += chip->start; 807 adr += chip->start;
808 808
@@ -889,7 +889,7 @@ retry:
889 map->name, chip->state); 889 map->name, chip->state);
890 set_current_state(TASK_UNINTERRUPTIBLE); 890 set_current_state(TASK_UNINTERRUPTIBLE);
891 add_wait_queue(&chip->wq, &wait); 891 add_wait_queue(&chip->wq, &wait);
892 892
893 spin_unlock_bh(chip->mutex); 893 spin_unlock_bh(chip->mutex);
894 894
895 schedule(); 895 schedule();
@@ -901,7 +901,7 @@ retry:
901 timeo = jiffies + HZ; 901 timeo = jiffies + HZ;
902 902
903 goto retry; 903 goto retry;
904 } 904 }
905 905
906 chip->state = FL_WRITING; 906 chip->state = FL_WRITING;
907 907
@@ -911,7 +911,7 @@ retry:
911 wide_write(map, datum, adr); 911 wide_write(map, datum, adr);
912 912
913 times_left = 500000; 913 times_left = 500000;
914 while (times_left-- && flash_is_busy(map, adr, private->interleave)) { 914 while (times_left-- && flash_is_busy(map, adr, private->interleave)) {
915 if (need_resched()) { 915 if (need_resched()) {
916 spin_unlock_bh(chip->mutex); 916 spin_unlock_bh(chip->mutex);
917 schedule(); 917 schedule();
@@ -989,7 +989,7 @@ static int amd_flash_write(struct mtd_info *mtd, loff_t to , size_t len,
989 if (ret) { 989 if (ret) {
990 return ret; 990 return ret;
991 } 991 }
992 992
993 ofs += n; 993 ofs += n;
994 buf += n; 994 buf += n;
995 (*retlen) += n; 995 (*retlen) += n;
@@ -1002,7 +1002,7 @@ static int amd_flash_write(struct mtd_info *mtd, loff_t to , size_t len,
1002 } 1002 }
1003 } 1003 }
1004 } 1004 }
1005 1005
1006 /* We are now aligned, write as much as possible. */ 1006 /* We are now aligned, write as much as possible. */
1007 while(len >= map->buswidth) { 1007 while(len >= map->buswidth) {
1008 __u32 datum; 1008 __u32 datum;
@@ -1063,7 +1063,7 @@ static int amd_flash_write(struct mtd_info *mtd, loff_t to , size_t len,
1063 if (ret) { 1063 if (ret) {
1064 return ret; 1064 return ret;
1065 } 1065 }
1066 1066
1067 (*retlen) += n; 1067 (*retlen) += n;
1068 } 1068 }
1069 1069
@@ -1085,7 +1085,7 @@ retry:
1085 if (chip->state != FL_READY){ 1085 if (chip->state != FL_READY){
1086 set_current_state(TASK_UNINTERRUPTIBLE); 1086 set_current_state(TASK_UNINTERRUPTIBLE);
1087 add_wait_queue(&chip->wq, &wait); 1087 add_wait_queue(&chip->wq, &wait);
1088 1088
1089 spin_unlock_bh(chip->mutex); 1089 spin_unlock_bh(chip->mutex);
1090 1090
1091 schedule(); 1091 schedule();
@@ -1098,7 +1098,7 @@ retry:
1098 timeo = jiffies + HZ; 1098 timeo = jiffies + HZ;
1099 1099
1100 goto retry; 1100 goto retry;
1101 } 1101 }
1102 1102
1103 chip->state = FL_ERASING; 1103 chip->state = FL_ERASING;
1104 1104
@@ -1106,30 +1106,30 @@ retry:
1106 ENABLE_VPP(map); 1106 ENABLE_VPP(map);
1107 send_cmd(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA); 1107 send_cmd(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA);
1108 send_cmd_to_addr(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA_2, adr); 1108 send_cmd_to_addr(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA_2, adr);
1109 1109
1110 timeo = jiffies + (HZ * 20); 1110 timeo = jiffies + (HZ * 20);
1111 1111
1112 spin_unlock_bh(chip->mutex); 1112 spin_unlock_bh(chip->mutex);
1113 msleep(1000); 1113 msleep(1000);
1114 spin_lock_bh(chip->mutex); 1114 spin_lock_bh(chip->mutex);
1115 1115
1116 while (flash_is_busy(map, adr, private->interleave)) { 1116 while (flash_is_busy(map, adr, private->interleave)) {
1117 1117
1118 if (chip->state != FL_ERASING) { 1118 if (chip->state != FL_ERASING) {
1119 /* Someone's suspended the erase. Sleep */ 1119 /* Someone's suspended the erase. Sleep */
1120 set_current_state(TASK_UNINTERRUPTIBLE); 1120 set_current_state(TASK_UNINTERRUPTIBLE);
1121 add_wait_queue(&chip->wq, &wait); 1121 add_wait_queue(&chip->wq, &wait);
1122 1122
1123 spin_unlock_bh(chip->mutex); 1123 spin_unlock_bh(chip->mutex);
1124 printk(KERN_INFO "%s: erase suspended. Sleeping\n", 1124 printk(KERN_INFO "%s: erase suspended. Sleeping\n",
1125 map->name); 1125 map->name);
1126 schedule(); 1126 schedule();
1127 remove_wait_queue(&chip->wq, &wait); 1127 remove_wait_queue(&chip->wq, &wait);
1128 1128
1129 if (signal_pending(current)) { 1129 if (signal_pending(current)) {
1130 return -EINTR; 1130 return -EINTR;
1131 } 1131 }
1132 1132
1133 timeo = jiffies + (HZ*2); /* FIXME */ 1133 timeo = jiffies + (HZ*2); /* FIXME */
1134 spin_lock_bh(chip->mutex); 1134 spin_lock_bh(chip->mutex);
1135 continue; 1135 continue;
@@ -1145,7 +1145,7 @@ retry:
1145 1145
1146 return -EIO; 1146 return -EIO;
1147 } 1147 }
1148 1148
1149 /* Latency issues. Drop the lock, wait a while and retry */ 1149 /* Latency issues. Drop the lock, wait a while and retry */
1150 spin_unlock_bh(chip->mutex); 1150 spin_unlock_bh(chip->mutex);
1151 1151
@@ -1153,7 +1153,7 @@ retry:
1153 schedule(); 1153 schedule();
1154 else 1154 else
1155 udelay(1); 1155 udelay(1);
1156 1156
1157 spin_lock_bh(chip->mutex); 1157 spin_lock_bh(chip->mutex);
1158 } 1158 }
1159 1159
@@ -1180,7 +1180,7 @@ retry:
1180 return -EIO; 1180 return -EIO;
1181 } 1181 }
1182 } 1182 }
1183 1183
1184 DISABLE_VPP(map); 1184 DISABLE_VPP(map);
1185 chip->state = FL_READY; 1185 chip->state = FL_READY;
1186 wake_up(&chip->wq); 1186 wake_up(&chip->wq);
@@ -1246,7 +1246,7 @@ static int amd_flash_erase(struct mtd_info *mtd, struct erase_info *instr)
1246 * with the erase region at that address. 1246 * with the erase region at that address.
1247 */ 1247 */
1248 1248
1249 while ((i < mtd->numeraseregions) && 1249 while ((i < mtd->numeraseregions) &&
1250 ((instr->addr + instr->len) >= regions[i].offset)) { 1250 ((instr->addr + instr->len) >= regions[i].offset)) {
1251 i++; 1251 i++;
1252 } 1252 }
@@ -1293,10 +1293,10 @@ static int amd_flash_erase(struct mtd_info *mtd, struct erase_info *instr)
1293 } 1293 }
1294 } 1294 }
1295 } 1295 }
1296 1296
1297 instr->state = MTD_ERASE_DONE; 1297 instr->state = MTD_ERASE_DONE;
1298 mtd_erase_callback(instr); 1298 mtd_erase_callback(instr);
1299 1299
1300 return 0; 1300 return 0;
1301} 1301}
1302 1302
@@ -1324,7 +1324,7 @@ static void amd_flash_sync(struct mtd_info *mtd)
1324 case FL_JEDEC_QUERY: 1324 case FL_JEDEC_QUERY:
1325 chip->oldstate = chip->state; 1325 chip->oldstate = chip->state;
1326 chip->state = FL_SYNCING; 1326 chip->state = FL_SYNCING;
1327 /* No need to wake_up() on this state change - 1327 /* No need to wake_up() on this state change -
1328 * as the whole point is that nobody can do anything 1328 * as the whole point is that nobody can do anything
1329 * with the chip now anyway. 1329 * with the chip now anyway.
1330 */ 1330 */
@@ -1335,13 +1335,13 @@ static void amd_flash_sync(struct mtd_info *mtd)
1335 default: 1335 default:
1336 /* Not an idle state */ 1336 /* Not an idle state */
1337 add_wait_queue(&chip->wq, &wait); 1337 add_wait_queue(&chip->wq, &wait);
1338 1338
1339 spin_unlock_bh(chip->mutex); 1339 spin_unlock_bh(chip->mutex);
1340 1340
1341 schedule(); 1341 schedule();
1342 1342
1343 remove_wait_queue(&chip->wq, &wait); 1343 remove_wait_queue(&chip->wq, &wait);
1344 1344
1345 goto retry; 1345 goto retry;
1346 } 1346 }
1347 } 1347 }
@@ -1351,7 +1351,7 @@ static void amd_flash_sync(struct mtd_info *mtd)
1351 chip = &private->chips[i]; 1351 chip = &private->chips[i];
1352 1352
1353 spin_lock_bh(chip->mutex); 1353 spin_lock_bh(chip->mutex);
1354 1354
1355 if (chip->state == FL_SYNCING) { 1355 if (chip->state == FL_SYNCING) {
1356 chip->state = chip->oldstate; 1356 chip->state = chip->oldstate;
1357 wake_up(&chip->wq); 1357 wake_up(&chip->wq);
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index c3fc9b2f21fb..143f01a4c170 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -4,9 +4,9 @@
4 * 4 *
5 * (C) 2000 Red Hat. GPL'd 5 * (C) 2000 Red Hat. GPL'd
6 * 6 *
7 * $Id: cfi_cmdset_0001.c,v 1.178 2005/05/19 17:05:43 nico Exp $ 7 * $Id: cfi_cmdset_0001.c,v 1.185 2005/11/07 11:14:22 gleixner Exp $
8 *
8 * 9 *
9 *
10 * 10/10/2000 Nicolas Pitre <nico@cam.org> 10 * 10/10/2000 Nicolas Pitre <nico@cam.org>
11 * - completely revamped method functions so they are aware and 11 * - completely revamped method functions so they are aware and
12 * independent of the flash geometry (buswidth, interleave, etc.) 12 * independent of the flash geometry (buswidth, interleave, etc.)
@@ -51,6 +51,7 @@
51static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); 51static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
52static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); 52static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
53static int cfi_intelext_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); 53static int cfi_intelext_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
54static int cfi_intelext_writev(struct mtd_info *, const struct kvec *, unsigned long, loff_t, size_t *);
54static int cfi_intelext_erase_varsize(struct mtd_info *, struct erase_info *); 55static int cfi_intelext_erase_varsize(struct mtd_info *, struct erase_info *);
55static void cfi_intelext_sync (struct mtd_info *); 56static void cfi_intelext_sync (struct mtd_info *);
56static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len); 57static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len);
@@ -105,6 +106,7 @@ static struct mtd_chip_driver cfi_intelext_chipdrv = {
105static void cfi_tell_features(struct cfi_pri_intelext *extp) 106static void cfi_tell_features(struct cfi_pri_intelext *extp)
106{ 107{
107 int i; 108 int i;
109 printk(" Extended Query version %c.%c\n", extp->MajorVersion, extp->MinorVersion);
108 printk(" Feature/Command Support: %4.4X\n", extp->FeatureSupport); 110 printk(" Feature/Command Support: %4.4X\n", extp->FeatureSupport);
109 printk(" - Chip Erase: %s\n", extp->FeatureSupport&1?"supported":"unsupported"); 111 printk(" - Chip Erase: %s\n", extp->FeatureSupport&1?"supported":"unsupported");
110 printk(" - Suspend Erase: %s\n", extp->FeatureSupport&2?"supported":"unsupported"); 112 printk(" - Suspend Erase: %s\n", extp->FeatureSupport&2?"supported":"unsupported");
@@ -116,36 +118,43 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp)
116 printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported"); 118 printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported");
117 printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported"); 119 printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported");
118 printk(" - Simultaneous operations: %s\n", extp->FeatureSupport&512?"supported":"unsupported"); 120 printk(" - Simultaneous operations: %s\n", extp->FeatureSupport&512?"supported":"unsupported");
119 for (i=10; i<32; i++) { 121 printk(" - Extended Flash Array: %s\n", extp->FeatureSupport&1024?"supported":"unsupported");
120 if (extp->FeatureSupport & (1<<i)) 122 for (i=11; i<32; i++) {
123 if (extp->FeatureSupport & (1<<i))
121 printk(" - Unknown Bit %X: supported\n", i); 124 printk(" - Unknown Bit %X: supported\n", i);
122 } 125 }
123 126
124 printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport); 127 printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport);
125 printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported"); 128 printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported");
126 for (i=1; i<8; i++) { 129 for (i=1; i<8; i++) {
127 if (extp->SuspendCmdSupport & (1<<i)) 130 if (extp->SuspendCmdSupport & (1<<i))
128 printk(" - Unknown Bit %X: supported\n", i); 131 printk(" - Unknown Bit %X: supported\n", i);
129 } 132 }
130 133
131 printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask); 134 printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask);
132 printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no"); 135 printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no");
133 printk(" - Valid Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no"); 136 printk(" - Lock-Down Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no");
134 for (i=2; i<16; i++) { 137 for (i=2; i<3; i++) {
135 if (extp->BlkStatusRegMask & (1<<i)) 138 if (extp->BlkStatusRegMask & (1<<i))
136 printk(" - Unknown Bit %X Active: yes\n",i); 139 printk(" - Unknown Bit %X Active: yes\n",i);
137 } 140 }
138 141 printk(" - EFA Lock Bit: %s\n", extp->BlkStatusRegMask&16?"yes":"no");
139 printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n", 142 printk(" - EFA Lock-Down Bit: %s\n", extp->BlkStatusRegMask&32?"yes":"no");
143 for (i=6; i<16; i++) {
144 if (extp->BlkStatusRegMask & (1<<i))
145 printk(" - Unknown Bit %X Active: yes\n",i);
146 }
147
148 printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n",
140 extp->VccOptimal >> 4, extp->VccOptimal & 0xf); 149 extp->VccOptimal >> 4, extp->VccOptimal & 0xf);
141 if (extp->VppOptimal) 150 if (extp->VppOptimal)
142 printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n", 151 printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n",
143 extp->VppOptimal >> 4, extp->VppOptimal & 0xf); 152 extp->VppOptimal >> 4, extp->VppOptimal & 0xf);
144} 153}
145#endif 154#endif
146 155
147#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE 156#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
148/* Some Intel Strata Flash prior to FPO revision C has bugs in this area */ 157/* Some Intel Strata Flash prior to FPO revision C has bugs in this area */
149static void fixup_intel_strataflash(struct mtd_info *mtd, void* param) 158static void fixup_intel_strataflash(struct mtd_info *mtd, void* param)
150{ 159{
151 struct map_info *map = mtd->priv; 160 struct map_info *map = mtd->priv;
@@ -176,7 +185,7 @@ static void fixup_st_m28w320ct(struct mtd_info *mtd, void* param)
176{ 185{
177 struct map_info *map = mtd->priv; 186 struct map_info *map = mtd->priv;
178 struct cfi_private *cfi = map->fldrv_priv; 187 struct cfi_private *cfi = map->fldrv_priv;
179 188
180 cfi->cfiq->BufWriteTimeoutTyp = 0; /* Not supported */ 189 cfi->cfiq->BufWriteTimeoutTyp = 0; /* Not supported */
181 cfi->cfiq->BufWriteTimeoutMax = 0; /* Not supported */ 190 cfi->cfiq->BufWriteTimeoutMax = 0; /* Not supported */
182} 191}
@@ -185,7 +194,7 @@ static void fixup_st_m28w320cb(struct mtd_info *mtd, void* param)
185{ 194{
186 struct map_info *map = mtd->priv; 195 struct map_info *map = mtd->priv;
187 struct cfi_private *cfi = map->fldrv_priv; 196 struct cfi_private *cfi = map->fldrv_priv;
188 197
189 /* Note this is done after the region info is endian swapped */ 198 /* Note this is done after the region info is endian swapped */
190 cfi->cfiq->EraseRegionInfo[1] = 199 cfi->cfiq->EraseRegionInfo[1] =
191 (cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e; 200 (cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e;
@@ -207,12 +216,13 @@ static void fixup_use_write_buffers(struct mtd_info *mtd, void *param)
207 if (cfi->cfiq->BufWriteTimeoutTyp) { 216 if (cfi->cfiq->BufWriteTimeoutTyp) {
208 printk(KERN_INFO "Using buffer write method\n" ); 217 printk(KERN_INFO "Using buffer write method\n" );
209 mtd->write = cfi_intelext_write_buffers; 218 mtd->write = cfi_intelext_write_buffers;
219 mtd->writev = cfi_intelext_writev;
210 } 220 }
211} 221}
212 222
213static struct cfi_fixup cfi_fixup_table[] = { 223static struct cfi_fixup cfi_fixup_table[] = {
214#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE 224#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
215 { CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash, NULL }, 225 { CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash, NULL },
216#endif 226#endif
217#ifdef CMDSET0001_DISABLE_WRITE_SUSPEND 227#ifdef CMDSET0001_DISABLE_WRITE_SUSPEND
218 { CFI_MFR_ANY, CFI_ID_ANY, fixup_no_write_suspend, NULL }, 228 { CFI_MFR_ANY, CFI_ID_ANY, fixup_no_write_suspend, NULL },
@@ -252,12 +262,21 @@ read_pri_intelext(struct map_info *map, __u16 adr)
252 if (!extp) 262 if (!extp)
253 return NULL; 263 return NULL;
254 264
265 if (extp->MajorVersion != '1' ||
266 (extp->MinorVersion < '0' || extp->MinorVersion > '4')) {
267 printk(KERN_ERR " Unknown Intel/Sharp Extended Query "
268 "version %c.%c.\n", extp->MajorVersion,
269 extp->MinorVersion);
270 kfree(extp);
271 return NULL;
272 }
273
255 /* Do some byteswapping if necessary */ 274 /* Do some byteswapping if necessary */
256 extp->FeatureSupport = le32_to_cpu(extp->FeatureSupport); 275 extp->FeatureSupport = le32_to_cpu(extp->FeatureSupport);
257 extp->BlkStatusRegMask = le16_to_cpu(extp->BlkStatusRegMask); 276 extp->BlkStatusRegMask = le16_to_cpu(extp->BlkStatusRegMask);
258 extp->ProtRegAddr = le16_to_cpu(extp->ProtRegAddr); 277 extp->ProtRegAddr = le16_to_cpu(extp->ProtRegAddr);
259 278
260 if (extp->MajorVersion == '1' && extp->MinorVersion == '3') { 279 if (extp->MajorVersion == '1' && extp->MinorVersion >= '3') {
261 unsigned int extra_size = 0; 280 unsigned int extra_size = 0;
262 int nb_parts, i; 281 int nb_parts, i;
263 282
@@ -266,7 +285,10 @@ read_pri_intelext(struct map_info *map, __u16 adr)
266 sizeof(struct cfi_intelext_otpinfo); 285 sizeof(struct cfi_intelext_otpinfo);
267 286
268 /* Burst Read info */ 287 /* Burst Read info */
269 extra_size += 6; 288 extra_size += 2;
289 if (extp_size < sizeof(*extp) + extra_size)
290 goto need_more;
291 extra_size += extp->extra[extra_size-1];
270 292
271 /* Number of hardware-partitions */ 293 /* Number of hardware-partitions */
272 extra_size += 1; 294 extra_size += 1;
@@ -274,6 +296,10 @@ read_pri_intelext(struct map_info *map, __u16 adr)
274 goto need_more; 296 goto need_more;
275 nb_parts = extp->extra[extra_size - 1]; 297 nb_parts = extp->extra[extra_size - 1];
276 298
299 /* skip the sizeof(partregion) field in CFI 1.4 */
300 if (extp->MinorVersion >= '4')
301 extra_size += 2;
302
277 for (i = 0; i < nb_parts; i++) { 303 for (i = 0; i < nb_parts; i++) {
278 struct cfi_intelext_regioninfo *rinfo; 304 struct cfi_intelext_regioninfo *rinfo;
279 rinfo = (struct cfi_intelext_regioninfo *)&extp->extra[extra_size]; 305 rinfo = (struct cfi_intelext_regioninfo *)&extp->extra[extra_size];
@@ -285,6 +311,9 @@ read_pri_intelext(struct map_info *map, __u16 adr)
285 * sizeof(struct cfi_intelext_blockinfo); 311 * sizeof(struct cfi_intelext_blockinfo);
286 } 312 }
287 313
314 if (extp->MinorVersion >= '4')
315 extra_size += sizeof(struct cfi_intelext_programming_regioninfo);
316
288 if (extp_size < sizeof(*extp) + extra_size) { 317 if (extp_size < sizeof(*extp) + extra_size) {
289 need_more: 318 need_more:
290 extp_size = sizeof(*extp) + extra_size; 319 extp_size = sizeof(*extp) + extra_size;
@@ -298,7 +327,7 @@ read_pri_intelext(struct map_info *map, __u16 adr)
298 goto again; 327 goto again;
299 } 328 }
300 } 329 }
301 330
302 return extp; 331 return extp;
303} 332}
304 333
@@ -339,7 +368,7 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
339 mtd->reboot_notifier.notifier_call = cfi_intelext_reboot; 368 mtd->reboot_notifier.notifier_call = cfi_intelext_reboot;
340 369
341 if (cfi->cfi_mode == CFI_MODE_CFI) { 370 if (cfi->cfi_mode == CFI_MODE_CFI) {
342 /* 371 /*
343 * It's a real CFI chip, not one for which the probe 372 * It's a real CFI chip, not one for which the probe
344 * routine faked a CFI structure. So we read the feature 373 * routine faked a CFI structure. So we read the feature
345 * table from it. 374 * table from it.
@@ -354,14 +383,14 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
354 } 383 }
355 384
356 /* Install our own private info structure */ 385 /* Install our own private info structure */
357 cfi->cmdset_priv = extp; 386 cfi->cmdset_priv = extp;
358 387
359 cfi_fixup(mtd, cfi_fixup_table); 388 cfi_fixup(mtd, cfi_fixup_table);
360 389
361#ifdef DEBUG_CFI_FEATURES 390#ifdef DEBUG_CFI_FEATURES
362 /* Tell the user about it in lots of lovely detail */ 391 /* Tell the user about it in lots of lovely detail */
363 cfi_tell_features(extp); 392 cfi_tell_features(extp);
364#endif 393#endif
365 394
366 if(extp->SuspendCmdSupport & 1) { 395 if(extp->SuspendCmdSupport & 1) {
367 printk(KERN_NOTICE "cfi_cmdset_0001: Erase suspend on write enabled\n"); 396 printk(KERN_NOTICE "cfi_cmdset_0001: Erase suspend on write enabled\n");
@@ -379,10 +408,10 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
379 cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp; 408 cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
380 cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp; 409 cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
381 cfi->chips[i].ref_point_counter = 0; 410 cfi->chips[i].ref_point_counter = 0;
382 } 411 }
383 412
384 map->fldrv = &cfi_intelext_chipdrv; 413 map->fldrv = &cfi_intelext_chipdrv;
385 414
386 return cfi_intelext_setup(mtd); 415 return cfi_intelext_setup(mtd);
387} 416}
388 417
@@ -399,13 +428,13 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
399 mtd->size = devsize * cfi->numchips; 428 mtd->size = devsize * cfi->numchips;
400 429
401 mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; 430 mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
402 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) 431 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
403 * mtd->numeraseregions, GFP_KERNEL); 432 * mtd->numeraseregions, GFP_KERNEL);
404 if (!mtd->eraseregions) { 433 if (!mtd->eraseregions) {
405 printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n"); 434 printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n");
406 goto setup_err; 435 goto setup_err;
407 } 436 }
408 437
409 for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { 438 for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
410 unsigned long ernum, ersize; 439 unsigned long ernum, ersize;
411 ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; 440 ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
@@ -429,7 +458,7 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
429 } 458 }
430 459
431 for (i=0; i<mtd->numeraseregions;i++){ 460 for (i=0; i<mtd->numeraseregions;i++){
432 printk(KERN_DEBUG "%d: offset=0x%x,size=0x%x,blocks=%d\n", 461 printk(KERN_DEBUG "erase region %d: offset=0x%x,size=0x%x,blocks=%d\n",
433 i,mtd->eraseregions[i].offset, 462 i,mtd->eraseregions[i].offset,
434 mtd->eraseregions[i].erasesize, 463 mtd->eraseregions[i].erasesize,
435 mtd->eraseregions[i].numblocks); 464 mtd->eraseregions[i].numblocks);
@@ -480,7 +509,7 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
480 * arrangement at this point. This can be rearranged in the future 509 * arrangement at this point. This can be rearranged in the future
481 * if someone feels motivated enough. --nico 510 * if someone feels motivated enough. --nico
482 */ 511 */
483 if (extp && extp->MajorVersion == '1' && extp->MinorVersion == '3' 512 if (extp && extp->MajorVersion == '1' && extp->MinorVersion >= '3'
484 && extp->FeatureSupport & (1 << 9)) { 513 && extp->FeatureSupport & (1 << 9)) {
485 struct cfi_private *newcfi; 514 struct cfi_private *newcfi;
486 struct flchip *chip; 515 struct flchip *chip;
@@ -492,12 +521,16 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
492 sizeof(struct cfi_intelext_otpinfo); 521 sizeof(struct cfi_intelext_otpinfo);
493 522
494 /* Burst Read info */ 523 /* Burst Read info */
495 offs += 6; 524 offs += extp->extra[offs+1]+2;
496 525
497 /* Number of partition regions */ 526 /* Number of partition regions */
498 numregions = extp->extra[offs]; 527 numregions = extp->extra[offs];
499 offs += 1; 528 offs += 1;
500 529
530 /* skip the sizeof(partregion) field in CFI 1.4 */
531 if (extp->MinorVersion >= '4')
532 offs += 2;
533
501 /* Number of hardware partitions */ 534 /* Number of hardware partitions */
502 numparts = 0; 535 numparts = 0;
503 for (i = 0; i < numregions; i++) { 536 for (i = 0; i < numregions; i++) {
@@ -509,6 +542,20 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
509 sizeof(struct cfi_intelext_blockinfo); 542 sizeof(struct cfi_intelext_blockinfo);
510 } 543 }
511 544
545 /* Programming Region info */
546 if (extp->MinorVersion >= '4') {
547 struct cfi_intelext_programming_regioninfo *prinfo;
548 prinfo = (struct cfi_intelext_programming_regioninfo *)&extp->extra[offs];
549 MTD_PROGREGION_SIZE(mtd) = cfi->interleave << prinfo->ProgRegShift;
550 MTD_PROGREGION_CTRLMODE_VALID(mtd) = cfi->interleave * prinfo->ControlValid;
551 MTD_PROGREGION_CTRLMODE_INVALID(mtd) = cfi->interleave * prinfo->ControlInvalid;
552 mtd->flags |= MTD_PROGRAM_REGIONS;
553 printk(KERN_DEBUG "%s: program region size/ctrl_valid/ctrl_inval = %d/%d/%d\n",
554 map->name, MTD_PROGREGION_SIZE(mtd),
555 MTD_PROGREGION_CTRLMODE_VALID(mtd),
556 MTD_PROGREGION_CTRLMODE_INVALID(mtd));
557 }
558
512 /* 559 /*
513 * All functions below currently rely on all chips having 560 * All functions below currently rely on all chips having
514 * the same geometry so we'll just assume that all hardware 561 * the same geometry so we'll just assume that all hardware
@@ -653,8 +700,8 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
653 break; 700 break;
654 701
655 if (time_after(jiffies, timeo)) { 702 if (time_after(jiffies, timeo)) {
656 printk(KERN_ERR "Waiting for chip to be ready timed out. Status %lx\n", 703 printk(KERN_ERR "%s: Waiting for chip to be ready timed out. Status %lx\n",
657 status.x[0]); 704 map->name, status.x[0]);
658 return -EIO; 705 return -EIO;
659 } 706 }
660 spin_unlock(chip->mutex); 707 spin_unlock(chip->mutex);
@@ -663,7 +710,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
663 /* Someone else might have been playing with it. */ 710 /* Someone else might have been playing with it. */
664 goto retry; 711 goto retry;
665 } 712 }
666 713
667 case FL_READY: 714 case FL_READY:
668 case FL_CFI_QUERY: 715 case FL_CFI_QUERY:
669 case FL_JEDEC_QUERY: 716 case FL_JEDEC_QUERY:
@@ -701,8 +748,8 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
701 map_write(map, CMD(0x70), adr); 748 map_write(map, CMD(0x70), adr);
702 chip->state = FL_ERASING; 749 chip->state = FL_ERASING;
703 chip->oldstate = FL_READY; 750 chip->oldstate = FL_READY;
704 printk(KERN_ERR "Chip not ready after erase " 751 printk(KERN_ERR "%s: Chip not ready after erase "
705 "suspended: status = 0x%lx\n", status.x[0]); 752 "suspended: status = 0x%lx\n", map->name, status.x[0]);
706 return -EIO; 753 return -EIO;
707 } 754 }
708 755
@@ -782,14 +829,14 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
782 switch(chip->oldstate) { 829 switch(chip->oldstate) {
783 case FL_ERASING: 830 case FL_ERASING:
784 chip->state = chip->oldstate; 831 chip->state = chip->oldstate;
785 /* What if one interleaved chip has finished and the 832 /* What if one interleaved chip has finished and the
786 other hasn't? The old code would leave the finished 833 other hasn't? The old code would leave the finished
787 one in READY mode. That's bad, and caused -EROFS 834 one in READY mode. That's bad, and caused -EROFS
788 errors to be returned from do_erase_oneblock because 835 errors to be returned from do_erase_oneblock because
789 that's the only bit it checked for at the time. 836 that's the only bit it checked for at the time.
790 As the state machine appears to explicitly allow 837 As the state machine appears to explicitly allow
791 sending the 0x70 (Read Status) command to an erasing 838 sending the 0x70 (Read Status) command to an erasing
792 chip and expecting it to be ignored, that's what we 839 chip and expecting it to be ignored, that's what we
793 do. */ 840 do. */
794 map_write(map, CMD(0xd0), adr); 841 map_write(map, CMD(0xd0), adr);
795 map_write(map, CMD(0x70), adr); 842 map_write(map, CMD(0x70), adr);
@@ -809,7 +856,7 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
809 DISABLE_VPP(map); 856 DISABLE_VPP(map);
810 break; 857 break;
811 default: 858 default:
812 printk(KERN_ERR "put_chip() called with oldstate %d!!\n", chip->oldstate); 859 printk(KERN_ERR "%s: put_chip() called with oldstate %d!!\n", map->name, chip->oldstate);
813 } 860 }
814 wake_up(&chip->wq); 861 wake_up(&chip->wq);
815} 862}
@@ -1025,8 +1072,8 @@ static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t a
1025 1072
1026 adr += chip->start; 1073 adr += chip->start;
1027 1074
1028 /* Ensure cmd read/writes are aligned. */ 1075 /* Ensure cmd read/writes are aligned. */
1029 cmd_addr = adr & ~(map_bankwidth(map)-1); 1076 cmd_addr = adr & ~(map_bankwidth(map)-1);
1030 1077
1031 spin_lock(chip->mutex); 1078 spin_lock(chip->mutex);
1032 1079
@@ -1054,7 +1101,7 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, si
1054 1101
1055 if (!map->virt || (from + len > mtd->size)) 1102 if (!map->virt || (from + len > mtd->size))
1056 return -EINVAL; 1103 return -EINVAL;
1057 1104
1058 *mtdbuf = (void *)map->virt + from; 1105 *mtdbuf = (void *)map->virt + from;
1059 *retlen = 0; 1106 *retlen = 0;
1060 1107
@@ -1081,7 +1128,7 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, si
1081 1128
1082 *retlen += thislen; 1129 *retlen += thislen;
1083 len -= thislen; 1130 len -= thislen;
1084 1131
1085 ofs = 0; 1132 ofs = 0;
1086 chipnum++; 1133 chipnum++;
1087 } 1134 }
@@ -1120,7 +1167,7 @@ static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t fro
1120 if(chip->ref_point_counter == 0) 1167 if(chip->ref_point_counter == 0)
1121 chip->state = FL_READY; 1168 chip->state = FL_READY;
1122 } else 1169 } else
1123 printk(KERN_ERR "Warning: unpoint called on non pointed region\n"); /* Should this give an error? */ 1170 printk(KERN_ERR "%s: Warning: unpoint called on non pointed region\n", map->name); /* Should this give an error? */
1124 1171
1125 put_chip(map, chip, chip->start); 1172 put_chip(map, chip, chip->start);
1126 spin_unlock(chip->mutex); 1173 spin_unlock(chip->mutex);
@@ -1139,8 +1186,8 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
1139 1186
1140 adr += chip->start; 1187 adr += chip->start;
1141 1188
1142 /* Ensure cmd read/writes are aligned. */ 1189 /* Ensure cmd read/writes are aligned. */
1143 cmd_addr = adr & ~(map_bankwidth(map)-1); 1190 cmd_addr = adr & ~(map_bankwidth(map)-1);
1144 1191
1145 spin_lock(chip->mutex); 1192 spin_lock(chip->mutex);
1146 ret = get_chip(map, chip, cmd_addr, FL_READY); 1193 ret = get_chip(map, chip, cmd_addr, FL_READY);
@@ -1195,7 +1242,7 @@ static int cfi_intelext_read (struct mtd_info *mtd, loff_t from, size_t len, siz
1195 *retlen += thislen; 1242 *retlen += thislen;
1196 len -= thislen; 1243 len -= thislen;
1197 buf += thislen; 1244 buf += thislen;
1198 1245
1199 ofs = 0; 1246 ofs = 0;
1200 chipnum++; 1247 chipnum++;
1201 } 1248 }
@@ -1212,12 +1259,17 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
1212 1259
1213 adr += chip->start; 1260 adr += chip->start;
1214 1261
1215 /* Let's determine this according to the interleave only once */ 1262 /* Let's determine those according to the interleave only once */
1216 status_OK = CMD(0x80); 1263 status_OK = CMD(0x80);
1217 switch (mode) { 1264 switch (mode) {
1218 case FL_WRITING: write_cmd = CMD(0x40); break; 1265 case FL_WRITING:
1219 case FL_OTP_WRITE: write_cmd = CMD(0xc0); break; 1266 write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0x40) : CMD(0x41);
1220 default: return -EINVAL; 1267 break;
1268 case FL_OTP_WRITE:
1269 write_cmd = CMD(0xc0);
1270 break;
1271 default:
1272 return -EINVAL;
1221 } 1273 }
1222 1274
1223 spin_lock(chip->mutex); 1275 spin_lock(chip->mutex);
@@ -1258,12 +1310,13 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
1258 status = map_read(map, adr); 1310 status = map_read(map, adr);
1259 if (map_word_andequal(map, status, status_OK, status_OK)) 1311 if (map_word_andequal(map, status, status_OK, status_OK))
1260 break; 1312 break;
1261 1313
1262 /* OK Still waiting */ 1314 /* OK Still waiting */
1263 if (time_after(jiffies, timeo)) { 1315 if (time_after(jiffies, timeo)) {
1316 map_write(map, CMD(0x70), adr);
1264 chip->state = FL_STATUS; 1317 chip->state = FL_STATUS;
1265 xip_enable(map, chip, adr); 1318 xip_enable(map, chip, adr);
1266 printk(KERN_ERR "waiting for chip to be ready timed out in word write\n"); 1319 printk(KERN_ERR "%s: word write error (status timeout)\n", map->name);
1267 ret = -EIO; 1320 ret = -EIO;
1268 goto out; 1321 goto out;
1269 } 1322 }
@@ -1275,27 +1328,39 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
1275 if (!z) { 1328 if (!z) {
1276 chip->word_write_time--; 1329 chip->word_write_time--;
1277 if (!chip->word_write_time) 1330 if (!chip->word_write_time)
1278 chip->word_write_time++; 1331 chip->word_write_time = 1;
1279 } 1332 }
1280 if (z > 1) 1333 if (z > 1)
1281 chip->word_write_time++; 1334 chip->word_write_time++;
1282 1335
1283 /* Done and happy. */ 1336 /* Done and happy. */
1284 chip->state = FL_STATUS; 1337 chip->state = FL_STATUS;
1285 1338
1286 /* check for lock bit */ 1339 /* check for errors */
1287 if (map_word_bitsset(map, status, CMD(0x02))) { 1340 if (map_word_bitsset(map, status, CMD(0x1a))) {
1288 /* clear status */ 1341 unsigned long chipstatus = MERGESTATUS(status);
1342
1343 /* reset status */
1289 map_write(map, CMD(0x50), adr); 1344 map_write(map, CMD(0x50), adr);
1290 /* put back into read status register mode */
1291 map_write(map, CMD(0x70), adr); 1345 map_write(map, CMD(0x70), adr);
1292 ret = -EROFS; 1346 xip_enable(map, chip, adr);
1347
1348 if (chipstatus & 0x02) {
1349 ret = -EROFS;
1350 } else if (chipstatus & 0x08) {
1351 printk(KERN_ERR "%s: word write error (bad VPP)\n", map->name);
1352 ret = -EIO;
1353 } else {
1354 printk(KERN_ERR "%s: word write error (status 0x%lx)\n", map->name, chipstatus);
1355 ret = -EINVAL;
1356 }
1357
1358 goto out;
1293 } 1359 }
1294 1360
1295 xip_enable(map, chip, adr); 1361 xip_enable(map, chip, adr);
1296 out: put_chip(map, chip, adr); 1362 out: put_chip(map, chip, adr);
1297 spin_unlock(chip->mutex); 1363 spin_unlock(chip->mutex);
1298
1299 return ret; 1364 return ret;
1300} 1365}
1301 1366
@@ -1328,7 +1393,7 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
1328 1393
1329 ret = do_write_oneword(map, &cfi->chips[chipnum], 1394 ret = do_write_oneword(map, &cfi->chips[chipnum],
1330 bus_ofs, datum, FL_WRITING); 1395 bus_ofs, datum, FL_WRITING);
1331 if (ret) 1396 if (ret)
1332 return ret; 1397 return ret;
1333 1398
1334 len -= n; 1399 len -= n;
@@ -1337,13 +1402,13 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
1337 (*retlen) += n; 1402 (*retlen) += n;
1338 1403
1339 if (ofs >> cfi->chipshift) { 1404 if (ofs >> cfi->chipshift) {
1340 chipnum ++; 1405 chipnum ++;
1341 ofs = 0; 1406 ofs = 0;
1342 if (chipnum == cfi->numchips) 1407 if (chipnum == cfi->numchips)
1343 return 0; 1408 return 0;
1344 } 1409 }
1345 } 1410 }
1346 1411
1347 while(len >= map_bankwidth(map)) { 1412 while(len >= map_bankwidth(map)) {
1348 map_word datum = map_word_load(map, buf); 1413 map_word datum = map_word_load(map, buf);
1349 1414
@@ -1358,7 +1423,7 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
1358 len -= map_bankwidth(map); 1423 len -= map_bankwidth(map);
1359 1424
1360 if (ofs >> cfi->chipshift) { 1425 if (ofs >> cfi->chipshift) {
1361 chipnum ++; 1426 chipnum ++;
1362 ofs = 0; 1427 ofs = 0;
1363 if (chipnum == cfi->numchips) 1428 if (chipnum == cfi->numchips)
1364 return 0; 1429 return 0;
@@ -1373,9 +1438,9 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
1373 1438
1374 ret = do_write_oneword(map, &cfi->chips[chipnum], 1439 ret = do_write_oneword(map, &cfi->chips[chipnum],
1375 ofs, datum, FL_WRITING); 1440 ofs, datum, FL_WRITING);
1376 if (ret) 1441 if (ret)
1377 return ret; 1442 return ret;
1378 1443
1379 (*retlen) += len; 1444 (*retlen) += len;
1380 } 1445 }
1381 1446
@@ -1383,20 +1448,24 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
1383} 1448}
1384 1449
1385 1450
1386static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, 1451static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1387 unsigned long adr, const u_char *buf, int len) 1452 unsigned long adr, const struct kvec **pvec,
1453 unsigned long *pvec_seek, int len)
1388{ 1454{
1389 struct cfi_private *cfi = map->fldrv_priv; 1455 struct cfi_private *cfi = map->fldrv_priv;
1390 map_word status, status_OK; 1456 map_word status, status_OK, write_cmd, datum;
1391 unsigned long cmd_adr, timeo; 1457 unsigned long cmd_adr, timeo;
1392 int wbufsize, z, ret=0, bytes, words; 1458 int wbufsize, z, ret=0, word_gap, words;
1459 const struct kvec *vec;
1460 unsigned long vec_seek;
1393 1461
1394 wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; 1462 wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
1395 adr += chip->start; 1463 adr += chip->start;
1396 cmd_adr = adr & ~(wbufsize-1); 1464 cmd_adr = adr & ~(wbufsize-1);
1397 1465
1398 /* Let's determine this according to the interleave only once */ 1466 /* Let's determine this according to the interleave only once */
1399 status_OK = CMD(0x80); 1467 status_OK = CMD(0x80);
1468 write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0xe8) : CMD(0xe9);
1400 1469
1401 spin_lock(chip->mutex); 1470 spin_lock(chip->mutex);
1402 ret = get_chip(map, chip, cmd_adr, FL_WRITING); 1471 ret = get_chip(map, chip, cmd_adr, FL_WRITING);
@@ -1410,7 +1479,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1410 xip_disable(map, chip, cmd_adr); 1479 xip_disable(map, chip, cmd_adr);
1411 1480
1412 /* §4.8 of the 28FxxxJ3A datasheet says "Any time SR.4 and/or SR.5 is set 1481 /* §4.8 of the 28FxxxJ3A datasheet says "Any time SR.4 and/or SR.5 is set
1413 [...], the device will not accept any more Write to Buffer commands". 1482 [...], the device will not accept any more Write to Buffer commands".
1414 So we must check here and reset those bits if they're set. Otherwise 1483 So we must check here and reset those bits if they're set. Otherwise
1415 we're just pissing in the wind */ 1484 we're just pissing in the wind */
1416 if (chip->state != FL_STATUS) 1485 if (chip->state != FL_STATUS)
@@ -1428,7 +1497,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1428 1497
1429 z = 0; 1498 z = 0;
1430 for (;;) { 1499 for (;;) {
1431 map_write(map, CMD(0xe8), cmd_adr); 1500 map_write(map, write_cmd, cmd_adr);
1432 1501
1433 status = map_read(map, cmd_adr); 1502 status = map_read(map, cmd_adr);
1434 if (map_word_andequal(map, status, status_OK, status_OK)) 1503 if (map_word_andequal(map, status, status_OK, status_OK))
@@ -1446,41 +1515,66 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1446 map_write(map, CMD(0x50), cmd_adr); 1515 map_write(map, CMD(0x50), cmd_adr);
1447 map_write(map, CMD(0x70), cmd_adr); 1516 map_write(map, CMD(0x70), cmd_adr);
1448 xip_enable(map, chip, cmd_adr); 1517 xip_enable(map, chip, cmd_adr);
1449 printk(KERN_ERR "Chip not ready for buffer write. status = %lx, Xstatus = %lx\n", 1518 printk(KERN_ERR "%s: Chip not ready for buffer write. status = %lx, Xstatus = %lx\n",
1450 status.x[0], Xstatus.x[0]); 1519 map->name, status.x[0], Xstatus.x[0]);
1451 ret = -EIO; 1520 ret = -EIO;
1452 goto out; 1521 goto out;
1453 } 1522 }
1454 } 1523 }
1455 1524
1525 /* Figure out the number of words to write */
1526 word_gap = (-adr & (map_bankwidth(map)-1));
1527 words = (len - word_gap + map_bankwidth(map) - 1) / map_bankwidth(map);
1528 if (!word_gap) {
1529 words--;
1530 } else {
1531 word_gap = map_bankwidth(map) - word_gap;
1532 adr -= word_gap;
1533 datum = map_word_ff(map);
1534 }
1535
1456 /* Write length of data to come */ 1536 /* Write length of data to come */
1457 bytes = len & (map_bankwidth(map)-1); 1537 map_write(map, CMD(words), cmd_adr );
1458 words = len / map_bankwidth(map);
1459 map_write(map, CMD(words - !bytes), cmd_adr );
1460 1538
1461 /* Write data */ 1539 /* Write data */
1462 z = 0; 1540 vec = *pvec;
1463 while(z < words * map_bankwidth(map)) { 1541 vec_seek = *pvec_seek;
1464 map_word datum = map_word_load(map, buf); 1542 do {
1465 map_write(map, datum, adr+z); 1543 int n = map_bankwidth(map) - word_gap;
1544 if (n > vec->iov_len - vec_seek)
1545 n = vec->iov_len - vec_seek;
1546 if (n > len)
1547 n = len;
1466 1548
1467 z += map_bankwidth(map); 1549 if (!word_gap && len < map_bankwidth(map))
1468 buf += map_bankwidth(map); 1550 datum = map_word_ff(map);
1469 }
1470 1551
1471 if (bytes) { 1552 datum = map_word_load_partial(map, datum,
1472 map_word datum; 1553 vec->iov_base + vec_seek,
1554 word_gap, n);
1473 1555
1474 datum = map_word_ff(map); 1556 len -= n;
1475 datum = map_word_load_partial(map, datum, buf, 0, bytes); 1557 word_gap += n;
1476 map_write(map, datum, adr+z); 1558 if (!len || word_gap == map_bankwidth(map)) {
1477 } 1559 map_write(map, datum, adr);
1560 adr += map_bankwidth(map);
1561 word_gap = 0;
1562 }
1563
1564 vec_seek += n;
1565 if (vec_seek == vec->iov_len) {
1566 vec++;
1567 vec_seek = 0;
1568 }
1569 } while (len);
1570 *pvec = vec;
1571 *pvec_seek = vec_seek;
1478 1572
1479 /* GO GO GO */ 1573 /* GO GO GO */
1480 map_write(map, CMD(0xd0), cmd_adr); 1574 map_write(map, CMD(0xd0), cmd_adr);
1481 chip->state = FL_WRITING; 1575 chip->state = FL_WRITING;
1482 1576
1483 INVALIDATE_CACHE_UDELAY(map, chip, 1577 INVALIDATE_CACHE_UDELAY(map, chip,
1484 cmd_adr, len, 1578 cmd_adr, len,
1485 chip->buffer_write_time); 1579 chip->buffer_write_time);
1486 1580
@@ -1506,13 +1600,14 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1506 1600
1507 /* OK Still waiting */ 1601 /* OK Still waiting */
1508 if (time_after(jiffies, timeo)) { 1602 if (time_after(jiffies, timeo)) {
1603 map_write(map, CMD(0x70), cmd_adr);
1509 chip->state = FL_STATUS; 1604 chip->state = FL_STATUS;
1510 xip_enable(map, chip, cmd_adr); 1605 xip_enable(map, chip, cmd_adr);
1511 printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n"); 1606 printk(KERN_ERR "%s: buffer write error (status timeout)\n", map->name);
1512 ret = -EIO; 1607 ret = -EIO;
1513 goto out; 1608 goto out;
1514 } 1609 }
1515 1610
1516 /* Latency issues. Drop the lock, wait a while and retry */ 1611 /* Latency issues. Drop the lock, wait a while and retry */
1517 z++; 1612 z++;
1518 UDELAY(map, chip, cmd_adr, 1); 1613 UDELAY(map, chip, cmd_adr, 1);
@@ -1520,21 +1615,34 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1520 if (!z) { 1615 if (!z) {
1521 chip->buffer_write_time--; 1616 chip->buffer_write_time--;
1522 if (!chip->buffer_write_time) 1617 if (!chip->buffer_write_time)
1523 chip->buffer_write_time++; 1618 chip->buffer_write_time = 1;
1524 } 1619 }
1525 if (z > 1) 1620 if (z > 1)
1526 chip->buffer_write_time++; 1621 chip->buffer_write_time++;
1527 1622
1528 /* Done and happy. */ 1623 /* Done and happy. */
1529 chip->state = FL_STATUS; 1624 chip->state = FL_STATUS;
1530 1625
1531 /* check for lock bit */ 1626 /* check for errors */
1532 if (map_word_bitsset(map, status, CMD(0x02))) { 1627 if (map_word_bitsset(map, status, CMD(0x1a))) {
1533 /* clear status */ 1628 unsigned long chipstatus = MERGESTATUS(status);
1629
1630 /* reset status */
1534 map_write(map, CMD(0x50), cmd_adr); 1631 map_write(map, CMD(0x50), cmd_adr);
1535 /* put back into read status register mode */ 1632 map_write(map, CMD(0x70), cmd_adr);
1536 map_write(map, CMD(0x70), adr); 1633 xip_enable(map, chip, cmd_adr);
1537 ret = -EROFS; 1634
1635 if (chipstatus & 0x02) {
1636 ret = -EROFS;
1637 } else if (chipstatus & 0x08) {
1638 printk(KERN_ERR "%s: buffer write error (bad VPP)\n", map->name);
1639 ret = -EIO;
1640 } else {
1641 printk(KERN_ERR "%s: buffer write error (status 0x%lx)\n", map->name, chipstatus);
1642 ret = -EINVAL;
1643 }
1644
1645 goto out;
1538 } 1646 }
1539 1647
1540 xip_enable(map, chip, cmd_adr); 1648 xip_enable(map, chip, cmd_adr);
@@ -1543,70 +1651,65 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1543 return ret; 1651 return ret;
1544} 1652}
1545 1653
1546static int cfi_intelext_write_buffers (struct mtd_info *mtd, loff_t to, 1654static int cfi_intelext_writev (struct mtd_info *mtd, const struct kvec *vecs,
1547 size_t len, size_t *retlen, const u_char *buf) 1655 unsigned long count, loff_t to, size_t *retlen)
1548{ 1656{
1549 struct map_info *map = mtd->priv; 1657 struct map_info *map = mtd->priv;
1550 struct cfi_private *cfi = map->fldrv_priv; 1658 struct cfi_private *cfi = map->fldrv_priv;
1551 int wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; 1659 int wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
1552 int ret = 0; 1660 int ret = 0;
1553 int chipnum; 1661 int chipnum;
1554 unsigned long ofs; 1662 unsigned long ofs, vec_seek, i;
1663 size_t len = 0;
1664
1665 for (i = 0; i < count; i++)
1666 len += vecs[i].iov_len;
1555 1667
1556 *retlen = 0; 1668 *retlen = 0;
1557 if (!len) 1669 if (!len)
1558 return 0; 1670 return 0;
1559 1671
1560 chipnum = to >> cfi->chipshift; 1672 chipnum = to >> cfi->chipshift;
1561 ofs = to - (chipnum << cfi->chipshift); 1673 ofs = to - (chipnum << cfi->chipshift);
1562 1674 vec_seek = 0;
1563 /* If it's not bus-aligned, do the first word write */
1564 if (ofs & (map_bankwidth(map)-1)) {
1565 size_t local_len = (-ofs)&(map_bankwidth(map)-1);
1566 if (local_len > len)
1567 local_len = len;
1568 ret = cfi_intelext_write_words(mtd, to, local_len,
1569 retlen, buf);
1570 if (ret)
1571 return ret;
1572 ofs += local_len;
1573 buf += local_len;
1574 len -= local_len;
1575
1576 if (ofs >> cfi->chipshift) {
1577 chipnum ++;
1578 ofs = 0;
1579 if (chipnum == cfi->numchips)
1580 return 0;
1581 }
1582 }
1583 1675
1584 while(len) { 1676 do {
1585 /* We must not cross write block boundaries */ 1677 /* We must not cross write block boundaries */
1586 int size = wbufsize - (ofs & (wbufsize-1)); 1678 int size = wbufsize - (ofs & (wbufsize-1));
1587 1679
1588 if (size > len) 1680 if (size > len)
1589 size = len; 1681 size = len;
1590 ret = do_write_buffer(map, &cfi->chips[chipnum], 1682 ret = do_write_buffer(map, &cfi->chips[chipnum],
1591 ofs, buf, size); 1683 ofs, &vecs, &vec_seek, size);
1592 if (ret) 1684 if (ret)
1593 return ret; 1685 return ret;
1594 1686
1595 ofs += size; 1687 ofs += size;
1596 buf += size;
1597 (*retlen) += size; 1688 (*retlen) += size;
1598 len -= size; 1689 len -= size;
1599 1690
1600 if (ofs >> cfi->chipshift) { 1691 if (ofs >> cfi->chipshift) {
1601 chipnum ++; 1692 chipnum ++;
1602 ofs = 0; 1693 ofs = 0;
1603 if (chipnum == cfi->numchips) 1694 if (chipnum == cfi->numchips)
1604 return 0; 1695 return 0;
1605 } 1696 }
1606 } 1697 } while (len);
1698
1607 return 0; 1699 return 0;
1608} 1700}
1609 1701
1702static int cfi_intelext_write_buffers (struct mtd_info *mtd, loff_t to,
1703 size_t len, size_t *retlen, const u_char *buf)
1704{
1705 struct kvec vec;
1706
1707 vec.iov_base = (void *) buf;
1708 vec.iov_len = len;
1709
1710 return cfi_intelext_writev(mtd, &vec, 1, to, retlen);
1711}
1712
1610static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, 1713static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
1611 unsigned long adr, int len, void *thunk) 1714 unsigned long adr, int len, void *thunk)
1612{ 1715{
@@ -1672,23 +1775,17 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
1672 status = map_read(map, adr); 1775 status = map_read(map, adr);
1673 if (map_word_andequal(map, status, status_OK, status_OK)) 1776 if (map_word_andequal(map, status, status_OK, status_OK))
1674 break; 1777 break;
1675 1778
1676 /* OK Still waiting */ 1779 /* OK Still waiting */
1677 if (time_after(jiffies, timeo)) { 1780 if (time_after(jiffies, timeo)) {
1678 map_word Xstatus;
1679 map_write(map, CMD(0x70), adr); 1781 map_write(map, CMD(0x70), adr);
1680 chip->state = FL_STATUS; 1782 chip->state = FL_STATUS;
1681 Xstatus = map_read(map, adr);
1682 /* Clear status bits */
1683 map_write(map, CMD(0x50), adr);
1684 map_write(map, CMD(0x70), adr);
1685 xip_enable(map, chip, adr); 1783 xip_enable(map, chip, adr);
1686 printk(KERN_ERR "waiting for erase at %08lx to complete timed out. status = %lx, Xstatus = %lx.\n", 1784 printk(KERN_ERR "%s: block erase error: (status timeout)\n", map->name);
1687 adr, status.x[0], Xstatus.x[0]);
1688 ret = -EIO; 1785 ret = -EIO;
1689 goto out; 1786 goto out;
1690 } 1787 }
1691 1788
1692 /* Latency issues. Drop the lock, wait a while and retry */ 1789 /* Latency issues. Drop the lock, wait a while and retry */
1693 UDELAY(map, chip, adr, 1000000/HZ); 1790 UDELAY(map, chip, adr, 1000000/HZ);
1694 } 1791 }
@@ -1698,43 +1795,40 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
1698 chip->state = FL_STATUS; 1795 chip->state = FL_STATUS;
1699 status = map_read(map, adr); 1796 status = map_read(map, adr);
1700 1797
1701 /* check for lock bit */ 1798 /* check for errors */
1702 if (map_word_bitsset(map, status, CMD(0x3a))) { 1799 if (map_word_bitsset(map, status, CMD(0x3a))) {
1703 unsigned long chipstatus; 1800 unsigned long chipstatus = MERGESTATUS(status);
1704 1801
1705 /* Reset the error bits */ 1802 /* Reset the error bits */
1706 map_write(map, CMD(0x50), adr); 1803 map_write(map, CMD(0x50), adr);
1707 map_write(map, CMD(0x70), adr); 1804 map_write(map, CMD(0x70), adr);
1708 xip_enable(map, chip, adr); 1805 xip_enable(map, chip, adr);
1709 1806
1710 chipstatus = MERGESTATUS(status);
1711
1712 if ((chipstatus & 0x30) == 0x30) { 1807 if ((chipstatus & 0x30) == 0x30) {
1713 printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%lx\n", chipstatus); 1808 printk(KERN_ERR "%s: block erase error: (bad command sequence, status 0x%lx)\n", map->name, chipstatus);
1714 ret = -EIO; 1809 ret = -EINVAL;
1715 } else if (chipstatus & 0x02) { 1810 } else if (chipstatus & 0x02) {
1716 /* Protection bit set */ 1811 /* Protection bit set */
1717 ret = -EROFS; 1812 ret = -EROFS;
1718 } else if (chipstatus & 0x8) { 1813 } else if (chipstatus & 0x8) {
1719 /* Voltage */ 1814 /* Voltage */
1720 printk(KERN_WARNING "Chip reports voltage low on erase: status 0x%lx\n", chipstatus); 1815 printk(KERN_ERR "%s: block erase error: (bad VPP)\n", map->name);
1721 ret = -EIO; 1816 ret = -EIO;
1722 } else if (chipstatus & 0x20) { 1817 } else if (chipstatus & 0x20 && retries--) {
1723 if (retries--) { 1818 printk(KERN_DEBUG "block erase failed at 0x%08lx: status 0x%lx. Retrying...\n", adr, chipstatus);
1724 printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%lx. Retrying...\n", adr, chipstatus); 1819 timeo = jiffies + HZ;
1725 timeo = jiffies + HZ; 1820 put_chip(map, chip, adr);
1726 put_chip(map, chip, adr); 1821 spin_unlock(chip->mutex);
1727 spin_unlock(chip->mutex); 1822 goto retry;
1728 goto retry; 1823 } else {
1729 } 1824 printk(KERN_ERR "%s: block erase failed at 0x%08lx (status 0x%lx)\n", map->name, adr, chipstatus);
1730 printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%lx\n", adr, chipstatus);
1731 ret = -EIO; 1825 ret = -EIO;
1732 } 1826 }
1733 } else { 1827
1734 xip_enable(map, chip, adr); 1828 goto out;
1735 ret = 0;
1736 } 1829 }
1737 1830
1831 xip_enable(map, chip, adr);
1738 out: put_chip(map, chip, adr); 1832 out: put_chip(map, chip, adr);
1739 spin_unlock(chip->mutex); 1833 spin_unlock(chip->mutex);
1740 return ret; 1834 return ret;
@@ -1754,7 +1848,7 @@ int cfi_intelext_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
1754 1848
1755 instr->state = MTD_ERASE_DONE; 1849 instr->state = MTD_ERASE_DONE;
1756 mtd_erase_callback(instr); 1850 mtd_erase_callback(instr);
1757 1851
1758 return 0; 1852 return 0;
1759} 1853}
1760 1854
@@ -1775,7 +1869,7 @@ static void cfi_intelext_sync (struct mtd_info *mtd)
1775 if (!ret) { 1869 if (!ret) {
1776 chip->oldstate = chip->state; 1870 chip->oldstate = chip->state;
1777 chip->state = FL_SYNCING; 1871 chip->state = FL_SYNCING;
1778 /* No need to wake_up() on this state change - 1872 /* No need to wake_up() on this state change -
1779 * as the whole point is that nobody can do anything 1873 * as the whole point is that nobody can do anything
1780 * with the chip now anyway. 1874 * with the chip now anyway.
1781 */ 1875 */
@@ -1789,7 +1883,7 @@ static void cfi_intelext_sync (struct mtd_info *mtd)
1789 chip = &cfi->chips[i]; 1883 chip = &cfi->chips[i];
1790 1884
1791 spin_lock(chip->mutex); 1885 spin_lock(chip->mutex);
1792 1886
1793 if (chip->state == FL_SYNCING) { 1887 if (chip->state == FL_SYNCING) {
1794 chip->state = chip->oldstate; 1888 chip->state = chip->oldstate;
1795 chip->oldstate = FL_READY; 1889 chip->oldstate = FL_READY;
@@ -1846,7 +1940,7 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
1846 1940
1847 ENABLE_VPP(map); 1941 ENABLE_VPP(map);
1848 xip_disable(map, chip, adr); 1942 xip_disable(map, chip, adr);
1849 1943
1850 map_write(map, CMD(0x60), adr); 1944 map_write(map, CMD(0x60), adr);
1851 if (thunk == DO_XXLOCK_ONEBLOCK_LOCK) { 1945 if (thunk == DO_XXLOCK_ONEBLOCK_LOCK) {
1852 map_write(map, CMD(0x01), adr); 1946 map_write(map, CMD(0x01), adr);
@@ -1874,25 +1968,22 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
1874 status = map_read(map, adr); 1968 status = map_read(map, adr);
1875 if (map_word_andequal(map, status, status_OK, status_OK)) 1969 if (map_word_andequal(map, status, status_OK, status_OK))
1876 break; 1970 break;
1877 1971
1878 /* OK Still waiting */ 1972 /* OK Still waiting */
1879 if (time_after(jiffies, timeo)) { 1973 if (time_after(jiffies, timeo)) {
1880 map_word Xstatus;
1881 map_write(map, CMD(0x70), adr); 1974 map_write(map, CMD(0x70), adr);
1882 chip->state = FL_STATUS; 1975 chip->state = FL_STATUS;
1883 Xstatus = map_read(map, adr);
1884 xip_enable(map, chip, adr); 1976 xip_enable(map, chip, adr);
1885 printk(KERN_ERR "waiting for unlock to complete timed out. status = %lx, Xstatus = %lx.\n", 1977 printk(KERN_ERR "%s: block unlock error: (status timeout)\n", map->name);
1886 status.x[0], Xstatus.x[0]);
1887 put_chip(map, chip, adr); 1978 put_chip(map, chip, adr);
1888 spin_unlock(chip->mutex); 1979 spin_unlock(chip->mutex);
1889 return -EIO; 1980 return -EIO;
1890 } 1981 }
1891 1982
1892 /* Latency issues. Drop the lock, wait a while and retry */ 1983 /* Latency issues. Drop the lock, wait a while and retry */
1893 UDELAY(map, chip, adr, 1); 1984 UDELAY(map, chip, adr, 1);
1894 } 1985 }
1895 1986
1896 /* Done and happy. */ 1987 /* Done and happy. */
1897 chip->state = FL_STATUS; 1988 chip->state = FL_STATUS;
1898 xip_enable(map, chip, adr); 1989 xip_enable(map, chip, adr);
@@ -1912,9 +2003,9 @@ static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
1912 ofs, len, 0); 2003 ofs, len, 0);
1913#endif 2004#endif
1914 2005
1915 ret = cfi_varsize_frob(mtd, do_xxlock_oneblock, 2006 ret = cfi_varsize_frob(mtd, do_xxlock_oneblock,
1916 ofs, len, DO_XXLOCK_ONEBLOCK_LOCK); 2007 ofs, len, DO_XXLOCK_ONEBLOCK_LOCK);
1917 2008
1918#ifdef DEBUG_LOCK_BITS 2009#ifdef DEBUG_LOCK_BITS
1919 printk(KERN_DEBUG "%s: lock status after, ret=%d\n", 2010 printk(KERN_DEBUG "%s: lock status after, ret=%d\n",
1920 __FUNCTION__, ret); 2011 __FUNCTION__, ret);
@@ -1938,20 +2029,20 @@ static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1938 2029
1939 ret = cfi_varsize_frob(mtd, do_xxlock_oneblock, 2030 ret = cfi_varsize_frob(mtd, do_xxlock_oneblock,
1940 ofs, len, DO_XXLOCK_ONEBLOCK_UNLOCK); 2031 ofs, len, DO_XXLOCK_ONEBLOCK_UNLOCK);
1941 2032
1942#ifdef DEBUG_LOCK_BITS 2033#ifdef DEBUG_LOCK_BITS
1943 printk(KERN_DEBUG "%s: lock status after, ret=%d\n", 2034 printk(KERN_DEBUG "%s: lock status after, ret=%d\n",
1944 __FUNCTION__, ret); 2035 __FUNCTION__, ret);
1945 cfi_varsize_frob(mtd, do_printlockstatus_oneblock, 2036 cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
1946 ofs, len, 0); 2037 ofs, len, 0);
1947#endif 2038#endif
1948 2039
1949 return ret; 2040 return ret;
1950} 2041}
1951 2042
1952#ifdef CONFIG_MTD_OTP 2043#ifdef CONFIG_MTD_OTP
1953 2044
1954typedef int (*otp_op_t)(struct map_info *map, struct flchip *chip, 2045typedef int (*otp_op_t)(struct map_info *map, struct flchip *chip,
1955 u_long data_offset, u_char *buf, u_int size, 2046 u_long data_offset, u_char *buf, u_int size,
1956 u_long prot_offset, u_int groupno, u_int groupsize); 2047 u_long prot_offset, u_int groupno, u_int groupsize);
1957 2048
@@ -2002,7 +2093,7 @@ do_otp_write(struct map_info *map, struct flchip *chip, u_long offset,
2002 2093
2003 datum = map_word_load_partial(map, datum, buf, gap, n); 2094 datum = map_word_load_partial(map, datum, buf, gap, n);
2004 ret = do_write_oneword(map, chip, bus_ofs, datum, FL_OTP_WRITE); 2095 ret = do_write_oneword(map, chip, bus_ofs, datum, FL_OTP_WRITE);
2005 if (ret) 2096 if (ret)
2006 return ret; 2097 return ret;
2007 2098
2008 offset += n; 2099 offset += n;
@@ -2195,7 +2286,7 @@ static int cfi_intelext_lock_user_prot_reg(struct mtd_info *mtd,
2195 NULL, do_otp_lock, 1); 2286 NULL, do_otp_lock, 1);
2196} 2287}
2197 2288
2198static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd, 2289static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd,
2199 struct otp_info *buf, size_t len) 2290 struct otp_info *buf, size_t len)
2200{ 2291{
2201 size_t retlen; 2292 size_t retlen;
@@ -2238,7 +2329,7 @@ static int cfi_intelext_suspend(struct mtd_info *mtd)
2238 if (chip->oldstate == FL_READY) { 2329 if (chip->oldstate == FL_READY) {
2239 chip->oldstate = chip->state; 2330 chip->oldstate = chip->state;
2240 chip->state = FL_PM_SUSPENDED; 2331 chip->state = FL_PM_SUSPENDED;
2241 /* No need to wake_up() on this state change - 2332 /* No need to wake_up() on this state change -
2242 * as the whole point is that nobody can do anything 2333 * as the whole point is that nobody can do anything
2243 * with the chip now anyway. 2334 * with the chip now anyway.
2244 */ 2335 */
@@ -2266,9 +2357,9 @@ static int cfi_intelext_suspend(struct mtd_info *mtd)
2266 if (ret) { 2357 if (ret) {
2267 for (i--; i >=0; i--) { 2358 for (i--; i >=0; i--) {
2268 chip = &cfi->chips[i]; 2359 chip = &cfi->chips[i];
2269 2360
2270 spin_lock(chip->mutex); 2361 spin_lock(chip->mutex);
2271 2362
2272 if (chip->state == FL_PM_SUSPENDED) { 2363 if (chip->state == FL_PM_SUSPENDED) {
2273 /* No need to force it into a known state here, 2364 /* No need to force it into a known state here,
2274 because we're returning failure, and it didn't 2365 because we're returning failure, and it didn't
@@ -2279,8 +2370,8 @@ static int cfi_intelext_suspend(struct mtd_info *mtd)
2279 } 2370 }
2280 spin_unlock(chip->mutex); 2371 spin_unlock(chip->mutex);
2281 } 2372 }
2282 } 2373 }
2283 2374
2284 return ret; 2375 return ret;
2285} 2376}
2286 2377
@@ -2292,11 +2383,11 @@ static void cfi_intelext_resume(struct mtd_info *mtd)
2292 struct flchip *chip; 2383 struct flchip *chip;
2293 2384
2294 for (i=0; i<cfi->numchips; i++) { 2385 for (i=0; i<cfi->numchips; i++) {
2295 2386
2296 chip = &cfi->chips[i]; 2387 chip = &cfi->chips[i];
2297 2388
2298 spin_lock(chip->mutex); 2389 spin_lock(chip->mutex);
2299 2390
2300 /* Go to known state. Chip may have been power cycled */ 2391 /* Go to known state. Chip may have been power cycled */
2301 if (chip->state == FL_PM_SUSPENDED) { 2392 if (chip->state == FL_PM_SUSPENDED) {
2302 map_write(map, CMD(0xFF), cfi->chips[i].start); 2393 map_write(map, CMD(0xFF), cfi->chips[i].start);
@@ -2318,7 +2409,7 @@ static int cfi_intelext_reset(struct mtd_info *mtd)
2318 struct flchip *chip = &cfi->chips[i]; 2409 struct flchip *chip = &cfi->chips[i];
2319 2410
2320 /* force the completion of any ongoing operation 2411 /* force the completion of any ongoing operation
2321 and switch to array mode so any bootloader in 2412 and switch to array mode so any bootloader in
2322 flash is accessible for soft reboot. */ 2413 flash is accessible for soft reboot. */
2323 spin_lock(chip->mutex); 2414 spin_lock(chip->mutex);
2324 ret = get_chip(map, chip, chip->start, FL_SYNCING); 2415 ret = get_chip(map, chip, chip->start, FL_SYNCING);
@@ -2355,20 +2446,23 @@ static void cfi_intelext_destroy(struct mtd_info *mtd)
2355 kfree(mtd->eraseregions); 2446 kfree(mtd->eraseregions);
2356} 2447}
2357 2448
2358static char im_name_1[]="cfi_cmdset_0001"; 2449static char im_name_0001[] = "cfi_cmdset_0001";
2359static char im_name_3[]="cfi_cmdset_0003"; 2450static char im_name_0003[] = "cfi_cmdset_0003";
2451static char im_name_0200[] = "cfi_cmdset_0200";
2360 2452
2361static int __init cfi_intelext_init(void) 2453static int __init cfi_intelext_init(void)
2362{ 2454{
2363 inter_module_register(im_name_1, THIS_MODULE, &cfi_cmdset_0001); 2455 inter_module_register(im_name_0001, THIS_MODULE, &cfi_cmdset_0001);
2364 inter_module_register(im_name_3, THIS_MODULE, &cfi_cmdset_0001); 2456 inter_module_register(im_name_0003, THIS_MODULE, &cfi_cmdset_0001);
2457 inter_module_register(im_name_0200, THIS_MODULE, &cfi_cmdset_0001);
2365 return 0; 2458 return 0;
2366} 2459}
2367 2460
2368static void __exit cfi_intelext_exit(void) 2461static void __exit cfi_intelext_exit(void)
2369{ 2462{
2370 inter_module_unregister(im_name_1); 2463 inter_module_unregister(im_name_0001);
2371 inter_module_unregister(im_name_3); 2464 inter_module_unregister(im_name_0003);
2465 inter_module_unregister(im_name_0200);
2372} 2466}
2373 2467
2374module_init(cfi_intelext_init); 2468module_init(cfi_intelext_init);
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 0e6475050da9..aed10bd5c3c3 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -10,14 +10,14 @@
10 * 10 *
11 * 4_by_16 work by Carolyn J. Smith 11 * 4_by_16 work by Carolyn J. Smith
12 * 12 *
13 * XIP support hooks by Vitaly Wool (based on code for Intel flash 13 * XIP support hooks by Vitaly Wool (based on code for Intel flash
14 * by Nicolas Pitre) 14 * by Nicolas Pitre)
15 * 15 *
16 * Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com 16 * Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com
17 * 17 *
18 * This code is GPL 18 * This code is GPL
19 * 19 *
20 * $Id: cfi_cmdset_0002.c,v 1.118 2005/07/04 22:34:29 gleixner Exp $ 20 * $Id: cfi_cmdset_0002.c,v 1.122 2005/11/07 11:14:22 gleixner Exp $
21 * 21 *
22 */ 22 */
23 23
@@ -93,7 +93,7 @@ static void cfi_tell_features(struct cfi_pri_amdstd *extp)
93 }; 93 };
94 94
95 printk(" Silicon revision: %d\n", extp->SiliconRevision >> 1); 95 printk(" Silicon revision: %d\n", extp->SiliconRevision >> 1);
96 printk(" Address sensitive unlock: %s\n", 96 printk(" Address sensitive unlock: %s\n",
97 (extp->SiliconRevision & 1) ? "Not required" : "Required"); 97 (extp->SiliconRevision & 1) ? "Not required" : "Required");
98 98
99 if (extp->EraseSuspend < ARRAY_SIZE(erase_suspend)) 99 if (extp->EraseSuspend < ARRAY_SIZE(erase_suspend))
@@ -118,9 +118,9 @@ static void cfi_tell_features(struct cfi_pri_amdstd *extp)
118 else 118 else
119 printk(" Page mode: %d word page\n", extp->PageMode << 2); 119 printk(" Page mode: %d word page\n", extp->PageMode << 2);
120 120
121 printk(" Vpp Supply Minimum Program/Erase Voltage: %d.%d V\n", 121 printk(" Vpp Supply Minimum Program/Erase Voltage: %d.%d V\n",
122 extp->VppMin >> 4, extp->VppMin & 0xf); 122 extp->VppMin >> 4, extp->VppMin & 0xf);
123 printk(" Vpp Supply Maximum Program/Erase Voltage: %d.%d V\n", 123 printk(" Vpp Supply Maximum Program/Erase Voltage: %d.%d V\n",
124 extp->VppMax >> 4, extp->VppMax & 0xf); 124 extp->VppMax >> 4, extp->VppMax & 0xf);
125 125
126 if (extp->TopBottom < ARRAY_SIZE(top_bottom)) 126 if (extp->TopBottom < ARRAY_SIZE(top_bottom))
@@ -177,7 +177,7 @@ static void fixup_use_erase_chip(struct mtd_info *mtd, void *param)
177 ((cfi->cfiq->EraseRegionInfo[0] & 0xffff) == 0)) { 177 ((cfi->cfiq->EraseRegionInfo[0] & 0xffff) == 0)) {
178 mtd->erase = cfi_amdstd_erase_chip; 178 mtd->erase = cfi_amdstd_erase_chip;
179 } 179 }
180 180
181} 181}
182 182
183static struct cfi_fixup cfi_fixup_table[] = { 183static struct cfi_fixup cfi_fixup_table[] = {
@@ -239,7 +239,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
239 239
240 if (cfi->cfi_mode==CFI_MODE_CFI){ 240 if (cfi->cfi_mode==CFI_MODE_CFI){
241 unsigned char bootloc; 241 unsigned char bootloc;
242 /* 242 /*
243 * It's a real CFI chip, not one for which the probe 243 * It's a real CFI chip, not one for which the probe
244 * routine faked a CFI structure. So we read the feature 244 * routine faked a CFI structure. So we read the feature
245 * table from it. 245 * table from it.
@@ -253,8 +253,18 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
253 return NULL; 253 return NULL;
254 } 254 }
255 255
256 if (extp->MajorVersion != '1' ||
257 (extp->MinorVersion < '0' || extp->MinorVersion > '4')) {
258 printk(KERN_ERR " Unknown Amd/Fujitsu Extended Query "
259 "version %c.%c.\n", extp->MajorVersion,
260 extp->MinorVersion);
261 kfree(extp);
262 kfree(mtd);
263 return NULL;
264 }
265
256 /* Install our own private info structure */ 266 /* Install our own private info structure */
257 cfi->cmdset_priv = extp; 267 cfi->cmdset_priv = extp;
258 268
259 /* Apply cfi device specific fixups */ 269 /* Apply cfi device specific fixups */
260 cfi_fixup(mtd, cfi_fixup_table); 270 cfi_fixup(mtd, cfi_fixup_table);
@@ -262,7 +272,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
262#ifdef DEBUG_CFI_FEATURES 272#ifdef DEBUG_CFI_FEATURES
263 /* Tell the user about it in lots of lovely detail */ 273 /* Tell the user about it in lots of lovely detail */
264 cfi_tell_features(extp); 274 cfi_tell_features(extp);
265#endif 275#endif
266 276
267 bootloc = extp->TopBottom; 277 bootloc = extp->TopBottom;
268 if ((bootloc != 2) && (bootloc != 3)) { 278 if ((bootloc != 2) && (bootloc != 3)) {
@@ -273,11 +283,11 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
273 283
274 if (bootloc == 3 && cfi->cfiq->NumEraseRegions > 1) { 284 if (bootloc == 3 && cfi->cfiq->NumEraseRegions > 1) {
275 printk(KERN_WARNING "%s: Swapping erase regions for broken CFI table.\n", map->name); 285 printk(KERN_WARNING "%s: Swapping erase regions for broken CFI table.\n", map->name);
276 286
277 for (i=0; i<cfi->cfiq->NumEraseRegions / 2; i++) { 287 for (i=0; i<cfi->cfiq->NumEraseRegions / 2; i++) {
278 int j = (cfi->cfiq->NumEraseRegions-1)-i; 288 int j = (cfi->cfiq->NumEraseRegions-1)-i;
279 __u32 swap; 289 __u32 swap;
280 290
281 swap = cfi->cfiq->EraseRegionInfo[i]; 291 swap = cfi->cfiq->EraseRegionInfo[i];
282 cfi->cfiq->EraseRegionInfo[i] = cfi->cfiq->EraseRegionInfo[j]; 292 cfi->cfiq->EraseRegionInfo[i] = cfi->cfiq->EraseRegionInfo[j];
283 cfi->cfiq->EraseRegionInfo[j] = swap; 293 cfi->cfiq->EraseRegionInfo[j] = swap;
@@ -288,11 +298,11 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
288 cfi->addr_unlock2 = 0x2aa; 298 cfi->addr_unlock2 = 0x2aa;
289 /* Modify the unlock address if we are in compatibility mode */ 299 /* Modify the unlock address if we are in compatibility mode */
290 if ( /* x16 in x8 mode */ 300 if ( /* x16 in x8 mode */
291 ((cfi->device_type == CFI_DEVICETYPE_X8) && 301 ((cfi->device_type == CFI_DEVICETYPE_X8) &&
292 (cfi->cfiq->InterfaceDesc == 2)) || 302 (cfi->cfiq->InterfaceDesc == 2)) ||
293 /* x32 in x16 mode */ 303 /* x32 in x16 mode */
294 ((cfi->device_type == CFI_DEVICETYPE_X16) && 304 ((cfi->device_type == CFI_DEVICETYPE_X16) &&
295 (cfi->cfiq->InterfaceDesc == 4))) 305 (cfi->cfiq->InterfaceDesc == 4)))
296 { 306 {
297 cfi->addr_unlock1 = 0xaaa; 307 cfi->addr_unlock1 = 0xaaa;
298 cfi->addr_unlock2 = 0x555; 308 cfi->addr_unlock2 = 0x555;
@@ -310,10 +320,10 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
310 cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp; 320 cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;
311 cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp; 321 cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
312 cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp; 322 cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
313 } 323 }
314 324
315 map->fldrv = &cfi_amdstd_chipdrv; 325 map->fldrv = &cfi_amdstd_chipdrv;
316 326
317 return cfi_amdstd_setup(mtd); 327 return cfi_amdstd_setup(mtd);
318} 328}
319 329
@@ -326,24 +336,24 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
326 unsigned long offset = 0; 336 unsigned long offset = 0;
327 int i,j; 337 int i,j;
328 338
329 printk(KERN_NOTICE "number of %s chips: %d\n", 339 printk(KERN_NOTICE "number of %s chips: %d\n",
330 (cfi->cfi_mode == CFI_MODE_CFI)?"CFI":"JEDEC",cfi->numchips); 340 (cfi->cfi_mode == CFI_MODE_CFI)?"CFI":"JEDEC",cfi->numchips);
331 /* Select the correct geometry setup */ 341 /* Select the correct geometry setup */
332 mtd->size = devsize * cfi->numchips; 342 mtd->size = devsize * cfi->numchips;
333 343
334 mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; 344 mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
335 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) 345 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
336 * mtd->numeraseregions, GFP_KERNEL); 346 * mtd->numeraseregions, GFP_KERNEL);
337 if (!mtd->eraseregions) { 347 if (!mtd->eraseregions) {
338 printk(KERN_WARNING "Failed to allocate memory for MTD erase region info\n"); 348 printk(KERN_WARNING "Failed to allocate memory for MTD erase region info\n");
339 goto setup_err; 349 goto setup_err;
340 } 350 }
341 351
342 for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { 352 for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
343 unsigned long ernum, ersize; 353 unsigned long ernum, ersize;
344 ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; 354 ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
345 ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1; 355 ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1;
346 356
347 if (mtd->erasesize < ersize) { 357 if (mtd->erasesize < ersize) {
348 mtd->erasesize = ersize; 358 mtd->erasesize = ersize;
349 } 359 }
@@ -429,7 +439,7 @@ static int __xipram chip_good(struct map_info *map, unsigned long addr, map_word
429 oldd = map_read(map, addr); 439 oldd = map_read(map, addr);
430 curd = map_read(map, addr); 440 curd = map_read(map, addr);
431 441
432 return map_word_equal(map, oldd, curd) && 442 return map_word_equal(map, oldd, curd) &&
433 map_word_equal(map, curd, expected); 443 map_word_equal(map, curd, expected);
434} 444}
435 445
@@ -461,7 +471,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
461 /* Someone else might have been playing with it. */ 471 /* Someone else might have been playing with it. */
462 goto retry; 472 goto retry;
463 } 473 }
464 474
465 case FL_READY: 475 case FL_READY:
466 case FL_CFI_QUERY: 476 case FL_CFI_QUERY:
467 case FL_JEDEC_QUERY: 477 case FL_JEDEC_QUERY:
@@ -504,7 +514,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
504 printk(KERN_ERR "MTD %s(): chip not ready after erase suspend\n", __func__); 514 printk(KERN_ERR "MTD %s(): chip not ready after erase suspend\n", __func__);
505 return -EIO; 515 return -EIO;
506 } 516 }
507 517
508 spin_unlock(chip->mutex); 518 spin_unlock(chip->mutex);
509 cfi_udelay(1); 519 cfi_udelay(1);
510 spin_lock(chip->mutex); 520 spin_lock(chip->mutex);
@@ -607,7 +617,7 @@ static void __xipram xip_enable(struct map_info *map, struct flchip *chip,
607 * When a delay is required for the flash operation to complete, the 617 * When a delay is required for the flash operation to complete, the
608 * xip_udelay() function is polling for both the given timeout and pending 618 * xip_udelay() function is polling for both the given timeout and pending
609 * (but still masked) hardware interrupts. Whenever there is an interrupt 619 * (but still masked) hardware interrupts. Whenever there is an interrupt
610 * pending then the flash erase operation is suspended, array mode restored 620 * pending then the flash erase operation is suspended, array mode restored
611 * and interrupts unmasked. Task scheduling might also happen at that 621 * and interrupts unmasked. Task scheduling might also happen at that
612 * point. The CPU eventually returns from the interrupt or the call to 622 * point. The CPU eventually returns from the interrupt or the call to
613 * schedule() and the suspended flash operation is resumed for the remaining 623 * schedule() and the suspended flash operation is resumed for the remaining
@@ -631,9 +641,9 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
631 ((chip->state == FL_ERASING && (extp->EraseSuspend & 2))) && 641 ((chip->state == FL_ERASING && (extp->EraseSuspend & 2))) &&
632 (cfi_interleave_is_1(cfi) || chip->oldstate == FL_READY)) { 642 (cfi_interleave_is_1(cfi) || chip->oldstate == FL_READY)) {
633 /* 643 /*
634 * Let's suspend the erase operation when supported. 644 * Let's suspend the erase operation when supported.
635 * Note that we currently don't try to suspend 645 * Note that we currently don't try to suspend
636 * interleaved chips if there is already another 646 * interleaved chips if there is already another
637 * operation suspended (imagine what happens 647 * operation suspended (imagine what happens
638 * when one chip was already done with the current 648 * when one chip was already done with the current
639 * operation while another chip suspended it, then 649 * operation while another chip suspended it, then
@@ -769,8 +779,8 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
769 779
770 adr += chip->start; 780 adr += chip->start;
771 781
772 /* Ensure cmd read/writes are aligned. */ 782 /* Ensure cmd read/writes are aligned. */
773 cmd_addr = adr & ~(map_bankwidth(map)-1); 783 cmd_addr = adr & ~(map_bankwidth(map)-1);
774 784
775 spin_lock(chip->mutex); 785 spin_lock(chip->mutex);
776 ret = get_chip(map, chip, cmd_addr, FL_READY); 786 ret = get_chip(map, chip, cmd_addr, FL_READY);
@@ -850,7 +860,7 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
850#endif 860#endif
851 set_current_state(TASK_UNINTERRUPTIBLE); 861 set_current_state(TASK_UNINTERRUPTIBLE);
852 add_wait_queue(&chip->wq, &wait); 862 add_wait_queue(&chip->wq, &wait);
853 863
854 spin_unlock(chip->mutex); 864 spin_unlock(chip->mutex);
855 865
856 schedule(); 866 schedule();
@@ -862,7 +872,7 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
862 timeo = jiffies + HZ; 872 timeo = jiffies + HZ;
863 873
864 goto retry; 874 goto retry;
865 } 875 }
866 876
867 adr += chip->start; 877 adr += chip->start;
868 878
@@ -871,14 +881,14 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
871 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 881 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
872 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); 882 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
873 cfi_send_gen_cmd(0x88, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 883 cfi_send_gen_cmd(0x88, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
874 884
875 map_copy_from(map, buf, adr, len); 885 map_copy_from(map, buf, adr, len);
876 886
877 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 887 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
878 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); 888 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
879 cfi_send_gen_cmd(0x90, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 889 cfi_send_gen_cmd(0x90, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
880 cfi_send_gen_cmd(0x00, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 890 cfi_send_gen_cmd(0x00, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
881 891
882 wake_up(&chip->wq); 892 wake_up(&chip->wq);
883 spin_unlock(chip->mutex); 893 spin_unlock(chip->mutex);
884 894
@@ -987,7 +997,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
987 chip->word_write_time); 997 chip->word_write_time);
988 998
989 /* See comment above for timeout value. */ 999 /* See comment above for timeout value. */
990 timeo = jiffies + uWriteTimeout; 1000 timeo = jiffies + uWriteTimeout;
991 for (;;) { 1001 for (;;) {
992 if (chip->state != FL_WRITING) { 1002 if (chip->state != FL_WRITING) {
993 /* Someone's suspended the write. Sleep */ 1003 /* Someone's suspended the write. Sleep */
@@ -1003,16 +1013,16 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
1003 continue; 1013 continue;
1004 } 1014 }
1005 1015
1006 if (chip_ready(map, adr)) 1016 if (time_after(jiffies, timeo) && !chip_ready(map, adr)){
1007 break;
1008
1009 if (time_after(jiffies, timeo)) {
1010 xip_enable(map, chip, adr); 1017 xip_enable(map, chip, adr);
1011 printk(KERN_WARNING "MTD %s(): software timeout\n", __func__); 1018 printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
1012 xip_disable(map, chip, adr); 1019 xip_disable(map, chip, adr);
1013 break; 1020 break;
1014 } 1021 }
1015 1022
1023 if (chip_ready(map, adr))
1024 break;
1025
1016 /* Latency issues. Drop the lock, wait a while and retry */ 1026 /* Latency issues. Drop the lock, wait a while and retry */
1017 UDELAY(map, chip, adr, 1); 1027 UDELAY(map, chip, adr, 1);
1018 } 1028 }
@@ -1022,7 +1032,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
1022 map_write( map, CMD(0xF0), chip->start ); 1032 map_write( map, CMD(0xF0), chip->start );
1023 /* FIXME - should have reset delay before continuing */ 1033 /* FIXME - should have reset delay before continuing */
1024 1034
1025 if (++retry_cnt <= MAX_WORD_RETRIES) 1035 if (++retry_cnt <= MAX_WORD_RETRIES)
1026 goto retry; 1036 goto retry;
1027 1037
1028 ret = -EIO; 1038 ret = -EIO;
@@ -1090,27 +1100,27 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
1090 1100
1091 /* Number of bytes to copy from buffer */ 1101 /* Number of bytes to copy from buffer */
1092 n = min_t(int, len, map_bankwidth(map)-i); 1102 n = min_t(int, len, map_bankwidth(map)-i);
1093 1103
1094 tmp_buf = map_word_load_partial(map, tmp_buf, buf, i, n); 1104 tmp_buf = map_word_load_partial(map, tmp_buf, buf, i, n);
1095 1105
1096 ret = do_write_oneword(map, &cfi->chips[chipnum], 1106 ret = do_write_oneword(map, &cfi->chips[chipnum],
1097 bus_ofs, tmp_buf); 1107 bus_ofs, tmp_buf);
1098 if (ret) 1108 if (ret)
1099 return ret; 1109 return ret;
1100 1110
1101 ofs += n; 1111 ofs += n;
1102 buf += n; 1112 buf += n;
1103 (*retlen) += n; 1113 (*retlen) += n;
1104 len -= n; 1114 len -= n;
1105 1115
1106 if (ofs >> cfi->chipshift) { 1116 if (ofs >> cfi->chipshift) {
1107 chipnum ++; 1117 chipnum ++;
1108 ofs = 0; 1118 ofs = 0;
1109 if (chipnum == cfi->numchips) 1119 if (chipnum == cfi->numchips)
1110 return 0; 1120 return 0;
1111 } 1121 }
1112 } 1122 }
1113 1123
1114 /* We are now aligned, write as much as possible */ 1124 /* We are now aligned, write as much as possible */
1115 while(len >= map_bankwidth(map)) { 1125 while(len >= map_bankwidth(map)) {
1116 map_word datum; 1126 map_word datum;
@@ -1128,7 +1138,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
1128 len -= map_bankwidth(map); 1138 len -= map_bankwidth(map);
1129 1139
1130 if (ofs >> cfi->chipshift) { 1140 if (ofs >> cfi->chipshift) {
1131 chipnum ++; 1141 chipnum ++;
1132 ofs = 0; 1142 ofs = 0;
1133 if (chipnum == cfi->numchips) 1143 if (chipnum == cfi->numchips)
1134 return 0; 1144 return 0;
@@ -1166,12 +1176,12 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
1166 spin_unlock(cfi->chips[chipnum].mutex); 1176 spin_unlock(cfi->chips[chipnum].mutex);
1167 1177
1168 tmp_buf = map_word_load_partial(map, tmp_buf, buf, 0, len); 1178 tmp_buf = map_word_load_partial(map, tmp_buf, buf, 0, len);
1169 1179
1170 ret = do_write_oneword(map, &cfi->chips[chipnum], 1180 ret = do_write_oneword(map, &cfi->chips[chipnum],
1171 ofs, tmp_buf); 1181 ofs, tmp_buf);
1172 if (ret) 1182 if (ret)
1173 return ret; 1183 return ret;
1174 1184
1175 (*retlen) += len; 1185 (*retlen) += len;
1176 } 1186 }
1177 1187
@@ -1183,7 +1193,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
1183 * FIXME: interleaved mode not tested, and probably not supported! 1193 * FIXME: interleaved mode not tested, and probably not supported!
1184 */ 1194 */
1185static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, 1195static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1186 unsigned long adr, const u_char *buf, 1196 unsigned long adr, const u_char *buf,
1187 int len) 1197 int len)
1188{ 1198{
1189 struct cfi_private *cfi = map->fldrv_priv; 1199 struct cfi_private *cfi = map->fldrv_priv;
@@ -1213,7 +1223,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1213 XIP_INVAL_CACHED_RANGE(map, adr, len); 1223 XIP_INVAL_CACHED_RANGE(map, adr, len);
1214 ENABLE_VPP(map); 1224 ENABLE_VPP(map);
1215 xip_disable(map, chip, cmd_adr); 1225 xip_disable(map, chip, cmd_adr);
1216 1226
1217 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 1227 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
1218 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); 1228 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
1219 //cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 1229 //cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
@@ -1247,8 +1257,8 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1247 adr, map_bankwidth(map), 1257 adr, map_bankwidth(map),
1248 chip->word_write_time); 1258 chip->word_write_time);
1249 1259
1250 timeo = jiffies + uWriteTimeout; 1260 timeo = jiffies + uWriteTimeout;
1251 1261
1252 for (;;) { 1262 for (;;) {
1253 if (chip->state != FL_WRITING) { 1263 if (chip->state != FL_WRITING) {
1254 /* Someone's suspended the write. Sleep */ 1264 /* Someone's suspended the write. Sleep */
@@ -1264,13 +1274,13 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1264 continue; 1274 continue;
1265 } 1275 }
1266 1276
1277 if (time_after(jiffies, timeo) && !chip_ready(map, adr))
1278 break;
1279
1267 if (chip_ready(map, adr)) { 1280 if (chip_ready(map, adr)) {
1268 xip_enable(map, chip, adr); 1281 xip_enable(map, chip, adr);
1269 goto op_done; 1282 goto op_done;
1270 } 1283 }
1271
1272 if( time_after(jiffies, timeo))
1273 break;
1274 1284
1275 /* Latency issues. Drop the lock, wait a while and retry */ 1285 /* Latency issues. Drop the lock, wait a while and retry */
1276 UDELAY(map, chip, adr, 1); 1286 UDELAY(map, chip, adr, 1);
@@ -1342,7 +1352,7 @@ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
1342 if (size % map_bankwidth(map)) 1352 if (size % map_bankwidth(map))
1343 size -= size % map_bankwidth(map); 1353 size -= size % map_bankwidth(map);
1344 1354
1345 ret = do_write_buffer(map, &cfi->chips[chipnum], 1355 ret = do_write_buffer(map, &cfi->chips[chipnum],
1346 ofs, buf, size); 1356 ofs, buf, size);
1347 if (ret) 1357 if (ret)
1348 return ret; 1358 return ret;
@@ -1353,7 +1363,7 @@ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
1353 len -= size; 1363 len -= size;
1354 1364
1355 if (ofs >> cfi->chipshift) { 1365 if (ofs >> cfi->chipshift) {
1356 chipnum ++; 1366 chipnum ++;
1357 ofs = 0; 1367 ofs = 0;
1358 if (chipnum == cfi->numchips) 1368 if (chipnum == cfi->numchips)
1359 return 0; 1369 return 0;
@@ -1570,7 +1580,7 @@ int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
1570 1580
1571 instr->state = MTD_ERASE_DONE; 1581 instr->state = MTD_ERASE_DONE;
1572 mtd_erase_callback(instr); 1582 mtd_erase_callback(instr);
1573 1583
1574 return 0; 1584 return 0;
1575} 1585}
1576 1586
@@ -1593,7 +1603,7 @@ static int cfi_amdstd_erase_chip(struct mtd_info *mtd, struct erase_info *instr)
1593 1603
1594 instr->state = MTD_ERASE_DONE; 1604 instr->state = MTD_ERASE_DONE;
1595 mtd_erase_callback(instr); 1605 mtd_erase_callback(instr);
1596 1606
1597 return 0; 1607 return 0;
1598} 1608}
1599 1609
@@ -1620,7 +1630,7 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
1620 case FL_JEDEC_QUERY: 1630 case FL_JEDEC_QUERY:
1621 chip->oldstate = chip->state; 1631 chip->oldstate = chip->state;
1622 chip->state = FL_SYNCING; 1632 chip->state = FL_SYNCING;
1623 /* No need to wake_up() on this state change - 1633 /* No need to wake_up() on this state change -
1624 * as the whole point is that nobody can do anything 1634 * as the whole point is that nobody can do anything
1625 * with the chip now anyway. 1635 * with the chip now anyway.
1626 */ 1636 */
@@ -1631,13 +1641,13 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
1631 default: 1641 default:
1632 /* Not an idle state */ 1642 /* Not an idle state */
1633 add_wait_queue(&chip->wq, &wait); 1643 add_wait_queue(&chip->wq, &wait);
1634 1644
1635 spin_unlock(chip->mutex); 1645 spin_unlock(chip->mutex);
1636 1646
1637 schedule(); 1647 schedule();
1638 1648
1639 remove_wait_queue(&chip->wq, &wait); 1649 remove_wait_queue(&chip->wq, &wait);
1640 1650
1641 goto retry; 1651 goto retry;
1642 } 1652 }
1643 } 1653 }
@@ -1648,7 +1658,7 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
1648 chip = &cfi->chips[i]; 1658 chip = &cfi->chips[i];
1649 1659
1650 spin_lock(chip->mutex); 1660 spin_lock(chip->mutex);
1651 1661
1652 if (chip->state == FL_SYNCING) { 1662 if (chip->state == FL_SYNCING) {
1653 chip->state = chip->oldstate; 1663 chip->state = chip->oldstate;
1654 wake_up(&chip->wq); 1664 wake_up(&chip->wq);
@@ -1678,7 +1688,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
1678 case FL_JEDEC_QUERY: 1688 case FL_JEDEC_QUERY:
1679 chip->oldstate = chip->state; 1689 chip->oldstate = chip->state;
1680 chip->state = FL_PM_SUSPENDED; 1690 chip->state = FL_PM_SUSPENDED;
1681 /* No need to wake_up() on this state change - 1691 /* No need to wake_up() on this state change -
1682 * as the whole point is that nobody can do anything 1692 * as the whole point is that nobody can do anything
1683 * with the chip now anyway. 1693 * with the chip now anyway.
1684 */ 1694 */
@@ -1699,7 +1709,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
1699 chip = &cfi->chips[i]; 1709 chip = &cfi->chips[i];
1700 1710
1701 spin_lock(chip->mutex); 1711 spin_lock(chip->mutex);
1702 1712
1703 if (chip->state == FL_PM_SUSPENDED) { 1713 if (chip->state == FL_PM_SUSPENDED) {
1704 chip->state = chip->oldstate; 1714 chip->state = chip->oldstate;
1705 wake_up(&chip->wq); 1715 wake_up(&chip->wq);
@@ -1707,7 +1717,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
1707 spin_unlock(chip->mutex); 1717 spin_unlock(chip->mutex);
1708 } 1718 }
1709 } 1719 }
1710 1720
1711 return ret; 1721 return ret;
1712} 1722}
1713 1723
@@ -1720,11 +1730,11 @@ static void cfi_amdstd_resume(struct mtd_info *mtd)
1720 struct flchip *chip; 1730 struct flchip *chip;
1721 1731
1722 for (i=0; i<cfi->numchips; i++) { 1732 for (i=0; i<cfi->numchips; i++) {
1723 1733
1724 chip = &cfi->chips[i]; 1734 chip = &cfi->chips[i];
1725 1735
1726 spin_lock(chip->mutex); 1736 spin_lock(chip->mutex);
1727 1737
1728 if (chip->state == FL_PM_SUSPENDED) { 1738 if (chip->state == FL_PM_SUSPENDED) {
1729 chip->state = FL_READY; 1739 chip->state = FL_READY;
1730 map_write(map, CMD(0xF0), chip->start); 1740 map_write(map, CMD(0xF0), chip->start);
diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c
index c894f8801578..c4a19d2dc67f 100644
--- a/drivers/mtd/chips/cfi_cmdset_0020.c
+++ b/drivers/mtd/chips/cfi_cmdset_0020.c
@@ -4,8 +4,8 @@
4 * 4 *
5 * (C) 2000 Red Hat. GPL'd 5 * (C) 2000 Red Hat. GPL'd
6 * 6 *
7 * $Id: cfi_cmdset_0020.c,v 1.19 2005/07/13 15:52:45 dwmw2 Exp $ 7 * $Id: cfi_cmdset_0020.c,v 1.22 2005/11/07 11:14:22 gleixner Exp $
8 * 8 *
9 * 10/10/2000 Nicolas Pitre <nico@cam.org> 9 * 10/10/2000 Nicolas Pitre <nico@cam.org>
10 * - completely revamped method functions so they are aware and 10 * - completely revamped method functions so they are aware and
11 * independent of the flash geometry (buswidth, interleave, etc.) 11 * independent of the flash geometry (buswidth, interleave, etc.)
@@ -81,17 +81,17 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp)
81 printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported"); 81 printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported");
82 printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported"); 82 printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported");
83 for (i=9; i<32; i++) { 83 for (i=9; i<32; i++) {
84 if (extp->FeatureSupport & (1<<i)) 84 if (extp->FeatureSupport & (1<<i))
85 printk(" - Unknown Bit %X: supported\n", i); 85 printk(" - Unknown Bit %X: supported\n", i);
86 } 86 }
87 87
88 printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport); 88 printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport);
89 printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported"); 89 printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported");
90 for (i=1; i<8; i++) { 90 for (i=1; i<8; i++) {
91 if (extp->SuspendCmdSupport & (1<<i)) 91 if (extp->SuspendCmdSupport & (1<<i))
92 printk(" - Unknown Bit %X: supported\n", i); 92 printk(" - Unknown Bit %X: supported\n", i);
93 } 93 }
94 94
95 printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask); 95 printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask);
96 printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no"); 96 printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no");
97 printk(" - Valid Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no"); 97 printk(" - Valid Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no");
@@ -99,11 +99,11 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp)
99 if (extp->BlkStatusRegMask & (1<<i)) 99 if (extp->BlkStatusRegMask & (1<<i))
100 printk(" - Unknown Bit %X Active: yes\n",i); 100 printk(" - Unknown Bit %X Active: yes\n",i);
101 } 101 }
102 102
103 printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n", 103 printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n",
104 extp->VccOptimal >> 8, extp->VccOptimal & 0xf); 104 extp->VccOptimal >> 8, extp->VccOptimal & 0xf);
105 if (extp->VppOptimal) 105 if (extp->VppOptimal)
106 printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n", 106 printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n",
107 extp->VppOptimal >> 8, extp->VppOptimal & 0xf); 107 extp->VppOptimal >> 8, extp->VppOptimal & 0xf);
108} 108}
109#endif 109#endif
@@ -121,7 +121,7 @@ struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary)
121 int i; 121 int i;
122 122
123 if (cfi->cfi_mode) { 123 if (cfi->cfi_mode) {
124 /* 124 /*
125 * It's a real CFI chip, not one for which the probe 125 * It's a real CFI chip, not one for which the probe
126 * routine faked a CFI structure. So we read the feature 126 * routine faked a CFI structure. So we read the feature
127 * table from it. 127 * table from it.
@@ -133,24 +133,33 @@ struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary)
133 if (!extp) 133 if (!extp)
134 return NULL; 134 return NULL;
135 135
136 if (extp->MajorVersion != '1' ||
137 (extp->MinorVersion < '0' || extp->MinorVersion > '3')) {
138 printk(KERN_ERR " Unknown ST Microelectronics"
139 " Extended Query version %c.%c.\n",
140 extp->MajorVersion, extp->MinorVersion);
141 kfree(extp);
142 return NULL;
143 }
144
136 /* Do some byteswapping if necessary */ 145 /* Do some byteswapping if necessary */
137 extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport); 146 extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport);
138 extp->BlkStatusRegMask = cfi32_to_cpu(extp->BlkStatusRegMask); 147 extp->BlkStatusRegMask = cfi32_to_cpu(extp->BlkStatusRegMask);
139 148
140#ifdef DEBUG_CFI_FEATURES 149#ifdef DEBUG_CFI_FEATURES
141 /* Tell the user about it in lots of lovely detail */ 150 /* Tell the user about it in lots of lovely detail */
142 cfi_tell_features(extp); 151 cfi_tell_features(extp);
143#endif 152#endif
144 153
145 /* Install our own private info structure */ 154 /* Install our own private info structure */
146 cfi->cmdset_priv = extp; 155 cfi->cmdset_priv = extp;
147 } 156 }
148 157
149 for (i=0; i< cfi->numchips; i++) { 158 for (i=0; i< cfi->numchips; i++) {
150 cfi->chips[i].word_write_time = 128; 159 cfi->chips[i].word_write_time = 128;
151 cfi->chips[i].buffer_write_time = 128; 160 cfi->chips[i].buffer_write_time = 128;
152 cfi->chips[i].erase_time = 1024; 161 cfi->chips[i].erase_time = 1024;
153 } 162 }
154 163
155 return cfi_staa_setup(map); 164 return cfi_staa_setup(map);
156} 165}
@@ -178,15 +187,15 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map)
178 mtd->size = devsize * cfi->numchips; 187 mtd->size = devsize * cfi->numchips;
179 188
180 mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; 189 mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
181 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) 190 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
182 * mtd->numeraseregions, GFP_KERNEL); 191 * mtd->numeraseregions, GFP_KERNEL);
183 if (!mtd->eraseregions) { 192 if (!mtd->eraseregions) {
184 printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n"); 193 printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n");
185 kfree(cfi->cmdset_priv); 194 kfree(cfi->cmdset_priv);
186 kfree(mtd); 195 kfree(mtd);
187 return NULL; 196 return NULL;
188 } 197 }
189 198
190 for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { 199 for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
191 unsigned long ernum, ersize; 200 unsigned long ernum, ersize;
192 ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; 201 ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
@@ -219,7 +228,7 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map)
219 mtd->eraseregions[i].numblocks); 228 mtd->eraseregions[i].numblocks);
220 } 229 }
221 230
222 /* Also select the correct geometry setup too */ 231 /* Also select the correct geometry setup too */
223 mtd->erase = cfi_staa_erase_varsize; 232 mtd->erase = cfi_staa_erase_varsize;
224 mtd->read = cfi_staa_read; 233 mtd->read = cfi_staa_read;
225 mtd->write = cfi_staa_write_buffers; 234 mtd->write = cfi_staa_write_buffers;
@@ -250,8 +259,8 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
250 259
251 adr += chip->start; 260 adr += chip->start;
252 261
253 /* Ensure cmd read/writes are aligned. */ 262 /* Ensure cmd read/writes are aligned. */
254 cmd_addr = adr & ~(map_bankwidth(map)-1); 263 cmd_addr = adr & ~(map_bankwidth(map)-1);
255 264
256 /* Let's determine this according to the interleave only once */ 265 /* Let's determine this according to the interleave only once */
257 status_OK = CMD(0x80); 266 status_OK = CMD(0x80);
@@ -267,7 +276,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
267 case FL_ERASING: 276 case FL_ERASING:
268 if (!(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2)) 277 if (!(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2))
269 goto sleep; /* We don't support erase suspend */ 278 goto sleep; /* We don't support erase suspend */
270 279
271 map_write (map, CMD(0xb0), cmd_addr); 280 map_write (map, CMD(0xb0), cmd_addr);
272 /* If the flash has finished erasing, then 'erase suspend' 281 /* If the flash has finished erasing, then 'erase suspend'
273 * appears to make some (28F320) flash devices switch to 282 * appears to make some (28F320) flash devices switch to
@@ -282,7 +291,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
282 status = map_read(map, cmd_addr); 291 status = map_read(map, cmd_addr);
283 if (map_word_andequal(map, status, status_OK, status_OK)) 292 if (map_word_andequal(map, status, status_OK, status_OK))
284 break; 293 break;
285 294
286 if (time_after(jiffies, timeo)) { 295 if (time_after(jiffies, timeo)) {
287 /* Urgh */ 296 /* Urgh */
288 map_write(map, CMD(0xd0), cmd_addr); 297 map_write(map, CMD(0xd0), cmd_addr);
@@ -294,17 +303,17 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
294 "suspended: status = 0x%lx\n", status.x[0]); 303 "suspended: status = 0x%lx\n", status.x[0]);
295 return -EIO; 304 return -EIO;
296 } 305 }
297 306
298 spin_unlock_bh(chip->mutex); 307 spin_unlock_bh(chip->mutex);
299 cfi_udelay(1); 308 cfi_udelay(1);
300 spin_lock_bh(chip->mutex); 309 spin_lock_bh(chip->mutex);
301 } 310 }
302 311
303 suspended = 1; 312 suspended = 1;
304 map_write(map, CMD(0xff), cmd_addr); 313 map_write(map, CMD(0xff), cmd_addr);
305 chip->state = FL_READY; 314 chip->state = FL_READY;
306 break; 315 break;
307 316
308#if 0 317#if 0
309 case FL_WRITING: 318 case FL_WRITING:
310 /* Not quite yet */ 319 /* Not quite yet */
@@ -325,7 +334,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
325 chip->state = FL_READY; 334 chip->state = FL_READY;
326 break; 335 break;
327 } 336 }
328 337
329 /* Urgh. Chip not yet ready to talk to us. */ 338 /* Urgh. Chip not yet ready to talk to us. */
330 if (time_after(jiffies, timeo)) { 339 if (time_after(jiffies, timeo)) {
331 spin_unlock_bh(chip->mutex); 340 spin_unlock_bh(chip->mutex);
@@ -355,17 +364,17 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
355 364
356 if (suspended) { 365 if (suspended) {
357 chip->state = chip->oldstate; 366 chip->state = chip->oldstate;
358 /* What if one interleaved chip has finished and the 367 /* What if one interleaved chip has finished and the
359 other hasn't? The old code would leave the finished 368 other hasn't? The old code would leave the finished
360 one in READY mode. That's bad, and caused -EROFS 369 one in READY mode. That's bad, and caused -EROFS
361 errors to be returned from do_erase_oneblock because 370 errors to be returned from do_erase_oneblock because
362 that's the only bit it checked for at the time. 371 that's the only bit it checked for at the time.
363 As the state machine appears to explicitly allow 372 As the state machine appears to explicitly allow
364 sending the 0x70 (Read Status) command to an erasing 373 sending the 0x70 (Read Status) command to an erasing
365 chip and expecting it to be ignored, that's what we 374 chip and expecting it to be ignored, that's what we
366 do. */ 375 do. */
367 map_write(map, CMD(0xd0), cmd_addr); 376 map_write(map, CMD(0xd0), cmd_addr);
368 map_write(map, CMD(0x70), cmd_addr); 377 map_write(map, CMD(0x70), cmd_addr);
369 } 378 }
370 379
371 wake_up(&chip->wq); 380 wake_up(&chip->wq);
@@ -405,14 +414,14 @@ static int cfi_staa_read (struct mtd_info *mtd, loff_t from, size_t len, size_t
405 *retlen += thislen; 414 *retlen += thislen;
406 len -= thislen; 415 len -= thislen;
407 buf += thislen; 416 buf += thislen;
408 417
409 ofs = 0; 418 ofs = 0;
410 chipnum++; 419 chipnum++;
411 } 420 }
412 return ret; 421 return ret;
413} 422}
414 423
415static inline int do_write_buffer(struct map_info *map, struct flchip *chip, 424static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
416 unsigned long adr, const u_char *buf, int len) 425 unsigned long adr, const u_char *buf, int len)
417{ 426{
418 struct cfi_private *cfi = map->fldrv_priv; 427 struct cfi_private *cfi = map->fldrv_priv;
@@ -420,7 +429,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
420 unsigned long cmd_adr, timeo; 429 unsigned long cmd_adr, timeo;
421 DECLARE_WAITQUEUE(wait, current); 430 DECLARE_WAITQUEUE(wait, current);
422 int wbufsize, z; 431 int wbufsize, z;
423 432
424 /* M58LW064A requires bus alignment for buffer wriets -- saw */ 433 /* M58LW064A requires bus alignment for buffer wriets -- saw */
425 if (adr & (map_bankwidth(map)-1)) 434 if (adr & (map_bankwidth(map)-1))
426 return -EINVAL; 435 return -EINVAL;
@@ -428,10 +437,10 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
428 wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; 437 wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
429 adr += chip->start; 438 adr += chip->start;
430 cmd_adr = adr & ~(wbufsize-1); 439 cmd_adr = adr & ~(wbufsize-1);
431 440
432 /* Let's determine this according to the interleave only once */ 441 /* Let's determine this according to the interleave only once */
433 status_OK = CMD(0x80); 442 status_OK = CMD(0x80);
434 443
435 timeo = jiffies + HZ; 444 timeo = jiffies + HZ;
436 retry: 445 retry:
437 446
@@ -439,7 +448,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
439 printk("%s: chip->state[%d]\n", __FUNCTION__, chip->state); 448 printk("%s: chip->state[%d]\n", __FUNCTION__, chip->state);
440#endif 449#endif
441 spin_lock_bh(chip->mutex); 450 spin_lock_bh(chip->mutex);
442 451
443 /* Check that the chip's ready to talk to us. 452 /* Check that the chip's ready to talk to us.
444 * Later, we can actually think about interrupting it 453 * Later, we can actually think about interrupting it
445 * if it's in FL_ERASING state. 454 * if it's in FL_ERASING state.
@@ -448,7 +457,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
448 switch (chip->state) { 457 switch (chip->state) {
449 case FL_READY: 458 case FL_READY:
450 break; 459 break;
451 460
452 case FL_CFI_QUERY: 461 case FL_CFI_QUERY:
453 case FL_JEDEC_QUERY: 462 case FL_JEDEC_QUERY:
454 map_write(map, CMD(0x70), cmd_adr); 463 map_write(map, CMD(0x70), cmd_adr);
@@ -513,7 +522,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
513 522
514 /* Write length of data to come */ 523 /* Write length of data to come */
515 map_write(map, CMD(len/map_bankwidth(map)-1), cmd_adr ); 524 map_write(map, CMD(len/map_bankwidth(map)-1), cmd_adr );
516 525
517 /* Write data */ 526 /* Write data */
518 for (z = 0; z < len; 527 for (z = 0; z < len;
519 z += map_bankwidth(map), buf += map_bankwidth(map)) { 528 z += map_bankwidth(map), buf += map_bankwidth(map)) {
@@ -560,7 +569,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
560 printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n"); 569 printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n");
561 return -EIO; 570 return -EIO;
562 } 571 }
563 572
564 /* Latency issues. Drop the lock, wait a while and retry */ 573 /* Latency issues. Drop the lock, wait a while and retry */
565 spin_unlock_bh(chip->mutex); 574 spin_unlock_bh(chip->mutex);
566 cfi_udelay(1); 575 cfi_udelay(1);
@@ -572,9 +581,9 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
572 if (!chip->buffer_write_time) 581 if (!chip->buffer_write_time)
573 chip->buffer_write_time++; 582 chip->buffer_write_time++;
574 } 583 }
575 if (z > 1) 584 if (z > 1)
576 chip->buffer_write_time++; 585 chip->buffer_write_time++;
577 586
578 /* Done and happy. */ 587 /* Done and happy. */
579 DISABLE_VPP(map); 588 DISABLE_VPP(map);
580 chip->state = FL_STATUS; 589 chip->state = FL_STATUS;
@@ -598,7 +607,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
598 return 0; 607 return 0;
599} 608}
600 609
601static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to, 610static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
602 size_t len, size_t *retlen, const u_char *buf) 611 size_t len, size_t *retlen, const u_char *buf)
603{ 612{
604 struct map_info *map = mtd->priv; 613 struct map_info *map = mtd->priv;
@@ -620,7 +629,7 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
620 printk("%s: chipnum[%x] wbufsize[%x]\n", __FUNCTION__, chipnum, wbufsize); 629 printk("%s: chipnum[%x] wbufsize[%x]\n", __FUNCTION__, chipnum, wbufsize);
621 printk("%s: ofs[%x] len[%x]\n", __FUNCTION__, ofs, len); 630 printk("%s: ofs[%x] len[%x]\n", __FUNCTION__, ofs, len);
622#endif 631#endif
623 632
624 /* Write buffer is worth it only if more than one word to write... */ 633 /* Write buffer is worth it only if more than one word to write... */
625 while (len > 0) { 634 while (len > 0) {
626 /* We must not cross write block boundaries */ 635 /* We must not cross write block boundaries */
@@ -629,7 +638,7 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
629 if (size > len) 638 if (size > len)
630 size = len; 639 size = len;
631 640
632 ret = do_write_buffer(map, &cfi->chips[chipnum], 641 ret = do_write_buffer(map, &cfi->chips[chipnum],
633 ofs, buf, size); 642 ofs, buf, size);
634 if (ret) 643 if (ret)
635 return ret; 644 return ret;
@@ -640,13 +649,13 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
640 len -= size; 649 len -= size;
641 650
642 if (ofs >> cfi->chipshift) { 651 if (ofs >> cfi->chipshift) {
643 chipnum ++; 652 chipnum ++;
644 ofs = 0; 653 ofs = 0;
645 if (chipnum == cfi->numchips) 654 if (chipnum == cfi->numchips)
646 return 0; 655 return 0;
647 } 656 }
648 } 657 }
649 658
650 return 0; 659 return 0;
651} 660}
652 661
@@ -756,7 +765,7 @@ retry:
756 status = map_read(map, adr); 765 status = map_read(map, adr);
757 if (map_word_andequal(map, status, status_OK, status_OK)) 766 if (map_word_andequal(map, status, status_OK, status_OK))
758 break; 767 break;
759 768
760 /* Urgh. Chip not yet ready to talk to us. */ 769 /* Urgh. Chip not yet ready to talk to us. */
761 if (time_after(jiffies, timeo)) { 770 if (time_after(jiffies, timeo)) {
762 spin_unlock_bh(chip->mutex); 771 spin_unlock_bh(chip->mutex);
@@ -789,7 +798,7 @@ retry:
789 map_write(map, CMD(0x20), adr); 798 map_write(map, CMD(0x20), adr);
790 map_write(map, CMD(0xD0), adr); 799 map_write(map, CMD(0xD0), adr);
791 chip->state = FL_ERASING; 800 chip->state = FL_ERASING;
792 801
793 spin_unlock_bh(chip->mutex); 802 spin_unlock_bh(chip->mutex);
794 msleep(1000); 803 msleep(1000);
795 spin_lock_bh(chip->mutex); 804 spin_lock_bh(chip->mutex);
@@ -814,7 +823,7 @@ retry:
814 status = map_read(map, adr); 823 status = map_read(map, adr);
815 if (map_word_andequal(map, status, status_OK, status_OK)) 824 if (map_word_andequal(map, status, status_OK, status_OK))
816 break; 825 break;
817 826
818 /* OK Still waiting */ 827 /* OK Still waiting */
819 if (time_after(jiffies, timeo)) { 828 if (time_after(jiffies, timeo)) {
820 map_write(map, CMD(0x70), adr); 829 map_write(map, CMD(0x70), adr);
@@ -824,13 +833,13 @@ retry:
824 spin_unlock_bh(chip->mutex); 833 spin_unlock_bh(chip->mutex);
825 return -EIO; 834 return -EIO;
826 } 835 }
827 836
828 /* Latency issues. Drop the lock, wait a while and retry */ 837 /* Latency issues. Drop the lock, wait a while and retry */
829 spin_unlock_bh(chip->mutex); 838 spin_unlock_bh(chip->mutex);
830 cfi_udelay(1); 839 cfi_udelay(1);
831 spin_lock_bh(chip->mutex); 840 spin_lock_bh(chip->mutex);
832 } 841 }
833 842
834 DISABLE_VPP(map); 843 DISABLE_VPP(map);
835 ret = 0; 844 ret = 0;
836 845
@@ -855,7 +864,7 @@ retry:
855 /* Reset the error bits */ 864 /* Reset the error bits */
856 map_write(map, CMD(0x50), adr); 865 map_write(map, CMD(0x50), adr);
857 map_write(map, CMD(0x70), adr); 866 map_write(map, CMD(0x70), adr);
858 867
859 if ((chipstatus & 0x30) == 0x30) { 868 if ((chipstatus & 0x30) == 0x30) {
860 printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%x\n", chipstatus); 869 printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%x\n", chipstatus);
861 ret = -EIO; 870 ret = -EIO;
@@ -904,17 +913,17 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
904 913
905 i = 0; 914 i = 0;
906 915
907 /* Skip all erase regions which are ended before the start of 916 /* Skip all erase regions which are ended before the start of
908 the requested erase. Actually, to save on the calculations, 917 the requested erase. Actually, to save on the calculations,
909 we skip to the first erase region which starts after the 918 we skip to the first erase region which starts after the
910 start of the requested erase, and then go back one. 919 start of the requested erase, and then go back one.
911 */ 920 */
912 921
913 while (i < mtd->numeraseregions && instr->addr >= regions[i].offset) 922 while (i < mtd->numeraseregions && instr->addr >= regions[i].offset)
914 i++; 923 i++;
915 i--; 924 i--;
916 925
917 /* OK, now i is pointing at the erase region in which this 926 /* OK, now i is pointing at the erase region in which this
918 erase request starts. Check the start of the requested 927 erase request starts. Check the start of the requested
919 erase range is aligned with the erase size which is in 928 erase range is aligned with the erase size which is in
920 effect here. 929 effect here.
@@ -937,7 +946,7 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
937 the address actually falls 946 the address actually falls
938 */ 947 */
939 i--; 948 i--;
940 949
941 if ((instr->addr + instr->len) & (regions[i].erasesize-1)) 950 if ((instr->addr + instr->len) & (regions[i].erasesize-1))
942 return -EINVAL; 951 return -EINVAL;
943 952
@@ -949,7 +958,7 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
949 958
950 while(len) { 959 while(len) {
951 ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr); 960 ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr);
952 961
953 if (ret) 962 if (ret)
954 return ret; 963 return ret;
955 964
@@ -962,15 +971,15 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
962 if (adr >> cfi->chipshift) { 971 if (adr >> cfi->chipshift) {
963 adr = 0; 972 adr = 0;
964 chipnum++; 973 chipnum++;
965 974
966 if (chipnum >= cfi->numchips) 975 if (chipnum >= cfi->numchips)
967 break; 976 break;
968 } 977 }
969 } 978 }
970 979
971 instr->state = MTD_ERASE_DONE; 980 instr->state = MTD_ERASE_DONE;
972 mtd_erase_callback(instr); 981 mtd_erase_callback(instr);
973 982
974 return 0; 983 return 0;
975} 984}
976 985
@@ -996,7 +1005,7 @@ static void cfi_staa_sync (struct mtd_info *mtd)
996 case FL_JEDEC_QUERY: 1005 case FL_JEDEC_QUERY:
997 chip->oldstate = chip->state; 1006 chip->oldstate = chip->state;
998 chip->state = FL_SYNCING; 1007 chip->state = FL_SYNCING;
999 /* No need to wake_up() on this state change - 1008 /* No need to wake_up() on this state change -
1000 * as the whole point is that nobody can do anything 1009 * as the whole point is that nobody can do anything
1001 * with the chip now anyway. 1010 * with the chip now anyway.
1002 */ 1011 */
@@ -1007,11 +1016,11 @@ static void cfi_staa_sync (struct mtd_info *mtd)
1007 default: 1016 default:
1008 /* Not an idle state */ 1017 /* Not an idle state */
1009 add_wait_queue(&chip->wq, &wait); 1018 add_wait_queue(&chip->wq, &wait);
1010 1019
1011 spin_unlock_bh(chip->mutex); 1020 spin_unlock_bh(chip->mutex);
1012 schedule(); 1021 schedule();
1013 remove_wait_queue(&chip->wq, &wait); 1022 remove_wait_queue(&chip->wq, &wait);
1014 1023
1015 goto retry; 1024 goto retry;
1016 } 1025 }
1017 } 1026 }
@@ -1022,7 +1031,7 @@ static void cfi_staa_sync (struct mtd_info *mtd)
1022 chip = &cfi->chips[i]; 1031 chip = &cfi->chips[i];
1023 1032
1024 spin_lock_bh(chip->mutex); 1033 spin_lock_bh(chip->mutex);
1025 1034
1026 if (chip->state == FL_SYNCING) { 1035 if (chip->state == FL_SYNCING) {
1027 chip->state = chip->oldstate; 1036 chip->state = chip->oldstate;
1028 wake_up(&chip->wq); 1037 wake_up(&chip->wq);
@@ -1057,9 +1066,9 @@ retry:
1057 1066
1058 case FL_STATUS: 1067 case FL_STATUS:
1059 status = map_read(map, adr); 1068 status = map_read(map, adr);
1060 if (map_word_andequal(map, status, status_OK, status_OK)) 1069 if (map_word_andequal(map, status, status_OK, status_OK))
1061 break; 1070 break;
1062 1071
1063 /* Urgh. Chip not yet ready to talk to us. */ 1072 /* Urgh. Chip not yet ready to talk to us. */
1064 if (time_after(jiffies, timeo)) { 1073 if (time_after(jiffies, timeo)) {
1065 spin_unlock_bh(chip->mutex); 1074 spin_unlock_bh(chip->mutex);
@@ -1088,7 +1097,7 @@ retry:
1088 map_write(map, CMD(0x60), adr); 1097 map_write(map, CMD(0x60), adr);
1089 map_write(map, CMD(0x01), adr); 1098 map_write(map, CMD(0x01), adr);
1090 chip->state = FL_LOCKING; 1099 chip->state = FL_LOCKING;
1091 1100
1092 spin_unlock_bh(chip->mutex); 1101 spin_unlock_bh(chip->mutex);
1093 msleep(1000); 1102 msleep(1000);
1094 spin_lock_bh(chip->mutex); 1103 spin_lock_bh(chip->mutex);
@@ -1102,7 +1111,7 @@ retry:
1102 status = map_read(map, adr); 1111 status = map_read(map, adr);
1103 if (map_word_andequal(map, status, status_OK, status_OK)) 1112 if (map_word_andequal(map, status, status_OK, status_OK))
1104 break; 1113 break;
1105 1114
1106 /* OK Still waiting */ 1115 /* OK Still waiting */
1107 if (time_after(jiffies, timeo)) { 1116 if (time_after(jiffies, timeo)) {
1108 map_write(map, CMD(0x70), adr); 1117 map_write(map, CMD(0x70), adr);
@@ -1112,13 +1121,13 @@ retry:
1112 spin_unlock_bh(chip->mutex); 1121 spin_unlock_bh(chip->mutex);
1113 return -EIO; 1122 return -EIO;
1114 } 1123 }
1115 1124
1116 /* Latency issues. Drop the lock, wait a while and retry */ 1125 /* Latency issues. Drop the lock, wait a while and retry */
1117 spin_unlock_bh(chip->mutex); 1126 spin_unlock_bh(chip->mutex);
1118 cfi_udelay(1); 1127 cfi_udelay(1);
1119 spin_lock_bh(chip->mutex); 1128 spin_lock_bh(chip->mutex);
1120 } 1129 }
1121 1130
1122 /* Done and happy. */ 1131 /* Done and happy. */
1123 chip->state = FL_STATUS; 1132 chip->state = FL_STATUS;
1124 DISABLE_VPP(map); 1133 DISABLE_VPP(map);
@@ -1162,8 +1171,8 @@ static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
1162 cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL); 1171 cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
1163 printk("after lock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor))); 1172 printk("after lock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor)));
1164 cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL); 1173 cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
1165#endif 1174#endif
1166 1175
1167 if (ret) 1176 if (ret)
1168 return ret; 1177 return ret;
1169 1178
@@ -1173,7 +1182,7 @@ static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
1173 if (adr >> cfi->chipshift) { 1182 if (adr >> cfi->chipshift) {
1174 adr = 0; 1183 adr = 0;
1175 chipnum++; 1184 chipnum++;
1176 1185
1177 if (chipnum >= cfi->numchips) 1186 if (chipnum >= cfi->numchips)
1178 break; 1187 break;
1179 } 1188 }
@@ -1208,7 +1217,7 @@ retry:
1208 status = map_read(map, adr); 1217 status = map_read(map, adr);
1209 if (map_word_andequal(map, status, status_OK, status_OK)) 1218 if (map_word_andequal(map, status, status_OK, status_OK))
1210 break; 1219 break;
1211 1220
1212 /* Urgh. Chip not yet ready to talk to us. */ 1221 /* Urgh. Chip not yet ready to talk to us. */
1213 if (time_after(jiffies, timeo)) { 1222 if (time_after(jiffies, timeo)) {
1214 spin_unlock_bh(chip->mutex); 1223 spin_unlock_bh(chip->mutex);
@@ -1237,7 +1246,7 @@ retry:
1237 map_write(map, CMD(0x60), adr); 1246 map_write(map, CMD(0x60), adr);
1238 map_write(map, CMD(0xD0), adr); 1247 map_write(map, CMD(0xD0), adr);
1239 chip->state = FL_UNLOCKING; 1248 chip->state = FL_UNLOCKING;
1240 1249
1241 spin_unlock_bh(chip->mutex); 1250 spin_unlock_bh(chip->mutex);
1242 msleep(1000); 1251 msleep(1000);
1243 spin_lock_bh(chip->mutex); 1252 spin_lock_bh(chip->mutex);
@@ -1251,7 +1260,7 @@ retry:
1251 status = map_read(map, adr); 1260 status = map_read(map, adr);
1252 if (map_word_andequal(map, status, status_OK, status_OK)) 1261 if (map_word_andequal(map, status, status_OK, status_OK))
1253 break; 1262 break;
1254 1263
1255 /* OK Still waiting */ 1264 /* OK Still waiting */
1256 if (time_after(jiffies, timeo)) { 1265 if (time_after(jiffies, timeo)) {
1257 map_write(map, CMD(0x70), adr); 1266 map_write(map, CMD(0x70), adr);
@@ -1261,13 +1270,13 @@ retry:
1261 spin_unlock_bh(chip->mutex); 1270 spin_unlock_bh(chip->mutex);
1262 return -EIO; 1271 return -EIO;
1263 } 1272 }
1264 1273
1265 /* Latency issues. Drop the unlock, wait a while and retry */ 1274 /* Latency issues. Drop the unlock, wait a while and retry */
1266 spin_unlock_bh(chip->mutex); 1275 spin_unlock_bh(chip->mutex);
1267 cfi_udelay(1); 1276 cfi_udelay(1);
1268 spin_lock_bh(chip->mutex); 1277 spin_lock_bh(chip->mutex);
1269 } 1278 }
1270 1279
1271 /* Done and happy. */ 1280 /* Done and happy. */
1272 chip->state = FL_STATUS; 1281 chip->state = FL_STATUS;
1273 DISABLE_VPP(map); 1282 DISABLE_VPP(map);
@@ -1292,7 +1301,7 @@ static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1292 { 1301 {
1293 unsigned long temp_adr = adr; 1302 unsigned long temp_adr = adr;
1294 unsigned long temp_len = len; 1303 unsigned long temp_len = len;
1295 1304
1296 cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL); 1305 cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
1297 while (temp_len) { 1306 while (temp_len) {
1298 printk("before unlock %x: block status register is %x\n",temp_adr,cfi_read_query(map, temp_adr+(2*ofs_factor))); 1307 printk("before unlock %x: block status register is %x\n",temp_adr,cfi_read_query(map, temp_adr+(2*ofs_factor)));
@@ -1310,7 +1319,7 @@ static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1310 printk("after unlock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor))); 1319 printk("after unlock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor)));
1311 cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL); 1320 cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
1312#endif 1321#endif
1313 1322
1314 return ret; 1323 return ret;
1315} 1324}
1316 1325
@@ -1334,7 +1343,7 @@ static int cfi_staa_suspend(struct mtd_info *mtd)
1334 case FL_JEDEC_QUERY: 1343 case FL_JEDEC_QUERY:
1335 chip->oldstate = chip->state; 1344 chip->oldstate = chip->state;
1336 chip->state = FL_PM_SUSPENDED; 1345 chip->state = FL_PM_SUSPENDED;
1337 /* No need to wake_up() on this state change - 1346 /* No need to wake_up() on this state change -
1338 * as the whole point is that nobody can do anything 1347 * as the whole point is that nobody can do anything
1339 * with the chip now anyway. 1348 * with the chip now anyway.
1340 */ 1349 */
@@ -1353,9 +1362,9 @@ static int cfi_staa_suspend(struct mtd_info *mtd)
1353 if (ret) { 1362 if (ret) {
1354 for (i--; i >=0; i--) { 1363 for (i--; i >=0; i--) {
1355 chip = &cfi->chips[i]; 1364 chip = &cfi->chips[i];
1356 1365
1357 spin_lock_bh(chip->mutex); 1366 spin_lock_bh(chip->mutex);
1358 1367
1359 if (chip->state == FL_PM_SUSPENDED) { 1368 if (chip->state == FL_PM_SUSPENDED) {
1360 /* No need to force it into a known state here, 1369 /* No need to force it into a known state here,
1361 because we're returning failure, and it didn't 1370 because we're returning failure, and it didn't
@@ -1365,8 +1374,8 @@ static int cfi_staa_suspend(struct mtd_info *mtd)
1365 } 1374 }
1366 spin_unlock_bh(chip->mutex); 1375 spin_unlock_bh(chip->mutex);
1367 } 1376 }
1368 } 1377 }
1369 1378
1370 return ret; 1379 return ret;
1371} 1380}
1372 1381
@@ -1378,11 +1387,11 @@ static void cfi_staa_resume(struct mtd_info *mtd)
1378 struct flchip *chip; 1387 struct flchip *chip;
1379 1388
1380 for (i=0; i<cfi->numchips; i++) { 1389 for (i=0; i<cfi->numchips; i++) {
1381 1390
1382 chip = &cfi->chips[i]; 1391 chip = &cfi->chips[i];
1383 1392
1384 spin_lock_bh(chip->mutex); 1393 spin_lock_bh(chip->mutex);
1385 1394
1386 /* Go to known state. Chip may have been power cycled */ 1395 /* Go to known state. Chip may have been power cycled */
1387 if (chip->state == FL_PM_SUSPENDED) { 1396 if (chip->state == FL_PM_SUSPENDED) {
1388 map_write(map, CMD(0xFF), 0); 1397 map_write(map, CMD(0xFF), 0);
diff --git a/drivers/mtd/chips/cfi_probe.c b/drivers/mtd/chips/cfi_probe.c
index cf750038ce6a..90eb30e06b7c 100644
--- a/drivers/mtd/chips/cfi_probe.c
+++ b/drivers/mtd/chips/cfi_probe.c
@@ -1,7 +1,7 @@
1/* 1/*
2 Common Flash Interface probe code. 2 Common Flash Interface probe code.
3 (C) 2000 Red Hat. GPL'd. 3 (C) 2000 Red Hat. GPL'd.
4 $Id: cfi_probe.c,v 1.83 2004/11/16 18:19:02 nico Exp $ 4 $Id: cfi_probe.c,v 1.84 2005/11/07 11:14:23 gleixner Exp $
5*/ 5*/
6 6
7#include <linux/config.h> 7#include <linux/config.h>
@@ -20,7 +20,7 @@
20#include <linux/mtd/cfi.h> 20#include <linux/mtd/cfi.h>
21#include <linux/mtd/gen_probe.h> 21#include <linux/mtd/gen_probe.h>
22 22
23//#define DEBUG_CFI 23//#define DEBUG_CFI
24 24
25#ifdef DEBUG_CFI 25#ifdef DEBUG_CFI
26static void print_cfi_ident(struct cfi_ident *); 26static void print_cfi_ident(struct cfi_ident *);
@@ -103,7 +103,7 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
103 unsigned long *chip_map, struct cfi_private *cfi) 103 unsigned long *chip_map, struct cfi_private *cfi)
104{ 104{
105 int i; 105 int i;
106 106
107 if ((base + 0) >= map->size) { 107 if ((base + 0) >= map->size) {
108 printk(KERN_NOTICE 108 printk(KERN_NOTICE
109 "Probe at base[0x00](0x%08lx) past the end of the map(0x%08lx)\n", 109 "Probe at base[0x00](0x%08lx) past the end of the map(0x%08lx)\n",
@@ -128,7 +128,7 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
128 } 128 }
129 129
130 if (!cfi->numchips) { 130 if (!cfi->numchips) {
131 /* This is the first time we're called. Set up the CFI 131 /* This is the first time we're called. Set up the CFI
132 stuff accordingly and return */ 132 stuff accordingly and return */
133 return cfi_chip_setup(map, cfi); 133 return cfi_chip_setup(map, cfi);
134 } 134 }
@@ -138,13 +138,13 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
138 unsigned long start; 138 unsigned long start;
139 if(!test_bit(i, chip_map)) { 139 if(!test_bit(i, chip_map)) {
140 /* Skip location; no valid chip at this address */ 140 /* Skip location; no valid chip at this address */
141 continue; 141 continue;
142 } 142 }
143 start = i << cfi->chipshift; 143 start = i << cfi->chipshift;
144 /* This chip should be in read mode if it's one 144 /* This chip should be in read mode if it's one
145 we've already touched. */ 145 we've already touched. */
146 if (qry_present(map, start, cfi)) { 146 if (qry_present(map, start, cfi)) {
147 /* Eep. This chip also had the QRY marker. 147 /* Eep. This chip also had the QRY marker.
148 * Is it an alias for the new one? */ 148 * Is it an alias for the new one? */
149 cfi_send_gen_cmd(0xF0, 0, start, map, cfi, cfi->device_type, NULL); 149 cfi_send_gen_cmd(0xF0, 0, start, map, cfi, cfi->device_type, NULL);
150 cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL); 150 cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL);
@@ -156,13 +156,13 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
156 map->name, base, start); 156 map->name, base, start);
157 return 0; 157 return 0;
158 } 158 }
159 /* Yes, it's actually got QRY for data. Most 159 /* Yes, it's actually got QRY for data. Most
160 * unfortunate. Stick the new chip in read mode 160 * unfortunate. Stick the new chip in read mode
161 * too and if it's the same, assume it's an alias. */ 161 * too and if it's the same, assume it's an alias. */
162 /* FIXME: Use other modes to do a proper check */ 162 /* FIXME: Use other modes to do a proper check */
163 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); 163 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
164 cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL); 164 cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL);
165 165
166 if (qry_present(map, base, cfi)) { 166 if (qry_present(map, base, cfi)) {
167 xip_allowed(base, map); 167 xip_allowed(base, map);
168 printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n", 168 printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
@@ -171,12 +171,12 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
171 } 171 }
172 } 172 }
173 } 173 }
174 174
175 /* OK, if we got to here, then none of the previous chips appear to 175 /* OK, if we got to here, then none of the previous chips appear to
176 be aliases for the current one. */ 176 be aliases for the current one. */
177 set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */ 177 set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */
178 cfi->numchips++; 178 cfi->numchips++;
179 179
180 /* Put it back into Read Mode */ 180 /* Put it back into Read Mode */
181 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); 181 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
182 cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); 182 cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
@@ -185,11 +185,11 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
185 printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n", 185 printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n",
186 map->name, cfi->interleave, cfi->device_type*8, base, 186 map->name, cfi->interleave, cfi->device_type*8, base,
187 map->bankwidth*8); 187 map->bankwidth*8);
188 188
189 return 1; 189 return 1;
190} 190}
191 191
192static int __xipram cfi_chip_setup(struct map_info *map, 192static int __xipram cfi_chip_setup(struct map_info *map,
193 struct cfi_private *cfi) 193 struct cfi_private *cfi)
194{ 194{
195 int ofs_factor = cfi->interleave*cfi->device_type; 195 int ofs_factor = cfi->interleave*cfi->device_type;
@@ -209,11 +209,11 @@ static int __xipram cfi_chip_setup(struct map_info *map,
209 printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name); 209 printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
210 return 0; 210 return 0;
211 } 211 }
212 212
213 memset(cfi->cfiq,0,sizeof(struct cfi_ident)); 213 memset(cfi->cfiq,0,sizeof(struct cfi_ident));
214 214
215 cfi->cfi_mode = CFI_MODE_CFI; 215 cfi->cfi_mode = CFI_MODE_CFI;
216 216
217 /* Read the CFI info structure */ 217 /* Read the CFI info structure */
218 xip_disable_qry(base, map, cfi); 218 xip_disable_qry(base, map, cfi);
219 for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++) 219 for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++)
@@ -231,7 +231,7 @@ static int __xipram cfi_chip_setup(struct map_info *map,
231 cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL); 231 cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL);
232 cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL); 232 cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL);
233 cfi->mfr = cfi_read_query(map, base); 233 cfi->mfr = cfi_read_query(map, base);
234 cfi->id = cfi_read_query(map, base + ofs_factor); 234 cfi->id = cfi_read_query(map, base + ofs_factor);
235 235
236 /* Put it back into Read Mode */ 236 /* Put it back into Read Mode */
237 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); 237 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
@@ -255,10 +255,10 @@ static int __xipram cfi_chip_setup(struct map_info *map,
255 255
256 for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { 256 for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
257 cfi->cfiq->EraseRegionInfo[i] = le32_to_cpu(cfi->cfiq->EraseRegionInfo[i]); 257 cfi->cfiq->EraseRegionInfo[i] = le32_to_cpu(cfi->cfiq->EraseRegionInfo[i]);
258 258
259#ifdef DEBUG_CFI 259#ifdef DEBUG_CFI
260 printk(" Erase Region #%d: BlockSize 0x%4.4X bytes, %d blocks\n", 260 printk(" Erase Region #%d: BlockSize 0x%4.4X bytes, %d blocks\n",
261 i, (cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff, 261 i, (cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff,
262 (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1); 262 (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1);
263#endif 263#endif
264 } 264 }
@@ -271,33 +271,33 @@ static int __xipram cfi_chip_setup(struct map_info *map,
271} 271}
272 272
273#ifdef DEBUG_CFI 273#ifdef DEBUG_CFI
274static char *vendorname(__u16 vendor) 274static char *vendorname(__u16 vendor)
275{ 275{
276 switch (vendor) { 276 switch (vendor) {
277 case P_ID_NONE: 277 case P_ID_NONE:
278 return "None"; 278 return "None";
279 279
280 case P_ID_INTEL_EXT: 280 case P_ID_INTEL_EXT:
281 return "Intel/Sharp Extended"; 281 return "Intel/Sharp Extended";
282 282
283 case P_ID_AMD_STD: 283 case P_ID_AMD_STD:
284 return "AMD/Fujitsu Standard"; 284 return "AMD/Fujitsu Standard";
285 285
286 case P_ID_INTEL_STD: 286 case P_ID_INTEL_STD:
287 return "Intel/Sharp Standard"; 287 return "Intel/Sharp Standard";
288 288
289 case P_ID_AMD_EXT: 289 case P_ID_AMD_EXT:
290 return "AMD/Fujitsu Extended"; 290 return "AMD/Fujitsu Extended";
291 291
292 case P_ID_WINBOND: 292 case P_ID_WINBOND:
293 return "Winbond Standard"; 293 return "Winbond Standard";
294 294
295 case P_ID_ST_ADV: 295 case P_ID_ST_ADV:
296 return "ST Advanced"; 296 return "ST Advanced";
297 297
298 case P_ID_MITSUBISHI_STD: 298 case P_ID_MITSUBISHI_STD:
299 return "Mitsubishi Standard"; 299 return "Mitsubishi Standard";
300 300
301 case P_ID_MITSUBISHI_EXT: 301 case P_ID_MITSUBISHI_EXT:
302 return "Mitsubishi Extended"; 302 return "Mitsubishi Extended";
303 303
@@ -306,13 +306,13 @@ static char *vendorname(__u16 vendor)
306 306
307 case P_ID_INTEL_PERFORMANCE: 307 case P_ID_INTEL_PERFORMANCE:
308 return "Intel Performance Code"; 308 return "Intel Performance Code";
309 309
310 case P_ID_INTEL_DATA: 310 case P_ID_INTEL_DATA:
311 return "Intel Data"; 311 return "Intel Data";
312 312
313 case P_ID_RESERVED: 313 case P_ID_RESERVED:
314 return "Not Allowed / Reserved for Future Use"; 314 return "Not Allowed / Reserved for Future Use";
315 315
316 default: 316 default:
317 return "Unknown"; 317 return "Unknown";
318 } 318 }
@@ -325,21 +325,21 @@ static void print_cfi_ident(struct cfi_ident *cfip)
325 if (cfip->qry[0] != 'Q' || cfip->qry[1] != 'R' || cfip->qry[2] != 'Y') { 325 if (cfip->qry[0] != 'Q' || cfip->qry[1] != 'R' || cfip->qry[2] != 'Y') {
326 printk("Invalid CFI ident structure.\n"); 326 printk("Invalid CFI ident structure.\n");
327 return; 327 return;
328 } 328 }
329#endif 329#endif
330 printk("Primary Vendor Command Set: %4.4X (%s)\n", cfip->P_ID, vendorname(cfip->P_ID)); 330 printk("Primary Vendor Command Set: %4.4X (%s)\n", cfip->P_ID, vendorname(cfip->P_ID));
331 if (cfip->P_ADR) 331 if (cfip->P_ADR)
332 printk("Primary Algorithm Table at %4.4X\n", cfip->P_ADR); 332 printk("Primary Algorithm Table at %4.4X\n", cfip->P_ADR);
333 else 333 else
334 printk("No Primary Algorithm Table\n"); 334 printk("No Primary Algorithm Table\n");
335 335
336 printk("Alternative Vendor Command Set: %4.4X (%s)\n", cfip->A_ID, vendorname(cfip->A_ID)); 336 printk("Alternative Vendor Command Set: %4.4X (%s)\n", cfip->A_ID, vendorname(cfip->A_ID));
337 if (cfip->A_ADR) 337 if (cfip->A_ADR)
338 printk("Alternate Algorithm Table at %4.4X\n", cfip->A_ADR); 338 printk("Alternate Algorithm Table at %4.4X\n", cfip->A_ADR);
339 else 339 else
340 printk("No Alternate Algorithm Table\n"); 340 printk("No Alternate Algorithm Table\n");
341 341
342 342
343 printk("Vcc Minimum: %2d.%d V\n", cfip->VccMin >> 4, cfip->VccMin & 0xf); 343 printk("Vcc Minimum: %2d.%d V\n", cfip->VccMin >> 4, cfip->VccMin & 0xf);
344 printk("Vcc Maximum: %2d.%d V\n", cfip->VccMax >> 4, cfip->VccMax & 0xf); 344 printk("Vcc Maximum: %2d.%d V\n", cfip->VccMax >> 4, cfip->VccMax & 0xf);
345 if (cfip->VppMin) { 345 if (cfip->VppMin) {
@@ -348,61 +348,61 @@ static void print_cfi_ident(struct cfi_ident *cfip)
348 } 348 }
349 else 349 else
350 printk("No Vpp line\n"); 350 printk("No Vpp line\n");
351 351
352 printk("Typical byte/word write timeout: %d µs\n", 1<<cfip->WordWriteTimeoutTyp); 352 printk("Typical byte/word write timeout: %d µs\n", 1<<cfip->WordWriteTimeoutTyp);
353 printk("Maximum byte/word write timeout: %d µs\n", (1<<cfip->WordWriteTimeoutMax) * (1<<cfip->WordWriteTimeoutTyp)); 353 printk("Maximum byte/word write timeout: %d µs\n", (1<<cfip->WordWriteTimeoutMax) * (1<<cfip->WordWriteTimeoutTyp));
354 354
355 if (cfip->BufWriteTimeoutTyp || cfip->BufWriteTimeoutMax) { 355 if (cfip->BufWriteTimeoutTyp || cfip->BufWriteTimeoutMax) {
356 printk("Typical full buffer write timeout: %d µs\n", 1<<cfip->BufWriteTimeoutTyp); 356 printk("Typical full buffer write timeout: %d µs\n", 1<<cfip->BufWriteTimeoutTyp);
357 printk("Maximum full buffer write timeout: %d µs\n", (1<<cfip->BufWriteTimeoutMax) * (1<<cfip->BufWriteTimeoutTyp)); 357 printk("Maximum full buffer write timeout: %d µs\n", (1<<cfip->BufWriteTimeoutMax) * (1<<cfip->BufWriteTimeoutTyp));
358 } 358 }
359 else 359 else
360 printk("Full buffer write not supported\n"); 360 printk("Full buffer write not supported\n");
361 361
362 printk("Typical block erase timeout: %d ms\n", 1<<cfip->BlockEraseTimeoutTyp); 362 printk("Typical block erase timeout: %d ms\n", 1<<cfip->BlockEraseTimeoutTyp);
363 printk("Maximum block erase timeout: %d ms\n", (1<<cfip->BlockEraseTimeoutMax) * (1<<cfip->BlockEraseTimeoutTyp)); 363 printk("Maximum block erase timeout: %d ms\n", (1<<cfip->BlockEraseTimeoutMax) * (1<<cfip->BlockEraseTimeoutTyp));
364 if (cfip->ChipEraseTimeoutTyp || cfip->ChipEraseTimeoutMax) { 364 if (cfip->ChipEraseTimeoutTyp || cfip->ChipEraseTimeoutMax) {
365 printk("Typical chip erase timeout: %d ms\n", 1<<cfip->ChipEraseTimeoutTyp); 365 printk("Typical chip erase timeout: %d ms\n", 1<<cfip->ChipEraseTimeoutTyp);
366 printk("Maximum chip erase timeout: %d ms\n", (1<<cfip->ChipEraseTimeoutMax) * (1<<cfip->ChipEraseTimeoutTyp)); 366 printk("Maximum chip erase timeout: %d ms\n", (1<<cfip->ChipEraseTimeoutMax) * (1<<cfip->ChipEraseTimeoutTyp));
367 } 367 }
368 else 368 else
369 printk("Chip erase not supported\n"); 369 printk("Chip erase not supported\n");
370 370
371 printk("Device size: 0x%X bytes (%d MiB)\n", 1 << cfip->DevSize, 1<< (cfip->DevSize - 20)); 371 printk("Device size: 0x%X bytes (%d MiB)\n", 1 << cfip->DevSize, 1<< (cfip->DevSize - 20));
372 printk("Flash Device Interface description: 0x%4.4X\n", cfip->InterfaceDesc); 372 printk("Flash Device Interface description: 0x%4.4X\n", cfip->InterfaceDesc);
373 switch(cfip->InterfaceDesc) { 373 switch(cfip->InterfaceDesc) {
374 case 0: 374 case 0:
375 printk(" - x8-only asynchronous interface\n"); 375 printk(" - x8-only asynchronous interface\n");
376 break; 376 break;
377 377
378 case 1: 378 case 1:
379 printk(" - x16-only asynchronous interface\n"); 379 printk(" - x16-only asynchronous interface\n");
380 break; 380 break;
381 381
382 case 2: 382 case 2:
383 printk(" - supports x8 and x16 via BYTE# with asynchronous interface\n"); 383 printk(" - supports x8 and x16 via BYTE# with asynchronous interface\n");
384 break; 384 break;
385 385
386 case 3: 386 case 3:
387 printk(" - x32-only asynchronous interface\n"); 387 printk(" - x32-only asynchronous interface\n");
388 break; 388 break;
389 389
390 case 4: 390 case 4:
391 printk(" - supports x16 and x32 via Word# with asynchronous interface\n"); 391 printk(" - supports x16 and x32 via Word# with asynchronous interface\n");
392 break; 392 break;
393 393
394 case 65535: 394 case 65535:
395 printk(" - Not Allowed / Reserved\n"); 395 printk(" - Not Allowed / Reserved\n");
396 break; 396 break;
397 397
398 default: 398 default:
399 printk(" - Unknown\n"); 399 printk(" - Unknown\n");
400 break; 400 break;
401 } 401 }
402 402
403 printk("Max. bytes in buffer write: 0x%x\n", 1<< cfip->MaxBufWriteSize); 403 printk("Max. bytes in buffer write: 0x%x\n", 1<< cfip->MaxBufWriteSize);
404 printk("Number of Erase Block Regions: %d\n", cfip->NumEraseRegions); 404 printk("Number of Erase Block Regions: %d\n", cfip->NumEraseRegions);
405 405
406} 406}
407#endif /* DEBUG_CFI */ 407#endif /* DEBUG_CFI */
408 408
diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c
index 2b2ede2bfcca..d8e7a026ba5a 100644
--- a/drivers/mtd/chips/cfi_util.c
+++ b/drivers/mtd/chips/cfi_util.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * This code is covered by the GPL. 8 * This code is covered by the GPL.
9 * 9 *
10 * $Id: cfi_util.c,v 1.8 2004/12/14 19:55:56 nico Exp $ 10 * $Id: cfi_util.c,v 1.10 2005/11/07 11:14:23 gleixner Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -56,7 +56,7 @@ __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* n
56 56
57 /* Read in the Extended Query Table */ 57 /* Read in the Extended Query Table */
58 for (i=0; i<size; i++) { 58 for (i=0; i<size; i++) {
59 ((unsigned char *)extp)[i] = 59 ((unsigned char *)extp)[i] =
60 cfi_read_query(map, base+((adr+i)*ofs_factor)); 60 cfi_read_query(map, base+((adr+i)*ofs_factor));
61 } 61 }
62 62
@@ -70,15 +70,6 @@ __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* n
70 local_irq_enable(); 70 local_irq_enable();
71#endif 71#endif
72 72
73 if (extp->MajorVersion != '1' ||
74 (extp->MinorVersion < '0' || extp->MinorVersion > '3')) {
75 printk(KERN_WARNING " Unknown %s Extended Query "
76 "version %c.%c.\n", name, extp->MajorVersion,
77 extp->MinorVersion);
78 kfree(extp);
79 extp = NULL;
80 }
81
82 out: return extp; 73 out: return extp;
83} 74}
84 75
@@ -122,17 +113,17 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
122 113
123 i = 0; 114 i = 0;
124 115
125 /* Skip all erase regions which are ended before the start of 116 /* Skip all erase regions which are ended before the start of
126 the requested erase. Actually, to save on the calculations, 117 the requested erase. Actually, to save on the calculations,
127 we skip to the first erase region which starts after the 118 we skip to the first erase region which starts after the
128 start of the requested erase, and then go back one. 119 start of the requested erase, and then go back one.
129 */ 120 */
130 121
131 while (i < mtd->numeraseregions && ofs >= regions[i].offset) 122 while (i < mtd->numeraseregions && ofs >= regions[i].offset)
132 i++; 123 i++;
133 i--; 124 i--;
134 125
135 /* OK, now i is pointing at the erase region in which this 126 /* OK, now i is pointing at the erase region in which this
136 erase request starts. Check the start of the requested 127 erase request starts. Check the start of the requested
137 erase range is aligned with the erase size which is in 128 erase range is aligned with the erase size which is in
138 effect here. 129 effect here.
@@ -155,7 +146,7 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
155 the address actually falls 146 the address actually falls
156 */ 147 */
157 i--; 148 i--;
158 149
159 if ((ofs + len) & (regions[i].erasesize-1)) 150 if ((ofs + len) & (regions[i].erasesize-1))
160 return -EINVAL; 151 return -EINVAL;
161 152
@@ -168,7 +159,7 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
168 int size = regions[i].erasesize; 159 int size = regions[i].erasesize;
169 160
170 ret = (*frob)(map, &cfi->chips[chipnum], adr, size, thunk); 161 ret = (*frob)(map, &cfi->chips[chipnum], adr, size, thunk);
171 162
172 if (ret) 163 if (ret)
173 return ret; 164 return ret;
174 165
@@ -182,7 +173,7 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
182 if (adr >> cfi->chipshift) { 173 if (adr >> cfi->chipshift) {
183 adr = 0; 174 adr = 0;
184 chipnum++; 175 chipnum++;
185 176
186 if (chipnum >= cfi->numchips) 177 if (chipnum >= cfi->numchips)
187 break; 178 break;
188 } 179 }
diff --git a/drivers/mtd/chips/chipreg.c b/drivers/mtd/chips/chipreg.c
index d7d739a108ae..c2127840a183 100644
--- a/drivers/mtd/chips/chipreg.c
+++ b/drivers/mtd/chips/chipreg.c
@@ -41,7 +41,7 @@ static struct mtd_chip_driver *get_mtd_chip_driver (const char *name)
41 41
42 list_for_each(pos, &chip_drvs_list) { 42 list_for_each(pos, &chip_drvs_list) {
43 this = list_entry(pos, typeof(*this), list); 43 this = list_entry(pos, typeof(*this), list);
44 44
45 if (!strcmp(this->name, name)) { 45 if (!strcmp(this->name, name)) {
46 ret = this; 46 ret = this;
47 break; 47 break;
@@ -73,7 +73,7 @@ struct mtd_info *do_map_probe(const char *name, struct map_info *map)
73 73
74 ret = drv->probe(map); 74 ret = drv->probe(map);
75 75
76 /* We decrease the use count here. It may have been a 76 /* We decrease the use count here. It may have been a
77 probe-only module, which is no longer required from this 77 probe-only module, which is no longer required from this
78 point, having given us a handle on (and increased the use 78 point, having given us a handle on (and increased the use
79 count of) the actual driver code. 79 count of) the actual driver code.
@@ -82,7 +82,7 @@ struct mtd_info *do_map_probe(const char *name, struct map_info *map)
82 82
83 if (ret) 83 if (ret)
84 return ret; 84 return ret;
85 85
86 return NULL; 86 return NULL;
87} 87}
88/* 88/*
diff --git a/drivers/mtd/chips/fwh_lock.h b/drivers/mtd/chips/fwh_lock.h
index e1a5b76596c5..77303ce5dcf1 100644
--- a/drivers/mtd/chips/fwh_lock.h
+++ b/drivers/mtd/chips/fwh_lock.h
@@ -25,7 +25,7 @@ struct fwh_xxlock_thunk {
25 * so this code has not been tested with interleaved chips, 25 * so this code has not been tested with interleaved chips,
26 * and will likely fail in that context. 26 * and will likely fail in that context.
27 */ 27 */
28static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip, 28static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip,
29 unsigned long adr, int len, void *thunk) 29 unsigned long adr, int len, void *thunk)
30{ 30{
31 struct cfi_private *cfi = map->fldrv_priv; 31 struct cfi_private *cfi = map->fldrv_priv;
@@ -44,7 +44,7 @@ static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip,
44 * - on 64k boundariesand 44 * - on 64k boundariesand
45 * - bit 1 set high 45 * - bit 1 set high
46 * - block lock registers are 4MiB lower - overflow subtract (danger) 46 * - block lock registers are 4MiB lower - overflow subtract (danger)
47 * 47 *
48 * The address manipulation is first done on the logical address 48 * The address manipulation is first done on the logical address
49 * which is 0 at the start of the chip, and then the offset of 49 * which is 0 at the start of the chip, and then the offset of
50 * the individual chip is addted to it. Any other order a weird 50 * the individual chip is addted to it. Any other order a weird
@@ -93,7 +93,7 @@ static int fwh_unlock_varsize(struct mtd_info *mtd, loff_t ofs, size_t len)
93 93
94 ret = cfi_varsize_frob(mtd, fwh_xxlock_oneblock, ofs, len, 94 ret = cfi_varsize_frob(mtd, fwh_xxlock_oneblock, ofs, len,
95 (void *)&FWH_XXLOCK_ONEBLOCK_UNLOCK); 95 (void *)&FWH_XXLOCK_ONEBLOCK_UNLOCK);
96 96
97 return ret; 97 return ret;
98} 98}
99 99
diff --git a/drivers/mtd/chips/gen_probe.c b/drivers/mtd/chips/gen_probe.c
index dc065b22f79e..41bd59d20d85 100644
--- a/drivers/mtd/chips/gen_probe.c
+++ b/drivers/mtd/chips/gen_probe.c
@@ -2,7 +2,7 @@
2 * Routines common to all CFI-type probes. 2 * Routines common to all CFI-type probes.
3 * (C) 2001-2003 Red Hat, Inc. 3 * (C) 2001-2003 Red Hat, Inc.
4 * GPL'd 4 * GPL'd
5 * $Id: gen_probe.c,v 1.22 2005/01/24 23:49:50 rmk Exp $ 5 * $Id: gen_probe.c,v 1.24 2005/11/07 11:14:23 gleixner Exp $
6 */ 6 */
7 7
8#include <linux/kernel.h> 8#include <linux/kernel.h>
@@ -26,7 +26,7 @@ struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp)
26 26
27 /* First probe the map to see if we have CFI stuff there. */ 27 /* First probe the map to see if we have CFI stuff there. */
28 cfi = genprobe_ident_chips(map, cp); 28 cfi = genprobe_ident_chips(map, cp);
29 29
30 if (!cfi) 30 if (!cfi)
31 return NULL; 31 return NULL;
32 32
@@ -36,12 +36,12 @@ struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp)
36 mtd = check_cmd_set(map, 1); /* First the primary cmdset */ 36 mtd = check_cmd_set(map, 1); /* First the primary cmdset */
37 if (!mtd) 37 if (!mtd)
38 mtd = check_cmd_set(map, 0); /* Then the secondary */ 38 mtd = check_cmd_set(map, 0); /* Then the secondary */
39 39
40 if (mtd) 40 if (mtd)
41 return mtd; 41 return mtd;
42 42
43 printk(KERN_WARNING"gen_probe: No supported Vendor Command Set found\n"); 43 printk(KERN_WARNING"gen_probe: No supported Vendor Command Set found\n");
44 44
45 kfree(cfi->cfiq); 45 kfree(cfi->cfiq);
46 kfree(cfi); 46 kfree(cfi);
47 map->fldrv_priv = NULL; 47 map->fldrv_priv = NULL;
@@ -60,14 +60,14 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
60 60
61 memset(&cfi, 0, sizeof(cfi)); 61 memset(&cfi, 0, sizeof(cfi));
62 62
63 /* Call the probetype-specific code with all permutations of 63 /* Call the probetype-specific code with all permutations of
64 interleave and device type, etc. */ 64 interleave and device type, etc. */
65 if (!genprobe_new_chip(map, cp, &cfi)) { 65 if (!genprobe_new_chip(map, cp, &cfi)) {
66 /* The probe didn't like it */ 66 /* The probe didn't like it */
67 printk(KERN_DEBUG "%s: Found no %s device at location zero\n", 67 printk(KERN_DEBUG "%s: Found no %s device at location zero\n",
68 cp->name, map->name); 68 cp->name, map->name);
69 return NULL; 69 return NULL;
70 } 70 }
71 71
72#if 0 /* Let the CFI probe routine do this sanity check. The Intel and AMD 72#if 0 /* Let the CFI probe routine do this sanity check. The Intel and AMD
73 probe routines won't ever return a broken CFI structure anyway, 73 probe routines won't ever return a broken CFI structure anyway,
@@ -92,13 +92,13 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
92 } else { 92 } else {
93 BUG(); 93 BUG();
94 } 94 }
95 95
96 cfi.numchips = 1; 96 cfi.numchips = 1;
97 97
98 /* 98 /*
99 * Allocate memory for bitmap of valid chips. 99 * Allocate memory for bitmap of valid chips.
100 * Align bitmap storage size to full byte. 100 * Align bitmap storage size to full byte.
101 */ 101 */
102 max_chips = map->size >> cfi.chipshift; 102 max_chips = map->size >> cfi.chipshift;
103 mapsize = (max_chips / 8) + ((max_chips % 8) ? 1 : 0); 103 mapsize = (max_chips / 8) + ((max_chips % 8) ? 1 : 0);
104 chip_map = kmalloc(mapsize, GFP_KERNEL); 104 chip_map = kmalloc(mapsize, GFP_KERNEL);
@@ -122,7 +122,7 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
122 } 122 }
123 123
124 /* 124 /*
125 * Now allocate the space for the structures we need to return to 125 * Now allocate the space for the structures we need to return to
126 * our caller, and copy the appropriate data into them. 126 * our caller, and copy the appropriate data into them.
127 */ 127 */
128 128
@@ -154,7 +154,7 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
154 return retcfi; 154 return retcfi;
155} 155}
156 156
157 157
158static int genprobe_new_chip(struct map_info *map, struct chip_probe *cp, 158static int genprobe_new_chip(struct map_info *map, struct chip_probe *cp,
159 struct cfi_private *cfi) 159 struct cfi_private *cfi)
160{ 160{
@@ -189,7 +189,7 @@ extern cfi_cmdset_fn_t cfi_cmdset_0001;
189extern cfi_cmdset_fn_t cfi_cmdset_0002; 189extern cfi_cmdset_fn_t cfi_cmdset_0002;
190extern cfi_cmdset_fn_t cfi_cmdset_0020; 190extern cfi_cmdset_fn_t cfi_cmdset_0020;
191 191
192static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map, 192static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map,
193 int primary) 193 int primary)
194{ 194{
195 struct cfi_private *cfi = map->fldrv_priv; 195 struct cfi_private *cfi = map->fldrv_priv;
@@ -199,7 +199,7 @@ static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map,
199 cfi_cmdset_fn_t *probe_function; 199 cfi_cmdset_fn_t *probe_function;
200 200
201 sprintf(probename, "cfi_cmdset_%4.4X", type); 201 sprintf(probename, "cfi_cmdset_%4.4X", type);
202 202
203 probe_function = inter_module_get_request(probename, probename); 203 probe_function = inter_module_get_request(probename, probename);
204 204
205 if (probe_function) { 205 if (probe_function) {
@@ -221,7 +221,7 @@ static struct mtd_info *check_cmd_set(struct map_info *map, int primary)
221{ 221{
222 struct cfi_private *cfi = map->fldrv_priv; 222 struct cfi_private *cfi = map->fldrv_priv;
223 __u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID; 223 __u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID;
224 224
225 if (type == P_ID_NONE || type == P_ID_RESERVED) 225 if (type == P_ID_NONE || type == P_ID_RESERVED)
226 return NULL; 226 return NULL;
227 227
@@ -235,6 +235,7 @@ static struct mtd_info *check_cmd_set(struct map_info *map, int primary)
235#ifdef CONFIG_MTD_CFI_INTELEXT 235#ifdef CONFIG_MTD_CFI_INTELEXT
236 case 0x0001: 236 case 0x0001:
237 case 0x0003: 237 case 0x0003:
238 case 0x0200:
238 return cfi_cmdset_0001(map, primary); 239 return cfi_cmdset_0001(map, primary);
239#endif 240#endif
240#ifdef CONFIG_MTD_CFI_AMDSTD 241#ifdef CONFIG_MTD_CFI_AMDSTD
diff --git a/drivers/mtd/chips/jedec.c b/drivers/mtd/chips/jedec.c
index 4f6778f3ee3e..c40b48dabed3 100644
--- a/drivers/mtd/chips/jedec.c
+++ b/drivers/mtd/chips/jedec.c
@@ -1,6 +1,6 @@
1 1
2/* JEDEC Flash Interface. 2/* JEDEC Flash Interface.
3 * This is an older type of interface for self programming flash. It is 3 * This is an older type of interface for self programming flash. It is
4 * commonly use in older AMD chips and is obsolete compared with CFI. 4 * commonly use in older AMD chips and is obsolete compared with CFI.
5 * It is called JEDEC because the JEDEC association distributes the ID codes 5 * It is called JEDEC because the JEDEC association distributes the ID codes
6 * for the chips. 6 * for the chips.
@@ -88,9 +88,9 @@ static const struct JEDECTable JEDEC_table[] = {
88 88
89static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id); 89static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id);
90static void jedec_sync(struct mtd_info *mtd) {}; 90static void jedec_sync(struct mtd_info *mtd) {};
91static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len, 91static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len,
92 size_t *retlen, u_char *buf); 92 size_t *retlen, u_char *buf);
93static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len, 93static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
94 size_t *retlen, u_char *buf); 94 size_t *retlen, u_char *buf);
95 95
96static struct mtd_info *jedec_probe(struct map_info *map); 96static struct mtd_info *jedec_probe(struct map_info *map);
@@ -122,7 +122,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
122 122
123 memset(MTD, 0, sizeof(struct mtd_info) + sizeof(struct jedec_private)); 123 memset(MTD, 0, sizeof(struct mtd_info) + sizeof(struct jedec_private));
124 priv = (struct jedec_private *)&MTD[1]; 124 priv = (struct jedec_private *)&MTD[1];
125 125
126 my_bank_size = map->size; 126 my_bank_size = map->size;
127 127
128 if (map->size/my_bank_size > MAX_JEDEC_CHIPS) 128 if (map->size/my_bank_size > MAX_JEDEC_CHIPS)
@@ -131,13 +131,13 @@ static struct mtd_info *jedec_probe(struct map_info *map)
131 kfree(MTD); 131 kfree(MTD);
132 return NULL; 132 return NULL;
133 } 133 }
134 134
135 for (Base = 0; Base < map->size; Base += my_bank_size) 135 for (Base = 0; Base < map->size; Base += my_bank_size)
136 { 136 {
137 // Perhaps zero could designate all tests? 137 // Perhaps zero could designate all tests?
138 if (map->buswidth == 0) 138 if (map->buswidth == 0)
139 map->buswidth = 1; 139 map->buswidth = 1;
140 140
141 if (map->buswidth == 1){ 141 if (map->buswidth == 1){
142 if (jedec_probe8(map,Base,priv) == 0) { 142 if (jedec_probe8(map,Base,priv) == 0) {
143 printk("did recognize jedec chip\n"); 143 printk("did recognize jedec chip\n");
@@ -150,7 +150,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
150 if (map->buswidth == 4) 150 if (map->buswidth == 4)
151 jedec_probe32(map,Base,priv); 151 jedec_probe32(map,Base,priv);
152 } 152 }
153 153
154 // Get the biggest sector size 154 // Get the biggest sector size
155 SectorSize = 0; 155 SectorSize = 0;
156 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) 156 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
@@ -160,7 +160,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
160 if (priv->chips[I].sectorsize > SectorSize) 160 if (priv->chips[I].sectorsize > SectorSize)
161 SectorSize = priv->chips[I].sectorsize; 161 SectorSize = priv->chips[I].sectorsize;
162 } 162 }
163 163
164 // Quickly ensure that the other sector sizes are factors of the largest 164 // Quickly ensure that the other sector sizes are factors of the largest
165 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) 165 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
166 { 166 {
@@ -169,9 +169,9 @@ static struct mtd_info *jedec_probe(struct map_info *map)
169 printk("mtd: Failed. Device has incompatible mixed sector sizes\n"); 169 printk("mtd: Failed. Device has incompatible mixed sector sizes\n");
170 kfree(MTD); 170 kfree(MTD);
171 return NULL; 171 return NULL;
172 } 172 }
173 } 173 }
174 174
175 /* Generate a part name that includes the number of different chips and 175 /* Generate a part name that includes the number of different chips and
176 other configuration information */ 176 other configuration information */
177 count = 1; 177 count = 1;
@@ -181,13 +181,13 @@ static struct mtd_info *jedec_probe(struct map_info *map)
181 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) 181 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
182 { 182 {
183 const struct JEDECTable *JEDEC; 183 const struct JEDECTable *JEDEC;
184 184
185 if (priv->chips[I+1].jedec == priv->chips[I].jedec) 185 if (priv->chips[I+1].jedec == priv->chips[I].jedec)
186 { 186 {
187 count++; 187 count++;
188 continue; 188 continue;
189 } 189 }
190 190
191 // Locate the chip in the jedec table 191 // Locate the chip in the jedec table
192 JEDEC = jedec_idtoinf(priv->chips[I].jedec >> 8,priv->chips[I].jedec); 192 JEDEC = jedec_idtoinf(priv->chips[I].jedec >> 8,priv->chips[I].jedec);
193 if (JEDEC == 0) 193 if (JEDEC == 0)
@@ -196,11 +196,11 @@ static struct mtd_info *jedec_probe(struct map_info *map)
196 kfree(MTD); 196 kfree(MTD);
197 return NULL; 197 return NULL;
198 } 198 }
199 199
200 if (Uniq != 0) 200 if (Uniq != 0)
201 strcat(Part,","); 201 strcat(Part,",");
202 Uniq++; 202 Uniq++;
203 203
204 if (count != 1) 204 if (count != 1)
205 sprintf(Part+strlen(Part),"%x*[%s]",count,JEDEC->name); 205 sprintf(Part+strlen(Part),"%x*[%s]",count,JEDEC->name);
206 else 206 else
@@ -208,7 +208,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
208 if (strlen(Part) > sizeof(Part)*2/3) 208 if (strlen(Part) > sizeof(Part)*2/3)
209 break; 209 break;
210 count = 1; 210 count = 1;
211 } 211 }
212 212
213 /* Determine if the chips are organized in a linear fashion, or if there 213 /* Determine if the chips are organized in a linear fashion, or if there
214 are empty banks. Note, the last bank does not count here, only the 214 are empty banks. Note, the last bank does not count here, only the
@@ -233,7 +233,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
233 { 233 {
234 if (priv->bank_fill[I] != my_bank_size) 234 if (priv->bank_fill[I] != my_bank_size)
235 priv->is_banked = 1; 235 priv->is_banked = 1;
236 236
237 /* This even could be eliminated, but new de-optimized read/write 237 /* This even could be eliminated, but new de-optimized read/write
238 functions have to be written */ 238 functions have to be written */
239 printk("priv->bank_fill[%d] is %lx, priv->bank_fill[0] is %lx\n",I,priv->bank_fill[I],priv->bank_fill[0]); 239 printk("priv->bank_fill[%d] is %lx, priv->bank_fill[0] is %lx\n",I,priv->bank_fill[I],priv->bank_fill[0]);
@@ -242,7 +242,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
242 printk("mtd: Failed. Cannot handle unsymmetric banking\n"); 242 printk("mtd: Failed. Cannot handle unsymmetric banking\n");
243 kfree(MTD); 243 kfree(MTD);
244 return NULL; 244 return NULL;
245 } 245 }
246 } 246 }
247 } 247 }
248 } 248 }
@@ -250,7 +250,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
250 strcat(Part,", banked"); 250 strcat(Part,", banked");
251 251
252 // printk("Part: '%s'\n",Part); 252 // printk("Part: '%s'\n",Part);
253 253
254 memset(MTD,0,sizeof(*MTD)); 254 memset(MTD,0,sizeof(*MTD));
255 // strlcpy(MTD->name,Part,sizeof(MTD->name)); 255 // strlcpy(MTD->name,Part,sizeof(MTD->name));
256 MTD->name = map->name; 256 MTD->name = map->name;
@@ -291,7 +291,7 @@ static int checkparity(u_char C)
291 291
292/* Take an array of JEDEC numbers that represent interleved flash chips 292/* Take an array of JEDEC numbers that represent interleved flash chips
293 and process them. Check to make sure they are good JEDEC numbers, look 293 and process them. Check to make sure they are good JEDEC numbers, look
294 them up and then add them to the chip list */ 294 them up and then add them to the chip list */
295static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count, 295static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
296 unsigned long base,struct jedec_private *priv) 296 unsigned long base,struct jedec_private *priv)
297{ 297{
@@ -306,16 +306,16 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
306 if (checkparity(Mfg[I]) == 0 || checkparity(Id[I]) == 0) 306 if (checkparity(Mfg[I]) == 0 || checkparity(Id[I]) == 0)
307 return 0; 307 return 0;
308 } 308 }
309 309
310 // Finally, just make sure all the chip sizes are the same 310 // Finally, just make sure all the chip sizes are the same
311 JEDEC = jedec_idtoinf(Mfg[0],Id[0]); 311 JEDEC = jedec_idtoinf(Mfg[0],Id[0]);
312 312
313 if (JEDEC == 0) 313 if (JEDEC == 0)
314 { 314 {
315 printk("mtd: Found JEDEC flash chip, but do not have a table entry for %x:%x\n",Mfg[0],Mfg[1]); 315 printk("mtd: Found JEDEC flash chip, but do not have a table entry for %x:%x\n",Mfg[0],Mfg[1]);
316 return 0; 316 return 0;
317 } 317 }
318 318
319 Size = JEDEC->size; 319 Size = JEDEC->size;
320 SectorSize = JEDEC->sectorsize; 320 SectorSize = JEDEC->sectorsize;
321 for (I = 0; I != Count; I++) 321 for (I = 0; I != Count; I++)
@@ -331,7 +331,7 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
331 { 331 {
332 printk("mtd: Failed. Interleved flash does not have matching characteristics\n"); 332 printk("mtd: Failed. Interleved flash does not have matching characteristics\n");
333 return 0; 333 return 0;
334 } 334 }
335 } 335 }
336 336
337 // Load the Chips 337 // Load the Chips
@@ -345,13 +345,13 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
345 { 345 {
346 printk("mtd: Device has too many chips. Increase MAX_JEDEC_CHIPS\n"); 346 printk("mtd: Device has too many chips. Increase MAX_JEDEC_CHIPS\n");
347 return 0; 347 return 0;
348 } 348 }
349 349
350 // Add them to the table 350 // Add them to the table
351 for (J = 0; J != Count; J++) 351 for (J = 0; J != Count; J++)
352 { 352 {
353 unsigned long Bank; 353 unsigned long Bank;
354 354
355 JEDEC = jedec_idtoinf(Mfg[J],Id[J]); 355 JEDEC = jedec_idtoinf(Mfg[J],Id[J]);
356 priv->chips[I].jedec = (Mfg[J] << 8) | Id[J]; 356 priv->chips[I].jedec = (Mfg[J] << 8) | Id[J];
357 priv->chips[I].size = JEDEC->size; 357 priv->chips[I].size = JEDEC->size;
@@ -364,17 +364,17 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
364 // log2 n :| 364 // log2 n :|
365 priv->chips[I].addrshift = 0; 365 priv->chips[I].addrshift = 0;
366 for (Bank = Count; Bank != 1; Bank >>= 1, priv->chips[I].addrshift++); 366 for (Bank = Count; Bank != 1; Bank >>= 1, priv->chips[I].addrshift++);
367 367
368 // Determine how filled this bank is. 368 // Determine how filled this bank is.
369 Bank = base & (~(my_bank_size-1)); 369 Bank = base & (~(my_bank_size-1));
370 if (priv->bank_fill[Bank/my_bank_size] < base + 370 if (priv->bank_fill[Bank/my_bank_size] < base +
371 (JEDEC->size << priv->chips[I].addrshift) - Bank) 371 (JEDEC->size << priv->chips[I].addrshift) - Bank)
372 priv->bank_fill[Bank/my_bank_size] = base + (JEDEC->size << priv->chips[I].addrshift) - Bank; 372 priv->bank_fill[Bank/my_bank_size] = base + (JEDEC->size << priv->chips[I].addrshift) - Bank;
373 I++; 373 I++;
374 } 374 }
375 375
376 priv->size += priv->chips[I-1].size*Count; 376 priv->size += priv->chips[I-1].size*Count;
377 377
378 return priv->chips[I-1].size; 378 return priv->chips[I-1].size;
379} 379}
380 380
@@ -392,7 +392,7 @@ static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id)
392// Look for flash using an 8 bit bus interface 392// Look for flash using an 8 bit bus interface
393static int jedec_probe8(struct map_info *map,unsigned long base, 393static int jedec_probe8(struct map_info *map,unsigned long base,
394 struct jedec_private *priv) 394 struct jedec_private *priv)
395{ 395{
396 #define flread(x) map_read8(map,base+x) 396 #define flread(x) map_read8(map,base+x)
397 #define flwrite(v,x) map_write8(map,v,base+x) 397 #define flwrite(v,x) map_write8(map,v,base+x)
398 398
@@ -410,20 +410,20 @@ static int jedec_probe8(struct map_info *map,unsigned long base,
410 OldVal = flread(base); 410 OldVal = flread(base);
411 for (I = 0; OldVal != flread(base) && I < 10000; I++) 411 for (I = 0; OldVal != flread(base) && I < 10000; I++)
412 OldVal = flread(base); 412 OldVal = flread(base);
413 413
414 // Reset the chip 414 // Reset the chip
415 flwrite(Reset,0x555); 415 flwrite(Reset,0x555);
416 416
417 // Send the sequence 417 // Send the sequence
418 flwrite(AutoSel1,0x555); 418 flwrite(AutoSel1,0x555);
419 flwrite(AutoSel2,0x2AA); 419 flwrite(AutoSel2,0x2AA);
420 flwrite(AutoSel3,0x555); 420 flwrite(AutoSel3,0x555);
421 421
422 // Get the JEDEC numbers 422 // Get the JEDEC numbers
423 Mfg[0] = flread(0); 423 Mfg[0] = flread(0);
424 Id[0] = flread(1); 424 Id[0] = flread(1);
425 // printk("Mfg is %x, Id is %x\n",Mfg[0],Id[0]); 425 // printk("Mfg is %x, Id is %x\n",Mfg[0],Id[0]);
426 426
427 Size = handle_jedecs(map,Mfg,Id,1,base,priv); 427 Size = handle_jedecs(map,Mfg,Id,1,base,priv);
428 // printk("handle_jedecs Size is %x\n",(unsigned int)Size); 428 // printk("handle_jedecs Size is %x\n",(unsigned int)Size);
429 if (Size == 0) 429 if (Size == 0)
@@ -431,13 +431,13 @@ static int jedec_probe8(struct map_info *map,unsigned long base,
431 flwrite(Reset,0x555); 431 flwrite(Reset,0x555);
432 return 0; 432 return 0;
433 } 433 }
434 434
435 435
436 // Reset. 436 // Reset.
437 flwrite(Reset,0x555); 437 flwrite(Reset,0x555);
438 438
439 return 1; 439 return 1;
440 440
441 #undef flread 441 #undef flread
442 #undef flwrite 442 #undef flwrite
443} 443}
@@ -470,17 +470,17 @@ static int jedec_probe32(struct map_info *map,unsigned long base,
470 OldVal = flread(base); 470 OldVal = flread(base);
471 for (I = 0; OldVal != flread(base) && I < 10000; I++) 471 for (I = 0; OldVal != flread(base) && I < 10000; I++)
472 OldVal = flread(base); 472 OldVal = flread(base);
473 473
474 // Reset the chip 474 // Reset the chip
475 flwrite(Reset,0x555); 475 flwrite(Reset,0x555);
476 476
477 // Send the sequence 477 // Send the sequence
478 flwrite(AutoSel1,0x555); 478 flwrite(AutoSel1,0x555);
479 flwrite(AutoSel2,0x2AA); 479 flwrite(AutoSel2,0x2AA);
480 flwrite(AutoSel3,0x555); 480 flwrite(AutoSel3,0x555);
481 481
482 // Test #1, JEDEC numbers are readable from 0x??00/0x??01 482 // Test #1, JEDEC numbers are readable from 0x??00/0x??01
483 if (flread(0) != flread(0x100) || 483 if (flread(0) != flread(0x100) ||
484 flread(1) != flread(0x101)) 484 flread(1) != flread(0x101))
485 { 485 {
486 flwrite(Reset,0x555); 486 flwrite(Reset,0x555);
@@ -494,14 +494,14 @@ static int jedec_probe32(struct map_info *map,unsigned long base,
494 OldVal = flread(1); 494 OldVal = flread(1);
495 for (I = 0; I != 4; I++) 495 for (I = 0; I != 4; I++)
496 Id[I] = (OldVal >> (I*8)); 496 Id[I] = (OldVal >> (I*8));
497 497
498 Size = handle_jedecs(map,Mfg,Id,4,base,priv); 498 Size = handle_jedecs(map,Mfg,Id,4,base,priv);
499 if (Size == 0) 499 if (Size == 0)
500 { 500 {
501 flwrite(Reset,0x555); 501 flwrite(Reset,0x555);
502 return 0; 502 return 0;
503 } 503 }
504 504
505 /* Check if there is address wrap around within a single bank, if this 505 /* Check if there is address wrap around within a single bank, if this
506 returns JEDEC numbers then we assume that it is wrap around. Notice 506 returns JEDEC numbers then we assume that it is wrap around. Notice
507 we call this routine with the JEDEC return still enabled, if two or 507 we call this routine with the JEDEC return still enabled, if two or
@@ -519,27 +519,27 @@ static int jedec_probe32(struct map_info *map,unsigned long base,
519 519
520 // Reset. 520 // Reset.
521 flwrite(0xF0F0F0F0,0x555); 521 flwrite(0xF0F0F0F0,0x555);
522 522
523 return 1; 523 return 1;
524 524
525 #undef flread 525 #undef flread
526 #undef flwrite 526 #undef flwrite
527} 527}
528 528
529/* Linear read. */ 529/* Linear read. */
530static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len, 530static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len,
531 size_t *retlen, u_char *buf) 531 size_t *retlen, u_char *buf)
532{ 532{
533 struct map_info *map = mtd->priv; 533 struct map_info *map = mtd->priv;
534 534
535 map_copy_from(map, buf, from, len); 535 map_copy_from(map, buf, from, len);
536 *retlen = len; 536 *retlen = len;
537 return 0; 537 return 0;
538} 538}
539 539
540/* Banked read. Take special care to jump past the holes in the bank 540/* Banked read. Take special care to jump past the holes in the bank
541 mapping. This version assumes symetry in the holes.. */ 541 mapping. This version assumes symetry in the holes.. */
542static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len, 542static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
543 size_t *retlen, u_char *buf) 543 size_t *retlen, u_char *buf)
544{ 544{
545 struct map_info *map = mtd->priv; 545 struct map_info *map = mtd->priv;
@@ -555,17 +555,17 @@ static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
555 if (priv->bank_fill[0] - offset < len) 555 if (priv->bank_fill[0] - offset < len)
556 get = priv->bank_fill[0] - offset; 556 get = priv->bank_fill[0] - offset;
557 557
558 bank /= priv->bank_fill[0]; 558 bank /= priv->bank_fill[0];
559 map_copy_from(map,buf + *retlen,bank*my_bank_size + offset,get); 559 map_copy_from(map,buf + *retlen,bank*my_bank_size + offset,get);
560 560
561 len -= get; 561 len -= get;
562 *retlen += get; 562 *retlen += get;
563 from += get; 563 from += get;
564 } 564 }
565 return 0; 565 return 0;
566} 566}
567 567
568/* Pass the flags value that the flash return before it re-entered read 568/* Pass the flags value that the flash return before it re-entered read
569 mode. */ 569 mode. */
570static void jedec_flash_failed(unsigned char code) 570static void jedec_flash_failed(unsigned char code)
571{ 571{
@@ -579,17 +579,17 @@ static void jedec_flash_failed(unsigned char code)
579 printk("mtd: Programming didn't take\n"); 579 printk("mtd: Programming didn't take\n");
580} 580}
581 581
582/* This uses the erasure function described in the AMD Flash Handbook, 582/* This uses the erasure function described in the AMD Flash Handbook,
583 it will work for flashes with a fixed sector size only. Flashes with 583 it will work for flashes with a fixed sector size only. Flashes with
584 a selection of sector sizes (ie the AMD Am29F800B) will need a different 584 a selection of sector sizes (ie the AMD Am29F800B) will need a different
585 routine. This routine tries to parallize erasing multiple chips/sectors 585 routine. This routine tries to parallize erasing multiple chips/sectors
586 where possible */ 586 where possible */
587static int flash_erase(struct mtd_info *mtd, struct erase_info *instr) 587static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
588{ 588{
589 // Does IO to the currently selected chip 589 // Does IO to the currently selected chip
590 #define flread(x) map_read8(map,chip->base+((x)<<chip->addrshift)) 590 #define flread(x) map_read8(map,chip->base+((x)<<chip->addrshift))
591 #define flwrite(v,x) map_write8(map,v,chip->base+((x)<<chip->addrshift)) 591 #define flwrite(v,x) map_write8(map,v,chip->base+((x)<<chip->addrshift))
592 592
593 unsigned long Time = 0; 593 unsigned long Time = 0;
594 unsigned long NoTime = 0; 594 unsigned long NoTime = 0;
595 unsigned long start = instr->addr, len = instr->len; 595 unsigned long start = instr->addr, len = instr->len;
@@ -603,7 +603,7 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
603 (len % mtd->erasesize) != 0 || 603 (len % mtd->erasesize) != 0 ||
604 (len/mtd->erasesize) == 0) 604 (len/mtd->erasesize) == 0)
605 return -EINVAL; 605 return -EINVAL;
606 606
607 jedec_flash_chip_scan(priv,start,len); 607 jedec_flash_chip_scan(priv,start,len);
608 608
609 // Start the erase sequence on each chip 609 // Start the erase sequence on each chip
@@ -611,16 +611,16 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
611 { 611 {
612 unsigned long off; 612 unsigned long off;
613 struct jedec_flash_chip *chip = priv->chips + I; 613 struct jedec_flash_chip *chip = priv->chips + I;
614 614
615 if (chip->length == 0) 615 if (chip->length == 0)
616 continue; 616 continue;
617 617
618 if (chip->start + chip->length > chip->size) 618 if (chip->start + chip->length > chip->size)
619 { 619 {
620 printk("DIE\n"); 620 printk("DIE\n");
621 return -EIO; 621 return -EIO;
622 } 622 }
623 623
624 flwrite(0xF0,chip->start + 0x555); 624 flwrite(0xF0,chip->start + 0x555);
625 flwrite(0xAA,chip->start + 0x555); 625 flwrite(0xAA,chip->start + 0x555);
626 flwrite(0x55,chip->start + 0x2AA); 626 flwrite(0x55,chip->start + 0x2AA);
@@ -628,8 +628,8 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
628 flwrite(0xAA,chip->start + 0x555); 628 flwrite(0xAA,chip->start + 0x555);
629 flwrite(0x55,chip->start + 0x2AA); 629 flwrite(0x55,chip->start + 0x2AA);
630 630
631 /* Once we start selecting the erase sectors the delay between each 631 /* Once we start selecting the erase sectors the delay between each
632 command must not exceed 50us or it will immediately start erasing 632 command must not exceed 50us or it will immediately start erasing
633 and ignore the other sectors */ 633 and ignore the other sectors */
634 for (off = 0; off < len; off += chip->sectorsize) 634 for (off = 0; off < len; off += chip->sectorsize)
635 { 635 {
@@ -641,19 +641,19 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
641 { 641 {
642 printk("mtd: Ack! We timed out the erase timer!\n"); 642 printk("mtd: Ack! We timed out the erase timer!\n");
643 return -EIO; 643 return -EIO;
644 } 644 }
645 } 645 }
646 } 646 }
647 647
648 /* We could split this into a timer routine and return early, performing 648 /* We could split this into a timer routine and return early, performing
649 background erasure.. Maybe later if the need warrents */ 649 background erasure.. Maybe later if the need warrents */
650 650
651 /* Poll the flash for erasure completion, specs say this can take as long 651 /* Poll the flash for erasure completion, specs say this can take as long
652 as 480 seconds to do all the sectors (for a 2 meg flash). 652 as 480 seconds to do all the sectors (for a 2 meg flash).
653 Erasure time is dependent on chip age, temp and wear.. */ 653 Erasure time is dependent on chip age, temp and wear.. */
654 654
655 /* This being a generic routine assumes a 32 bit bus. It does read32s 655 /* This being a generic routine assumes a 32 bit bus. It does read32s
656 and bundles interleved chips into the same grouping. This will work 656 and bundles interleved chips into the same grouping. This will work
657 for all bus widths */ 657 for all bus widths */
658 Time = 0; 658 Time = 0;
659 NoTime = 0; 659 NoTime = 0;
@@ -664,20 +664,20 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
664 unsigned todo[4] = {0,0,0,0}; 664 unsigned todo[4] = {0,0,0,0};
665 unsigned todo_left = 0; 665 unsigned todo_left = 0;
666 unsigned J; 666 unsigned J;
667 667
668 if (chip->length == 0) 668 if (chip->length == 0)
669 continue; 669 continue;
670 670
671 /* Find all chips in this data line, realistically this is all 671 /* Find all chips in this data line, realistically this is all
672 or nothing up to the interleve count */ 672 or nothing up to the interleve count */
673 for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++) 673 for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++)
674 { 674 {
675 if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) == 675 if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) ==
676 (chip->base & (~((1<<chip->addrshift)-1)))) 676 (chip->base & (~((1<<chip->addrshift)-1))))
677 { 677 {
678 todo_left++; 678 todo_left++;
679 todo[priv->chips[J].base & ((1<<chip->addrshift)-1)] = 1; 679 todo[priv->chips[J].base & ((1<<chip->addrshift)-1)] = 1;
680 } 680 }
681 } 681 }
682 682
683 /* printk("todo: %x %x %x %x\n",(short)todo[0],(short)todo[1], 683 /* printk("todo: %x %x %x %x\n",(short)todo[0],(short)todo[1],
@@ -687,7 +687,7 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
687 { 687 {
688 __u32 Last[4]; 688 __u32 Last[4];
689 unsigned long Count = 0; 689 unsigned long Count = 0;
690 690
691 /* During erase bit 7 is held low and bit 6 toggles, we watch this, 691 /* During erase bit 7 is held low and bit 6 toggles, we watch this,
692 should it stop toggling or go high then the erase is completed, 692 should it stop toggling or go high then the erase is completed,
693 or this is not really flash ;> */ 693 or this is not really flash ;> */
@@ -718,23 +718,23 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
718 __u8 Byte3 = (Last[(Count-3)%4] >> (J*8)) & 0xFF; 718 __u8 Byte3 = (Last[(Count-3)%4] >> (J*8)) & 0xFF;
719 if (todo[J] == 0) 719 if (todo[J] == 0)
720 continue; 720 continue;
721 721
722 if ((Byte1 & (1 << 7)) == 0 && Byte1 != Byte2) 722 if ((Byte1 & (1 << 7)) == 0 && Byte1 != Byte2)
723 { 723 {
724// printk("Check %x %x %x\n",(short)J,(short)Byte1,(short)Byte2); 724// printk("Check %x %x %x\n",(short)J,(short)Byte1,(short)Byte2);
725 continue; 725 continue;
726 } 726 }
727 727
728 if (Byte1 == Byte2) 728 if (Byte1 == Byte2)
729 { 729 {
730 jedec_flash_failed(Byte3); 730 jedec_flash_failed(Byte3);
731 return -EIO; 731 return -EIO;
732 } 732 }
733 733
734 todo[J] = 0; 734 todo[J] = 0;
735 todo_left--; 735 todo_left--;
736 } 736 }
737 737
738/* if (NoTime == 0) 738/* if (NoTime == 0)
739 Time += HZ/10 - schedule_timeout(HZ/10);*/ 739 Time += HZ/10 - schedule_timeout(HZ/10);*/
740 NoTime = 0; 740 NoTime = 0;
@@ -751,7 +751,7 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
751 break; 751 break;
752 } 752 }
753 Count++; 753 Count++;
754 754
755/* // Count time, max of 15s per sector (according to AMD) 755/* // Count time, max of 15s per sector (according to AMD)
756 if (Time > 15*len/mtd->erasesize*HZ) 756 if (Time > 15*len/mtd->erasesize*HZ)
757 { 757 {
@@ -759,38 +759,38 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
759 return -EIO; 759 return -EIO;
760 } */ 760 } */
761 } 761 }
762 762
763 // Skip to the next chip if we used chip erase 763 // Skip to the next chip if we used chip erase
764 if (chip->length == chip->size) 764 if (chip->length == chip->size)
765 off = chip->size; 765 off = chip->size;
766 else 766 else
767 off += chip->sectorsize; 767 off += chip->sectorsize;
768 768
769 if (off >= chip->length) 769 if (off >= chip->length)
770 break; 770 break;
771 NoTime = 1; 771 NoTime = 1;
772 } 772 }
773 773
774 for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++) 774 for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++)
775 { 775 {
776 if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) == 776 if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) ==
777 (chip->base & (~((1<<chip->addrshift)-1)))) 777 (chip->base & (~((1<<chip->addrshift)-1))))
778 priv->chips[J].length = 0; 778 priv->chips[J].length = 0;
779 } 779 }
780 } 780 }
781 781
782 //printk("done\n"); 782 //printk("done\n");
783 instr->state = MTD_ERASE_DONE; 783 instr->state = MTD_ERASE_DONE;
784 mtd_erase_callback(instr); 784 mtd_erase_callback(instr);
785 return 0; 785 return 0;
786 786
787 #undef flread 787 #undef flread
788 #undef flwrite 788 #undef flwrite
789} 789}
790 790
791/* This is the simple flash writing function. It writes to every byte, in 791/* This is the simple flash writing function. It writes to every byte, in
792 sequence. It takes care of how to properly address the flash if 792 sequence. It takes care of how to properly address the flash if
793 the flash is interleved. It can only be used if all the chips in the 793 the flash is interleved. It can only be used if all the chips in the
794 array are identical!*/ 794 array are identical!*/
795static int flash_write(struct mtd_info *mtd, loff_t start, size_t len, 795static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
796 size_t *retlen, const u_char *buf) 796 size_t *retlen, const u_char *buf)
@@ -800,25 +800,25 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
800 of addrshift (interleave index) and then adds the control register index. */ 800 of addrshift (interleave index) and then adds the control register index. */
801 #define flread(x) map_read8(map,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift)) 801 #define flread(x) map_read8(map,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
802 #define flwrite(v,x) map_write8(map,v,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift)) 802 #define flwrite(v,x) map_write8(map,v,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
803 803
804 struct map_info *map = mtd->priv; 804 struct map_info *map = mtd->priv;
805 struct jedec_private *priv = map->fldrv_priv; 805 struct jedec_private *priv = map->fldrv_priv;
806 unsigned long base; 806 unsigned long base;
807 unsigned long off; 807 unsigned long off;
808 size_t save_len = len; 808 size_t save_len = len;
809 809
810 if (start + len > mtd->size) 810 if (start + len > mtd->size)
811 return -EIO; 811 return -EIO;
812 812
813 //printk("Here"); 813 //printk("Here");
814 814
815 //printk("flash_write: start is %x, len is %x\n",start,(unsigned long)len); 815 //printk("flash_write: start is %x, len is %x\n",start,(unsigned long)len);
816 while (len != 0) 816 while (len != 0)
817 { 817 {
818 struct jedec_flash_chip *chip = priv->chips; 818 struct jedec_flash_chip *chip = priv->chips;
819 unsigned long bank; 819 unsigned long bank;
820 unsigned long boffset; 820 unsigned long boffset;
821 821
822 // Compute the base of the flash. 822 // Compute the base of the flash.
823 off = ((unsigned long)start) % (chip->size << chip->addrshift); 823 off = ((unsigned long)start) % (chip->size << chip->addrshift);
824 base = start - off; 824 base = start - off;
@@ -828,10 +828,10 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
828 boffset = base & (priv->bank_fill[0]-1); 828 boffset = base & (priv->bank_fill[0]-1);
829 bank = (bank/priv->bank_fill[0])*my_bank_size; 829 bank = (bank/priv->bank_fill[0])*my_bank_size;
830 base = bank + boffset; 830 base = bank + boffset;
831 831
832 // printk("Flasing %X %X %X\n",base,chip->size,len); 832 // printk("Flasing %X %X %X\n",base,chip->size,len);
833 // printk("off is %x, compare with %x\n",off,chip->size << chip->addrshift); 833 // printk("off is %x, compare with %x\n",off,chip->size << chip->addrshift);
834 834
835 // Loop over this page 835 // Loop over this page
836 for (; off != (chip->size << chip->addrshift) && len != 0; start++, len--, off++,buf++) 836 for (; off != (chip->size << chip->addrshift) && len != 0; start++, len--, off++,buf++)
837 { 837 {
@@ -845,7 +845,7 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
845 } 845 }
846 if (((~oldbyte) & *buf) != 0) 846 if (((~oldbyte) & *buf) != 0)
847 printk("mtd: warn: Trying to set a 0 to a 1\n"); 847 printk("mtd: warn: Trying to set a 0 to a 1\n");
848 848
849 // Write 849 // Write
850 flwrite(0xAA,0x555); 850 flwrite(0xAA,0x555);
851 flwrite(0x55,0x2AA); 851 flwrite(0x55,0x2AA);
@@ -854,10 +854,10 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
854 Last[0] = map_read8(map,base + off); 854 Last[0] = map_read8(map,base + off);
855 Last[1] = map_read8(map,base + off); 855 Last[1] = map_read8(map,base + off);
856 Last[2] = map_read8(map,base + off); 856 Last[2] = map_read8(map,base + off);
857 857
858 /* Wait for the flash to finish the operation. We store the last 4 858 /* Wait for the flash to finish the operation. We store the last 4
859 status bytes that have been retrieved so we can determine why 859 status bytes that have been retrieved so we can determine why
860 it failed. The toggle bits keep toggling when there is a 860 it failed. The toggle bits keep toggling when there is a
861 failure */ 861 failure */
862 for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] && 862 for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] &&
863 Count < 10000; Count++) 863 Count < 10000; Count++)
@@ -866,7 +866,7 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
866 { 866 {
867 jedec_flash_failed(Last[(Count - 3) % 4]); 867 jedec_flash_failed(Last[(Count - 3) % 4]);
868 return -EIO; 868 return -EIO;
869 } 869 }
870 } 870 }
871 } 871 }
872 *retlen = save_len; 872 *retlen = save_len;
@@ -885,24 +885,24 @@ static void jedec_flash_chip_scan(struct jedec_private *priv,unsigned long start
885 // Zero the records 885 // Zero the records
886 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) 886 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
887 priv->chips[I].start = priv->chips[I].length = 0; 887 priv->chips[I].start = priv->chips[I].length = 0;
888 888
889 // Intersect the region with each chip 889 // Intersect the region with each chip
890 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) 890 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
891 { 891 {
892 struct jedec_flash_chip *chip = priv->chips + I; 892 struct jedec_flash_chip *chip = priv->chips + I;
893 unsigned long ByteStart; 893 unsigned long ByteStart;
894 unsigned long ChipEndByte = chip->offset + (chip->size << chip->addrshift); 894 unsigned long ChipEndByte = chip->offset + (chip->size << chip->addrshift);
895 895
896 // End is before this chip or the start is after it 896 // End is before this chip or the start is after it
897 if (start+len < chip->offset || 897 if (start+len < chip->offset ||
898 ChipEndByte - (1 << chip->addrshift) < start) 898 ChipEndByte - (1 << chip->addrshift) < start)
899 continue; 899 continue;
900 900
901 if (start < chip->offset) 901 if (start < chip->offset)
902 { 902 {
903 ByteStart = chip->offset; 903 ByteStart = chip->offset;
904 chip->start = 0; 904 chip->start = 0;
905 } 905 }
906 else 906 else
907 { 907 {
908 chip->start = (start - chip->offset + (1 << chip->addrshift)-1) >> chip->addrshift; 908 chip->start = (start - chip->offset + (1 << chip->addrshift)-1) >> chip->addrshift;
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c
index 30da428eb7b9..edb306c03c0a 100644
--- a/drivers/mtd/chips/jedec_probe.c
+++ b/drivers/mtd/chips/jedec_probe.c
@@ -1,7 +1,7 @@
1/* 1/*
2 Common Flash Interface probe code. 2 Common Flash Interface probe code.
3 (C) 2000 Red Hat. GPL'd. 3 (C) 2000 Red Hat. GPL'd.
4 $Id: jedec_probe.c,v 1.63 2005/02/14 16:30:32 bjd Exp $ 4 $Id: jedec_probe.c,v 1.66 2005/11/07 11:14:23 gleixner Exp $
5 See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5) 5 See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5)
6 for the standard this probe goes back to. 6 for the standard this probe goes back to.
7 7
@@ -1719,7 +1719,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
1719 1719
1720static struct mtd_info *jedec_probe(struct map_info *map); 1720static struct mtd_info *jedec_probe(struct map_info *map);
1721 1721
1722static inline u32 jedec_read_mfr(struct map_info *map, __u32 base, 1722static inline u32 jedec_read_mfr(struct map_info *map, __u32 base,
1723 struct cfi_private *cfi) 1723 struct cfi_private *cfi)
1724{ 1724{
1725 map_word result; 1725 map_word result;
@@ -1730,7 +1730,7 @@ static inline u32 jedec_read_mfr(struct map_info *map, __u32 base,
1730 return result.x[0] & mask; 1730 return result.x[0] & mask;
1731} 1731}
1732 1732
1733static inline u32 jedec_read_id(struct map_info *map, __u32 base, 1733static inline u32 jedec_read_id(struct map_info *map, __u32 base,
1734 struct cfi_private *cfi) 1734 struct cfi_private *cfi)
1735{ 1735{
1736 map_word result; 1736 map_word result;
@@ -1741,7 +1741,7 @@ static inline u32 jedec_read_id(struct map_info *map, __u32 base,
1741 return result.x[0] & mask; 1741 return result.x[0] & mask;
1742} 1742}
1743 1743
1744static inline void jedec_reset(u32 base, struct map_info *map, 1744static inline void jedec_reset(u32 base, struct map_info *map,
1745 struct cfi_private *cfi) 1745 struct cfi_private *cfi)
1746{ 1746{
1747 /* Reset */ 1747 /* Reset */
@@ -1765,7 +1765,7 @@ static inline void jedec_reset(u32 base, struct map_info *map,
1765 * so ensure we're in read mode. Send both the Intel and the AMD command 1765 * so ensure we're in read mode. Send both the Intel and the AMD command
1766 * for this. Intel uses 0xff for this, AMD uses 0xff for NOP, so 1766 * for this. Intel uses 0xff for this, AMD uses 0xff for NOP, so
1767 * this should be safe. 1767 * this should be safe.
1768 */ 1768 */
1769 cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); 1769 cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
1770 /* FIXME - should have reset delay before continuing */ 1770 /* FIXME - should have reset delay before continuing */
1771} 1771}
@@ -1807,14 +1807,14 @@ static int cfi_jedec_setup(struct cfi_private *p_cfi, int index)
1807 printk("Found: %s\n",jedec_table[index].name); 1807 printk("Found: %s\n",jedec_table[index].name);
1808 1808
1809 num_erase_regions = jedec_table[index].NumEraseRegions; 1809 num_erase_regions = jedec_table[index].NumEraseRegions;
1810 1810
1811 p_cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL); 1811 p_cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL);
1812 if (!p_cfi->cfiq) { 1812 if (!p_cfi->cfiq) {
1813 //xx printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name); 1813 //xx printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
1814 return 0; 1814 return 0;
1815 } 1815 }
1816 1816
1817 memset(p_cfi->cfiq,0,sizeof(struct cfi_ident)); 1817 memset(p_cfi->cfiq,0,sizeof(struct cfi_ident));
1818 1818
1819 p_cfi->cfiq->P_ID = jedec_table[index].CmdSet; 1819 p_cfi->cfiq->P_ID = jedec_table[index].CmdSet;
1820 p_cfi->cfiq->NumEraseRegions = jedec_table[index].NumEraseRegions; 1820 p_cfi->cfiq->NumEraseRegions = jedec_table[index].NumEraseRegions;
@@ -1969,7 +1969,7 @@ static inline int jedec_match( __u32 base,
1969 cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL); 1969 cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
1970 /* FIXME - should have a delay before continuing */ 1970 /* FIXME - should have a delay before continuing */
1971 1971
1972 match_done: 1972 match_done:
1973 return rc; 1973 return rc;
1974} 1974}
1975 1975
@@ -1998,23 +1998,23 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
1998 "Probe at base(0x%08x) past the end of the map(0x%08lx)\n", 1998 "Probe at base(0x%08x) past the end of the map(0x%08lx)\n",
1999 base, map->size -1); 1999 base, map->size -1);
2000 return 0; 2000 return 0;
2001 2001
2002 } 2002 }
2003 /* Ensure the unlock addresses we try stay inside the map */ 2003 /* Ensure the unlock addresses we try stay inside the map */
2004 probe_offset1 = cfi_build_cmd_addr( 2004 probe_offset1 = cfi_build_cmd_addr(
2005 cfi->addr_unlock1, 2005 cfi->addr_unlock1,
2006 cfi_interleave(cfi), 2006 cfi_interleave(cfi),
2007 cfi->device_type); 2007 cfi->device_type);
2008 probe_offset2 = cfi_build_cmd_addr( 2008 probe_offset2 = cfi_build_cmd_addr(
2009 cfi->addr_unlock1, 2009 cfi->addr_unlock1,
2010 cfi_interleave(cfi), 2010 cfi_interleave(cfi),
2011 cfi->device_type); 2011 cfi->device_type);
2012 if ( ((base + probe_offset1 + map_bankwidth(map)) >= map->size) || 2012 if ( ((base + probe_offset1 + map_bankwidth(map)) >= map->size) ||
2013 ((base + probe_offset2 + map_bankwidth(map)) >= map->size)) 2013 ((base + probe_offset2 + map_bankwidth(map)) >= map->size))
2014 { 2014 {
2015 goto retry; 2015 goto retry;
2016 } 2016 }
2017 2017
2018 /* Reset */ 2018 /* Reset */
2019 jedec_reset(base, map, cfi); 2019 jedec_reset(base, map, cfi);
2020 2020
@@ -2027,13 +2027,13 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
2027 /* FIXME - should have a delay before continuing */ 2027 /* FIXME - should have a delay before continuing */
2028 2028
2029 if (!cfi->numchips) { 2029 if (!cfi->numchips) {
2030 /* This is the first time we're called. Set up the CFI 2030 /* This is the first time we're called. Set up the CFI
2031 stuff accordingly and return */ 2031 stuff accordingly and return */
2032 2032
2033 cfi->mfr = jedec_read_mfr(map, base, cfi); 2033 cfi->mfr = jedec_read_mfr(map, base, cfi);
2034 cfi->id = jedec_read_id(map, base, cfi); 2034 cfi->id = jedec_read_id(map, base, cfi);
2035 DEBUG(MTD_DEBUG_LEVEL3, 2035 DEBUG(MTD_DEBUG_LEVEL3,
2036 "Search for id:(%02x %02x) interleave(%d) type(%d)\n", 2036 "Search for id:(%02x %02x) interleave(%d) type(%d)\n",
2037 cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type); 2037 cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type);
2038 for (i=0; i<sizeof(jedec_table)/sizeof(jedec_table[0]); i++) { 2038 for (i=0; i<sizeof(jedec_table)/sizeof(jedec_table[0]); i++) {
2039 if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) { 2039 if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) {
@@ -2062,7 +2062,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
2062 return 0; 2062 return 0;
2063 } 2063 }
2064 } 2064 }
2065 2065
2066 /* Check each previous chip locations to see if it's an alias */ 2066 /* Check each previous chip locations to see if it's an alias */
2067 for (i=0; i < (base >> cfi->chipshift); i++) { 2067 for (i=0; i < (base >> cfi->chipshift); i++) {
2068 unsigned long start; 2068 unsigned long start;
@@ -2083,7 +2083,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
2083 map->name, base, start); 2083 map->name, base, start);
2084 return 0; 2084 return 0;
2085 } 2085 }
2086 2086
2087 /* Yes, it's actually got the device IDs as data. Most 2087 /* Yes, it's actually got the device IDs as data. Most
2088 * unfortunate. Stick the new chip in read mode 2088 * unfortunate. Stick the new chip in read mode
2089 * too and if it's the same, assume it's an alias. */ 2089 * too and if it's the same, assume it's an alias. */
@@ -2097,20 +2097,20 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
2097 } 2097 }
2098 } 2098 }
2099 } 2099 }
2100 2100
2101 /* OK, if we got to here, then none of the previous chips appear to 2101 /* OK, if we got to here, then none of the previous chips appear to
2102 be aliases for the current one. */ 2102 be aliases for the current one. */
2103 set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */ 2103 set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */
2104 cfi->numchips++; 2104 cfi->numchips++;
2105 2105
2106ok_out: 2106ok_out:
2107 /* Put it back into Read Mode */ 2107 /* Put it back into Read Mode */
2108 jedec_reset(base, map, cfi); 2108 jedec_reset(base, map, cfi);
2109 2109
2110 printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n", 2110 printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n",
2111 map->name, cfi_interleave(cfi), cfi->device_type*8, base, 2111 map->name, cfi_interleave(cfi), cfi->device_type*8, base,
2112 map->bankwidth*8); 2112 map->bankwidth*8);
2113 2113
2114 return 1; 2114 return 1;
2115} 2115}
2116 2116
diff --git a/drivers/mtd/chips/map_absent.c b/drivers/mtd/chips/map_absent.c
index c6c83833cc32..a611de9b1515 100644
--- a/drivers/mtd/chips/map_absent.c
+++ b/drivers/mtd/chips/map_absent.c
@@ -1,11 +1,11 @@
1/* 1/*
2 * Common code to handle absent "placeholder" devices 2 * Common code to handle absent "placeholder" devices
3 * Copyright 2001 Resilience Corporation <ebrower@resilience.com> 3 * Copyright 2001 Resilience Corporation <ebrower@resilience.com>
4 * $Id: map_absent.c,v 1.5 2004/11/16 18:29:00 dwmw2 Exp $ 4 * $Id: map_absent.c,v 1.6 2005/11/07 11:14:23 gleixner Exp $
5 * 5 *
6 * This map driver is used to allocate "placeholder" MTD 6 * This map driver is used to allocate "placeholder" MTD
7 * devices on systems that have socketed/removable media. 7 * devices on systems that have socketed/removable media.
8 * Use of this driver as a fallback preserves the expected 8 * Use of this driver as a fallback preserves the expected
9 * registration of MTD device nodes regardless of probe outcome. 9 * registration of MTD device nodes regardless of probe outcome.
10 * A usage example is as follows: 10 * A usage example is as follows:
11 * 11 *
@@ -80,7 +80,7 @@ static int map_absent_read(struct mtd_info *mtd, loff_t from, size_t len, size_t
80static int map_absent_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) 80static int map_absent_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
81{ 81{
82 *retlen = 0; 82 *retlen = 0;
83 return -ENODEV; 83 return -ENODEV;
84} 84}
85 85
86static int map_absent_erase(struct mtd_info *mtd, struct erase_info *instr) 86static int map_absent_erase(struct mtd_info *mtd, struct erase_info *instr)
diff --git a/drivers/mtd/chips/sharp.c b/drivers/mtd/chips/sharp.c
index c3cf0f63bc93..2d26bdef82d5 100644
--- a/drivers/mtd/chips/sharp.c
+++ b/drivers/mtd/chips/sharp.c
@@ -4,7 +4,7 @@
4 * Copyright 2000,2001 David A. Schleef <ds@schleef.org> 4 * Copyright 2000,2001 David A. Schleef <ds@schleef.org>
5 * 2000,2001 Lineo, Inc. 5 * 2000,2001 Lineo, Inc.
6 * 6 *
7 * $Id: sharp.c,v 1.14 2004/08/09 13:19:43 dwmw2 Exp $ 7 * $Id: sharp.c,v 1.16 2005/11/07 11:14:23 gleixner Exp $
8 * 8 *
9 * Devices supported: 9 * Devices supported:
10 * LH28F016SCT Symmetrical block flash memory, 2Mx8 10 * LH28F016SCT Symmetrical block flash memory, 2Mx8
@@ -31,6 +31,7 @@
31#include <linux/mtd/cfi.h> 31#include <linux/mtd/cfi.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/init.h> 33#include <linux/init.h>
34#include <linux/slab.h>
34 35
35#define CMD_RESET 0xffffffff 36#define CMD_RESET 0xffffffff
36#define CMD_READ_ID 0x90909090 37#define CMD_READ_ID 0x90909090
@@ -214,7 +215,7 @@ static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd)
214/* This function returns with the chip->mutex lock held. */ 215/* This function returns with the chip->mutex lock held. */
215static int sharp_wait(struct map_info *map, struct flchip *chip) 216static int sharp_wait(struct map_info *map, struct flchip *chip)
216{ 217{
217 __u16 status; 218 int status, i;
218 unsigned long timeo = jiffies + HZ; 219 unsigned long timeo = jiffies + HZ;
219 DECLARE_WAITQUEUE(wait, current); 220 DECLARE_WAITQUEUE(wait, current);
220 int adr = 0; 221 int adr = 0;
@@ -227,13 +228,11 @@ retry:
227 map_write32(map,CMD_READ_STATUS,adr); 228 map_write32(map,CMD_READ_STATUS,adr);
228 chip->state = FL_STATUS; 229 chip->state = FL_STATUS;
229 case FL_STATUS: 230 case FL_STATUS:
230 status = map_read32(map,adr); 231 for(i=0;i<100;i++){
231//printk("status=%08x\n",status); 232 status = map_read32(map,adr);
232 233 if((status & SR_READY)==SR_READY)
233 udelay(100); 234 break;
234 if((status & SR_READY)!=SR_READY){ 235 udelay(1);
235//printk(".status=%08x\n",status);
236 udelay(100);
237 } 236 }
238 break; 237 break;
239 default: 238 default:
@@ -460,12 +459,12 @@ static int sharp_do_wait_for_ready(struct map_info *map, struct flchip *chip,
460 remove_wait_queue(&chip->wq, &wait); 459 remove_wait_queue(&chip->wq, &wait);
461 460
462 //spin_lock_bh(chip->mutex); 461 //spin_lock_bh(chip->mutex);
463 462
464 if (signal_pending(current)){ 463 if (signal_pending(current)){
465 ret = -EINTR; 464 ret = -EINTR;
466 goto out; 465 goto out;
467 } 466 }
468 467
469 } 468 }
470 ret = -ETIME; 469 ret = -ETIME;
471out: 470out:
@@ -564,7 +563,7 @@ static int sharp_suspend(struct mtd_info *mtd)
564static void sharp_resume(struct mtd_info *mtd) 563static void sharp_resume(struct mtd_info *mtd)
565{ 564{
566 printk("sharp_resume()\n"); 565 printk("sharp_resume()\n");
567 566
568} 567}
569 568
570static void sharp_destroy(struct mtd_info *mtd) 569static void sharp_destroy(struct mtd_info *mtd)
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c
index ef24837019d3..6b8bb2e4dcfd 100644
--- a/drivers/mtd/cmdlinepart.c
+++ b/drivers/mtd/cmdlinepart.c
@@ -1,24 +1,24 @@
1/* 1/*
2 * $Id: cmdlinepart.c,v 1.18 2005/06/07 15:04:26 joern Exp $ 2 * $Id: cmdlinepart.c,v 1.19 2005/11/07 11:14:19 gleixner Exp $
3 * 3 *
4 * Read flash partition table from command line 4 * Read flash partition table from command line
5 * 5 *
6 * Copyright 2002 SYSGO Real-Time Solutions GmbH 6 * Copyright 2002 SYSGO Real-Time Solutions GmbH
7 * 7 *
8 * The format for the command line is as follows: 8 * The format for the command line is as follows:
9 * 9 *
10 * mtdparts=<mtddef>[;<mtddef] 10 * mtdparts=<mtddef>[;<mtddef]
11 * <mtddef> := <mtd-id>:<partdef>[,<partdef>] 11 * <mtddef> := <mtd-id>:<partdef>[,<partdef>]
12 * <partdef> := <size>[@offset][<name>][ro] 12 * <partdef> := <size>[@offset][<name>][ro]
13 * <mtd-id> := unique name used in mapping driver/device (mtd->name) 13 * <mtd-id> := unique name used in mapping driver/device (mtd->name)
14 * <size> := standard linux memsize OR "-" to denote all remaining space 14 * <size> := standard linux memsize OR "-" to denote all remaining space
15 * <name> := '(' NAME ')' 15 * <name> := '(' NAME ')'
16 * 16 *
17 * Examples: 17 * Examples:
18 * 18 *
19 * 1 NOR Flash, with 1 single writable partition: 19 * 1 NOR Flash, with 1 single writable partition:
20 * edb7312-nor:- 20 * edb7312-nor:-
21 * 21 *
22 * 1 NOR Flash with 2 partitions, 1 NAND with one 22 * 1 NOR Flash with 2 partitions, 1 NAND with one
23 * edb7312-nor:256k(ARMboot)ro,-(root);edb7312-nand:-(home) 23 * edb7312-nor:256k(ARMboot)ro,-(root);edb7312-nand:-(home)
24 */ 24 */
@@ -60,17 +60,17 @@ static int cmdline_parsed = 0;
60 60
61/* 61/*
62 * Parse one partition definition for an MTD. Since there can be many 62 * Parse one partition definition for an MTD. Since there can be many
63 * comma separated partition definitions, this function calls itself 63 * comma separated partition definitions, this function calls itself
64 * recursively until no more partition definitions are found. Nice side 64 * recursively until no more partition definitions are found. Nice side
65 * effect: the memory to keep the mtd_partition structs and the names 65 * effect: the memory to keep the mtd_partition structs and the names
66 * is allocated upon the last definition being found. At that point the 66 * is allocated upon the last definition being found. At that point the
67 * syntax has been verified ok. 67 * syntax has been verified ok.
68 */ 68 */
69static struct mtd_partition * newpart(char *s, 69static struct mtd_partition * newpart(char *s,
70 char **retptr, 70 char **retptr,
71 int *num_parts, 71 int *num_parts,
72 int this_part, 72 int this_part,
73 unsigned char **extra_mem_ptr, 73 unsigned char **extra_mem_ptr,
74 int extra_mem_size) 74 int extra_mem_size)
75{ 75{
76 struct mtd_partition *parts; 76 struct mtd_partition *parts;
@@ -102,7 +102,7 @@ static struct mtd_partition * newpart(char *s,
102 mask_flags = 0; /* this is going to be a regular partition */ 102 mask_flags = 0; /* this is going to be a regular partition */
103 delim = 0; 103 delim = 0;
104 /* check for offset */ 104 /* check for offset */
105 if (*s == '@') 105 if (*s == '@')
106 { 106 {
107 s++; 107 s++;
108 offset = memparse(s, &s); 108 offset = memparse(s, &s);
@@ -112,7 +112,7 @@ static struct mtd_partition * newpart(char *s,
112 { 112 {
113 delim = ')'; 113 delim = ')';
114 } 114 }
115 115
116 if (delim) 116 if (delim)
117 { 117 {
118 char *p; 118 char *p;
@@ -131,12 +131,12 @@ static struct mtd_partition * newpart(char *s,
131 name = NULL; 131 name = NULL;
132 name_len = 13; /* Partition_000 */ 132 name_len = 13; /* Partition_000 */
133 } 133 }
134 134
135 /* record name length for memory allocation later */ 135 /* record name length for memory allocation later */
136 extra_mem_size += name_len + 1; 136 extra_mem_size += name_len + 1;
137 137
138 /* test for options */ 138 /* test for options */
139 if (strncmp(s, "ro", 2) == 0) 139 if (strncmp(s, "ro", 2) == 0)
140 { 140 {
141 mask_flags |= MTD_WRITEABLE; 141 mask_flags |= MTD_WRITEABLE;
142 s += 2; 142 s += 2;
@@ -151,7 +151,7 @@ static struct mtd_partition * newpart(char *s,
151 return NULL; 151 return NULL;
152 } 152 }
153 /* more partitions follow, parse them */ 153 /* more partitions follow, parse them */
154 if ((parts = newpart(s + 1, &s, num_parts, 154 if ((parts = newpart(s + 1, &s, num_parts,
155 this_part + 1, &extra_mem, extra_mem_size)) == 0) 155 this_part + 1, &extra_mem, extra_mem_size)) == 0)
156 return NULL; 156 return NULL;
157 } 157 }
@@ -187,7 +187,7 @@ static struct mtd_partition * newpart(char *s,
187 extra_mem += name_len + 1; 187 extra_mem += name_len + 1;
188 188
189 dbg(("partition %d: name <%s>, offset %x, size %x, mask flags %x\n", 189 dbg(("partition %d: name <%s>, offset %x, size %x, mask flags %x\n",
190 this_part, 190 this_part,
191 parts[this_part].name, 191 parts[this_part].name,
192 parts[this_part].offset, 192 parts[this_part].offset,
193 parts[this_part].size, 193 parts[this_part].size,
@@ -204,8 +204,8 @@ static struct mtd_partition * newpart(char *s,
204 return parts; 204 return parts;
205} 205}
206 206
207/* 207/*
208 * Parse the command line. 208 * Parse the command line.
209 */ 209 */
210static int mtdpart_setup_real(char *s) 210static int mtdpart_setup_real(char *s)
211{ 211{
@@ -230,7 +230,7 @@ static int mtdpart_setup_real(char *s)
230 230
231 dbg(("parsing <%s>\n", p+1)); 231 dbg(("parsing <%s>\n", p+1));
232 232
233 /* 233 /*
234 * parse one mtd. have it reserve memory for the 234 * parse one mtd. have it reserve memory for the
235 * struct cmdline_mtd_partition and the mtd-id string. 235 * struct cmdline_mtd_partition and the mtd-id string.
236 */ 236 */
@@ -239,7 +239,7 @@ static int mtdpart_setup_real(char *s)
239 &num_parts, /* out: number of parts */ 239 &num_parts, /* out: number of parts */
240 0, /* first partition */ 240 0, /* first partition */
241 (unsigned char**)&this_mtd, /* out: extra mem */ 241 (unsigned char**)&this_mtd, /* out: extra mem */
242 mtd_id_len + 1 + sizeof(*this_mtd) + 242 mtd_id_len + 1 + sizeof(*this_mtd) +
243 sizeof(void*)-1 /*alignment*/); 243 sizeof(void*)-1 /*alignment*/);
244 if(!parts) 244 if(!parts)
245 { 245 {
@@ -254,21 +254,21 @@ static int mtdpart_setup_real(char *s)
254 } 254 }
255 255
256 /* align this_mtd */ 256 /* align this_mtd */
257 this_mtd = (struct cmdline_mtd_partition *) 257 this_mtd = (struct cmdline_mtd_partition *)
258 ALIGN((unsigned long)this_mtd, sizeof(void*)); 258 ALIGN((unsigned long)this_mtd, sizeof(void*));
259 /* enter results */ 259 /* enter results */
260 this_mtd->parts = parts; 260 this_mtd->parts = parts;
261 this_mtd->num_parts = num_parts; 261 this_mtd->num_parts = num_parts;
262 this_mtd->mtd_id = (char*)(this_mtd + 1); 262 this_mtd->mtd_id = (char*)(this_mtd + 1);
263 strlcpy(this_mtd->mtd_id, mtd_id, mtd_id_len + 1); 263 strlcpy(this_mtd->mtd_id, mtd_id, mtd_id_len + 1);
264 264
265 /* link into chain */ 265 /* link into chain */
266 this_mtd->next = partitions; 266 this_mtd->next = partitions;
267 partitions = this_mtd; 267 partitions = this_mtd;
268 268
269 dbg(("mtdid=<%s> num_parts=<%d>\n", 269 dbg(("mtdid=<%s> num_parts=<%d>\n",
270 this_mtd->mtd_id, this_mtd->num_parts)); 270 this_mtd->mtd_id, this_mtd->num_parts));
271 271
272 272
273 /* EOS - we're done */ 273 /* EOS - we're done */
274 if (*s == 0) 274 if (*s == 0)
@@ -292,7 +292,7 @@ static int mtdpart_setup_real(char *s)
292 * information. It returns partitions for the requested mtd device, or 292 * information. It returns partitions for the requested mtd device, or
293 * the first one in the chain if a NULL mtd_id is passed in. 293 * the first one in the chain if a NULL mtd_id is passed in.
294 */ 294 */
295static int parse_cmdline_partitions(struct mtd_info *master, 295static int parse_cmdline_partitions(struct mtd_info *master,
296 struct mtd_partition **pparts, 296 struct mtd_partition **pparts,
297 unsigned long origin) 297 unsigned long origin)
298{ 298{
@@ -322,7 +322,7 @@ static int parse_cmdline_partitions(struct mtd_info *master,
322 part->parts[i].size = master->size - offset; 322 part->parts[i].size = master->size - offset;
323 if (offset + part->parts[i].size > master->size) 323 if (offset + part->parts[i].size > master->size)
324 { 324 {
325 printk(KERN_WARNING ERRP 325 printk(KERN_WARNING ERRP
326 "%s: partitioning exceeds flash size, truncating\n", 326 "%s: partitioning exceeds flash size, truncating\n",
327 part->mtd_id); 327 part->mtd_id);
328 part->parts[i].size = master->size - offset; 328 part->parts[i].size = master->size - offset;
@@ -338,8 +338,8 @@ static int parse_cmdline_partitions(struct mtd_info *master,
338} 338}
339 339
340 340
341/* 341/*
342 * This is the handler for our kernel parameter, called from 342 * This is the handler for our kernel parameter, called from
343 * main.c::checksetup(). Note that we can not yet kmalloc() anything, 343 * main.c::checksetup(). Note that we can not yet kmalloc() anything,
344 * so we only save the commandline for later processing. 344 * so we only save the commandline for later processing.
345 * 345 *
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index c4a56a4ac5e2..9a2aa4033c6a 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -1,5 +1,5 @@
1# drivers/mtd/maps/Kconfig 1# drivers/mtd/maps/Kconfig
2# $Id: Kconfig,v 1.15 2004/12/22 17:51:15 joern Exp $ 2# $Id: Kconfig,v 1.18 2005/11/07 11:14:24 gleixner Exp $
3 3
4menu "Self-contained MTD device drivers" 4menu "Self-contained MTD device drivers"
5 depends on MTD!=n 5 depends on MTD!=n
@@ -110,7 +110,7 @@ config MTDRAM_ABS_POS
110 If you have system RAM accessible by the CPU but not used by Linux 110 If you have system RAM accessible by the CPU but not used by Linux
111 in normal operation, you can give the physical address at which the 111 in normal operation, you can give the physical address at which the
112 available RAM starts, and the MTDRAM driver will use it instead of 112 available RAM starts, and the MTDRAM driver will use it instead of
113 allocating space from Linux's available memory. Otherwise, leave 113 allocating space from Linux's available memory. Otherwise, leave
114 this set to zero. Most people will want to leave this as zero. 114 this set to zero. Most people will want to leave this as zero.
115 115
116config MTD_BLKMTD 116config MTD_BLKMTD
@@ -165,7 +165,7 @@ config MTD_DOC2001
165 select MTD_DOCPROBE 165 select MTD_DOCPROBE
166 select MTD_NAND_IDS 166 select MTD_NAND_IDS
167 ---help--- 167 ---help---
168 This provides an alternative MTD device driver for the M-Systems 168 This provides an alternative MTD device driver for the M-Systems
169 DiskOnChip Millennium devices. Use this if you have problems with 169 DiskOnChip Millennium devices. Use this if you have problems with
170 the combined DiskOnChip 2000 and Millennium driver above. To get 170 the combined DiskOnChip 2000 and Millennium driver above. To get
171 the DiskOnChip probe code to load and use this driver instead of 171 the DiskOnChip probe code to load and use this driver instead of
@@ -192,7 +192,7 @@ config MTD_DOC2001PLUS
192 192
193 If you use this device, you probably also want to enable the INFTL 193 If you use this device, you probably also want to enable the INFTL
194 'Inverse NAND Flash Translation Layer' option below, which is used 194 'Inverse NAND Flash Translation Layer' option below, which is used
195 to emulate a block device by using a kind of file system on the 195 to emulate a block device by using a kind of file system on the
196 flash chips. 196 flash chips.
197 197
198 NOTE: This driver will soon be replaced by the new DiskOnChip driver 198 NOTE: This driver will soon be replaced by the new DiskOnChip driver
diff --git a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c
index 59a29e616a22..f9db52f6bf00 100644
--- a/drivers/mtd/devices/blkmtd.c
+++ b/drivers/mtd/devices/blkmtd.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: blkmtd.c,v 1.24 2004/11/16 18:29:01 dwmw2 Exp $ 2 * $Id: blkmtd.c,v 1.27 2005/11/07 11:14:24 gleixner Exp $
3 * 3 *
4 * blkmtd.c - use a block device as a fake MTD 4 * blkmtd.c - use a block device as a fake MTD
5 * 5 *
@@ -39,7 +39,7 @@
39 39
40/* Default erase size in K, always make it a multiple of PAGE_SIZE */ 40/* Default erase size in K, always make it a multiple of PAGE_SIZE */
41#define CONFIG_MTD_BLKDEV_ERASESIZE (128 << 10) /* 128KiB */ 41#define CONFIG_MTD_BLKDEV_ERASESIZE (128 << 10) /* 128KiB */
42#define VERSION "$Revision: 1.24 $" 42#define VERSION "$Revision: 1.27 $"
43 43
44/* Info for the block device */ 44/* Info for the block device */
45struct blkmtd_dev { 45struct blkmtd_dev {
@@ -117,7 +117,7 @@ static int bi_write_complete(struct bio *bio, unsigned int bytes_done, int error
117 unlock_page(page); 117 unlock_page(page);
118 page_cache_release(page); 118 page_cache_release(page);
119 } while (bvec >= bio->bi_io_vec); 119 } while (bvec >= bio->bi_io_vec);
120 120
121 complete((struct completion*)bio->bi_private); 121 complete((struct completion*)bio->bi_private);
122 return 0; 122 return 0;
123} 123}
@@ -135,7 +135,7 @@ static int blkmtd_readpage(struct blkmtd_dev *dev, struct page *page)
135 unlock_page(page); 135 unlock_page(page);
136 return 0; 136 return 0;
137 } 137 }
138 138
139 ClearPageUptodate(page); 139 ClearPageUptodate(page);
140 ClearPageError(page); 140 ClearPageError(page);
141 141
@@ -707,7 +707,7 @@ static struct blkmtd_dev *add_device(char *devname, int readonly, int erase_size
707 dev->mtd_info.erasesize >> 10, 707 dev->mtd_info.erasesize >> 10,
708 readonly ? "(read-only)" : ""); 708 readonly ? "(read-only)" : "");
709 } 709 }
710 710
711 return dev; 711 return dev;
712 712
713 devinit_err: 713 devinit_err:
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index 4a7a805e7564..0aaa0ced9aba 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: block2mtd.c,v 1.28 2005/03/19 22:40:44 gleixner Exp $ 2 * $Id: block2mtd.c,v 1.29 2005/11/07 11:14:24 gleixner Exp $
3 * 3 *
4 * block2mtd.c - create an mtd from a block device 4 * block2mtd.c - create an mtd from a block device
5 * 5 *
@@ -19,7 +19,7 @@
19#include <linux/mtd/mtd.h> 19#include <linux/mtd/mtd.h>
20#include <linux/buffer_head.h> 20#include <linux/buffer_head.h>
21 21
22#define VERSION "$Revision: 1.28 $" 22#define VERSION "$Revision: 1.29 $"
23 23
24 24
25#define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args) 25#define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args)
@@ -111,7 +111,7 @@ static int _block2mtd_erase(struct block2mtd_dev *dev, loff_t to, size_t len)
111 return PTR_ERR(page); 111 return PTR_ERR(page);
112 112
113 max = (u_long*)page_address(page) + PAGE_SIZE; 113 max = (u_long*)page_address(page) + PAGE_SIZE;
114 for (p=(u_long*)page_address(page); p<max; p++) 114 for (p=(u_long*)page_address(page); p<max; p++)
115 if (*p != -1UL) { 115 if (*p != -1UL) {
116 lock_page(page); 116 lock_page(page);
117 memset(page_address(page), 0xff, PAGE_SIZE); 117 memset(page_address(page), 0xff, PAGE_SIZE);
@@ -206,7 +206,7 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf,
206 if (retlen) 206 if (retlen)
207 *retlen = 0; 207 *retlen = 0;
208 while (len) { 208 while (len) {
209 if ((offset+len) > PAGE_SIZE) 209 if ((offset+len) > PAGE_SIZE)
210 cpylen = PAGE_SIZE - offset; // multiple pages 210 cpylen = PAGE_SIZE - offset; // multiple pages
211 else 211 else
212 cpylen = len; // this page 212 cpylen = len; // this page
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
index 5fc532895a24..be5e88b3888d 100644
--- a/drivers/mtd/devices/doc2000.c
+++ b/drivers/mtd/devices/doc2000.c
@@ -4,7 +4,7 @@
4 * (c) 1999 Machine Vision Holdings, Inc. 4 * (c) 1999 Machine Vision Holdings, Inc.
5 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> 5 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
6 * 6 *
7 * $Id: doc2000.c,v 1.66 2005/01/05 18:05:12 dwmw2 Exp $ 7 * $Id: doc2000.c,v 1.67 2005/11/07 11:14:24 gleixner Exp $
8 */ 8 */
9 9
10#include <linux/kernel.h> 10#include <linux/kernel.h>
@@ -58,7 +58,7 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
58 size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); 58 size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
59static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, 59static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
60 size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); 60 size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
61static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, 61static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
62 unsigned long count, loff_t to, size_t *retlen, 62 unsigned long count, loff_t to, size_t *retlen,
63 u_char *eccbuf, struct nand_oobinfo *oobsel); 63 u_char *eccbuf, struct nand_oobinfo *oobsel);
64static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, 64static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
@@ -76,14 +76,14 @@ static void DoC_Delay(struct DiskOnChip *doc, unsigned short cycles)
76{ 76{
77 volatile char dummy; 77 volatile char dummy;
78 int i; 78 int i;
79 79
80 for (i = 0; i < cycles; i++) { 80 for (i = 0; i < cycles; i++) {
81 if (DoC_is_Millennium(doc)) 81 if (DoC_is_Millennium(doc))
82 dummy = ReadDOC(doc->virtadr, NOP); 82 dummy = ReadDOC(doc->virtadr, NOP);
83 else 83 else
84 dummy = ReadDOC(doc->virtadr, DOCStatus); 84 dummy = ReadDOC(doc->virtadr, DOCStatus);
85 } 85 }
86 86
87} 87}
88 88
89/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */ 89/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
@@ -220,8 +220,8 @@ static int DoC_Address(struct DiskOnChip *doc, int numbytes, unsigned long ofs,
220 WriteDOC(ofs & 0xff, docptr, WritePipeTerm); 220 WriteDOC(ofs & 0xff, docptr, WritePipeTerm);
221 221
222 DoC_Delay(doc, 2); /* Needed for some slow flash chips. mf. */ 222 DoC_Delay(doc, 2); /* Needed for some slow flash chips. mf. */
223 223
224 /* FIXME: The SlowIO's for millennium could be replaced by 224 /* FIXME: The SlowIO's for millennium could be replaced by
225 a single WritePipeTerm here. mf. */ 225 a single WritePipeTerm here. mf. */
226 226
227 /* Lower the ALE line */ 227 /* Lower the ALE line */
@@ -377,9 +377,9 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
377 if (mfr == 0xff || mfr == 0) 377 if (mfr == 0xff || mfr == 0)
378 return 0; 378 return 0;
379 379
380 /* Check it's the same as the first chip we identified. 380 /* Check it's the same as the first chip we identified.
381 * M-Systems say that any given DiskOnChip device should only 381 * M-Systems say that any given DiskOnChip device should only
382 * contain _one_ type of flash part, although that's not a 382 * contain _one_ type of flash part, although that's not a
383 * hardware restriction. */ 383 * hardware restriction. */
384 if (doc->mfr) { 384 if (doc->mfr) {
385 if (doc->mfr == mfr && doc->id == id) 385 if (doc->mfr == mfr && doc->id == id)
@@ -397,7 +397,7 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
397 for (j = 0; nand_manuf_ids[j].id != 0x0; j++) { 397 for (j = 0; nand_manuf_ids[j].id != 0x0; j++) {
398 if (nand_manuf_ids[j].id == mfr) 398 if (nand_manuf_ids[j].id == mfr)
399 break; 399 break;
400 } 400 }
401 printk(KERN_INFO 401 printk(KERN_INFO
402 "Flash chip found: Manufacturer ID: %2.2X, " 402 "Flash chip found: Manufacturer ID: %2.2X, "
403 "Chip ID: %2.2X (%s:%s)\n", mfr, id, 403 "Chip ID: %2.2X (%s:%s)\n", mfr, id,
@@ -405,7 +405,7 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
405 if (!doc->mfr) { 405 if (!doc->mfr) {
406 doc->mfr = mfr; 406 doc->mfr = mfr;
407 doc->id = id; 407 doc->id = id;
408 doc->chipshift = 408 doc->chipshift =
409 ffs((nand_flash_ids[i].chipsize << 20)) - 1; 409 ffs((nand_flash_ids[i].chipsize << 20)) - 1;
410 doc->page256 = (nand_flash_ids[i].pagesize == 256) ? 1 : 0; 410 doc->page256 = (nand_flash_ids[i].pagesize == 256) ? 1 : 0;
411 doc->pageadrlen = doc->chipshift > 25 ? 3 : 2; 411 doc->pageadrlen = doc->chipshift > 25 ? 3 : 2;
@@ -467,7 +467,7 @@ static void DoC_ScanChips(struct DiskOnChip *this, int maxchips)
467 467
468 ret = 0; 468 ret = 0;
469 469
470 /* Fill out the chip array with {floor, chipno} for each 470 /* Fill out the chip array with {floor, chipno} for each
471 * detected chip in the device. */ 471 * detected chip in the device. */
472 for (floor = 0; floor < MAX_FLOORS; floor++) { 472 for (floor = 0; floor < MAX_FLOORS; floor++) {
473 for (chip = 0; chip < numchips[floor]; chip++) { 473 for (chip = 0; chip < numchips[floor]; chip++) {
@@ -757,12 +757,12 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
757 (long)from, eccbuf[0], eccbuf[1], eccbuf[2], 757 (long)from, eccbuf[0], eccbuf[1], eccbuf[2],
758 eccbuf[3], eccbuf[4], eccbuf[5]); 758 eccbuf[3], eccbuf[4], eccbuf[5]);
759#endif 759#endif
760 760
761 /* disable the ECC engine */ 761 /* disable the ECC engine */
762 WriteDOC(DOC_ECC_DIS, docptr , ECCConf); 762 WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
763 } 763 }
764 764
765 /* according to 11.4.1, we need to wait for the busy line 765 /* according to 11.4.1, we need to wait for the busy line
766 * drop if we read to the end of the page. */ 766 * drop if we read to the end of the page. */
767 if(0 == ((from + len) & 0x1ff)) 767 if(0 == ((from + len) & 0x1ff))
768 { 768 {
@@ -941,7 +941,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
941 941
942 /* Let the caller know we completed it */ 942 /* Let the caller know we completed it */
943 *retlen += len; 943 *retlen += len;
944 944
945 if (eccbuf) { 945 if (eccbuf) {
946 unsigned char x[8]; 946 unsigned char x[8];
947 size_t dummy; 947 size_t dummy;
@@ -950,10 +950,10 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
950 /* Write the ECC data to flash */ 950 /* Write the ECC data to flash */
951 for (di=0; di<6; di++) 951 for (di=0; di<6; di++)
952 x[di] = eccbuf[di]; 952 x[di] = eccbuf[di];
953 953
954 x[6]=0x55; 954 x[6]=0x55;
955 x[7]=0x55; 955 x[7]=0x55;
956 956
957 ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x); 957 ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x);
958 if (ret) { 958 if (ret) {
959 up(&this->lock); 959 up(&this->lock);
@@ -970,7 +970,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
970 return 0; 970 return 0;
971} 971}
972 972
973static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, 973static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
974 unsigned long count, loff_t to, size_t *retlen, 974 unsigned long count, loff_t to, size_t *retlen,
975 u_char *eccbuf, struct nand_oobinfo *oobsel) 975 u_char *eccbuf, struct nand_oobinfo *oobsel)
976{ 976{
@@ -1022,7 +1022,7 @@ static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
1022 break; 1022 break;
1023 1023
1024 to += thislen; 1024 to += thislen;
1025 } 1025 }
1026 1026
1027 up(&writev_buf_sem); 1027 up(&writev_buf_sem);
1028 *retlen = totretlen; 1028 *retlen = totretlen;
@@ -1080,7 +1080,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
1080 /* Reading the full OOB data drops us off of the end of the page, 1080 /* Reading the full OOB data drops us off of the end of the page,
1081 * causing the flash device to go into busy mode, so we need 1081 * causing the flash device to go into busy mode, so we need
1082 * to wait until ready 11.4.1 and Toshiba TC58256FT docs */ 1082 * to wait until ready 11.4.1 and Toshiba TC58256FT docs */
1083 1083
1084 ret = DoC_WaitReady(this); 1084 ret = DoC_WaitReady(this);
1085 1085
1086 up(&this->lock); 1086 up(&this->lock);
@@ -1190,7 +1190,7 @@ static int doc_write_oob_nolock(struct mtd_info *mtd, loff_t ofs, size_t len,
1190 return 0; 1190 return 0;
1191 1191
1192} 1192}
1193 1193
1194static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, 1194static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
1195 size_t * retlen, const u_char * buf) 1195 size_t * retlen, const u_char * buf)
1196{ 1196{
@@ -1222,7 +1222,7 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
1222 } 1222 }
1223 1223
1224 instr->state = MTD_ERASING; 1224 instr->state = MTD_ERASING;
1225 1225
1226 /* FIXME: Do this in the background. Use timers or schedule_task() */ 1226 /* FIXME: Do this in the background. Use timers or schedule_task() */
1227 while(len) { 1227 while(len) {
1228 mychip = &this->chips[ofs >> this->chipshift]; 1228 mychip = &this->chips[ofs >> this->chipshift];
diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c
index 1e704915ef08..fcb28a6fd89f 100644
--- a/drivers/mtd/devices/doc2001.c
+++ b/drivers/mtd/devices/doc2001.c
@@ -4,7 +4,7 @@
4 * (c) 1999 Machine Vision Holdings, Inc. 4 * (c) 1999 Machine Vision Holdings, Inc.
5 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> 5 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
6 * 6 *
7 * $Id: doc2001.c,v 1.48 2005/01/05 18:05:12 dwmw2 Exp $ 7 * $Id: doc2001.c,v 1.49 2005/11/07 11:14:24 gleixner Exp $
8 */ 8 */
9 9
10#include <linux/kernel.h> 10#include <linux/kernel.h>
@@ -196,10 +196,10 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
196 DoC_Command(doc->virtadr, NAND_CMD_RESET, CDSN_CTRL_WP); 196 DoC_Command(doc->virtadr, NAND_CMD_RESET, CDSN_CTRL_WP);
197 DoC_WaitReady(doc->virtadr); 197 DoC_WaitReady(doc->virtadr);
198 198
199 /* Read the NAND chip ID: 1. Send ReadID command */ 199 /* Read the NAND chip ID: 1. Send ReadID command */
200 DoC_Command(doc->virtadr, NAND_CMD_READID, CDSN_CTRL_WP); 200 DoC_Command(doc->virtadr, NAND_CMD_READID, CDSN_CTRL_WP);
201 201
202 /* Read the NAND chip ID: 2. Send address byte zero */ 202 /* Read the NAND chip ID: 2. Send address byte zero */
203 DoC_Address(doc->virtadr, 1, 0x00, CDSN_CTRL_WP, 0x00); 203 DoC_Address(doc->virtadr, 1, 0x00, CDSN_CTRL_WP, 0x00);
204 204
205 /* Read the manufacturer and device id codes of the flash device through 205 /* Read the manufacturer and device id codes of the flash device through
@@ -223,7 +223,7 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
223 for (j = 0; nand_manuf_ids[j].id != 0x0; j++) { 223 for (j = 0; nand_manuf_ids[j].id != 0x0; j++) {
224 if (nand_manuf_ids[j].id == mfr) 224 if (nand_manuf_ids[j].id == mfr)
225 break; 225 break;
226 } 226 }
227 printk(KERN_INFO "Flash chip found: Manufacturer ID: %2.2X, " 227 printk(KERN_INFO "Flash chip found: Manufacturer ID: %2.2X, "
228 "Chip ID: %2.2X (%s:%s)\n", 228 "Chip ID: %2.2X (%s:%s)\n",
229 mfr, id, nand_manuf_ids[j].name, nand_flash_ids[i].name); 229 mfr, id, nand_manuf_ids[j].name, nand_flash_ids[i].name);
@@ -275,7 +275,7 @@ static void DoC_ScanChips(struct DiskOnChip *this)
275 return; 275 return;
276 } 276 }
277 277
278 /* Fill out the chip array with {floor, chipno} for each 278 /* Fill out the chip array with {floor, chipno} for each
279 * detected chip in the device. */ 279 * detected chip in the device. */
280 for (floor = 0, ret = 0; floor < MAX_FLOORS_MIL; floor++) { 280 for (floor = 0, ret = 0; floor < MAX_FLOORS_MIL; floor++) {
281 for (chip = 0 ; chip < numchips[floor] ; chip++) { 281 for (chip = 0 ; chip < numchips[floor] ; chip++) {
@@ -309,7 +309,7 @@ static int DoCMil_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
309 tmp2 = ReadDOC(doc2->virtadr, AliasResolution); 309 tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
310 if (tmp1 != tmp2) 310 if (tmp1 != tmp2)
311 return 0; 311 return 0;
312 312
313 WriteDOC((tmp1+1) % 0xff, doc1->virtadr, AliasResolution); 313 WriteDOC((tmp1+1) % 0xff, doc1->virtadr, AliasResolution);
314 tmp2 = ReadDOC(doc2->virtadr, AliasResolution); 314 tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
315 if (tmp2 == (tmp1+1) % 0xff) 315 if (tmp2 == (tmp1+1) % 0xff)
@@ -425,7 +425,7 @@ static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
425 return -EINVAL; 425 return -EINVAL;
426 426
427 /* Don't allow a single read to cross a 512-byte block boundary */ 427 /* Don't allow a single read to cross a 512-byte block boundary */
428 if (from + len > ((from | 0x1ff) + 1)) 428 if (from + len > ((from | 0x1ff) + 1))
429 len = ((from | 0x1ff) + 1) - from; 429 len = ((from | 0x1ff) + 1) - from;
430 430
431 /* Find the chip which is to be used and select it */ 431 /* Find the chip which is to be used and select it */
@@ -552,7 +552,7 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
552 552
553#if 0 553#if 0
554 /* Don't allow a single write to cross a 512-byte block boundary */ 554 /* Don't allow a single write to cross a 512-byte block boundary */
555 if (to + len > ( (to | 0x1ff) + 1)) 555 if (to + len > ( (to | 0x1ff) + 1))
556 len = ((to | 0x1ff) + 1) - to; 556 len = ((to | 0x1ff) + 1) - to;
557#else 557#else
558 /* Don't allow writes which aren't exactly one block */ 558 /* Don't allow writes which aren't exactly one block */
@@ -632,7 +632,7 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
632 632
633 /* write the block status BLOCK_USED (0x5555) at the end of ECC data 633 /* write the block status BLOCK_USED (0x5555) at the end of ECC data
634 FIXME: this is only a hack for programming the IPL area for LinuxBIOS 634 FIXME: this is only a hack for programming the IPL area for LinuxBIOS
635 and should be replace with proper codes in user space utilities */ 635 and should be replace with proper codes in user space utilities */
636 WriteDOC(0x55, docptr, Mil_CDSN_IO); 636 WriteDOC(0x55, docptr, Mil_CDSN_IO);
637 WriteDOC(0x55, docptr, Mil_CDSN_IO + 1); 637 WriteDOC(0x55, docptr, Mil_CDSN_IO + 1);
638 638
@@ -802,7 +802,7 @@ int doc_erase (struct mtd_info *mtd, struct erase_info *instr)
802 void __iomem *docptr = this->virtadr; 802 void __iomem *docptr = this->virtadr;
803 struct Nand *mychip = &this->chips[ofs >> this->chipshift]; 803 struct Nand *mychip = &this->chips[ofs >> this->chipshift];
804 804
805 if (len != mtd->erasesize) 805 if (len != mtd->erasesize)
806 printk(KERN_WARNING "Erase not right size (%x != %x)n", 806 printk(KERN_WARNING "Erase not right size (%x != %x)n",
807 len, mtd->erasesize); 807 len, mtd->erasesize);
808 808
@@ -870,9 +870,9 @@ static void __exit cleanup_doc2001(void)
870 while ((mtd=docmillist)) { 870 while ((mtd=docmillist)) {
871 this = mtd->priv; 871 this = mtd->priv;
872 docmillist = this->nextdoc; 872 docmillist = this->nextdoc;
873 873
874 del_mtd_device(mtd); 874 del_mtd_device(mtd);
875 875
876 iounmap(this->virtadr); 876 iounmap(this->virtadr);
877 kfree(this->chips); 877 kfree(this->chips);
878 kfree(mtd); 878 kfree(mtd);
diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c
index ed47bafb2ce2..0595cc7324b2 100644
--- a/drivers/mtd/devices/doc2001plus.c
+++ b/drivers/mtd/devices/doc2001plus.c
@@ -6,7 +6,7 @@
6 * (c) 1999 Machine Vision Holdings, Inc. 6 * (c) 1999 Machine Vision Holdings, Inc.
7 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> 7 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
8 * 8 *
9 * $Id: doc2001plus.c,v 1.13 2005/01/05 18:05:12 dwmw2 Exp $ 9 * $Id: doc2001plus.c,v 1.14 2005/11/07 11:14:24 gleixner Exp $
10 * 10 *
11 * Released under GPL 11 * Released under GPL
12 */ 12 */
@@ -293,10 +293,10 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
293 DoC_Command(docptr, NAND_CMD_RESET, 0); 293 DoC_Command(docptr, NAND_CMD_RESET, 0);
294 DoC_WaitReady(docptr); 294 DoC_WaitReady(docptr);
295 295
296 /* Read the NAND chip ID: 1. Send ReadID command */ 296 /* Read the NAND chip ID: 1. Send ReadID command */
297 DoC_Command(docptr, NAND_CMD_READID, 0); 297 DoC_Command(docptr, NAND_CMD_READID, 0);
298 298
299 /* Read the NAND chip ID: 2. Send address byte zero */ 299 /* Read the NAND chip ID: 2. Send address byte zero */
300 DoC_Address(doc, 1, 0x00, 0, 0x00); 300 DoC_Address(doc, 1, 0x00, 0, 0x00);
301 301
302 WriteDOC(0, docptr, Mplus_FlashControl); 302 WriteDOC(0, docptr, Mplus_FlashControl);
@@ -365,7 +365,7 @@ static void DoC_ScanChips(struct DiskOnChip *this)
365 this->interleave = 1; 365 this->interleave = 1;
366 366
367 /* Check the ASIC agrees */ 367 /* Check the ASIC agrees */
368 if ( (this->interleave << 2) != 368 if ( (this->interleave << 2) !=
369 (ReadDOC(this->virtadr, Mplus_Configuration) & 4)) { 369 (ReadDOC(this->virtadr, Mplus_Configuration) & 4)) {
370 u_char conf = ReadDOC(this->virtadr, Mplus_Configuration); 370 u_char conf = ReadDOC(this->virtadr, Mplus_Configuration);
371 printk(KERN_NOTICE "Setting DiskOnChip Millennium Plus interleave to %s\n", 371 printk(KERN_NOTICE "Setting DiskOnChip Millennium Plus interleave to %s\n",
@@ -398,7 +398,7 @@ static void DoC_ScanChips(struct DiskOnChip *this)
398 return; 398 return;
399 } 399 }
400 400
401 /* Fill out the chip array with {floor, chipno} for each 401 /* Fill out the chip array with {floor, chipno} for each
402 * detected chip in the device. */ 402 * detected chip in the device. */
403 for (floor = 0, ret = 0; floor < MAX_FLOORS_MPLUS; floor++) { 403 for (floor = 0, ret = 0; floor < MAX_FLOORS_MPLUS; floor++) {
404 for (chip = 0 ; chip < numchips[floor] ; chip++) { 404 for (chip = 0 ; chip < numchips[floor] ; chip++) {
@@ -432,7 +432,7 @@ static int DoCMilPlus_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
432 tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution); 432 tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution);
433 if (tmp1 != tmp2) 433 if (tmp1 != tmp2)
434 return 0; 434 return 0;
435 435
436 WriteDOC((tmp1+1) % 0xff, doc1->virtadr, Mplus_AliasResolution); 436 WriteDOC((tmp1+1) % 0xff, doc1->virtadr, Mplus_AliasResolution);
437 tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution); 437 tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution);
438 if (tmp2 == (tmp1+1) % 0xff) 438 if (tmp2 == (tmp1+1) % 0xff)
@@ -624,7 +624,7 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
624 return -EINVAL; 624 return -EINVAL;
625 625
626 /* Don't allow a single read to cross a 512-byte block boundary */ 626 /* Don't allow a single read to cross a 512-byte block boundary */
627 if (from + len > ((from | 0x1ff) + 1)) 627 if (from + len > ((from | 0x1ff) + 1))
628 len = ((from | 0x1ff) + 1) - from; 628 len = ((from | 0x1ff) + 1) - from;
629 629
630 DoC_CheckASIC(docptr); 630 DoC_CheckASIC(docptr);
@@ -1066,7 +1066,7 @@ int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
1066 1066
1067 DoC_CheckASIC(docptr); 1067 DoC_CheckASIC(docptr);
1068 1068
1069 if (len != mtd->erasesize) 1069 if (len != mtd->erasesize)
1070 printk(KERN_WARNING "MTD: Erase not right size (%x != %x)n", 1070 printk(KERN_WARNING "MTD: Erase not right size (%x != %x)n",
1071 len, mtd->erasesize); 1071 len, mtd->erasesize);
1072 1072
@@ -1136,9 +1136,9 @@ static void __exit cleanup_doc2001plus(void)
1136 while ((mtd=docmilpluslist)) { 1136 while ((mtd=docmilpluslist)) {
1137 this = mtd->priv; 1137 this = mtd->priv;
1138 docmilpluslist = this->nextdoc; 1138 docmilpluslist = this->nextdoc;
1139 1139
1140 del_mtd_device(mtd); 1140 del_mtd_device(mtd);
1141 1141
1142 iounmap(this->virtadr); 1142 iounmap(this->virtadr);
1143 kfree(this->chips); 1143 kfree(this->chips);
1144 kfree(mtd); 1144 kfree(mtd);
diff --git a/drivers/mtd/devices/docecc.c b/drivers/mtd/devices/docecc.c
index 24f670b5a4f3..cd3db72bef96 100644
--- a/drivers/mtd/devices/docecc.c
+++ b/drivers/mtd/devices/docecc.c
@@ -4,10 +4,10 @@
4 * GNU GPL License. The rest is simply to convert the disk on chip 4 * GNU GPL License. The rest is simply to convert the disk on chip
5 * syndrom into a standard syndom. 5 * syndrom into a standard syndom.
6 * 6 *
7 * Author: Fabrice Bellard (fabrice.bellard@netgem.com) 7 * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
8 * Copyright (C) 2000 Netgem S.A. 8 * Copyright (C) 2000 Netgem S.A.
9 * 9 *
10 * $Id: docecc.c,v 1.5 2003/05/21 15:15:06 dwmw2 Exp $ 10 * $Id: docecc.c,v 1.7 2005/11/07 11:14:25 gleixner Exp $
11 * 11 *
12 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by 13 * it under the terms of the GNU General Public License as published by
@@ -122,7 +122,7 @@ for(ci=(n)-1;ci >=0;ci--)\
122 a(0) + a(1) @ + a(2) @^2 + ... + a(m-1) @^(m-1) 122 a(0) + a(1) @ + a(2) @^2 + ... + a(m-1) @^(m-1)
123 we consider the integer "i" whose binary representation with a(0) being LSB 123 we consider the integer "i" whose binary representation with a(0) being LSB
124 and a(m-1) MSB is (a(0),a(1),...,a(m-1)) and locate the entry 124 and a(m-1) MSB is (a(0),a(1),...,a(m-1)) and locate the entry
125 "index_of[i]". Now, @^index_of[i] is that element whose polynomial 125 "index_of[i]". Now, @^index_of[i] is that element whose polynomial
126 representation is (a(0),a(1),a(2),...,a(m-1)). 126 representation is (a(0),a(1),a(2),...,a(m-1)).
127 NOTE: 127 NOTE:
128 The element alpha_to[2^m-1] = 0 always signifying that the 128 The element alpha_to[2^m-1] = 0 always signifying that the
@@ -130,7 +130,7 @@ for(ci=(n)-1;ci >=0;ci--)\
130 Similarily, the element index_of[0] = A0 always signifying 130 Similarily, the element index_of[0] = A0 always signifying
131 that the power of alpha which has the polynomial representation 131 that the power of alpha which has the polynomial representation
132 (0,0,...,0) is "infinity". 132 (0,0,...,0) is "infinity".
133 133
134*/ 134*/
135 135
136static void 136static void
@@ -176,7 +176,7 @@ generate_gf(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1])
176 * are written back. NOTE! This array must be at least NN-KK elements long. 176 * are written back. NOTE! This array must be at least NN-KK elements long.
177 * The corrected data are written in eras_val[]. They must be xor with the data 177 * The corrected data are written in eras_val[]. They must be xor with the data
178 * to retrieve the correct data : data[erase_pos[i]] ^= erase_val[i] . 178 * to retrieve the correct data : data[erase_pos[i]] ^= erase_val[i] .
179 * 179 *
180 * First "no_eras" erasures are declared by the calling program. Then, the 180 * First "no_eras" erasures are declared by the calling program. Then, the
181 * maximum # of errors correctable is t_after_eras = floor((NN-KK-no_eras)/2). 181 * maximum # of errors correctable is t_after_eras = floor((NN-KK-no_eras)/2).
182 * If the number of channel errors is not greater than "t_after_eras" the 182 * If the number of channel errors is not greater than "t_after_eras" the
@@ -189,7 +189,7 @@ generate_gf(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1])
189 * */ 189 * */
190static int 190static int
191eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1], 191eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
192 gf bb[NN - KK + 1], gf eras_val[NN-KK], int eras_pos[NN-KK], 192 gf bb[NN - KK + 1], gf eras_val[NN-KK], int eras_pos[NN-KK],
193 int no_eras) 193 int no_eras)
194{ 194{
195 int deg_lambda, el, deg_omega; 195 int deg_lambda, el, deg_omega;
@@ -212,7 +212,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
212 count = 0; 212 count = 0;
213 goto finish; 213 goto finish;
214 } 214 }
215 215
216 for(i=1;i<=NN-KK;i++){ 216 for(i=1;i<=NN-KK;i++){
217 s[i] = bb[0]; 217 s[i] = bb[0];
218 } 218 }
@@ -220,7 +220,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
220 if(bb[j] == 0) 220 if(bb[j] == 0)
221 continue; 221 continue;
222 tmp = Index_of[bb[j]]; 222 tmp = Index_of[bb[j]];
223 223
224 for(i=1;i<=NN-KK;i++) 224 for(i=1;i<=NN-KK;i++)
225 s[i] ^= Alpha_to[modnn(tmp + (B0+i-1)*PRIM*j)]; 225 s[i] ^= Alpha_to[modnn(tmp + (B0+i-1)*PRIM*j)];
226 } 226 }
@@ -234,7 +234,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
234 tmp = modnn(tmp + 2 * KK * (B0+i-1)*PRIM); 234 tmp = modnn(tmp + 2 * KK * (B0+i-1)*PRIM);
235 s[i] = tmp; 235 s[i] = tmp;
236 } 236 }
237 237
238 CLEAR(&lambda[1],NN-KK); 238 CLEAR(&lambda[1],NN-KK);
239 lambda[0] = 1; 239 lambda[0] = 1;
240 240
@@ -252,7 +252,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
252#if DEBUG_ECC >= 1 252#if DEBUG_ECC >= 1
253 /* Test code that verifies the erasure locator polynomial just constructed 253 /* Test code that verifies the erasure locator polynomial just constructed
254 Needed only for decoder debugging. */ 254 Needed only for decoder debugging. */
255 255
256 /* find roots of the erasure location polynomial */ 256 /* find roots of the erasure location polynomial */
257 for(i=1;i<=no_eras;i++) 257 for(i=1;i<=no_eras;i++)
258 reg[i] = Index_of[lambda[i]]; 258 reg[i] = Index_of[lambda[i]];
@@ -286,7 +286,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
286 } 286 }
287 for(i=0;i<NN-KK+1;i++) 287 for(i=0;i<NN-KK+1;i++)
288 b[i] = Index_of[lambda[i]]; 288 b[i] = Index_of[lambda[i]];
289 289
290 /* 290 /*
291 * Begin Berlekamp-Massey algorithm to determine error+erasure 291 * Begin Berlekamp-Massey algorithm to determine error+erasure
292 * locator polynomial 292 * locator polynomial
@@ -389,7 +389,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
389 omega[i] = Index_of[tmp]; 389 omega[i] = Index_of[tmp];
390 } 390 }
391 omega[NN-KK] = A0; 391 omega[NN-KK] = A0;
392 392
393 /* 393 /*
394 * Compute error values in poly-form. num1 = omega(inv(X(l))), num2 = 394 * Compute error values in poly-form. num1 = omega(inv(X(l))), num2 =
395 * inv(X(l))**(B0-1) and den = lambda_pr(inv(X(l))) all in poly-form 395 * inv(X(l))**(B0-1) and den = lambda_pr(inv(X(l))) all in poly-form
@@ -402,7 +402,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
402 } 402 }
403 num2 = Alpha_to[modnn(root[j] * (B0 - 1) + NN)]; 403 num2 = Alpha_to[modnn(root[j] * (B0 - 1) + NN)];
404 den = 0; 404 den = 0;
405 405
406 /* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */ 406 /* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */
407 for (i = min(deg_lambda,NN-KK-1) & ~1; i >= 0; i -=2) { 407 for (i = min(deg_lambda,NN-KK-1) & ~1; i >= 0; i -=2) {
408 if(lambda[i+1] != A0) 408 if(lambda[i+1] != A0)
@@ -436,11 +436,11 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
436/* The sector bytes are packed into NB_DATA MM bits words */ 436/* The sector bytes are packed into NB_DATA MM bits words */
437#define NB_DATA (((SECTOR_SIZE + 1) * 8 + 6) / MM) 437#define NB_DATA (((SECTOR_SIZE + 1) * 8 + 6) / MM)
438 438
439/* 439/*
440 * Correct the errors in 'sector[]' by using 'ecc1[]' which is the 440 * Correct the errors in 'sector[]' by using 'ecc1[]' which is the
441 * content of the feedback shift register applyied to the sector and 441 * content of the feedback shift register applyied to the sector and
442 * the ECC. Return the number of errors corrected (and correct them in 442 * the ECC. Return the number of errors corrected (and correct them in
443 * sector), or -1 if error 443 * sector), or -1 if error
444 */ 444 */
445int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6]) 445int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
446{ 446{
@@ -454,7 +454,7 @@ int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
454 Alpha_to = kmalloc((NN + 1) * sizeof(dtype), GFP_KERNEL); 454 Alpha_to = kmalloc((NN + 1) * sizeof(dtype), GFP_KERNEL);
455 if (!Alpha_to) 455 if (!Alpha_to)
456 return -1; 456 return -1;
457 457
458 Index_of = kmalloc((NN + 1) * sizeof(dtype), GFP_KERNEL); 458 Index_of = kmalloc((NN + 1) * sizeof(dtype), GFP_KERNEL);
459 if (!Index_of) { 459 if (!Index_of) {
460 kfree(Alpha_to); 460 kfree(Alpha_to);
@@ -470,7 +470,7 @@ int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
470 bb[2] = ((ecc1[2] & 0xf0) >> 4) | ((ecc1[3] & 0x3f) << 4); 470 bb[2] = ((ecc1[2] & 0xf0) >> 4) | ((ecc1[3] & 0x3f) << 4);
471 bb[3] = ((ecc1[3] & 0xc0) >> 6) | ((ecc1[0] & 0xff) << 2); 471 bb[3] = ((ecc1[3] & 0xc0) >> 6) | ((ecc1[0] & 0xff) << 2);
472 472
473 nb_errors = eras_dec_rs(Alpha_to, Index_of, bb, 473 nb_errors = eras_dec_rs(Alpha_to, Index_of, bb,
474 error_val, error_pos, 0); 474 error_val, error_pos, 0);
475 if (nb_errors <= 0) 475 if (nb_errors <= 0)
476 goto the_end; 476 goto the_end;
@@ -489,7 +489,7 @@ int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
489 can be modified since pos is even */ 489 can be modified since pos is even */
490 index = (pos >> 3) ^ 1; 490 index = (pos >> 3) ^ 1;
491 bitpos = pos & 7; 491 bitpos = pos & 7;
492 if ((index >= 0 && index < SECTOR_SIZE) || 492 if ((index >= 0 && index < SECTOR_SIZE) ||
493 index == (SECTOR_SIZE + 1)) { 493 index == (SECTOR_SIZE + 1)) {
494 val = error_val[i] >> (2 + bitpos); 494 val = error_val[i] >> (2 + bitpos);
495 parity ^= val; 495 parity ^= val;
@@ -500,7 +500,7 @@ int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
500 bitpos = (bitpos + 10) & 7; 500 bitpos = (bitpos + 10) & 7;
501 if (bitpos == 0) 501 if (bitpos == 0)
502 bitpos = 8; 502 bitpos = 8;
503 if ((index >= 0 && index < SECTOR_SIZE) || 503 if ((index >= 0 && index < SECTOR_SIZE) ||
504 index == (SECTOR_SIZE + 1)) { 504 index == (SECTOR_SIZE + 1)) {
505 val = error_val[i] << (8 - bitpos); 505 val = error_val[i] << (8 - bitpos);
506 parity ^= val; 506 parity ^= val;
@@ -509,7 +509,7 @@ int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
509 } 509 }
510 } 510 }
511 } 511 }
512 512
513 /* use parity to test extra errors */ 513 /* use parity to test extra errors */
514 if ((parity & 0xff) != 0) 514 if ((parity & 0xff) != 0)
515 nb_errors = -1; 515 nb_errors = -1;
diff --git a/drivers/mtd/devices/docprobe.c b/drivers/mtd/devices/docprobe.c
index 197d67045e1e..13178b9dd00a 100644
--- a/drivers/mtd/devices/docprobe.c
+++ b/drivers/mtd/devices/docprobe.c
@@ -4,22 +4,22 @@
4/* (C) 1999 Machine Vision Holdings, Inc. */ 4/* (C) 1999 Machine Vision Holdings, Inc. */
5/* (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> */ 5/* (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> */
6 6
7/* $Id: docprobe.c,v 1.44 2005/01/05 12:40:36 dwmw2 Exp $ */ 7/* $Id: docprobe.c,v 1.46 2005/11/07 11:14:25 gleixner Exp $ */
8 8
9 9
10 10
11/* DOC_PASSIVE_PROBE: 11/* DOC_PASSIVE_PROBE:
12 In order to ensure that the BIOS checksum is correct at boot time, and 12 In order to ensure that the BIOS checksum is correct at boot time, and
13 hence that the onboard BIOS extension gets executed, the DiskOnChip 13 hence that the onboard BIOS extension gets executed, the DiskOnChip
14 goes into reset mode when it is read sequentially: all registers 14 goes into reset mode when it is read sequentially: all registers
15 return 0xff until the chip is woken up again by writing to the 15 return 0xff until the chip is woken up again by writing to the
16 DOCControl register. 16 DOCControl register.
17 17
18 Unfortunately, this means that the probe for the DiskOnChip is unsafe, 18 Unfortunately, this means that the probe for the DiskOnChip is unsafe,
19 because one of the first things it does is write to where it thinks 19 because one of the first things it does is write to where it thinks
20 the DOCControl register should be - which may well be shared memory 20 the DOCControl register should be - which may well be shared memory
21 for another device. I've had machines which lock up when this is 21 for another device. I've had machines which lock up when this is
22 attempted. Hence the possibility to do a passive probe, which will fail 22 attempted. Hence the possibility to do a passive probe, which will fail
23 to detect a chip in reset mode, but is at least guaranteed not to lock 23 to detect a chip in reset mode, but is at least guaranteed not to lock
24 the machine. 24 the machine.
25 25
@@ -33,9 +33,9 @@
33 33
34 The old Millennium-only driver has been retained just in case there 34 The old Millennium-only driver has been retained just in case there
35 are problems with the new code. If the combined driver doesn't work 35 are problems with the new code. If the combined driver doesn't work
36 for you, you can try the old one by undefining DOC_SINGLE_DRIVER 36 for you, you can try the old one by undefining DOC_SINGLE_DRIVER
37 below and also enabling it in your configuration. If this fixes the 37 below and also enabling it in your configuration. If this fixes the
38 problems, please send a report to the MTD mailing list at 38 problems, please send a report to the MTD mailing list at
39 <linux-mtd@lists.infradead.org>. 39 <linux-mtd@lists.infradead.org>.
40*/ 40*/
41#define DOC_SINGLE_DRIVER 41#define DOC_SINGLE_DRIVER
@@ -68,16 +68,16 @@ MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe
68static unsigned long __initdata doc_locations[] = { 68static unsigned long __initdata doc_locations[] = {
69#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__) 69#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__)
70#ifdef CONFIG_MTD_DOCPROBE_HIGH 70#ifdef CONFIG_MTD_DOCPROBE_HIGH
71 0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000, 71 0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,
72 0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000, 72 0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000,
73 0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000, 73 0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000,
74 0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000, 74 0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000,
75 0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000, 75 0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000,
76#else /* CONFIG_MTD_DOCPROBE_HIGH */ 76#else /* CONFIG_MTD_DOCPROBE_HIGH */
77 0xc8000, 0xca000, 0xcc000, 0xce000, 77 0xc8000, 0xca000, 0xcc000, 0xce000,
78 0xd0000, 0xd2000, 0xd4000, 0xd6000, 78 0xd0000, 0xd2000, 0xd4000, 0xd6000,
79 0xd8000, 0xda000, 0xdc000, 0xde000, 79 0xd8000, 0xda000, 0xdc000, 0xde000,
80 0xe0000, 0xe2000, 0xe4000, 0xe6000, 80 0xe0000, 0xe2000, 0xe4000, 0xe6000,
81 0xe8000, 0xea000, 0xec000, 0xee000, 81 0xe8000, 0xea000, 0xec000, 0xee000,
82#endif /* CONFIG_MTD_DOCPROBE_HIGH */ 82#endif /* CONFIG_MTD_DOCPROBE_HIGH */
83#elif defined(__PPC__) 83#elif defined(__PPC__)
@@ -111,35 +111,35 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
111 return 0; 111 return 0;
112#endif /* CONFIG_MTD_DOCPROBE_55AA */ 112#endif /* CONFIG_MTD_DOCPROBE_55AA */
113 113
114#ifndef DOC_PASSIVE_PROBE 114#ifndef DOC_PASSIVE_PROBE
115 /* It's not possible to cleanly detect the DiskOnChip - the 115 /* It's not possible to cleanly detect the DiskOnChip - the
116 * bootup procedure will put the device into reset mode, and 116 * bootup procedure will put the device into reset mode, and
117 * it's not possible to talk to it without actually writing 117 * it's not possible to talk to it without actually writing
118 * to the DOCControl register. So we store the current contents 118 * to the DOCControl register. So we store the current contents
119 * of the DOCControl register's location, in case we later decide 119 * of the DOCControl register's location, in case we later decide
120 * that it's not a DiskOnChip, and want to put it back how we 120 * that it's not a DiskOnChip, and want to put it back how we
121 * found it. 121 * found it.
122 */ 122 */
123 tmp2 = ReadDOC(window, DOCControl); 123 tmp2 = ReadDOC(window, DOCControl);
124 124
125 /* Reset the DiskOnChip ASIC */ 125 /* Reset the DiskOnChip ASIC */
126 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, 126 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
127 window, DOCControl); 127 window, DOCControl);
128 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, 128 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
129 window, DOCControl); 129 window, DOCControl);
130 130
131 /* Enable the DiskOnChip ASIC */ 131 /* Enable the DiskOnChip ASIC */
132 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, 132 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
133 window, DOCControl); 133 window, DOCControl);
134 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, 134 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
135 window, DOCControl); 135 window, DOCControl);
136#endif /* !DOC_PASSIVE_PROBE */ 136#endif /* !DOC_PASSIVE_PROBE */
137 137
138 /* We need to read the ChipID register four times. For some 138 /* We need to read the ChipID register four times. For some
139 newer DiskOnChip 2000 units, the first three reads will 139 newer DiskOnChip 2000 units, the first three reads will
140 return the DiskOnChip Millennium ident. Don't ask. */ 140 return the DiskOnChip Millennium ident. Don't ask. */
141 ChipID = ReadDOC(window, ChipID); 141 ChipID = ReadDOC(window, ChipID);
142 142
143 switch (ChipID) { 143 switch (ChipID) {
144 case DOC_ChipID_Doc2k: 144 case DOC_ChipID_Doc2k:
145 /* Check the TOGGLE bit in the ECC register */ 145 /* Check the TOGGLE bit in the ECC register */
@@ -149,7 +149,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
149 if (tmp != tmpb && tmp == tmpc) 149 if (tmp != tmpb && tmp == tmpc)
150 return ChipID; 150 return ChipID;
151 break; 151 break;
152 152
153 case DOC_ChipID_DocMil: 153 case DOC_ChipID_DocMil:
154 /* Check for the new 2000 with Millennium ASIC */ 154 /* Check for the new 2000 with Millennium ASIC */
155 ReadDOC(window, ChipID); 155 ReadDOC(window, ChipID);
@@ -164,7 +164,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
164 if (tmp != tmpb && tmp == tmpc) 164 if (tmp != tmpb && tmp == tmpc)
165 return ChipID; 165 return ChipID;
166 break; 166 break;
167 167
168 case DOC_ChipID_DocMilPlus16: 168 case DOC_ChipID_DocMilPlus16:
169 case DOC_ChipID_DocMilPlus32: 169 case DOC_ChipID_DocMilPlus32:
170 case 0: 170 case 0:
@@ -179,7 +179,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
179 DOC_MODE_BDECT; 179 DOC_MODE_BDECT;
180 WriteDOC(tmp, window, Mplus_DOCControl); 180 WriteDOC(tmp, window, Mplus_DOCControl);
181 WriteDOC(~tmp, window, Mplus_CtrlConfirm); 181 WriteDOC(~tmp, window, Mplus_CtrlConfirm);
182 182
183 mdelay(1); 183 mdelay(1);
184 /* Enable the DiskOnChip ASIC */ 184 /* Enable the DiskOnChip ASIC */
185 tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT | 185 tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT |
@@ -187,7 +187,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
187 WriteDOC(tmp, window, Mplus_DOCControl); 187 WriteDOC(tmp, window, Mplus_DOCControl);
188 WriteDOC(~tmp, window, Mplus_CtrlConfirm); 188 WriteDOC(~tmp, window, Mplus_CtrlConfirm);
189 mdelay(1); 189 mdelay(1);
190#endif /* !DOC_PASSIVE_PROBE */ 190#endif /* !DOC_PASSIVE_PROBE */
191 191
192 ChipID = ReadDOC(window, ChipID); 192 ChipID = ReadDOC(window, ChipID);
193 193
@@ -227,7 +227,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
227 WriteDOC(tmp2, window, DOCControl); 227 WriteDOC(tmp2, window, DOCControl);
228#endif 228#endif
229 return 0; 229 return 0;
230} 230}
231 231
232static int docfound; 232static int docfound;
233 233
@@ -244,10 +244,10 @@ static void __init DoC_Probe(unsigned long physadr)
244 void (*initroutine)(struct mtd_info *) = NULL; 244 void (*initroutine)(struct mtd_info *) = NULL;
245 245
246 docptr = ioremap(physadr, DOC_IOREMAP_LEN); 246 docptr = ioremap(physadr, DOC_IOREMAP_LEN);
247 247
248 if (!docptr) 248 if (!docptr)
249 return; 249 return;
250 250
251 if ((ChipID = doccheck(docptr, physadr))) { 251 if ((ChipID = doccheck(docptr, physadr))) {
252 if (ChipID == DOC_ChipID_Doc2kTSOP) { 252 if (ChipID == DOC_ChipID_Doc2kTSOP) {
253 /* Remove this at your own peril. The hardware driver works but nothing prevents you from erasing bad blocks */ 253 /* Remove this at your own peril. The hardware driver works but nothing prevents you from erasing bad blocks */
@@ -263,9 +263,9 @@ static void __init DoC_Probe(unsigned long physadr)
263 iounmap(docptr); 263 iounmap(docptr);
264 return; 264 return;
265 } 265 }
266 266
267 this = (struct DiskOnChip *)(&mtd[1]); 267 this = (struct DiskOnChip *)(&mtd[1]);
268 268
269 memset((char *)mtd,0, sizeof(struct mtd_info)); 269 memset((char *)mtd,0, sizeof(struct mtd_info));
270 memset((char *)this, 0, sizeof(struct DiskOnChip)); 270 memset((char *)this, 0, sizeof(struct DiskOnChip));
271 271
@@ -281,13 +281,13 @@ static void __init DoC_Probe(unsigned long physadr)
281 im_funcname = "DoC2k_init"; 281 im_funcname = "DoC2k_init";
282 im_modname = "doc2000"; 282 im_modname = "doc2000";
283 break; 283 break;
284 284
285 case DOC_ChipID_Doc2k: 285 case DOC_ChipID_Doc2k:
286 name="2000"; 286 name="2000";
287 im_funcname = "DoC2k_init"; 287 im_funcname = "DoC2k_init";
288 im_modname = "doc2000"; 288 im_modname = "doc2000";
289 break; 289 break;
290 290
291 case DOC_ChipID_DocMil: 291 case DOC_ChipID_DocMil:
292 name="Millennium"; 292 name="Millennium";
293#ifdef DOC_SINGLE_DRIVER 293#ifdef DOC_SINGLE_DRIVER
@@ -331,7 +331,7 @@ static void __init DoC_Probe(unsigned long physadr)
331static int __init init_doc(void) 331static int __init init_doc(void)
332{ 332{
333 int i; 333 int i;
334 334
335 if (doc_config_location) { 335 if (doc_config_location) {
336 printk(KERN_INFO "Using configured DiskOnChip probe address 0x%lx\n", doc_config_location); 336 printk(KERN_INFO "Using configured DiskOnChip probe address 0x%lx\n", doc_config_location);
337 DoC_Probe(doc_config_location); 337 DoC_Probe(doc_config_location);
diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c
index df987a53ed9c..1e876fcb0408 100644
--- a/drivers/mtd/devices/lart.c
+++ b/drivers/mtd/devices/lart.c
@@ -2,7 +2,7 @@
2/* 2/*
3 * MTD driver for the 28F160F3 Flash Memory (non-CFI) on LART. 3 * MTD driver for the 28F160F3 Flash Memory (non-CFI) on LART.
4 * 4 *
5 * $Id: lart.c,v 1.7 2004/08/09 13:19:44 dwmw2 Exp $ 5 * $Id: lart.c,v 1.9 2005/11/07 11:14:25 gleixner Exp $
6 * 6 *
7 * Author: Abraham vd Merwe <abraham@2d3d.co.za> 7 * Author: Abraham vd Merwe <abraham@2d3d.co.za>
8 * 8 *
@@ -122,7 +122,7 @@ static char module_name[] = "lart";
122 122
123/* 123/*
124 * The data line mapping on LART is as follows: 124 * The data line mapping on LART is as follows:
125 * 125 *
126 * U2 CPU | U3 CPU 126 * U2 CPU | U3 CPU
127 * ------------------- 127 * -------------------
128 * 0 20 | 0 12 128 * 0 20 | 0 12
@@ -181,7 +181,7 @@ static char module_name[] = "lart";
181 (((x) & 0x00004000) >> 13) \ 181 (((x) & 0x00004000) >> 13) \
182 ) 182 )
183 183
184/* 184/*
185 * The address line mapping on LART is as follows: 185 * The address line mapping on LART is as follows:
186 * 186 *
187 * U3 CPU | U2 CPU 187 * U3 CPU | U2 CPU
@@ -204,7 +204,7 @@ static char module_name[] = "lart";
204 * 12 15 | 12 15 204 * 12 15 | 12 15
205 * 13 14 | 13 14 205 * 13 14 | 13 14
206 * 14 16 | 14 16 206 * 14 16 | 14 16
207 * 207 *
208 * MAIN BLOCK BOUNDARY 208 * MAIN BLOCK BOUNDARY
209 * 209 *
210 * 15 17 | 15 18 210 * 15 17 | 15 18
diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c
index 765c0179c8df..e8685ee6c1e4 100644
--- a/drivers/mtd/devices/phram.c
+++ b/drivers/mtd/devices/phram.c
@@ -1,5 +1,5 @@
1/** 1/**
2 * $Id: phram.c,v 1.14 2005/03/07 21:43:38 joern Exp $ 2 * $Id: phram.c,v 1.16 2005/11/07 11:14:25 gleixner Exp $
3 * 3 *
4 * Copyright (c) ???? Jochen Schäuble <psionic@psionic.de> 4 * Copyright (c) ???? Jochen Schäuble <psionic@psionic.de>
5 * Copyright (c) 2003-2004 Jörn Engel <joern@wh.fh-wedel.de> 5 * Copyright (c) 2003-2004 Jörn Engel <joern@wh.fh-wedel.de>
@@ -41,10 +41,10 @@ static int phram_erase(struct mtd_info *mtd, struct erase_info *instr)
41 41
42 if (instr->addr + instr->len > mtd->size) 42 if (instr->addr + instr->len > mtd->size)
43 return -EINVAL; 43 return -EINVAL;
44 44
45 memset(start + instr->addr, 0xff, instr->len); 45 memset(start + instr->addr, 0xff, instr->len);
46 46
47 /* This'll catch a few races. Free the thing before returning :) 47 /* This'll catch a few races. Free the thing before returning :)
48 * I don't feel at all ashamed. This kind of thing is possible anyway 48 * I don't feel at all ashamed. This kind of thing is possible anyway
49 * with flash, but unlikely. 49 * with flash, but unlikely.
50 */ 50 */
@@ -63,7 +63,7 @@ static int phram_point(struct mtd_info *mtd, loff_t from, size_t len,
63 63
64 if (from + len > mtd->size) 64 if (from + len > mtd->size)
65 return -EINVAL; 65 return -EINVAL;
66 66
67 *mtdbuf = start + from; 67 *mtdbuf = start + from;
68 *retlen = len; 68 *retlen = len;
69 return 0; 69 return 0;
@@ -84,7 +84,7 @@ static int phram_read(struct mtd_info *mtd, loff_t from, size_t len,
84 84
85 if (len > mtd->size - from) 85 if (len > mtd->size - from)
86 len = mtd->size - from; 86 len = mtd->size - from;
87 87
88 memcpy(buf, start + from, len); 88 memcpy(buf, start + from, len);
89 89
90 *retlen = len; 90 *retlen = len;
@@ -101,7 +101,7 @@ static int phram_write(struct mtd_info *mtd, loff_t to, size_t len,
101 101
102 if (len > mtd->size - to) 102 if (len > mtd->size - to)
103 len = mtd->size - to; 103 len = mtd->size - to;
104 104
105 memcpy(start + to, buf, len); 105 memcpy(start + to, buf, len);
106 106
107 *retlen = len; 107 *retlen = len;
@@ -159,7 +159,7 @@ static int register_device(char *name, unsigned long start, unsigned long len)
159 } 159 }
160 160
161 list_add_tail(&new->list, &phram_list); 161 list_add_tail(&new->list, &phram_list);
162 return 0; 162 return 0;
163 163
164out2: 164out2:
165 iounmap(new->mtd.priv); 165 iounmap(new->mtd.priv);
diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c
index 5b3defadf884..de48b35f5609 100644
--- a/drivers/mtd/devices/pmc551.c
+++ b/drivers/mtd/devices/pmc551.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: pmc551.c,v 1.30 2005/01/05 18:05:13 dwmw2 Exp $ 2 * $Id: pmc551.c,v 1.32 2005/11/07 11:14:25 gleixner Exp $
3 * 3 *
4 * PMC551 PCI Mezzanine Ram Device 4 * PMC551 PCI Mezzanine Ram Device
5 * 5 *
@@ -27,7 +27,7 @@
27 * it as high speed swap or for a high speed disk device of some 27 * it as high speed swap or for a high speed disk device of some
28 * sort. Which becomes very useful on diskless systems in the 28 * sort. Which becomes very useful on diskless systems in the
29 * embedded market I might add. 29 * embedded market I might add.
30 * 30 *
31 * Notes: 31 * Notes:
32 * Due to what I assume is more buggy SROM, the 64M PMC551 I 32 * Due to what I assume is more buggy SROM, the 64M PMC551 I
33 * have available claims that all 4 of it's DRAM banks have 64M 33 * have available claims that all 4 of it's DRAM banks have 64M
@@ -63,10 +63,10 @@
63 * Minyard set up the card to utilize a 1M sliding apature. 63 * Minyard set up the card to utilize a 1M sliding apature.
64 * 64 *
65 * Corey Minyard <minyard@nortelnetworks.com> 65 * Corey Minyard <minyard@nortelnetworks.com>
66 * * Modified driver to utilize a sliding aperture instead of 66 * * Modified driver to utilize a sliding aperture instead of
67 * mapping all memory into kernel space which turned out to 67 * mapping all memory into kernel space which turned out to
68 * be very wasteful. 68 * be very wasteful.
69 * * Located a bug in the SROM's initialization sequence that 69 * * Located a bug in the SROM's initialization sequence that
70 * made the memory unusable, added a fix to code to touch up 70 * made the memory unusable, added a fix to code to touch up
71 * the DRAM some. 71 * the DRAM some.
72 * 72 *
@@ -390,7 +390,7 @@ static u32 fixup_pmc551 (struct pci_dev *dev)
390 bcmd |= (0x40|0x20); 390 bcmd |= (0x40|0x20);
391 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd); 391 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd);
392 392
393 /* 393 /*
394 * Take care and turn off the memory on the device while we 394 * Take care and turn off the memory on the device while we
395 * tweak the configurations 395 * tweak the configurations
396 */ 396 */
@@ -408,7 +408,7 @@ static u32 fixup_pmc551 (struct pci_dev *dev)
408 * Grab old BAR0 config so that we can figure out memory size 408 * Grab old BAR0 config so that we can figure out memory size
409 * This is another bit of kludge going on. The reason for the 409 * This is another bit of kludge going on. The reason for the
410 * redundancy is I am hoping to retain the original configuration 410 * redundancy is I am hoping to retain the original configuration
411 * previously assigned to the card by the BIOS or some previous 411 * previously assigned to the card by the BIOS or some previous
412 * fixup routine in the kernel. So we read the old config into cfg, 412 * fixup routine in the kernel. So we read the old config into cfg,
413 * then write all 1's to the memory space, read back the result into 413 * then write all 1's to the memory space, read back the result into
414 * "size", and then write back all the old config. 414 * "size", and then write back all the old config.
@@ -480,7 +480,7 @@ static u32 fixup_pmc551 (struct pci_dev *dev)
480 } while ( (PCI_COMMAND_IO) & cmd ); 480 } while ( (PCI_COMMAND_IO) & cmd );
481 481
482 /* 482 /*
483 * Turn on auto refresh 483 * Turn on auto refresh
484 * The loop is taken directly from Ramix's example code. I assume that 484 * The loop is taken directly from Ramix's example code. I assume that
485 * this must be held high for some duration of time, but I can find no 485 * this must be held high for some duration of time, but I can find no
486 * documentation refrencing the reasons why. 486 * documentation refrencing the reasons why.
@@ -615,7 +615,7 @@ static u32 fixup_pmc551 (struct pci_dev *dev)
615 pci_read_config_byte(dev, PMC551_SYS_CTRL_REG, &bcmd ); 615 pci_read_config_byte(dev, PMC551_SYS_CTRL_REG, &bcmd );
616 printk( KERN_DEBUG "pmc551: EEPROM is under %s control\n" 616 printk( KERN_DEBUG "pmc551: EEPROM is under %s control\n"
617 "pmc551: System Control Register is %slocked to PCI access\n" 617 "pmc551: System Control Register is %slocked to PCI access\n"
618 "pmc551: System Control Register is %slocked to EEPROM access\n", 618 "pmc551: System Control Register is %slocked to EEPROM access\n",
619 (bcmd&0x1)?"software":"hardware", 619 (bcmd&0x1)?"software":"hardware",
620 (bcmd&0x20)?"":"un", (bcmd&0x40)?"":"un"); 620 (bcmd&0x20)?"":"un", (bcmd&0x40)?"":"un");
621#endif 621#endif
@@ -744,7 +744,7 @@ static int __init init_pmc551(void)
744 priv->start = ioremap(((PCI_Device->resource[0].start) 744 priv->start = ioremap(((PCI_Device->resource[0].start)
745 & PCI_BASE_ADDRESS_MEM_MASK), 745 & PCI_BASE_ADDRESS_MEM_MASK),
746 priv->asize); 746 priv->asize);
747 747
748 if (!priv->start) { 748 if (!priv->start) {
749 printk(KERN_NOTICE "pmc551: Unable to map IO space\n"); 749 printk(KERN_NOTICE "pmc551: Unable to map IO space\n");
750 kfree(mtd->priv); 750 kfree(mtd->priv);
@@ -765,7 +765,7 @@ static int __init init_pmc551(void)
765 priv->curr_map0 ); 765 priv->curr_map0 );
766 766
767#ifdef CONFIG_MTD_PMC551_DEBUG 767#ifdef CONFIG_MTD_PMC551_DEBUG
768 printk( KERN_DEBUG "pmc551: aperture set to %d\n", 768 printk( KERN_DEBUG "pmc551: aperture set to %d\n",
769 (priv->base_map0 & 0xF0)>>4 ); 769 (priv->base_map0 & 0xF0)>>4 );
770#endif 770#endif
771 771
@@ -823,13 +823,13 @@ static void __exit cleanup_pmc551(void)
823 while((mtd=pmc551list)) { 823 while((mtd=pmc551list)) {
824 priv = mtd->priv; 824 priv = mtd->priv;
825 pmc551list = priv->nextpmc551; 825 pmc551list = priv->nextpmc551;
826 826
827 if(priv->start) { 827 if(priv->start) {
828 printk (KERN_DEBUG "pmc551: unmapping %dM starting at 0x%p\n", 828 printk (KERN_DEBUG "pmc551: unmapping %dM starting at 0x%p\n",
829 priv->asize>>20, priv->start); 829 priv->asize>>20, priv->start);
830 iounmap (priv->start); 830 iounmap (priv->start);
831 } 831 }
832 832
833 kfree (mtd->priv); 833 kfree (mtd->priv);
834 del_mtd_device (mtd); 834 del_mtd_device (mtd);
835 kfree (mtd); 835 kfree (mtd);
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c
index 84fa91392a8c..6faee6c6958c 100644
--- a/drivers/mtd/devices/slram.c
+++ b/drivers/mtd/devices/slram.c
@@ -1,6 +1,6 @@
1/*====================================================================== 1/*======================================================================
2 2
3 $Id: slram.c,v 1.34 2005/01/06 21:16:42 jwboyer Exp $ 3 $Id: slram.c,v 1.36 2005/11/07 11:14:25 gleixner Exp $
4 4
5 This driver provides a method to access memory not used by the kernel 5 This driver provides a method to access memory not used by the kernel
6 itself (i.e. if the kernel commandline mem=xxx is used). To actually 6 itself (i.e. if the kernel commandline mem=xxx is used). To actually
@@ -18,14 +18,14 @@
18 <start>: start of the memory region, decimal or hex (0xabcdef) 18 <start>: start of the memory region, decimal or hex (0xabcdef)
19 <end/offset>: end of the memory region. It's possible to use +0x1234 19 <end/offset>: end of the memory region. It's possible to use +0x1234
20 to specify the offset instead of the absolute address 20 to specify the offset instead of the absolute address
21 21
22 NOTE: 22 NOTE:
23 With slram it's only possible to map a contigous memory region. Therfore 23 With slram it's only possible to map a contigous memory region. Therfore
24 if there's a device mapped somewhere in the region specified slram will 24 if there's a device mapped somewhere in the region specified slram will
25 fail to load (see kernel log if modprobe fails). 25 fail to load (see kernel log if modprobe fails).
26 26
27 - 27 -
28 28
29 Jochen Schaeuble <psionic@psionic.de> 29 Jochen Schaeuble <psionic@psionic.de>
30 30
31======================================================================*/ 31======================================================================*/
@@ -89,10 +89,10 @@ static int slram_erase(struct mtd_info *mtd, struct erase_info *instr)
89 if (instr->addr + instr->len > mtd->size) { 89 if (instr->addr + instr->len > mtd->size) {
90 return(-EINVAL); 90 return(-EINVAL);
91 } 91 }
92 92
93 memset(priv->start + instr->addr, 0xff, instr->len); 93 memset(priv->start + instr->addr, 0xff, instr->len);
94 94
95 /* This'll catch a few races. Free the thing before returning :) 95 /* This'll catch a few races. Free the thing before returning :)
96 * I don't feel at all ashamed. This kind of thing is possible anyway 96 * I don't feel at all ashamed. This kind of thing is possible anyway
97 * with flash, but unlikely. 97 * with flash, but unlikely.
98 */ 98 */
@@ -170,12 +170,12 @@ static int register_device(char *name, unsigned long start, unsigned long length
170 } 170 }
171 (*curmtd)->mtdinfo = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); 171 (*curmtd)->mtdinfo = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
172 (*curmtd)->next = NULL; 172 (*curmtd)->next = NULL;
173 173
174 if ((*curmtd)->mtdinfo) { 174 if ((*curmtd)->mtdinfo) {
175 memset((char *)(*curmtd)->mtdinfo, 0, sizeof(struct mtd_info)); 175 memset((char *)(*curmtd)->mtdinfo, 0, sizeof(struct mtd_info));
176 (*curmtd)->mtdinfo->priv = 176 (*curmtd)->mtdinfo->priv =
177 kmalloc(sizeof(slram_priv_t), GFP_KERNEL); 177 kmalloc(sizeof(slram_priv_t), GFP_KERNEL);
178 178
179 if (!(*curmtd)->mtdinfo->priv) { 179 if (!(*curmtd)->mtdinfo->priv) {
180 kfree((*curmtd)->mtdinfo); 180 kfree((*curmtd)->mtdinfo);
181 (*curmtd)->mtdinfo = NULL; 181 (*curmtd)->mtdinfo = NULL;
@@ -188,7 +188,7 @@ static int register_device(char *name, unsigned long start, unsigned long length
188 E("slram: Cannot allocate new MTD device.\n"); 188 E("slram: Cannot allocate new MTD device.\n");
189 return(-ENOMEM); 189 return(-ENOMEM);
190 } 190 }
191 191
192 if (!(((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start = 192 if (!(((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start =
193 ioremap(start, length))) { 193 ioremap(start, length))) {
194 E("slram: ioremap failed\n"); 194 E("slram: ioremap failed\n");
@@ -223,7 +223,7 @@ static int register_device(char *name, unsigned long start, unsigned long length
223 T("slram: Mapped from 0x%p to 0x%p\n", 223 T("slram: Mapped from 0x%p to 0x%p\n",
224 ((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start, 224 ((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start,
225 ((slram_priv_t *)(*curmtd)->mtdinfo->priv)->end); 225 ((slram_priv_t *)(*curmtd)->mtdinfo->priv)->end);
226 return(0); 226 return(0);
227} 227}
228 228
229static void unregister_devices(void) 229static void unregister_devices(void)
@@ -256,7 +256,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength)
256 char *buffer; 256 char *buffer;
257 unsigned long devstart; 257 unsigned long devstart;
258 unsigned long devlength; 258 unsigned long devlength;
259 259
260 if ((!devname) || (!szstart) || (!szlength)) { 260 if ((!devname) || (!szstart) || (!szlength)) {
261 unregister_devices(); 261 unregister_devices();
262 return(-EINVAL); 262 return(-EINVAL);
@@ -264,7 +264,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength)
264 264
265 devstart = simple_strtoul(szstart, &buffer, 0); 265 devstart = simple_strtoul(szstart, &buffer, 0);
266 devstart = handle_unit(devstart, buffer); 266 devstart = handle_unit(devstart, buffer);
267 267
268 if (*(szlength) != '+') { 268 if (*(szlength) != '+') {
269 devlength = simple_strtoul(szlength, &buffer, 0); 269 devlength = simple_strtoul(szlength, &buffer, 0);
270 devlength = handle_unit(devlength, buffer) - devstart; 270 devlength = handle_unit(devlength, buffer) - devstart;
@@ -278,7 +278,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength)
278 E("slram: Illegal start / length parameter.\n"); 278 E("slram: Illegal start / length parameter.\n");
279 return(-EINVAL); 279 return(-EINVAL);
280 } 280 }
281 281
282 if ((devstart = register_device(devname, devstart, devlength))){ 282 if ((devstart = register_device(devname, devstart, devlength))){
283 unregister_devices(); 283 unregister_devices();
284 return((int)devstart); 284 return((int)devstart);
@@ -335,7 +335,7 @@ static int init_slram(void)
335 } 335 }
336#else 336#else
337 int count; 337 int count;
338 338
339 for (count = 0; (map[count]) && (count < SLRAM_MAX_DEVICES_PARAMS); 339 for (count = 0; (map[count]) && (count < SLRAM_MAX_DEVICES_PARAMS);
340 count++) { 340 count++) {
341 } 341 }
@@ -350,10 +350,10 @@ static int init_slram(void)
350 if (parse_cmdline(devname, map[i * 3 + 1], map[i * 3 + 2])!=0) { 350 if (parse_cmdline(devname, map[i * 3 + 1], map[i * 3 + 2])!=0) {
351 return(-EINVAL); 351 return(-EINVAL);
352 } 352 }
353 353
354 } 354 }
355#endif /* !MODULE */ 355#endif /* !MODULE */
356 356
357 return(0); 357 return(0);
358} 358}
359 359
diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c
index d32c1b3a8ce3..de7e231d6d18 100644
--- a/drivers/mtd/ftl.c
+++ b/drivers/mtd/ftl.c
@@ -1,5 +1,5 @@
1/* This version ported to the Linux-MTD system by dwmw2@infradead.org 1/* This version ported to the Linux-MTD system by dwmw2@infradead.org
2 * $Id: ftl.c,v 1.55 2005/01/17 13:47:21 hvr Exp $ 2 * $Id: ftl.c,v 1.58 2005/11/07 11:14:19 gleixner Exp $
3 * 3 *
4 * Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br> 4 * Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
5 * - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups 5 * - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups
@@ -53,7 +53,7 @@
53 Use of the FTL format for non-PCMCIA applications may be an 53 Use of the FTL format for non-PCMCIA applications may be an
54 infringement of these patents. For additional information, 54 infringement of these patents. For additional information,
55 contact M-Systems (http://www.m-sys.com) directly. 55 contact M-Systems (http://www.m-sys.com) directly.
56 56
57======================================================================*/ 57======================================================================*/
58#include <linux/mtd/blktrans.h> 58#include <linux/mtd/blktrans.h>
59#include <linux/module.h> 59#include <linux/module.h>
@@ -160,7 +160,7 @@ static void ftl_erase_callback(struct erase_info *done);
160 Scan_header() checks to see if a memory region contains an FTL 160 Scan_header() checks to see if a memory region contains an FTL
161 partition. build_maps() reads all the erase unit headers, builds 161 partition. build_maps() reads all the erase unit headers, builds
162 the erase unit map, and then builds the virtual page map. 162 the erase unit map, and then builds the virtual page map.
163 163
164======================================================================*/ 164======================================================================*/
165 165
166static int scan_header(partition_t *part) 166static int scan_header(partition_t *part)
@@ -176,10 +176,10 @@ static int scan_header(partition_t *part)
176 (offset + sizeof(header)) < max_offset; 176 (offset + sizeof(header)) < max_offset;
177 offset += part->mbd.mtd->erasesize ? : 0x2000) { 177 offset += part->mbd.mtd->erasesize ? : 0x2000) {
178 178
179 err = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &ret, 179 err = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &ret,
180 (unsigned char *)&header); 180 (unsigned char *)&header);
181 181
182 if (err) 182 if (err)
183 return err; 183 return err;
184 184
185 if (strcmp(header.DataOrgTuple+3, "FTL100") == 0) break; 185 if (strcmp(header.DataOrgTuple+3, "FTL100") == 0) break;
@@ -232,10 +232,10 @@ static int build_maps(partition_t *part)
232 for (i = 0; i < le16_to_cpu(part->header.NumEraseUnits); i++) { 232 for (i = 0; i < le16_to_cpu(part->header.NumEraseUnits); i++) {
233 offset = ((i + le16_to_cpu(part->header.FirstPhysicalEUN)) 233 offset = ((i + le16_to_cpu(part->header.FirstPhysicalEUN))
234 << part->header.EraseUnitSize); 234 << part->header.EraseUnitSize);
235 ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &retval, 235 ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &retval,
236 (unsigned char *)&header); 236 (unsigned char *)&header);
237 237
238 if (ret) 238 if (ret)
239 goto out_XferInfo; 239 goto out_XferInfo;
240 240
241 ret = -1; 241 ret = -1;
@@ -274,7 +274,7 @@ static int build_maps(partition_t *part)
274 "don't add up!\n"); 274 "don't add up!\n");
275 goto out_XferInfo; 275 goto out_XferInfo;
276 } 276 }
277 277
278 /* Set up virtual page map */ 278 /* Set up virtual page map */
279 blocks = le32_to_cpu(header.FormattedSize) >> header.BlockSize; 279 blocks = le32_to_cpu(header.FormattedSize) >> header.BlockSize;
280 part->VirtualBlockMap = vmalloc(blocks * sizeof(u_int32_t)); 280 part->VirtualBlockMap = vmalloc(blocks * sizeof(u_int32_t));
@@ -296,12 +296,12 @@ static int build_maps(partition_t *part)
296 part->EUNInfo[i].Free = 0; 296 part->EUNInfo[i].Free = 0;
297 part->EUNInfo[i].Deleted = 0; 297 part->EUNInfo[i].Deleted = 0;
298 offset = part->EUNInfo[i].Offset + le32_to_cpu(header.BAMOffset); 298 offset = part->EUNInfo[i].Offset + le32_to_cpu(header.BAMOffset);
299 299
300 ret = part->mbd.mtd->read(part->mbd.mtd, offset, 300 ret = part->mbd.mtd->read(part->mbd.mtd, offset,
301 part->BlocksPerUnit * sizeof(u_int32_t), &retval, 301 part->BlocksPerUnit * sizeof(u_int32_t), &retval,
302 (unsigned char *)part->bam_cache); 302 (unsigned char *)part->bam_cache);
303 303
304 if (ret) 304 if (ret)
305 goto out_bam_cache; 305 goto out_bam_cache;
306 306
307 for (j = 0; j < part->BlocksPerUnit; j++) { 307 for (j = 0; j < part->BlocksPerUnit; j++) {
@@ -316,7 +316,7 @@ static int build_maps(partition_t *part)
316 part->EUNInfo[i].Deleted++; 316 part->EUNInfo[i].Deleted++;
317 } 317 }
318 } 318 }
319 319
320 ret = 0; 320 ret = 0;
321 goto out; 321 goto out;
322 322
@@ -336,7 +336,7 @@ out:
336 336
337 Erase_xfer() schedules an asynchronous erase operation for a 337 Erase_xfer() schedules an asynchronous erase operation for a
338 transfer unit. 338 transfer unit.
339 339
340======================================================================*/ 340======================================================================*/
341 341
342static int erase_xfer(partition_t *part, 342static int erase_xfer(partition_t *part,
@@ -351,10 +351,10 @@ static int erase_xfer(partition_t *part,
351 xfer->state = XFER_ERASING; 351 xfer->state = XFER_ERASING;
352 352
353 /* Is there a free erase slot? Always in MTD. */ 353 /* Is there a free erase slot? Always in MTD. */
354 354
355 355
356 erase=kmalloc(sizeof(struct erase_info), GFP_KERNEL); 356 erase=kmalloc(sizeof(struct erase_info), GFP_KERNEL);
357 if (!erase) 357 if (!erase)
358 return -ENOMEM; 358 return -ENOMEM;
359 359
360 erase->mtd = part->mbd.mtd; 360 erase->mtd = part->mbd.mtd;
@@ -362,7 +362,7 @@ static int erase_xfer(partition_t *part,
362 erase->addr = xfer->Offset; 362 erase->addr = xfer->Offset;
363 erase->len = 1 << part->header.EraseUnitSize; 363 erase->len = 1 << part->header.EraseUnitSize;
364 erase->priv = (u_long)part; 364 erase->priv = (u_long)part;
365 365
366 ret = part->mbd.mtd->erase(part->mbd.mtd, erase); 366 ret = part->mbd.mtd->erase(part->mbd.mtd, erase);
367 367
368 if (!ret) 368 if (!ret)
@@ -377,7 +377,7 @@ static int erase_xfer(partition_t *part,
377 377
378 Prepare_xfer() takes a freshly erased transfer unit and gives 378 Prepare_xfer() takes a freshly erased transfer unit and gives
379 it an appropriate header. 379 it an appropriate header.
380 380
381======================================================================*/ 381======================================================================*/
382 382
383static void ftl_erase_callback(struct erase_info *erase) 383static void ftl_erase_callback(struct erase_info *erase)
@@ -385,7 +385,7 @@ static void ftl_erase_callback(struct erase_info *erase)
385 partition_t *part; 385 partition_t *part;
386 struct xfer_info_t *xfer; 386 struct xfer_info_t *xfer;
387 int i; 387 int i;
388 388
389 /* Look up the transfer unit */ 389 /* Look up the transfer unit */
390 part = (partition_t *)(erase->priv); 390 part = (partition_t *)(erase->priv);
391 391
@@ -422,7 +422,7 @@ static int prepare_xfer(partition_t *part, int i)
422 422
423 xfer = &part->XferInfo[i]; 423 xfer = &part->XferInfo[i];
424 xfer->state = XFER_FAILED; 424 xfer->state = XFER_FAILED;
425 425
426 DEBUG(1, "ftl_cs: preparing xfer unit at 0x%x\n", xfer->Offset); 426 DEBUG(1, "ftl_cs: preparing xfer unit at 0x%x\n", xfer->Offset);
427 427
428 /* Write the transfer unit header */ 428 /* Write the transfer unit header */
@@ -446,7 +446,7 @@ static int prepare_xfer(partition_t *part, int i)
446 446
447 for (i = 0; i < nbam; i++, offset += sizeof(u_int32_t)) { 447 for (i = 0; i < nbam; i++, offset += sizeof(u_int32_t)) {
448 448
449 ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int32_t), 449 ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int32_t),
450 &retlen, (u_char *)&ctl); 450 &retlen, (u_char *)&ctl);
451 451
452 if (ret) 452 if (ret)
@@ -454,7 +454,7 @@ static int prepare_xfer(partition_t *part, int i)
454 } 454 }
455 xfer->state = XFER_PREPARED; 455 xfer->state = XFER_PREPARED;
456 return 0; 456 return 0;
457 457
458} /* prepare_xfer */ 458} /* prepare_xfer */
459 459
460/*====================================================================== 460/*======================================================================
@@ -466,7 +466,7 @@ static int prepare_xfer(partition_t *part, int i)
466 All data blocks are copied to the corresponding blocks in the 466 All data blocks are copied to the corresponding blocks in the
467 target unit, so the virtual block map does not need to be 467 target unit, so the virtual block map does not need to be
468 updated. 468 updated.
469 469
470======================================================================*/ 470======================================================================*/
471 471
472static int copy_erase_unit(partition_t *part, u_int16_t srcunit, 472static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
@@ -486,14 +486,14 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
486 xfer = &part->XferInfo[xferunit]; 486 xfer = &part->XferInfo[xferunit];
487 DEBUG(2, "ftl_cs: copying block 0x%x to 0x%x\n", 487 DEBUG(2, "ftl_cs: copying block 0x%x to 0x%x\n",
488 eun->Offset, xfer->Offset); 488 eun->Offset, xfer->Offset);
489 489
490 490
491 /* Read current BAM */ 491 /* Read current BAM */
492 if (part->bam_index != srcunit) { 492 if (part->bam_index != srcunit) {
493 493
494 offset = eun->Offset + le32_to_cpu(part->header.BAMOffset); 494 offset = eun->Offset + le32_to_cpu(part->header.BAMOffset);
495 495
496 ret = part->mbd.mtd->read(part->mbd.mtd, offset, 496 ret = part->mbd.mtd->read(part->mbd.mtd, offset,
497 part->BlocksPerUnit * sizeof(u_int32_t), 497 part->BlocksPerUnit * sizeof(u_int32_t),
498 &retlen, (u_char *) (part->bam_cache)); 498 &retlen, (u_char *) (part->bam_cache));
499 499
@@ -501,11 +501,11 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
501 part->bam_index = 0xffff; 501 part->bam_index = 0xffff;
502 502
503 if (ret) { 503 if (ret) {
504 printk( KERN_WARNING "ftl: Failed to read BAM cache in copy_erase_unit()!\n"); 504 printk( KERN_WARNING "ftl: Failed to read BAM cache in copy_erase_unit()!\n");
505 return ret; 505 return ret;
506 } 506 }
507 } 507 }
508 508
509 /* Write the LogicalEUN for the transfer unit */ 509 /* Write the LogicalEUN for the transfer unit */
510 xfer->state = XFER_UNKNOWN; 510 xfer->state = XFER_UNKNOWN;
511 offset = xfer->Offset + 20; /* Bad! */ 511 offset = xfer->Offset + 20; /* Bad! */
@@ -513,12 +513,12 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
513 513
514 ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int16_t), 514 ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int16_t),
515 &retlen, (u_char *) &unit); 515 &retlen, (u_char *) &unit);
516 516
517 if (ret) { 517 if (ret) {
518 printk( KERN_WARNING "ftl: Failed to write back to BAM cache in copy_erase_unit()!\n"); 518 printk( KERN_WARNING "ftl: Failed to write back to BAM cache in copy_erase_unit()!\n");
519 return ret; 519 return ret;
520 } 520 }
521 521
522 /* Copy all data blocks from source unit to transfer unit */ 522 /* Copy all data blocks from source unit to transfer unit */
523 src = eun->Offset; dest = xfer->Offset; 523 src = eun->Offset; dest = xfer->Offset;
524 524
@@ -558,15 +558,15 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
558 } 558 }
559 559
560 /* Write the BAM to the transfer unit */ 560 /* Write the BAM to the transfer unit */
561 ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + le32_to_cpu(part->header.BAMOffset), 561 ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + le32_to_cpu(part->header.BAMOffset),
562 part->BlocksPerUnit * sizeof(int32_t), &retlen, 562 part->BlocksPerUnit * sizeof(int32_t), &retlen,
563 (u_char *)part->bam_cache); 563 (u_char *)part->bam_cache);
564 if (ret) { 564 if (ret) {
565 printk( KERN_WARNING "ftl: Error writing BAM in copy_erase_unit\n"); 565 printk( KERN_WARNING "ftl: Error writing BAM in copy_erase_unit\n");
566 return ret; 566 return ret;
567 } 567 }
568 568
569 569
570 /* All clear? Then update the LogicalEUN again */ 570 /* All clear? Then update the LogicalEUN again */
571 ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + 20, sizeof(u_int16_t), 571 ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + 20, sizeof(u_int16_t),
572 &retlen, (u_char *)&srcunitswap); 572 &retlen, (u_char *)&srcunitswap);
@@ -574,9 +574,9 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
574 if (ret) { 574 if (ret) {
575 printk(KERN_WARNING "ftl: Error writing new LogicalEUN in copy_erase_unit\n"); 575 printk(KERN_WARNING "ftl: Error writing new LogicalEUN in copy_erase_unit\n");
576 return ret; 576 return ret;
577 } 577 }
578 578
579 579
580 /* Update the maps and usage stats*/ 580 /* Update the maps and usage stats*/
581 i = xfer->EraseCount; 581 i = xfer->EraseCount;
582 xfer->EraseCount = eun->EraseCount; 582 xfer->EraseCount = eun->EraseCount;
@@ -588,10 +588,10 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
588 part->FreeTotal += free; 588 part->FreeTotal += free;
589 eun->Free = free; 589 eun->Free = free;
590 eun->Deleted = 0; 590 eun->Deleted = 0;
591 591
592 /* Now, the cache should be valid for the new block */ 592 /* Now, the cache should be valid for the new block */
593 part->bam_index = srcunit; 593 part->bam_index = srcunit;
594 594
595 return 0; 595 return 0;
596} /* copy_erase_unit */ 596} /* copy_erase_unit */
597 597
@@ -608,7 +608,7 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
608 oldest data unit instead. This means that we generally postpone 608 oldest data unit instead. This means that we generally postpone
609 the next reclaimation as long as possible, but shuffle static 609 the next reclaimation as long as possible, but shuffle static
610 stuff around a bit for wear leveling. 610 stuff around a bit for wear leveling.
611 611
612======================================================================*/ 612======================================================================*/
613 613
614static int reclaim_block(partition_t *part) 614static int reclaim_block(partition_t *part)
@@ -666,7 +666,7 @@ static int reclaim_block(partition_t *part)
666 else 666 else
667 DEBUG(1, "ftl_cs: reclaim failed: no " 667 DEBUG(1, "ftl_cs: reclaim failed: no "
668 "suitable transfer units!\n"); 668 "suitable transfer units!\n");
669 669
670 return -EIO; 670 return -EIO;
671 } 671 }
672 } 672 }
@@ -715,7 +715,7 @@ static int reclaim_block(partition_t *part)
715 returns the block index -- the erase unit is just the currently 715 returns the block index -- the erase unit is just the currently
716 cached unit. If there are no free blocks, it returns 0 -- this 716 cached unit. If there are no free blocks, it returns 0 -- this
717 is never a valid data block because it contains the header. 717 is never a valid data block because it contains the header.
718 718
719======================================================================*/ 719======================================================================*/
720 720
721#ifdef PSYCHO_DEBUG 721#ifdef PSYCHO_DEBUG
@@ -737,7 +737,7 @@ static u_int32_t find_free(partition_t *part)
737 u_int32_t blk; 737 u_int32_t blk;
738 size_t retlen; 738 size_t retlen;
739 int ret; 739 int ret;
740 740
741 /* Find an erase unit with some free space */ 741 /* Find an erase unit with some free space */
742 stop = (part->bam_index == 0xffff) ? 0 : part->bam_index; 742 stop = (part->bam_index == 0xffff) ? 0 : part->bam_index;
743 eun = stop; 743 eun = stop;
@@ -749,17 +749,17 @@ static u_int32_t find_free(partition_t *part)
749 749
750 if (part->EUNInfo[eun].Free == 0) 750 if (part->EUNInfo[eun].Free == 0)
751 return 0; 751 return 0;
752 752
753 /* Is this unit's BAM cached? */ 753 /* Is this unit's BAM cached? */
754 if (eun != part->bam_index) { 754 if (eun != part->bam_index) {
755 /* Invalidate cache */ 755 /* Invalidate cache */
756 part->bam_index = 0xffff; 756 part->bam_index = 0xffff;
757 757
758 ret = part->mbd.mtd->read(part->mbd.mtd, 758 ret = part->mbd.mtd->read(part->mbd.mtd,
759 part->EUNInfo[eun].Offset + le32_to_cpu(part->header.BAMOffset), 759 part->EUNInfo[eun].Offset + le32_to_cpu(part->header.BAMOffset),
760 part->BlocksPerUnit * sizeof(u_int32_t), 760 part->BlocksPerUnit * sizeof(u_int32_t),
761 &retlen, (u_char *) (part->bam_cache)); 761 &retlen, (u_char *) (part->bam_cache));
762 762
763 if (ret) { 763 if (ret) {
764 printk(KERN_WARNING"ftl: Error reading BAM in find_free\n"); 764 printk(KERN_WARNING"ftl: Error reading BAM in find_free\n");
765 return 0; 765 return 0;
@@ -781,14 +781,14 @@ static u_int32_t find_free(partition_t *part)
781 } 781 }
782 DEBUG(2, "ftl_cs: found free block at %d in %d\n", blk, eun); 782 DEBUG(2, "ftl_cs: found free block at %d in %d\n", blk, eun);
783 return blk; 783 return blk;
784 784
785} /* find_free */ 785} /* find_free */
786 786
787 787
788/*====================================================================== 788/*======================================================================
789 789
790 Read a series of sectors from an FTL partition. 790 Read a series of sectors from an FTL partition.
791 791
792======================================================================*/ 792======================================================================*/
793 793
794static int ftl_read(partition_t *part, caddr_t buffer, 794static int ftl_read(partition_t *part, caddr_t buffer,
@@ -798,7 +798,7 @@ static int ftl_read(partition_t *part, caddr_t buffer,
798 u_long i; 798 u_long i;
799 int ret; 799 int ret;
800 size_t offset, retlen; 800 size_t offset, retlen;
801 801
802 DEBUG(2, "ftl_cs: ftl_read(0x%p, 0x%lx, %ld)\n", 802 DEBUG(2, "ftl_cs: ftl_read(0x%p, 0x%lx, %ld)\n",
803 part, sector, nblocks); 803 part, sector, nblocks);
804 if (!(part->state & FTL_FORMATTED)) { 804 if (!(part->state & FTL_FORMATTED)) {
@@ -834,7 +834,7 @@ static int ftl_read(partition_t *part, caddr_t buffer,
834/*====================================================================== 834/*======================================================================
835 835
836 Write a series of sectors to an FTL partition 836 Write a series of sectors to an FTL partition
837 837
838======================================================================*/ 838======================================================================*/
839 839
840static int set_bam_entry(partition_t *part, u_int32_t log_addr, 840static int set_bam_entry(partition_t *part, u_int32_t log_addr,
@@ -855,7 +855,7 @@ static int set_bam_entry(partition_t *part, u_int32_t log_addr,
855 blk = (log_addr % bsize) / SECTOR_SIZE; 855 blk = (log_addr % bsize) / SECTOR_SIZE;
856 offset = (part->EUNInfo[eun].Offset + blk * sizeof(u_int32_t) + 856 offset = (part->EUNInfo[eun].Offset + blk * sizeof(u_int32_t) +
857 le32_to_cpu(part->header.BAMOffset)); 857 le32_to_cpu(part->header.BAMOffset));
858 858
859#ifdef PSYCHO_DEBUG 859#ifdef PSYCHO_DEBUG
860 ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(u_int32_t), 860 ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(u_int32_t),
861 &retlen, (u_char *)&old_addr); 861 &retlen, (u_char *)&old_addr);
@@ -925,7 +925,7 @@ static int ftl_write(partition_t *part, caddr_t buffer,
925 if (ret) 925 if (ret)
926 return ret; 926 return ret;
927 } 927 }
928 928
929 bsize = 1 << part->header.EraseUnitSize; 929 bsize = 1 << part->header.EraseUnitSize;
930 930
931 virt_addr = sector * SECTOR_SIZE | BLOCK_DATA; 931 virt_addr = sector * SECTOR_SIZE | BLOCK_DATA;
@@ -949,12 +949,12 @@ static int ftl_write(partition_t *part, caddr_t buffer,
949 log_addr = part->bam_index * bsize + blk * SECTOR_SIZE; 949 log_addr = part->bam_index * bsize + blk * SECTOR_SIZE;
950 part->EUNInfo[part->bam_index].Free--; 950 part->EUNInfo[part->bam_index].Free--;
951 part->FreeTotal--; 951 part->FreeTotal--;
952 if (set_bam_entry(part, log_addr, 0xfffffffe)) 952 if (set_bam_entry(part, log_addr, 0xfffffffe))
953 return -EIO; 953 return -EIO;
954 part->EUNInfo[part->bam_index].Deleted++; 954 part->EUNInfo[part->bam_index].Deleted++;
955 offset = (part->EUNInfo[part->bam_index].Offset + 955 offset = (part->EUNInfo[part->bam_index].Offset +
956 blk * SECTOR_SIZE); 956 blk * SECTOR_SIZE);
957 ret = part->mbd.mtd->write(part->mbd.mtd, offset, SECTOR_SIZE, &retlen, 957 ret = part->mbd.mtd->write(part->mbd.mtd, offset, SECTOR_SIZE, &retlen,
958 buffer); 958 buffer);
959 959
960 if (ret) { 960 if (ret) {
@@ -964,7 +964,7 @@ static int ftl_write(partition_t *part, caddr_t buffer,
964 offset); 964 offset);
965 return -EIO; 965 return -EIO;
966 } 966 }
967 967
968 /* Only delete the old entry when the new entry is ready */ 968 /* Only delete the old entry when the new entry is ready */
969 old_addr = part->VirtualBlockMap[sector+i]; 969 old_addr = part->VirtualBlockMap[sector+i];
970 if (old_addr != 0xffffffff) { 970 if (old_addr != 0xffffffff) {
@@ -979,7 +979,7 @@ static int ftl_write(partition_t *part, caddr_t buffer,
979 return -EIO; 979 return -EIO;
980 part->VirtualBlockMap[sector+i] = log_addr; 980 part->VirtualBlockMap[sector+i] = log_addr;
981 part->EUNInfo[part->bam_index].Deleted--; 981 part->EUNInfo[part->bam_index].Deleted--;
982 982
983 buffer += SECTOR_SIZE; 983 buffer += SECTOR_SIZE;
984 virt_addr += SECTOR_SIZE; 984 virt_addr += SECTOR_SIZE;
985 } 985 }
@@ -1034,20 +1034,20 @@ static void ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
1034 partition_t *partition; 1034 partition_t *partition;
1035 1035
1036 partition = kmalloc(sizeof(partition_t), GFP_KERNEL); 1036 partition = kmalloc(sizeof(partition_t), GFP_KERNEL);
1037 1037
1038 if (!partition) { 1038 if (!partition) {
1039 printk(KERN_WARNING "No memory to scan for FTL on %s\n", 1039 printk(KERN_WARNING "No memory to scan for FTL on %s\n",
1040 mtd->name); 1040 mtd->name);
1041 return; 1041 return;
1042 } 1042 }
1043 1043
1044 memset(partition, 0, sizeof(partition_t)); 1044 memset(partition, 0, sizeof(partition_t));
1045 1045
1046 partition->mbd.mtd = mtd; 1046 partition->mbd.mtd = mtd;
1047 1047
1048 if ((scan_header(partition) == 0) && 1048 if ((scan_header(partition) == 0) &&
1049 (build_maps(partition) == 0)) { 1049 (build_maps(partition) == 0)) {
1050 1050
1051 partition->state = FTL_FORMATTED; 1051 partition->state = FTL_FORMATTED;
1052#ifdef PCMCIA_DEBUG 1052#ifdef PCMCIA_DEBUG
1053 printk(KERN_INFO "ftl_cs: opening %d KiB FTL partition\n", 1053 printk(KERN_INFO "ftl_cs: opening %d KiB FTL partition\n",
@@ -1086,7 +1086,7 @@ struct mtd_blktrans_ops ftl_tr = {
1086 1086
1087int init_ftl(void) 1087int init_ftl(void)
1088{ 1088{
1089 DEBUG(0, "$Id: ftl.c,v 1.55 2005/01/17 13:47:21 hvr Exp $\n"); 1089 DEBUG(0, "$Id: ftl.c,v 1.58 2005/11/07 11:14:19 gleixner Exp $\n");
1090 1090
1091 return register_mtd_blktrans(&ftl_tr); 1091 return register_mtd_blktrans(&ftl_tr);
1092} 1092}
diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c
index 8db65bf029ea..8a544890173d 100644
--- a/drivers/mtd/inftlcore.c
+++ b/drivers/mtd/inftlcore.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * inftlcore.c -- Linux driver for Inverse Flash Translation Layer (INFTL) 2 * inftlcore.c -- Linux driver for Inverse Flash Translation Layer (INFTL)
3 * 3 *
4 * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) 4 * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
@@ -7,7 +7,7 @@
7 * (c) 1999 Machine Vision Holdings, Inc. 7 * (c) 1999 Machine Vision Holdings, Inc.
8 * Author: David Woodhouse <dwmw2@infradead.org> 8 * Author: David Woodhouse <dwmw2@infradead.org>
9 * 9 *
10 * $Id: inftlcore.c,v 1.18 2004/11/16 18:28:59 dwmw2 Exp $ 10 * $Id: inftlcore.c,v 1.19 2005/11/07 11:14:20 gleixner Exp $
11 * 11 *
12 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by 13 * it under the terms of the GNU General Public License as published by
@@ -113,14 +113,14 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
113 113
114 if (inftl->mbd.size != inftl->heads * inftl->cylinders * inftl->sectors) { 114 if (inftl->mbd.size != inftl->heads * inftl->cylinders * inftl->sectors) {
115 /* 115 /*
116 Oh no we don't have 116 Oh no we don't have
117 mbd.size == heads * cylinders * sectors 117 mbd.size == heads * cylinders * sectors
118 */ 118 */
119 printk(KERN_WARNING "INFTL: cannot calculate a geometry to " 119 printk(KERN_WARNING "INFTL: cannot calculate a geometry to "
120 "match size of 0x%lx.\n", inftl->mbd.size); 120 "match size of 0x%lx.\n", inftl->mbd.size);
121 printk(KERN_WARNING "INFTL: using C:%d H:%d S:%d " 121 printk(KERN_WARNING "INFTL: using C:%d H:%d S:%d "
122 "(== 0x%lx sects)\n", 122 "(== 0x%lx sects)\n",
123 inftl->cylinders, inftl->heads , inftl->sectors, 123 inftl->cylinders, inftl->heads , inftl->sectors,
124 (long)inftl->cylinders * (long)inftl->heads * 124 (long)inftl->cylinders * (long)inftl->heads *
125 (long)inftl->sectors ); 125 (long)inftl->sectors );
126 } 126 }
@@ -219,7 +219,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
219 "Virtual Unit Chain %d!\n", thisVUC); 219 "Virtual Unit Chain %d!\n", thisVUC);
220 return BLOCK_NIL; 220 return BLOCK_NIL;
221 } 221 }
222 222
223 /* 223 /*
224 * Scan to find the Erase Unit which holds the actual data for each 224 * Scan to find the Erase Unit which holds the actual data for each
225 * 512-byte block within the Chain. 225 * 512-byte block within the Chain.
@@ -260,7 +260,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
260 "Unit Chain 0x%x\n", thisVUC); 260 "Unit Chain 0x%x\n", thisVUC);
261 return BLOCK_NIL; 261 return BLOCK_NIL;
262 } 262 }
263 263
264 thisEUN = inftl->PUtable[thisEUN]; 264 thisEUN = inftl->PUtable[thisEUN];
265 } 265 }
266 266
@@ -291,15 +291,15 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
291 */ 291 */
292 if (BlockMap[block] == BLOCK_NIL) 292 if (BlockMap[block] == BLOCK_NIL)
293 continue; 293 continue;
294 294
295 ret = MTD_READ(inftl->mbd.mtd, (inftl->EraseSize * 295 ret = MTD_READ(inftl->mbd.mtd, (inftl->EraseSize *
296 BlockMap[block]) + (block * SECTORSIZE), SECTORSIZE, 296 BlockMap[block]) + (block * SECTORSIZE), SECTORSIZE,
297 &retlen, movebuf); 297 &retlen, movebuf);
298 if (ret < 0) { 298 if (ret < 0) {
299 ret = MTD_READ(inftl->mbd.mtd, (inftl->EraseSize * 299 ret = MTD_READ(inftl->mbd.mtd, (inftl->EraseSize *
300 BlockMap[block]) + (block * SECTORSIZE), 300 BlockMap[block]) + (block * SECTORSIZE),
301 SECTORSIZE, &retlen, movebuf); 301 SECTORSIZE, &retlen, movebuf);
302 if (ret != -EIO) 302 if (ret != -EIO)
303 DEBUG(MTD_DEBUG_LEVEL1, "INFTL: error went " 303 DEBUG(MTD_DEBUG_LEVEL1, "INFTL: error went "
304 "away on retry?\n"); 304 "away on retry?\n");
305 } 305 }
@@ -351,7 +351,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
351static u16 INFTL_makefreeblock(struct INFTLrecord *inftl, unsigned pendingblock) 351static u16 INFTL_makefreeblock(struct INFTLrecord *inftl, unsigned pendingblock)
352{ 352{
353 /* 353 /*
354 * This is the part that needs some cleverness applied. 354 * This is the part that needs some cleverness applied.
355 * For now, I'm doing the minimum applicable to actually 355 * For now, I'm doing the minimum applicable to actually
356 * get the thing to work. 356 * get the thing to work.
357 * Wear-levelling and other clever stuff needs to be implemented 357 * Wear-levelling and other clever stuff needs to be implemented
@@ -410,7 +410,7 @@ static int nrbits(unsigned int val, int bitcount)
410} 410}
411 411
412/* 412/*
413 * INFTL_findwriteunit: Return the unit number into which we can write 413 * INFTL_findwriteunit: Return the unit number into which we can write
414 * for this block. Make it available if it isn't already. 414 * for this block. Make it available if it isn't already.
415 */ 415 */
416static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block) 416static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
@@ -459,10 +459,10 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
459 * Invalid block. Don't use it any more. 459 * Invalid block. Don't use it any more.
460 * Must implement. 460 * Must implement.
461 */ 461 */
462 break; 462 break;
463 } 463 }
464 464
465 if (!silly--) { 465 if (!silly--) {
466 printk(KERN_WARNING "INFTL: infinite loop in " 466 printk(KERN_WARNING "INFTL: infinite loop in "
467 "Virtual Unit Chain 0x%x\n", thisVUC); 467 "Virtual Unit Chain 0x%x\n", thisVUC);
468 return 0xffff; 468 return 0xffff;
@@ -478,7 +478,7 @@ hitused:
478 478
479 479
480 /* 480 /*
481 * OK. We didn't find one in the existing chain, or there 481 * OK. We didn't find one in the existing chain, or there
482 * is no existing chain. Allocate a new one. 482 * is no existing chain. Allocate a new one.
483 */ 483 */
484 writeEUN = INFTL_findfreeblock(inftl, 0); 484 writeEUN = INFTL_findfreeblock(inftl, 0);
@@ -502,8 +502,8 @@ hitused:
502 if (writeEUN == BLOCK_NIL) { 502 if (writeEUN == BLOCK_NIL) {
503 /* 503 /*
504 * Ouch. This should never happen - we should 504 * Ouch. This should never happen - we should
505 * always be able to make some room somehow. 505 * always be able to make some room somehow.
506 * If we get here, we've allocated more storage 506 * If we get here, we've allocated more storage
507 * space than actual media, or our makefreeblock 507 * space than actual media, or our makefreeblock
508 * routine is missing something. 508 * routine is missing something.
509 */ 509 */
@@ -514,7 +514,7 @@ hitused:
514 INFTL_dumpVUchains(inftl); 514 INFTL_dumpVUchains(inftl);
515#endif 515#endif
516 return BLOCK_NIL; 516 return BLOCK_NIL;
517 } 517 }
518 } 518 }
519 519
520 /* 520 /*
@@ -539,7 +539,7 @@ hitused:
539 parity |= (nrbits(prev_block, 16) & 0x1) ? 0x2 : 0; 539 parity |= (nrbits(prev_block, 16) & 0x1) ? 0x2 : 0;
540 parity |= (nrbits(anac, 8) & 0x1) ? 0x4 : 0; 540 parity |= (nrbits(anac, 8) & 0x1) ? 0x4 : 0;
541 parity |= (nrbits(nacs, 8) & 0x1) ? 0x8 : 0; 541 parity |= (nrbits(nacs, 8) & 0x1) ? 0x8 : 0;
542 542
543 oob.u.a.virtualUnitNo = cpu_to_le16(thisVUC); 543 oob.u.a.virtualUnitNo = cpu_to_le16(thisVUC);
544 oob.u.a.prevUnitNo = cpu_to_le16(prev_block); 544 oob.u.a.prevUnitNo = cpu_to_le16(prev_block);
545 oob.u.a.ANAC = anac; 545 oob.u.a.ANAC = anac;
@@ -558,7 +558,7 @@ hitused:
558 oob.u.b.parityPerField = parity; 558 oob.u.b.parityPerField = parity;
559 oob.u.b.discarded = 0xaa; 559 oob.u.b.discarded = 0xaa;
560 560
561 MTD_WRITEOOB(inftl->mbd.mtd, writeEUN * inftl->EraseSize + 561 MTD_WRITEOOB(inftl->mbd.mtd, writeEUN * inftl->EraseSize +
562 SECTORSIZE * 4 + 8, 8, &retlen, (char *)&oob.u); 562 SECTORSIZE * 4 + 8, 8, &retlen, (char *)&oob.u);
563 563
564 inftl->PUtable[writeEUN] = inftl->VUtable[thisVUC]; 564 inftl->PUtable[writeEUN] = inftl->VUtable[thisVUC];
@@ -598,7 +598,7 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
598 "Virtual Unit Chain %d!\n", thisVUC); 598 "Virtual Unit Chain %d!\n", thisVUC);
599 return; 599 return;
600 } 600 }
601 601
602 /* 602 /*
603 * Scan through the Erase Units to determine whether any data is in 603 * Scan through the Erase Units to determine whether any data is in
604 * each of the 512-byte blocks within the Chain. 604 * each of the 512-byte blocks within the Chain.
@@ -638,7 +638,7 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
638 "Unit Chain 0x%x\n", thisVUC); 638 "Unit Chain 0x%x\n", thisVUC);
639 return; 639 return;
640 } 640 }
641 641
642 thisEUN = inftl->PUtable[thisEUN]; 642 thisEUN = inftl->PUtable[thisEUN];
643 } 643 }
644 644
@@ -754,7 +754,7 @@ foundit:
754 return 0; 754 return 0;
755} 755}
756 756
757static int inftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block, 757static int inftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block,
758 char *buffer) 758 char *buffer)
759{ 759{
760 struct INFTLrecord *inftl = (void *)mbd; 760 struct INFTLrecord *inftl = (void *)mbd;
@@ -889,7 +889,7 @@ extern char inftlmountrev[];
889 889
890static int __init init_inftl(void) 890static int __init init_inftl(void)
891{ 891{
892 printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.18 $, " 892 printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.19 $, "
893 "inftlmount.c %s\n", inftlmountrev); 893 "inftlmount.c %s\n", inftlmountrev);
894 894
895 return register_mtd_blktrans(&inftl_tr); 895 return register_mtd_blktrans(&inftl_tr);
diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c
index 3dac53feeee2..43fdc9433882 100644
--- a/drivers/mtd/inftlmount.c
+++ b/drivers/mtd/inftlmount.c
@@ -1,14 +1,14 @@
1/* 1/*
2 * inftlmount.c -- INFTL mount code with extensive checks. 2 * inftlmount.c -- INFTL mount code with extensive checks.
3 * 3 *
4 * Author: Greg Ungerer (gerg@snapgear.com) 4 * Author: Greg Ungerer (gerg@snapgear.com)
5 * (C) Copyright 2002-2003, Greg Ungerer (gerg@snapgear.com) 5 * (C) Copyright 2002-2003, Greg Ungerer (gerg@snapgear.com)
6 * 6 *
7 * Based heavily on the nftlmount.c code which is: 7 * Based heavily on the nftlmount.c code which is:
8 * Author: Fabrice Bellard (fabrice.bellard@netgem.com) 8 * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
9 * Copyright (C) 2000 Netgem S.A. 9 * Copyright (C) 2000 Netgem S.A.
10 * 10 *
11 * $Id: inftlmount.c,v 1.16 2004/11/22 13:50:53 kalev Exp $ 11 * $Id: inftlmount.c,v 1.18 2005/11/07 11:14:20 gleixner Exp $
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by 14 * it under the terms of the GNU General Public License as published by
@@ -41,7 +41,7 @@
41#include <linux/mtd/inftl.h> 41#include <linux/mtd/inftl.h>
42#include <linux/mtd/compatmac.h> 42#include <linux/mtd/compatmac.h>
43 43
44char inftlmountrev[]="$Revision: 1.16 $"; 44char inftlmountrev[]="$Revision: 1.18 $";
45 45
46/* 46/*
47 * find_boot_record: Find the INFTL Media Header and its Spare copy which 47 * find_boot_record: Find the INFTL Media Header and its Spare copy which
@@ -273,7 +273,7 @@ static int find_boot_record(struct INFTLrecord *inftl)
273 inftl->nb_boot_blocks); 273 inftl->nb_boot_blocks);
274 return -1; 274 return -1;
275 } 275 }
276 276
277 inftl->mbd.size = inftl->numvunits * 277 inftl->mbd.size = inftl->numvunits *
278 (inftl->EraseSize / SECTORSIZE); 278 (inftl->EraseSize / SECTORSIZE);
279 279
@@ -302,7 +302,7 @@ static int find_boot_record(struct INFTLrecord *inftl)
302 inftl->nb_blocks * sizeof(u16)); 302 inftl->nb_blocks * sizeof(u16));
303 return -ENOMEM; 303 return -ENOMEM;
304 } 304 }
305 305
306 /* Mark the blocks before INFTL MediaHeader as reserved */ 306 /* Mark the blocks before INFTL MediaHeader as reserved */
307 for (i = 0; i < inftl->nb_boot_blocks; i++) 307 for (i = 0; i < inftl->nb_boot_blocks; i++)
308 inftl->PUtable[i] = BLOCK_RESERVED; 308 inftl->PUtable[i] = BLOCK_RESERVED;
@@ -380,7 +380,7 @@ static int check_free_sectors(struct INFTLrecord *inftl, unsigned int address,
380 * 380 *
381 * Return: 0 when succeed, -1 on error. 381 * Return: 0 when succeed, -1 on error.
382 * 382 *
383 * ToDo: 1. Is it neceressary to check_free_sector after erasing ?? 383 * ToDo: 1. Is it neceressary to check_free_sector after erasing ??
384 */ 384 */
385int INFTL_formatblock(struct INFTLrecord *inftl, int block) 385int INFTL_formatblock(struct INFTLrecord *inftl, int block)
386{ 386{
@@ -563,7 +563,7 @@ int INFTL_mount(struct INFTLrecord *s)
563 /* Search for INFTL MediaHeader and Spare INFTL Media Header */ 563 /* Search for INFTL MediaHeader and Spare INFTL Media Header */
564 if (find_boot_record(s) < 0) { 564 if (find_boot_record(s) < 0) {
565 printk(KERN_WARNING "INFTL: could not find valid boot record?\n"); 565 printk(KERN_WARNING "INFTL: could not find valid boot record?\n");
566 return -1; 566 return -ENXIO;
567 } 567 }
568 568
569 /* Init the logical to physical table */ 569 /* Init the logical to physical table */
@@ -601,7 +601,7 @@ int INFTL_mount(struct INFTLrecord *s)
601 601
602 for (chain_length = 0; ; chain_length++) { 602 for (chain_length = 0; ; chain_length++) {
603 603
604 if ((chain_length == 0) && 604 if ((chain_length == 0) &&
605 (s->PUtable[block] != BLOCK_NOTEXPLORED)) { 605 (s->PUtable[block] != BLOCK_NOTEXPLORED)) {
606 /* Nothing to do here, onto next block */ 606 /* Nothing to do here, onto next block */
607 break; 607 break;
@@ -748,7 +748,7 @@ int INFTL_mount(struct INFTLrecord *s)
748 "in virtual chain %d\n", 748 "in virtual chain %d\n",
749 s->PUtable[block], logical_block); 749 s->PUtable[block], logical_block);
750 s->PUtable[block] = BLOCK_NIL; 750 s->PUtable[block] = BLOCK_NIL;
751 751
752 } 752 }
753 if (ANACtable[block] != ANAC) { 753 if (ANACtable[block] != ANAC) {
754 /* 754 /*
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 44781a83b2e7..48638c8097a5 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -1,5 +1,5 @@
1# drivers/mtd/maps/Kconfig 1# drivers/mtd/maps/Kconfig
2# $Id: Kconfig,v 1.55 2005/07/02 01:53:24 tpoynor Exp $ 2# $Id: Kconfig,v 1.61 2005/11/07 11:14:26 gleixner Exp $
3 3
4menu "Mapping drivers for chip access" 4menu "Mapping drivers for chip access"
5 depends on MTD!=n 5 depends on MTD!=n
@@ -64,9 +64,9 @@ config MTD_SUN_UFLASH
64 tristate "Sun Microsystems userflash support" 64 tristate "Sun Microsystems userflash support"
65 depends on (SPARC32 || SPARC64) && MTD_CFI 65 depends on (SPARC32 || SPARC64) && MTD_CFI
66 help 66 help
67 This provides a 'mapping' driver which supports the way in 67 This provides a 'mapping' driver which supports the way in
68 which user-programmable flash chips are connected on various 68 which user-programmable flash chips are connected on various
69 Sun Microsystems boardsets. This driver will require CFI support 69 Sun Microsystems boardsets. This driver will require CFI support
70 in the kernel, so if you did not enable CFI previously, do that now. 70 in the kernel, so if you did not enable CFI previously, do that now.
71 71
72config MTD_PNC2000 72config MTD_PNC2000
@@ -89,22 +89,22 @@ config MTD_NETSC520
89 depends on X86 && MTD_CFI && MTD_PARTITIONS 89 depends on X86 && MTD_CFI && MTD_PARTITIONS
90 help 90 help
91 This enables access routines for the flash chips on the AMD NetSc520 91 This enables access routines for the flash chips on the AMD NetSc520
92 demonstration board. If you have one of these boards and would like 92 demonstration board. If you have one of these boards and would like
93 to use the flash chips on it, say 'Y'. 93 to use the flash chips on it, say 'Y'.
94 94
95config MTD_TS5500 95config MTD_TS5500
96 tristate "JEDEC Flash device mapped on Technologic Systems TS-5500" 96 tristate "JEDEC Flash device mapped on Technologic Systems TS-5500"
97 depends on X86 && MTD_JEDECPROBE && MTD_PARTITIONS 97 depends on ELAN
98 select MTD_PARTITIONS
99 select MTD_JEDECPROBE
100 select MTD_CFI_AMDSTD
98 help 101 help
99 This provides a driver for the on-board flash of the Technologic 102 This provides a driver for the on-board flash of the Technologic
100 System's TS-5500 board. The flash is split into 3 partitions 103 System's TS-5500 board. The 2MB flash is split into 3 partitions
101 which are accessed as separate MTD devices. 104 which are accessed as separate MTD devices.
102 105
103 mtd0 and mtd2 are the two BIOS drives. Unfortunately the BIOS 106 mtd0 and mtd2 are the two BIOS drives, which use the resident
104 uses a proprietary flash translation layer from General Software, 107 flash disk (RFD) flash translation layer.
105 which is not supported (the drives cannot be mounted). You can
106 create your own file system (jffs for example), but the BIOS
107 won't be able to boot from it.
108 108
109 mtd1 allows you to reprogram your BIOS. BE VERY CAREFUL. 109 mtd1 allows you to reprogram your BIOS. BE VERY CAREFUL.
110 110
@@ -212,11 +212,18 @@ config MTD_NETtel
212 Support for flash chips on NETtel/SecureEdge/SnapGear boards. 212 Support for flash chips on NETtel/SecureEdge/SnapGear boards.
213 213
214config MTD_ALCHEMY 214config MTD_ALCHEMY
215 tristate ' AMD Alchemy Pb1xxx/Db1xxx/RDK MTD support' 215 tristate ' AMD Alchemy Pb1xxx/Db1xxx/RDK MTD support'
216 depends on MIPS && SOC_AU1X00 216 depends on SOC_AU1X00
217 help 217 help
218 Flash memory access on AMD Alchemy Pb/Db/RDK Reference Boards 218 Flash memory access on AMD Alchemy Pb/Db/RDK Reference Boards
219 219
220config MTD_MTX1
221 tristate "4G Systems MTX-1 Flash device"
222 depends on MIPS && MIPS_MTX1
223 help
224 Flash memory access on 4G Systems MTX-1 Board. If you have one of
225 these boards and would like to use the flash chips on it, say 'Y'.
226
220config MTD_DILNETPC 227config MTD_DILNETPC
221 tristate "CFI Flash device mapped on DIL/Net PC" 228 tristate "CFI Flash device mapped on DIL/Net PC"
222 depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT 229 depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT
@@ -244,14 +251,14 @@ config MTD_L440GX
244 251
245config MTD_SBC8240 252config MTD_SBC8240
246 tristate "Flash device on SBC8240" 253 tristate "Flash device on SBC8240"
247 depends on PPC32 && MTD_JEDECPROBE && 6xx && 8260 254 depends on MTD_JEDECPROBE && 8260
248 help 255 help
249 Flash access on the SBC8240 board from Wind River. See 256 Flash access on the SBC8240 board from Wind River. See
250 <http://www.windriver.com/products/sbc8240/> 257 <http://www.windriver.com/products/sbc8240/>
251 258
252config MTD_TQM8XXL 259config MTD_TQM8XXL
253 tristate "CFI Flash device mapped on TQM8XXL" 260 tristate "CFI Flash device mapped on TQM8XXL"
254 depends on MTD_CFI && PPC32 && 8xx && TQM8xxL 261 depends on MTD_CFI && TQM8xxL
255 help 262 help
256 The TQM8xxL PowerPC board has up to two banks of CFI-compliant 263 The TQM8xxL PowerPC board has up to two banks of CFI-compliant
257 chips, currently uses AMD one. This 'mapping' driver supports 264 chips, currently uses AMD one. This 'mapping' driver supports
@@ -261,7 +268,7 @@ config MTD_TQM8XXL
261 268
262config MTD_RPXLITE 269config MTD_RPXLITE
263 tristate "CFI Flash device mapped on RPX Lite or CLLF" 270 tristate "CFI Flash device mapped on RPX Lite or CLLF"
264 depends on MTD_CFI && PPC32 && 8xx && (RPXCLASSIC || RPXLITE) 271 depends on MTD_CFI && (RPXCLASSIC || RPXLITE)
265 help 272 help
266 The RPXLite PowerPC board has CFI-compliant chips mapped in 273 The RPXLite PowerPC board has CFI-compliant chips mapped in
267 a strange sparse mapping. This 'mapping' driver supports that 274 a strange sparse mapping. This 'mapping' driver supports that
@@ -271,7 +278,7 @@ config MTD_RPXLITE
271 278
272config MTD_MBX860 279config MTD_MBX860
273 tristate "System flash on MBX860 board" 280 tristate "System flash on MBX860 board"
274 depends on MTD_CFI && PPC32 && 8xx && MBX 281 depends on MTD_CFI && MBX
275 help 282 help
276 This enables access routines for the flash chips on the Motorola 283 This enables access routines for the flash chips on the Motorola
277 MBX860 board. If you have one of these boards and would like 284 MBX860 board. If you have one of these boards and would like
@@ -279,7 +286,7 @@ config MTD_MBX860
279 286
280config MTD_DBOX2 287config MTD_DBOX2
281 tristate "CFI Flash device mapped on D-Box2" 288 tristate "CFI Flash device mapped on D-Box2"
282 depends on PPC32 && 8xx && DBOX2 && MTD_CFI_INTELSTD && MTD_CFI_INTELEXT && MTD_CFI_AMDSTD 289 depends on DBOX2 && MTD_CFI_INTELSTD && MTD_CFI_INTELEXT && MTD_CFI_AMDSTD
283 help 290 help
284 This enables access routines for the flash chips on the Nokia/Sagem 291 This enables access routines for the flash chips on the Nokia/Sagem
285 D-Box 2 board. If you have one of these boards and would like to use 292 D-Box 2 board. If you have one of these boards and would like to use
@@ -287,14 +294,14 @@ config MTD_DBOX2
287 294
288config MTD_CFI_FLAGADM 295config MTD_CFI_FLAGADM
289 tristate "CFI Flash device mapping on FlagaDM" 296 tristate "CFI Flash device mapping on FlagaDM"
290 depends on PPC32 && 8xx && MTD_CFI 297 depends on 8xx && MTD_CFI
291 help 298 help
292 Mapping for the Flaga digital module. If you don't have one, ignore 299 Mapping for the Flaga digital module. If you don't have one, ignore
293 this setting. 300 this setting.
294 301
295config MTD_BEECH 302config MTD_BEECH
296 tristate "CFI Flash device mapped on IBM 405LP Beech" 303 tristate "CFI Flash device mapped on IBM 405LP Beech"
297 depends on MTD_CFI && PPC32 && 40x && BEECH 304 depends on MTD_CFI && BEECH
298 help 305 help
299 This enables access routines for the flash chips on the IBM 306 This enables access routines for the flash chips on the IBM
300 405LP Beech board. If you have one of these boards and would like 307 405LP Beech board. If you have one of these boards and would like
@@ -302,7 +309,7 @@ config MTD_BEECH
302 309
303config MTD_ARCTIC 310config MTD_ARCTIC
304 tristate "CFI Flash device mapped on IBM 405LP Arctic" 311 tristate "CFI Flash device mapped on IBM 405LP Arctic"
305 depends on MTD_CFI && PPC32 && 40x && ARCTIC2 312 depends on MTD_CFI && ARCTIC2
306 help 313 help
307 This enables access routines for the flash chips on the IBM 405LP 314 This enables access routines for the flash chips on the IBM 405LP
308 Arctic board. If you have one of these boards and would like to 315 Arctic board. If you have one of these boards and would like to
@@ -310,7 +317,7 @@ config MTD_ARCTIC
310 317
311config MTD_WALNUT 318config MTD_WALNUT
312 tristate "Flash device mapped on IBM 405GP Walnut" 319 tristate "Flash device mapped on IBM 405GP Walnut"
313 depends on MTD_JEDECPROBE && PPC32 && 40x && WALNUT 320 depends on MTD_JEDECPROBE && WALNUT
314 help 321 help
315 This enables access routines for the flash chips on the IBM 405GP 322 This enables access routines for the flash chips on the IBM 405GP
316 Walnut board. If you have one of these boards and would like to 323 Walnut board. If you have one of these boards and would like to
@@ -318,7 +325,7 @@ config MTD_WALNUT
318 325
319config MTD_EBONY 326config MTD_EBONY
320 tristate "Flash devices mapped on IBM 440GP Ebony" 327 tristate "Flash devices mapped on IBM 440GP Ebony"
321 depends on MTD_JEDECPROBE && PPC32 && 44x && EBONY 328 depends on MTD_JEDECPROBE && EBONY
322 help 329 help
323 This enables access routines for the flash chips on the IBM 440GP 330 This enables access routines for the flash chips on the IBM 440GP
324 Ebony board. If you have one of these boards and would like to 331 Ebony board. If you have one of these boards and would like to
@@ -326,7 +333,7 @@ config MTD_EBONY
326 333
327config MTD_OCOTEA 334config MTD_OCOTEA
328 tristate "Flash devices mapped on IBM 440GX Ocotea" 335 tristate "Flash devices mapped on IBM 440GX Ocotea"
329 depends on MTD_CFI && PPC32 && 44x && OCOTEA 336 depends on MTD_CFI && OCOTEA
330 help 337 help
331 This enables access routines for the flash chips on the IBM 440GX 338 This enables access routines for the flash chips on the IBM 440GX
332 Ocotea board. If you have one of these boards and would like to 339 Ocotea board. If you have one of these boards and would like to
@@ -334,12 +341,20 @@ config MTD_OCOTEA
334 341
335config MTD_REDWOOD 342config MTD_REDWOOD
336 tristate "CFI Flash devices mapped on IBM Redwood" 343 tristate "CFI Flash devices mapped on IBM Redwood"
337 depends on MTD_CFI && PPC32 && 4xx && 40x && ( REDWOOD_4 || REDWOOD_5 || REDWOOD_6 ) 344 depends on MTD_CFI && ( REDWOOD_4 || REDWOOD_5 || REDWOOD_6 )
338 help 345 help
339 This enables access routines for the flash chips on the IBM 346 This enables access routines for the flash chips on the IBM
340 Redwood board. If you have one of these boards and would like to 347 Redwood board. If you have one of these boards and would like to
341 use the flash chips on it, say 'Y'. 348 use the flash chips on it, say 'Y'.
342 349
350config MTD_TQM834x
351 tristate "Flash device mapped on TQ Components TQM834x Boards"
352 depends on MTD_CFI && TQM834x
353 help
354 This enables access routines for the flash chips on the
355 TQ Components TQM834x boards. If you have one of these boards
356 and would like to use the flash chips on it, say 'Y'.
357
343config MTD_CSTM_MIPS_IXX 358config MTD_CSTM_MIPS_IXX
344 tristate "Flash chip mapping on ITE QED-4N-S01B, Globespan IVR or custom board" 359 tristate "Flash chip mapping on ITE QED-4N-S01B, Globespan IVR or custom board"
345 depends on MIPS && MTD_CFI && MTD_JEDECPROBE && MTD_PARTITIONS 360 depends on MIPS && MTD_CFI && MTD_JEDECPROBE && MTD_PARTITIONS
@@ -362,8 +377,8 @@ config MTD_CSTM_MIPS_IXX_START
362 default "0x8000000" 377 default "0x8000000"
363 help 378 help
364 This is the physical memory location that the MTD driver will 379 This is the physical memory location that the MTD driver will
365 use for the flash chips on your particular target board. 380 use for the flash chips on your particular target board.
366 Refer to the memory map which should hopefully be in the 381 Refer to the memory map which should hopefully be in the
367 documentation for your board. 382 documentation for your board.
368 383
369config MTD_CSTM_MIPS_IXX_LEN 384config MTD_CSTM_MIPS_IXX_LEN
@@ -371,7 +386,7 @@ config MTD_CSTM_MIPS_IXX_LEN
371 depends on MTD_CSTM_MIPS_IXX 386 depends on MTD_CSTM_MIPS_IXX
372 default "0x4000000" 387 default "0x4000000"
373 help 388 help
374 This is the total length that the MTD driver will use for the 389 This is the total length that the MTD driver will use for the
375 flash chips on your particular board. Refer to the memory 390 flash chips on your particular board. Refer to the memory
376 map which should hopefully be in the documentation for your 391 map which should hopefully be in the documentation for your
377 board. 392 board.
@@ -405,14 +420,14 @@ config MTD_ARM_INTEGRATOR
405 420
406config MTD_CDB89712 421config MTD_CDB89712
407 tristate "Cirrus CDB89712 evaluation board mappings" 422 tristate "Cirrus CDB89712 evaluation board mappings"
408 depends on ARM && MTD_CFI && ARCH_CDB89712 423 depends on MTD_CFI && ARCH_CDB89712
409 help 424 help
410 This enables access to the flash or ROM chips on the CDB89712 board. 425 This enables access to the flash or ROM chips on the CDB89712 board.
411 If you have such a board, say 'Y'. 426 If you have such a board, say 'Y'.
412 427
413config MTD_SA1100 428config MTD_SA1100
414 tristate "CFI Flash device mapped on StrongARM SA11x0" 429 tristate "CFI Flash device mapped on StrongARM SA11x0"
415 depends on ARM && MTD_CFI && ARCH_SA1100 && MTD_PARTITIONS 430 depends on MTD_CFI && ARCH_SA1100 && MTD_PARTITIONS
416 help 431 help
417 This enables access to the flash chips on most platforms based on 432 This enables access to the flash chips on most platforms based on
418 the SA1100 and SA1110, including the Assabet and the Compaq iPAQ. 433 the SA1100 and SA1110, including the Assabet and the Compaq iPAQ.
@@ -420,13 +435,13 @@ config MTD_SA1100
420 435
421config MTD_IPAQ 436config MTD_IPAQ
422 tristate "CFI Flash device mapped on Compaq/HP iPAQ" 437 tristate "CFI Flash device mapped on Compaq/HP iPAQ"
423 depends on ARM && IPAQ_HANDHELD && MTD_CFI 438 depends on IPAQ_HANDHELD && MTD_CFI
424 help 439 help
425 This provides a driver for the on-board flash of the iPAQ. 440 This provides a driver for the on-board flash of the iPAQ.
426 441
427config MTD_DC21285 442config MTD_DC21285
428 tristate "CFI Flash device mapped on DC21285 Footbridge" 443 tristate "CFI Flash device mapped on DC21285 Footbridge"
429 depends on ARM && MTD_CFI && ARCH_FOOTBRIDGE && MTD_COMPLEX_MAPPINGS 444 depends on MTD_CFI && ARCH_FOOTBRIDGE && MTD_COMPLEX_MAPPINGS
430 help 445 help
431 This provides a driver for the flash accessed using Intel's 446 This provides a driver for the flash accessed using Intel's
432 21285 bridge used with Intel's StrongARM processors. More info at 447 21285 bridge used with Intel's StrongARM processors. More info at
@@ -434,33 +449,33 @@ config MTD_DC21285
434 449
435config MTD_IQ80310 450config MTD_IQ80310
436 tristate "CFI Flash device mapped on the XScale IQ80310 board" 451 tristate "CFI Flash device mapped on the XScale IQ80310 board"
437 depends on ARM && MTD_CFI && ARCH_IQ80310 452 depends on MTD_CFI && ARCH_IQ80310
438 help 453 help
439 This enables access routines for the flash chips on the Intel XScale 454 This enables access routines for the flash chips on the Intel XScale
440 IQ80310 evaluation board. If you have one of these boards and would 455 IQ80310 evaluation board. If you have one of these boards and would
441 like to use the flash chips on it, say 'Y'. 456 like to use the flash chips on it, say 'Y'.
442 457
443config MTD_IXP4XX 458config MTD_IXP4XX
444 tristate "CFI Flash device mapped on Intel IXP4xx based systems" 459 tristate "CFI Flash device mapped on Intel IXP4xx based systems"
445 depends on ARM && MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP4XX 460 depends on MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP4XX
446 help 461 help
447 This enables MTD access to flash devices on platforms based 462 This enables MTD access to flash devices on platforms based
448 on Intel's IXP4xx family of network processors such as the 463 on Intel's IXP4xx family of network processors such as the
449 IXDP425 and Coyote. If you have an IXP4xx based board and 464 IXDP425 and Coyote. If you have an IXP4xx based board and
450 would like to use the flash chips on it, say 'Y'. 465 would like to use the flash chips on it, say 'Y'.
451 466
452config MTD_IXP2000 467config MTD_IXP2000
453 tristate "CFI Flash device mapped on Intel IXP2000 based systems" 468 tristate "CFI Flash device mapped on Intel IXP2000 based systems"
454 depends on ARM && MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP2000 469 depends on MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP2000
455 help 470 help
456 This enables MTD access to flash devices on platforms based 471 This enables MTD access to flash devices on platforms based
457 on Intel's IXP2000 family of network processors such as the 472 on Intel's IXP2000 family of network processors such as the
458 IXDP425 and Coyote. If you have an IXP2000 based board and 473 IXDP425 and Coyote. If you have an IXP2000 based board and
459 would like to use the flash chips on it, say 'Y'. 474 would like to use the flash chips on it, say 'Y'.
460 475
461config MTD_EPXA10DB 476config MTD_EPXA10DB
462 tristate "CFI Flash device mapped on Epxa10db" 477 tristate "CFI Flash device mapped on Epxa10db"
463 depends on ARM && MTD_CFI && MTD_PARTITIONS && ARCH_CAMELOT 478 depends on MTD_CFI && MTD_PARTITIONS && ARCH_CAMELOT
464 help 479 help
465 This enables support for the flash devices on the Altera 480 This enables support for the flash devices on the Altera
466 Excalibur XA10 Development Board. If you are building a kernel 481 Excalibur XA10 Development Board. If you are building a kernel
@@ -468,21 +483,21 @@ config MTD_EPXA10DB
468 483
469config MTD_FORTUNET 484config MTD_FORTUNET
470 tristate "CFI Flash device mapped on the FortuNet board" 485 tristate "CFI Flash device mapped on the FortuNet board"
471 depends on ARM && MTD_CFI && MTD_PARTITIONS && SA1100_FORTUNET 486 depends on MTD_CFI && MTD_PARTITIONS && SA1100_FORTUNET
472 help 487 help
473 This enables access to the Flash on the FortuNet board. If you 488 This enables access to the Flash on the FortuNet board. If you
474 have such a board, say 'Y'. 489 have such a board, say 'Y'.
475 490
476config MTD_AUTCPU12 491config MTD_AUTCPU12
477 tristate "NV-RAM mapping AUTCPU12 board" 492 tristate "NV-RAM mapping AUTCPU12 board"
478 depends on ARM && ARCH_AUTCPU12 493 depends on ARCH_AUTCPU12
479 help 494 help
480 This enables access to the NV-RAM on autronix autcpu12 board. 495 This enables access to the NV-RAM on autronix autcpu12 board.
481 If you have such a board, say 'Y'. 496 If you have such a board, say 'Y'.
482 497
483config MTD_EDB7312 498config MTD_EDB7312
484 tristate "CFI Flash device mapped on EDB7312" 499 tristate "CFI Flash device mapped on EDB7312"
485 depends on ARM && MTD_CFI 500 depends on ARCH_EDB7312 && MTD_CFI
486 help 501 help
487 This enables access to the CFI Flash on the Cogent EDB7312 board. 502 This enables access to the CFI Flash on the Cogent EDB7312 board.
488 If you have such a board, say 'Y' here. 503 If you have such a board, say 'Y' here.
@@ -496,7 +511,7 @@ config MTD_IMPA7
496 511
497config MTD_CEIVA 512config MTD_CEIVA
498 tristate "JEDEC Flash device mapped on Ceiva/Polaroid PhotoMax Digital Picture Frame" 513 tristate "JEDEC Flash device mapped on Ceiva/Polaroid PhotoMax Digital Picture Frame"
499 depends on ARM && MTD_JEDECPROBE && ARCH_CEIVA 514 depends on MTD_JEDECPROBE && ARCH_CEIVA
500 help 515 help
501 This enables access to the flash chips on the Ceiva/Polaroid 516 This enables access to the flash chips on the Ceiva/Polaroid
502 PhotoMax Digital Picture Frame. 517 PhotoMax Digital Picture Frame.
@@ -504,25 +519,31 @@ config MTD_CEIVA
504 519
505config MTD_NOR_TOTO 520config MTD_NOR_TOTO
506 tristate "NOR Flash device on TOTO board" 521 tristate "NOR Flash device on TOTO board"
507 depends on ARM && ARCH_OMAP && OMAP_TOTO 522 depends on ARCH_OMAP && OMAP_TOTO
508 help 523 help
509 This enables access to the NOR flash on the Texas Instruments 524 This enables access to the NOR flash on the Texas Instruments
510 TOTO board. 525 TOTO board.
511 526
512config MTD_H720X 527config MTD_H720X
513 tristate "Hynix evaluation board mappings" 528 tristate "Hynix evaluation board mappings"
514 depends on ARM && MTD_CFI && ( ARCH_H7201 || ARCH_H7202 ) 529 depends on MTD_CFI && ( ARCH_H7201 || ARCH_H7202 )
515 help 530 help
516 This enables access to the flash chips on the Hynix evaluation boards. 531 This enables access to the flash chips on the Hynix evaluation boards.
517 If you have such a board, say 'Y'. 532 If you have such a board, say 'Y'.
518 533
519config MTD_MPC1211 534config MTD_MPC1211
520 tristate "CFI Flash device mapped on Interface MPC-1211" 535 tristate "CFI Flash device mapped on Interface MPC-1211"
521 depends on SUPERH && SH_MPC1211 && MTD_CFI 536 depends on SH_MPC1211 && MTD_CFI
522 help 537 help
523 This enables access to the flash chips on the Interface MPC-1211(CTP/PCI/MPC-SH02). 538 This enables access to the flash chips on the Interface MPC-1211(CTP/PCI/MPC-SH02).
524 If you have such a board, say 'Y'. 539 If you have such a board, say 'Y'.
525 540
541config MTD_PQ2FADS
542 tristate "JEDEC flash SIMM mapped on PQ2FADS and 8272ADS boards"
543 depends on (ADS8272 || PQ2FADS) && MTD_PARTITIONS && MTD_JEDECPROBE && MTD_PHYSMAP && MTD_CFI_GEOMETRY && MTD_CFI_INTELEXT
544 help
545 This enables access to flash SIMM on PQ2FADS-like boards
546
526config MTD_OMAP_NOR 547config MTD_OMAP_NOR
527 tristate "TI OMAP board mappings" 548 tristate "TI OMAP board mappings"
528 depends on MTD_CFI && ARCH_OMAP 549 depends on MTD_CFI && ARCH_OMAP
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 7bcbc49e329f..7d9e940a1dcd 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -1,7 +1,7 @@
1# 1#
2# linux/drivers/maps/Makefile 2# linux/drivers/maps/Makefile
3# 3#
4# $Id: Makefile.common,v 1.30 2005/07/02 01:53:24 tpoynor Exp $ 4# $Id: Makefile.common,v 1.34 2005/11/07 11:14:26 gleixner Exp $
5 5
6ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y) 6ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y)
7obj-$(CONFIG_MTD) += map_funcs.o 7obj-$(CONFIG_MTD) += map_funcs.o
@@ -26,7 +26,7 @@ obj-$(CONFIG_MTD_MAINSTONE) += mainstone-flash.o
26obj-$(CONFIG_MTD_MBX860) += mbx860.o 26obj-$(CONFIG_MTD_MBX860) += mbx860.o
27obj-$(CONFIG_MTD_CEIVA) += ceiva.o 27obj-$(CONFIG_MTD_CEIVA) += ceiva.o
28obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o 28obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o
29obj-$(CONFIG_MTD_PHYSMAP) += physmap.o 29obj-$(CONFIG_MTD_PHYSMAP) += physmap.o
30obj-$(CONFIG_MTD_PNC2000) += pnc2000.o 30obj-$(CONFIG_MTD_PNC2000) += pnc2000.o
31obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o 31obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o
32obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o 32obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o
@@ -70,3 +70,6 @@ obj-$(CONFIG_MTD_DMV182) += dmv182.o
70obj-$(CONFIG_MTD_SHARP_SL) += sharpsl-flash.o 70obj-$(CONFIG_MTD_SHARP_SL) += sharpsl-flash.o
71obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o 71obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o
72obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o 72obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o
73obj-$(CONFIG_MTD_PQ2FADS) += pq2fads.o
74obj-$(CONFIG_MTD_MTX1) += mtx-1_flash.o
75obj-$(CONFIG_MTD_TQM834x) += tqm834x.o
diff --git a/drivers/mtd/maps/alchemy-flash.c b/drivers/mtd/maps/alchemy-flash.c
index 27fd2a3c3b60..a57791a6ce40 100644
--- a/drivers/mtd/maps/alchemy-flash.c
+++ b/drivers/mtd/maps/alchemy-flash.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * Flash memory access on AMD Alchemy evaluation boards 2 * Flash memory access on AMD Alchemy evaluation boards
3 * 3 *
4 * $Id: alchemy-flash.c,v 1.1 2005/02/27 21:50:21 ppopov Exp $ 4 * $Id: alchemy-flash.c,v 1.2 2005/11/07 11:14:26 gleixner Exp $
5 * 5 *
6 * (C) 2003, 2004 Pete Popov <ppopov@embeddedalley.com> 6 * (C) 2003, 2004 Pete Popov <ppopov@embeddedalley.com>
7 * 7 *
8 */ 8 */
9 9
10#include <linux/config.h> 10#include <linux/config.h>
@@ -22,7 +22,7 @@
22#ifdef DEBUG_RW 22#ifdef DEBUG_RW
23#define DBG(x...) printk(x) 23#define DBG(x...) printk(x)
24#else 24#else
25#define DBG(x...) 25#define DBG(x...)
26#endif 26#endif
27 27
28#ifdef CONFIG_MIPS_PB1000 28#ifdef CONFIG_MIPS_PB1000
@@ -136,7 +136,7 @@ int __init alchemy_mtd_init(void)
136 int nb_parts = 0; 136 int nb_parts = 0;
137 unsigned long window_addr; 137 unsigned long window_addr;
138 unsigned long window_size; 138 unsigned long window_size;
139 139
140 /* Default flash buswidth */ 140 /* Default flash buswidth */
141 alchemy_map.bankwidth = BOARD_FLASH_WIDTH; 141 alchemy_map.bankwidth = BOARD_FLASH_WIDTH;
142 142
@@ -161,7 +161,7 @@ int __init alchemy_mtd_init(void)
161 * Now let's probe for the actual flash. Do it here since 161 * Now let's probe for the actual flash. Do it here since
162 * specific machine settings might have been set above. 162 * specific machine settings might have been set above.
163 */ 163 */
164 printk(KERN_NOTICE BOARD_MAP_NAME ": probing %d-bit flash bus\n", 164 printk(KERN_NOTICE BOARD_MAP_NAME ": probing %d-bit flash bus\n",
165 alchemy_map.bankwidth*8); 165 alchemy_map.bankwidth*8);
166 alchemy_map.virt = ioremap(window_addr, window_size); 166 alchemy_map.virt = ioremap(window_addr, window_size);
167 mymtd = do_map_probe("cfi_probe", &alchemy_map); 167 mymtd = do_map_probe("cfi_probe", &alchemy_map);
diff --git a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c
index 9a64149f431d..c350878d4592 100644
--- a/drivers/mtd/maps/amd76xrom.c
+++ b/drivers/mtd/maps/amd76xrom.c
@@ -2,7 +2,7 @@
2 * amd76xrom.c 2 * amd76xrom.c
3 * 3 *
4 * Normal mappings of chips in physical memory 4 * Normal mappings of chips in physical memory
5 * $Id: amd76xrom.c,v 1.20 2005/03/18 14:04:35 gleixner Exp $ 5 * $Id: amd76xrom.c,v 1.21 2005/11/07 11:14:26 gleixner Exp $
6 */ 6 */
7 7
8#include <linux/module.h> 8#include <linux/module.h>
@@ -70,7 +70,7 @@ static void amd76xrom_cleanup(struct amd76xrom_window *window)
70 list_del(&map->list); 70 list_del(&map->list);
71 kfree(map); 71 kfree(map);
72 } 72 }
73 if (window->rsrc.parent) 73 if (window->rsrc.parent)
74 release_resource(&window->rsrc); 74 release_resource(&window->rsrc);
75 75
76 if (window->virt) { 76 if (window->virt) {
@@ -107,7 +107,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
107 window->phys = 0xffff0000; /* 64KiB */ 107 window->phys = 0xffff0000; /* 64KiB */
108 } 108 }
109 window->size = 0xffffffffUL - window->phys + 1UL; 109 window->size = 0xffffffffUL - window->phys + 1UL;
110 110
111 /* 111 /*
112 * Try to reserve the window mem region. If this fails then 112 * Try to reserve the window mem region. If this fails then
113 * it is likely due to a fragment of the window being 113 * it is likely due to a fragment of the window being
@@ -138,7 +138,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
138 /* Enable writes through the rom window */ 138 /* Enable writes through the rom window */
139 pci_read_config_byte(pdev, 0x40, &byte); 139 pci_read_config_byte(pdev, 0x40, &byte);
140 pci_write_config_byte(pdev, 0x40, byte | 1); 140 pci_write_config_byte(pdev, 0x40, byte | 1);
141 141
142 /* FIXME handle registers 0x80 - 0x8C the bios region locks */ 142 /* FIXME handle registers 0x80 - 0x8C the bios region locks */
143 143
144 /* For write accesses caches are useless */ 144 /* For write accesses caches are useless */
@@ -186,7 +186,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
186 MOD_NAME, map->map.phys); 186 MOD_NAME, map->map.phys);
187 187
188 /* There is no generic VPP support */ 188 /* There is no generic VPP support */
189 for(map->map.bankwidth = 32; map->map.bankwidth; 189 for(map->map.bankwidth = 32; map->map.bankwidth;
190 map->map.bankwidth >>= 1) 190 map->map.bankwidth >>= 1)
191 { 191 {
192 char **probe_type; 192 char **probe_type;
@@ -239,7 +239,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
239 for(i = 0; i < cfi->numchips; i++) { 239 for(i = 0; i < cfi->numchips; i++) {
240 cfi->chips[i].start += offset; 240 cfi->chips[i].start += offset;
241 } 241 }
242 242
243 /* Now that the mtd devices is complete claim and export it */ 243 /* Now that the mtd devices is complete claim and export it */
244 map->mtd->owner = THIS_MODULE; 244 map->mtd->owner = THIS_MODULE;
245 if (add_mtd_device(map->mtd)) { 245 if (add_mtd_device(map->mtd)) {
@@ -277,9 +277,9 @@ static void __devexit amd76xrom_remove_one (struct pci_dev *pdev)
277} 277}
278 278
279static struct pci_device_id amd76xrom_pci_tbl[] = { 279static struct pci_device_id amd76xrom_pci_tbl[] = {
280 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410, 280 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410,
281 PCI_ANY_ID, PCI_ANY_ID, }, 281 PCI_ANY_ID, PCI_ANY_ID, },
282 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7440, 282 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7440,
283 PCI_ANY_ID, PCI_ANY_ID, }, 283 PCI_ANY_ID, PCI_ANY_ID, },
284 { PCI_VENDOR_ID_AMD, 0x7468 }, /* amd8111 support */ 284 { PCI_VENDOR_ID_AMD, 0x7468 }, /* amd8111 support */
285 { 0, } 285 { 0, }
diff --git a/drivers/mtd/maps/arctic-mtd.c b/drivers/mtd/maps/arctic-mtd.c
index 777276fd0e15..d95ae582fbe9 100644
--- a/drivers/mtd/maps/arctic-mtd.c
+++ b/drivers/mtd/maps/arctic-mtd.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * $Id: arctic-mtd.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $ 2 * $Id: arctic-mtd.c,v 1.14 2005/11/07 11:14:26 gleixner Exp $
3 * 3 *
4 * drivers/mtd/maps/arctic-mtd.c MTD mappings and partition tables for 4 * drivers/mtd/maps/arctic-mtd.c MTD mappings and partition tables for
5 * IBM 405LP Arctic boards. 5 * IBM 405LP Arctic boards.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
diff --git a/drivers/mtd/maps/autcpu12-nvram.c b/drivers/mtd/maps/autcpu12-nvram.c
index cf362ccc3c8e..7ed3424dd959 100644
--- a/drivers/mtd/maps/autcpu12-nvram.c
+++ b/drivers/mtd/maps/autcpu12-nvram.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * NV-RAM memory access on autcpu12 2 * NV-RAM memory access on autcpu12
3 * (C) 2002 Thomas Gleixner (gleixner@autronix.de) 3 * (C) 2002 Thomas Gleixner (gleixner@autronix.de)
4 * 4 *
5 * $Id: autcpu12-nvram.c,v 1.8 2004/11/04 13:24:14 gleixner Exp $ 5 * $Id: autcpu12-nvram.c,v 1.9 2005/11/07 11:14:26 gleixner Exp $
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
@@ -55,10 +55,10 @@ static int __init init_autcpu12_sram (void)
55 } 55 }
56 simple_map_init(&autcpu_sram_map); 56 simple_map_init(&autcpu_sram_map);
57 57
58 /* 58 /*
59 * Check for 32K/128K 59 * Check for 32K/128K
60 * read ofs 0 60 * read ofs 0
61 * read ofs 0x10000 61 * read ofs 0x10000
62 * Write complement to ofs 0x100000 62 * Write complement to ofs 0x100000
63 * Read and check result on ofs 0x0 63 * Read and check result on ofs 0x0
64 * Restore contents 64 * Restore contents
@@ -66,7 +66,7 @@ static int __init init_autcpu12_sram (void)
66 save0 = map_read32(&autcpu12_sram_map,0); 66 save0 = map_read32(&autcpu12_sram_map,0);
67 save1 = map_read32(&autcpu12_sram_map,0x10000); 67 save1 = map_read32(&autcpu12_sram_map,0x10000);
68 map_write32(&autcpu12_sram_map,~save0,0x10000); 68 map_write32(&autcpu12_sram_map,~save0,0x10000);
69 /* if we find this pattern on 0x0, we have 32K size 69 /* if we find this pattern on 0x0, we have 32K size
70 * restore contents and exit 70 * restore contents and exit
71 */ 71 */
72 if ( map_read32(&autcpu12_sram_map,0) != save0) { 72 if ( map_read32(&autcpu12_sram_map,0) != save0) {
@@ -89,7 +89,7 @@ map:
89 89
90 sram_mtd->owner = THIS_MODULE; 90 sram_mtd->owner = THIS_MODULE;
91 sram_mtd->erasesize = 16; 91 sram_mtd->erasesize = 16;
92 92
93 if (add_mtd_device(sram_mtd)) { 93 if (add_mtd_device(sram_mtd)) {
94 printk("NV-RAM device addition failed\n"); 94 printk("NV-RAM device addition failed\n");
95 err = -ENOMEM; 95 err = -ENOMEM;
@@ -97,7 +97,7 @@ map:
97 } 97 }
98 98
99 printk("NV-RAM device size %ldKiB registered on AUTCPU12\n",autcpu12_sram_map.size/SZ_1K); 99 printk("NV-RAM device size %ldKiB registered on AUTCPU12\n",autcpu12_sram_map.size/SZ_1K);
100 100
101 return 0; 101 return 0;
102 102
103out_probe: 103out_probe:
diff --git a/drivers/mtd/maps/bast-flash.c b/drivers/mtd/maps/bast-flash.c
index 8c19d722ac79..b7858eb93534 100644
--- a/drivers/mtd/maps/bast-flash.c
+++ b/drivers/mtd/maps/bast-flash.c
@@ -9,7 +9,7 @@
9 * 20-Sep-2004 BJD Initial version 9 * 20-Sep-2004 BJD Initial version
10 * 17-Jan-2005 BJD Add whole device if no partitions found 10 * 17-Jan-2005 BJD Add whole device if no partitions found
11 * 11 *
12 * $Id: bast-flash.c,v 1.2 2005/01/18 11:13:47 bjd Exp $ 12 * $Id: bast-flash.c,v 1.5 2005/11/07 11:14:26 gleixner Exp $
13 * 13 *
14 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by 15 * it under the terms of the GNU General Public License as published by
@@ -75,7 +75,7 @@ static void bast_flash_setrw(int to)
75 75
76 local_irq_save(flags); 76 local_irq_save(flags);
77 val = __raw_readb(BAST_VA_CTRL3); 77 val = __raw_readb(BAST_VA_CTRL3);
78 78
79 if (to) 79 if (to)
80 val |= BAST_CPLD_CTRL3_ROMWEN; 80 val |= BAST_CPLD_CTRL3_ROMWEN;
81 else 81 else
@@ -93,7 +93,7 @@ static int bast_flash_remove(struct device *dev)
93 93
94 dev_set_drvdata(dev, NULL); 94 dev_set_drvdata(dev, NULL);
95 95
96 if (info == NULL) 96 if (info == NULL)
97 return 0; 97 return 0;
98 98
99 if (info->map.virt != NULL) 99 if (info->map.virt != NULL)
@@ -110,7 +110,7 @@ static int bast_flash_remove(struct device *dev)
110 release_resource(info->area); 110 release_resource(info->area);
111 kfree(info->area); 111 kfree(info->area);
112 } 112 }
113 113
114 kfree(info); 114 kfree(info);
115 115
116 return 0; 116 return 0;
@@ -137,15 +137,15 @@ static int bast_flash_probe(struct device *dev)
137 137
138 info->map.phys = res->start; 138 info->map.phys = res->start;
139 info->map.size = res->end - res->start + 1; 139 info->map.size = res->end - res->start + 1;
140 info->map.name = dev->bus_id; 140 info->map.name = dev->bus_id;
141 info->map.bankwidth = 2; 141 info->map.bankwidth = 2;
142 142
143 if (info->map.size > AREA_MAXSIZE) 143 if (info->map.size > AREA_MAXSIZE)
144 info->map.size = AREA_MAXSIZE; 144 info->map.size = AREA_MAXSIZE;
145 145
146 pr_debug("%s: area %08lx, size %ld\n", __FUNCTION__, 146 pr_debug("%s: area %08lx, size %ld\n", __FUNCTION__,
147 info->map.phys, info->map.size); 147 info->map.phys, info->map.size);
148 148
149 info->area = request_mem_region(res->start, info->map.size, 149 info->area = request_mem_region(res->start, info->map.size,
150 pdev->name); 150 pdev->name);
151 if (info->area == NULL) { 151 if (info->area == NULL) {
@@ -162,7 +162,7 @@ static int bast_flash_probe(struct device *dev)
162 err = -EIO; 162 err = -EIO;
163 goto exit_error; 163 goto exit_error;
164 } 164 }
165 165
166 simple_map_init(&info->map); 166 simple_map_init(&info->map);
167 167
168 /* enable the write to the flash area */ 168 /* enable the write to the flash area */
@@ -187,7 +187,7 @@ static int bast_flash_probe(struct device *dev)
187 err = parse_mtd_partitions(info->mtd, probes, &info->partitions, 0); 187 err = parse_mtd_partitions(info->mtd, probes, &info->partitions, 0);
188 if (err > 0) { 188 if (err > 0) {
189 err = add_mtd_partitions(info->mtd, info->partitions, err); 189 err = add_mtd_partitions(info->mtd, info->partitions, err);
190 if (err) 190 if (err)
191 printk(KERN_ERR PFX "cannot add/parse partitions\n"); 191 printk(KERN_ERR PFX "cannot add/parse partitions\n");
192 } else { 192 } else {
193 err = add_mtd_device(info->mtd); 193 err = add_mtd_device(info->mtd);
@@ -205,6 +205,7 @@ static int bast_flash_probe(struct device *dev)
205 205
206static struct device_driver bast_flash_driver = { 206static struct device_driver bast_flash_driver = {
207 .name = "bast-nor", 207 .name = "bast-nor",
208 .owner = THIS_MODULE,
208 .bus = &platform_bus_type, 209 .bus = &platform_bus_type,
209 .probe = bast_flash_probe, 210 .probe = bast_flash_probe,
210 .remove = bast_flash_remove, 211 .remove = bast_flash_remove,
diff --git a/drivers/mtd/maps/beech-mtd.c b/drivers/mtd/maps/beech-mtd.c
index 5e79c9d5da2b..5df7361d1407 100644
--- a/drivers/mtd/maps/beech-mtd.c
+++ b/drivers/mtd/maps/beech-mtd.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * $Id: beech-mtd.c,v 1.10 2004/11/04 13:24:14 gleixner Exp $ 2 * $Id: beech-mtd.c,v 1.11 2005/11/07 11:14:26 gleixner Exp $
3 * 3 *
4 * drivers/mtd/maps/beech-mtd.c MTD mappings and partition tables for 4 * drivers/mtd/maps/beech-mtd.c MTD mappings and partition tables for
5 * IBM 405LP Beech boards. 5 * IBM 405LP Beech boards.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
diff --git a/drivers/mtd/maps/cdb89712.c b/drivers/mtd/maps/cdb89712.c
index ab15dac2f936..9f17bb6c5a9d 100644
--- a/drivers/mtd/maps/cdb89712.c
+++ b/drivers/mtd/maps/cdb89712.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Flash on Cirrus CDB89712 2 * Flash on Cirrus CDB89712
3 * 3 *
4 * $Id: cdb89712.c,v 1.10 2004/11/04 13:24:14 gleixner Exp $ 4 * $Id: cdb89712.c,v 1.11 2005/11/07 11:14:26 gleixner Exp $
5 */ 5 */
6 6
7#include <linux/module.h> 7#include <linux/module.h>
@@ -37,13 +37,13 @@ struct resource cdb89712_flash_resource = {
37static int __init init_cdb89712_flash (void) 37static int __init init_cdb89712_flash (void)
38{ 38{
39 int err; 39 int err;
40 40
41 if (request_resource (&ioport_resource, &cdb89712_flash_resource)) { 41 if (request_resource (&ioport_resource, &cdb89712_flash_resource)) {
42 printk(KERN_NOTICE "Failed to reserve Cdb89712 FLASH space\n"); 42 printk(KERN_NOTICE "Failed to reserve Cdb89712 FLASH space\n");
43 err = -EBUSY; 43 err = -EBUSY;
44 goto out; 44 goto out;
45 } 45 }
46 46
47 cdb89712_flash_map.virt = ioremap(FLASH_START, FLASH_SIZE); 47 cdb89712_flash_map.virt = ioremap(FLASH_START, FLASH_SIZE);
48 if (!cdb89712_flash_map.virt) { 48 if (!cdb89712_flash_map.virt) {
49 printk(KERN_NOTICE "Failed to ioremap Cdb89712 FLASH space\n"); 49 printk(KERN_NOTICE "Failed to ioremap Cdb89712 FLASH space\n");
@@ -64,13 +64,13 @@ static int __init init_cdb89712_flash (void)
64 } 64 }
65 65
66 flash_mtd->owner = THIS_MODULE; 66 flash_mtd->owner = THIS_MODULE;
67 67
68 if (add_mtd_device(flash_mtd)) { 68 if (add_mtd_device(flash_mtd)) {
69 printk("FLASH device addition failed\n"); 69 printk("FLASH device addition failed\n");
70 err = -ENOMEM; 70 err = -ENOMEM;
71 goto out_probe; 71 goto out_probe;
72 } 72 }
73 73
74 return 0; 74 return 0;
75 75
76out_probe: 76out_probe:
@@ -107,13 +107,13 @@ struct resource cdb89712_sram_resource = {
107static int __init init_cdb89712_sram (void) 107static int __init init_cdb89712_sram (void)
108{ 108{
109 int err; 109 int err;
110 110
111 if (request_resource (&ioport_resource, &cdb89712_sram_resource)) { 111 if (request_resource (&ioport_resource, &cdb89712_sram_resource)) {
112 printk(KERN_NOTICE "Failed to reserve Cdb89712 SRAM space\n"); 112 printk(KERN_NOTICE "Failed to reserve Cdb89712 SRAM space\n");
113 err = -EBUSY; 113 err = -EBUSY;
114 goto out; 114 goto out;
115 } 115 }
116 116
117 cdb89712_sram_map.virt = ioremap(SRAM_START, SRAM_SIZE); 117 cdb89712_sram_map.virt = ioremap(SRAM_START, SRAM_SIZE);
118 if (!cdb89712_sram_map.virt) { 118 if (!cdb89712_sram_map.virt) {
119 printk(KERN_NOTICE "Failed to ioremap Cdb89712 SRAM space\n"); 119 printk(KERN_NOTICE "Failed to ioremap Cdb89712 SRAM space\n");
@@ -130,13 +130,13 @@ static int __init init_cdb89712_sram (void)
130 130
131 sram_mtd->owner = THIS_MODULE; 131 sram_mtd->owner = THIS_MODULE;
132 sram_mtd->erasesize = 16; 132 sram_mtd->erasesize = 16;
133 133
134 if (add_mtd_device(sram_mtd)) { 134 if (add_mtd_device(sram_mtd)) {
135 printk("SRAM device addition failed\n"); 135 printk("SRAM device addition failed\n");
136 err = -ENOMEM; 136 err = -ENOMEM;
137 goto out_probe; 137 goto out_probe;
138 } 138 }
139 139
140 return 0; 140 return 0;
141 141
142out_probe: 142out_probe:
@@ -175,13 +175,13 @@ struct resource cdb89712_bootrom_resource = {
175static int __init init_cdb89712_bootrom (void) 175static int __init init_cdb89712_bootrom (void)
176{ 176{
177 int err; 177 int err;
178 178
179 if (request_resource (&ioport_resource, &cdb89712_bootrom_resource)) { 179 if (request_resource (&ioport_resource, &cdb89712_bootrom_resource)) {
180 printk(KERN_NOTICE "Failed to reserve Cdb89712 BOOTROM space\n"); 180 printk(KERN_NOTICE "Failed to reserve Cdb89712 BOOTROM space\n");
181 err = -EBUSY; 181 err = -EBUSY;
182 goto out; 182 goto out;
183 } 183 }
184 184
185 cdb89712_bootrom_map.virt = ioremap(BOOTROM_START, BOOTROM_SIZE); 185 cdb89712_bootrom_map.virt = ioremap(BOOTROM_START, BOOTROM_SIZE);
186 if (!cdb89712_bootrom_map.virt) { 186 if (!cdb89712_bootrom_map.virt) {
187 printk(KERN_NOTICE "Failed to ioremap Cdb89712 BootROM space\n"); 187 printk(KERN_NOTICE "Failed to ioremap Cdb89712 BootROM space\n");
@@ -198,13 +198,13 @@ static int __init init_cdb89712_bootrom (void)
198 198
199 bootrom_mtd->owner = THIS_MODULE; 199 bootrom_mtd->owner = THIS_MODULE;
200 bootrom_mtd->erasesize = 0x10000; 200 bootrom_mtd->erasesize = 0x10000;
201 201
202 if (add_mtd_device(bootrom_mtd)) { 202 if (add_mtd_device(bootrom_mtd)) {
203 printk("BootROM device addition failed\n"); 203 printk("BootROM device addition failed\n");
204 err = -ENOMEM; 204 err = -ENOMEM;
205 goto out_probe; 205 goto out_probe;
206 } 206 }
207 207
208 return 0; 208 return 0;
209 209
210out_probe: 210out_probe:
@@ -225,16 +225,16 @@ out:
225static int __init init_cdb89712_maps(void) 225static int __init init_cdb89712_maps(void)
226{ 226{
227 227
228 printk(KERN_INFO "Cirrus CDB89712 MTD mappings:\n Flash 0x%x at 0x%x\n SRAM 0x%x at 0x%x\n BootROM 0x%x at 0x%x\n", 228 printk(KERN_INFO "Cirrus CDB89712 MTD mappings:\n Flash 0x%x at 0x%x\n SRAM 0x%x at 0x%x\n BootROM 0x%x at 0x%x\n",
229 FLASH_SIZE, FLASH_START, SRAM_SIZE, SRAM_START, BOOTROM_SIZE, BOOTROM_START); 229 FLASH_SIZE, FLASH_START, SRAM_SIZE, SRAM_START, BOOTROM_SIZE, BOOTROM_START);
230 230
231 init_cdb89712_flash(); 231 init_cdb89712_flash();
232 init_cdb89712_sram(); 232 init_cdb89712_sram();
233 init_cdb89712_bootrom(); 233 init_cdb89712_bootrom();
234 234
235 return 0; 235 return 0;
236} 236}
237 237
238 238
239static void __exit cleanup_cdb89712_maps(void) 239static void __exit cleanup_cdb89712_maps(void)
240{ 240{
@@ -244,7 +244,7 @@ static void __exit cleanup_cdb89712_maps(void)
244 iounmap((void *)cdb89712_sram_map.virt); 244 iounmap((void *)cdb89712_sram_map.virt);
245 release_resource (&cdb89712_sram_resource); 245 release_resource (&cdb89712_sram_resource);
246 } 246 }
247 247
248 if (flash_mtd) { 248 if (flash_mtd) {
249 del_mtd_device(flash_mtd); 249 del_mtd_device(flash_mtd);
250 map_destroy(flash_mtd); 250 map_destroy(flash_mtd);
diff --git a/drivers/mtd/maps/cfi_flagadm.c b/drivers/mtd/maps/cfi_flagadm.c
index f72e4f894b32..6a8c0415bde8 100644
--- a/drivers/mtd/maps/cfi_flagadm.c
+++ b/drivers/mtd/maps/cfi_flagadm.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * Copyright © 2001 Flaga hf. Medical Devices, Kári Davíðsson <kd@flaga.is> 2 * Copyright © 2001 Flaga hf. Medical Devices, Kári Davíðsson <kd@flaga.is>
3 * 3 *
4 * $Id: cfi_flagadm.c,v 1.14 2004/11/04 13:24:14 gleixner Exp $ 4 * $Id: cfi_flagadm.c,v 1.15 2005/11/07 11:14:26 gleixner Exp $
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the 7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your 8 * Free Software Foundation; either version 2 of the License, or (at your
@@ -42,7 +42,7 @@
42 */ 42 */
43 43
44#define FLASH_PHYS_ADDR 0x40000000 44#define FLASH_PHYS_ADDR 0x40000000
45#define FLASH_SIZE 0x400000 45#define FLASH_SIZE 0x400000
46 46
47#define FLASH_PARTITION0_ADDR 0x00000000 47#define FLASH_PARTITION0_ADDR 0x00000000
48#define FLASH_PARTITION0_SIZE 0x00020000 48#define FLASH_PARTITION0_SIZE 0x00020000
@@ -79,7 +79,7 @@ struct mtd_partition flagadm_parts[] = {
79 .offset = FLASH_PARTITION2_ADDR, 79 .offset = FLASH_PARTITION2_ADDR,
80 .size = FLASH_PARTITION2_SIZE 80 .size = FLASH_PARTITION2_SIZE
81 }, 81 },
82 { 82 {
83 .name = "Persistant storage", 83 .name = "Persistant storage",
84 .offset = FLASH_PARTITION3_ADDR, 84 .offset = FLASH_PARTITION3_ADDR,
85 .size = FLASH_PARTITION3_SIZE 85 .size = FLASH_PARTITION3_SIZE
@@ -91,10 +91,10 @@ struct mtd_partition flagadm_parts[] = {
91static struct mtd_info *mymtd; 91static struct mtd_info *mymtd;
92 92
93int __init init_flagadm(void) 93int __init init_flagadm(void)
94{ 94{
95 printk(KERN_NOTICE "FlagaDM flash device: %x at %x\n", 95 printk(KERN_NOTICE "FlagaDM flash device: %x at %x\n",
96 FLASH_SIZE, FLASH_PHYS_ADDR); 96 FLASH_SIZE, FLASH_PHYS_ADDR);
97 97
98 flagadm_map.phys = FLASH_PHYS_ADDR; 98 flagadm_map.phys = FLASH_PHYS_ADDR;
99 flagadm_map.virt = ioremap(FLASH_PHYS_ADDR, 99 flagadm_map.virt = ioremap(FLASH_PHYS_ADDR,
100 FLASH_SIZE); 100 FLASH_SIZE);
diff --git a/drivers/mtd/maps/cstm_mips_ixx.c b/drivers/mtd/maps/cstm_mips_ixx.c
index ae9252fbf176..a370953c1513 100644
--- a/drivers/mtd/maps/cstm_mips_ixx.c
+++ b/drivers/mtd/maps/cstm_mips_ixx.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * $Id: cstm_mips_ixx.c,v 1.12 2004/11/04 13:24:14 gleixner Exp $ 2 * $Id: cstm_mips_ixx.c,v 1.14 2005/11/07 11:14:26 gleixner Exp $
3 * 3 *
4 * Mapping of a custom board with both AMD CFI and JEDEC flash in partitions. 4 * Mapping of a custom board with both AMD CFI and JEDEC flash in partitions.
5 * Config with both CFI and JEDEC device support. 5 * Config with both CFI and JEDEC device support.
6 * 6 *
7 * Basically physmap.c with the addition of partitions and 7 * Basically physmap.c with the addition of partitions and
8 * an array of mapping info to accomodate more than one flash type per board. 8 * an array of mapping info to accomodate more than one flash type per board.
9 * 9 *
10 * Copyright 2000 MontaVista Software Inc. 10 * Copyright 2000 MontaVista Software Inc.
@@ -69,7 +69,7 @@ void cstm_mips_ixx_set_vpp(struct map_info *map,int vpp)
69 __u16 data; 69 __u16 data;
70 __u8 data1; 70 __u8 data1;
71 static u8 first = 1; 71 static u8 first = 1;
72 72
73 // Set GPIO port B pin3 to high 73 // Set GPIO port B pin3 to high
74 data = *(__u16 *)(CC_GPBCR); 74 data = *(__u16 *)(CC_GPBCR);
75 data = (data & 0xff0f) | 0x0040; 75 data = (data & 0xff0f) | 0x0040;
@@ -85,7 +85,7 @@ void cstm_mips_ixx_set_vpp(struct map_info *map,int vpp)
85 } else { 85 } else {
86 if (!--vpp_count) { 86 if (!--vpp_count) {
87 __u16 data; 87 __u16 data;
88 88
89 // Set GPIO port B pin3 to high 89 // Set GPIO port B pin3 to high
90 data = *(__u16 *)(CC_GPBCR); 90 data = *(__u16 *)(CC_GPBCR);
91 data = (data & 0xff3f) | 0x0040; 91 data = (data & 0xff3f) | 0x0040;
@@ -109,8 +109,8 @@ struct cstm_mips_ixx_info {
109}; 109};
110 110
111#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) 111#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
112#define PHYSMAP_NUMBER 1 // number of board desc structs needed, one per contiguous flash type 112#define PHYSMAP_NUMBER 1 // number of board desc structs needed, one per contiguous flash type
113const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] = 113const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] =
114{ 114{
115 { // 28F128J3A in 2x16 configuration 115 { // 28F128J3A in 2x16 configuration
116 "big flash", // name 116 "big flash", // name
@@ -131,10 +131,10 @@ static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP
131}, 131},
132}; 132};
133#else /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */ 133#else /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */
134#define PHYSMAP_NUMBER 1 // number of board desc structs needed, one per contiguous flash type 134#define PHYSMAP_NUMBER 1 // number of board desc structs needed, one per contiguous flash type
135const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] = 135const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] =
136{ 136{
137 { 137 {
138 "MTD flash", // name 138 "MTD flash", // name
139 CONFIG_MTD_CSTM_MIPS_IXX_START, // window_addr 139 CONFIG_MTD_CSTM_MIPS_IXX_START, // window_addr
140 CONFIG_MTD_CSTM_MIPS_IXX_LEN, // window_size 140 CONFIG_MTD_CSTM_MIPS_IXX_LEN, // window_size
@@ -144,7 +144,7 @@ const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] =
144 144
145}; 145};
146static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = { 146static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = {
147{ 147{
148 { 148 {
149 .name = "main partition", 149 .name = "main partition",
150 .size = CONFIG_MTD_CSTM_MIPS_IXX_LEN, 150 .size = CONFIG_MTD_CSTM_MIPS_IXX_LEN,
@@ -165,7 +165,7 @@ int __init init_cstm_mips_ixx(void)
165 165
166 /* Initialize mapping */ 166 /* Initialize mapping */
167 for (i=0;i<PHYSMAP_NUMBER;i++) { 167 for (i=0;i<PHYSMAP_NUMBER;i++) {
168 printk(KERN_NOTICE "cstm_mips_ixx flash device: 0x%lx at 0x%lx\n", 168 printk(KERN_NOTICE "cstm_mips_ixx flash device: 0x%lx at 0x%lx\n",
169 cstm_mips_ixx_board_desc[i].window_size, cstm_mips_ixx_board_desc[i].window_addr); 169 cstm_mips_ixx_board_desc[i].window_size, cstm_mips_ixx_board_desc[i].window_addr);
170 170
171 171
@@ -235,7 +235,7 @@ void PCISetULongByOffset(__u32 DevNumber, __u32 FuncNumber, __u32 Offset, __u32
235 235
236 offset = ( unsigned long )( 0x80000000 | ( DevNumber << 11 ) + ( FuncNumber << 8 ) + Offset) ; 236 offset = ( unsigned long )( 0x80000000 | ( DevNumber << 11 ) + ( FuncNumber << 8 ) + Offset) ;
237 237
238 *(__u32 *)CC_CONFADDR = offset; 238 *(__u32 *)CC_CONFADDR = offset;
239 *(__u32 *)CC_CONFDATA = data; 239 *(__u32 *)CC_CONFDATA = data;
240} 240}
241void setup_ITE_IVR_flash() 241void setup_ITE_IVR_flash()
diff --git a/drivers/mtd/maps/dbox2-flash.c b/drivers/mtd/maps/dbox2-flash.c
index d850a27a4b59..49d90542fc75 100644
--- a/drivers/mtd/maps/dbox2-flash.c
+++ b/drivers/mtd/maps/dbox2-flash.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: dbox2-flash.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $ 2 * $Id: dbox2-flash.c,v 1.14 2005/11/07 11:14:26 gleixner Exp $
3 * 3 *
4 * D-Box 2 flash driver 4 * D-Box 2 flash driver
5 */ 5 */
@@ -21,38 +21,38 @@
21static struct mtd_partition partition_info[]= { 21static struct mtd_partition partition_info[]= {
22 { 22 {
23 .name = "BR bootloader", 23 .name = "BR bootloader",
24 .size = 128 * 1024, 24 .size = 128 * 1024,
25 .offset = 0, 25 .offset = 0,
26 .mask_flags = MTD_WRITEABLE 26 .mask_flags = MTD_WRITEABLE
27 }, 27 },
28 { 28 {
29 .name = "FLFS (U-Boot)", 29 .name = "FLFS (U-Boot)",
30 .size = 128 * 1024, 30 .size = 128 * 1024,
31 .offset = MTDPART_OFS_APPEND, 31 .offset = MTDPART_OFS_APPEND,
32 .mask_flags = 0 32 .mask_flags = 0
33 }, 33 },
34 { 34 {
35 .name = "Root (SquashFS)", 35 .name = "Root (SquashFS)",
36 .size = 7040 * 1024, 36 .size = 7040 * 1024,
37 .offset = MTDPART_OFS_APPEND, 37 .offset = MTDPART_OFS_APPEND,
38 .mask_flags = 0 38 .mask_flags = 0
39 }, 39 },
40 { 40 {
41 .name = "var (JFFS2)", 41 .name = "var (JFFS2)",
42 .size = 896 * 1024, 42 .size = 896 * 1024,
43 .offset = MTDPART_OFS_APPEND, 43 .offset = MTDPART_OFS_APPEND,
44 .mask_flags = 0 44 .mask_flags = 0
45 }, 45 },
46 { 46 {
47 .name = "Flash without bootloader", 47 .name = "Flash without bootloader",
48 .size = MTDPART_SIZ_FULL, 48 .size = MTDPART_SIZ_FULL,
49 .offset = 128 * 1024, 49 .offset = 128 * 1024,
50 .mask_flags = 0 50 .mask_flags = 0
51 }, 51 },
52 { 52 {
53 .name = "Complete Flash", 53 .name = "Complete Flash",
54 .size = MTDPART_SIZ_FULL, 54 .size = MTDPART_SIZ_FULL,
55 .offset = 0, 55 .offset = 0,
56 .mask_flags = MTD_WRITEABLE 56 .mask_flags = MTD_WRITEABLE
57 } 57 }
58}; 58};
@@ -88,16 +88,16 @@ int __init init_dbox2_flash(void)
88 if (!mymtd) { 88 if (!mymtd) {
89 // Probe for single Intel 28F640 89 // Probe for single Intel 28F640
90 dbox2_flash_map.bankwidth = 2; 90 dbox2_flash_map.bankwidth = 2;
91 91
92 mymtd = do_map_probe("cfi_probe", &dbox2_flash_map); 92 mymtd = do_map_probe("cfi_probe", &dbox2_flash_map);
93 } 93 }
94 94
95 if (mymtd) { 95 if (mymtd) {
96 mymtd->owner = THIS_MODULE; 96 mymtd->owner = THIS_MODULE;
97 97
98 /* Create MTD devices for each partition. */ 98 /* Create MTD devices for each partition. */
99 add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS); 99 add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS);
100 100
101 return 0; 101 return 0;
102 } 102 }
103 103
diff --git a/drivers/mtd/maps/dc21285.c b/drivers/mtd/maps/dc21285.c
index e5b74169fde6..701620b6baed 100644
--- a/drivers/mtd/maps/dc21285.c
+++ b/drivers/mtd/maps/dc21285.c
@@ -4,8 +4,8 @@
4 * (C) 2000 Nicolas Pitre <nico@cam.org> 4 * (C) 2000 Nicolas Pitre <nico@cam.org>
5 * 5 *
6 * This code is GPL 6 * This code is GPL
7 * 7 *
8 * $Id: dc21285.c,v 1.22 2004/11/01 13:39:21 rmk Exp $ 8 * $Id: dc21285.c,v 1.24 2005/11/07 11:14:26 gleixner Exp $
9 */ 9 */
10#include <linux/config.h> 10#include <linux/config.h>
11#include <linux/module.h> 11#include <linux/module.h>
@@ -27,9 +27,9 @@
27static struct mtd_info *dc21285_mtd; 27static struct mtd_info *dc21285_mtd;
28 28
29#ifdef CONFIG_ARCH_NETWINDER 29#ifdef CONFIG_ARCH_NETWINDER
30/* 30/*
31 * This is really ugly, but it seams to be the only 31 * This is really ugly, but it seams to be the only
32 * realiable way to do it, as the cpld state machine 32 * realiable way to do it, as the cpld state machine
33 * is unpredictible. So we have a 25us penalty per 33 * is unpredictible. So we have a 25us penalty per
34 * write access. 34 * write access.
35 */ 35 */
@@ -150,7 +150,7 @@ static struct map_info dc21285_map = {
150static struct mtd_partition *dc21285_parts; 150static struct mtd_partition *dc21285_parts;
151static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; 151static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
152#endif 152#endif
153 153
154static int __init init_dc21285(void) 154static int __init init_dc21285(void)
155{ 155{
156 156
@@ -160,20 +160,20 @@ static int __init init_dc21285(void)
160 160
161 /* Determine bankwidth */ 161 /* Determine bankwidth */
162 switch (*CSR_SA110_CNTL & (3<<14)) { 162 switch (*CSR_SA110_CNTL & (3<<14)) {
163 case SA110_CNTL_ROMWIDTH_8: 163 case SA110_CNTL_ROMWIDTH_8:
164 dc21285_map.bankwidth = 1; 164 dc21285_map.bankwidth = 1;
165 dc21285_map.read = dc21285_read8; 165 dc21285_map.read = dc21285_read8;
166 dc21285_map.write = dc21285_write8; 166 dc21285_map.write = dc21285_write8;
167 dc21285_map.copy_to = dc21285_copy_to_8; 167 dc21285_map.copy_to = dc21285_copy_to_8;
168 break; 168 break;
169 case SA110_CNTL_ROMWIDTH_16: 169 case SA110_CNTL_ROMWIDTH_16:
170 dc21285_map.bankwidth = 2; 170 dc21285_map.bankwidth = 2;
171 dc21285_map.read = dc21285_read16; 171 dc21285_map.read = dc21285_read16;
172 dc21285_map.write = dc21285_write16; 172 dc21285_map.write = dc21285_write16;
173 dc21285_map.copy_to = dc21285_copy_to_16; 173 dc21285_map.copy_to = dc21285_copy_to_16;
174 break; 174 break;
175 case SA110_CNTL_ROMWIDTH_32: 175 case SA110_CNTL_ROMWIDTH_32:
176 dc21285_map.bankwidth = 4; 176 dc21285_map.bankwidth = 4;
177 dc21285_map.read = dc21285_read32; 177 dc21285_map.read = dc21285_read32;
178 dc21285_map.write = dc21285_write32; 178 dc21285_map.write = dc21285_write32;
179 dc21285_map.copy_to = dc21285_copy_to_32; 179 dc21285_map.copy_to = dc21285_copy_to_32;
@@ -201,20 +201,20 @@ static int __init init_dc21285(void)
201 if (!dc21285_mtd) { 201 if (!dc21285_mtd) {
202 iounmap(dc21285_map.virt); 202 iounmap(dc21285_map.virt);
203 return -ENXIO; 203 return -ENXIO;
204 } 204 }
205 205
206 dc21285_mtd->owner = THIS_MODULE; 206 dc21285_mtd->owner = THIS_MODULE;
207 207
208#ifdef CONFIG_MTD_PARTITIONS 208#ifdef CONFIG_MTD_PARTITIONS
209 nrparts = parse_mtd_partitions(dc21285_mtd, probes, &dc21285_parts, 0); 209 nrparts = parse_mtd_partitions(dc21285_mtd, probes, &dc21285_parts, 0);
210 if (nrparts > 0) 210 if (nrparts > 0)
211 add_mtd_partitions(dc21285_mtd, dc21285_parts, nrparts); 211 add_mtd_partitions(dc21285_mtd, dc21285_parts, nrparts);
212 else 212 else
213#endif 213#endif
214 add_mtd_device(dc21285_mtd); 214 add_mtd_device(dc21285_mtd);
215 215
216 if(machine_is_ebsa285()) { 216 if(machine_is_ebsa285()) {
217 /* 217 /*
218 * Flash timing is determined with bits 19-16 of the 218 * Flash timing is determined with bits 19-16 of the
219 * CSR_SA110_CNTL. The value is the number of wait cycles, or 219 * CSR_SA110_CNTL. The value is the number of wait cycles, or
220 * 0 for 16 cycles (the default). Cycles are 20 ns. 220 * 0 for 16 cycles (the default). Cycles are 20 ns.
@@ -227,7 +227,7 @@ static int __init init_dc21285(void)
227 /* tristate time */ 227 /* tristate time */
228 *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x0f000000) | (7 << 24)); 228 *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x0f000000) | (7 << 24));
229 } 229 }
230 230
231 return 0; 231 return 0;
232} 232}
233 233
diff --git a/drivers/mtd/maps/dilnetpc.c b/drivers/mtd/maps/dilnetpc.c
index f99519692cb7..b51c757817d8 100644
--- a/drivers/mtd/maps/dilnetpc.c
+++ b/drivers/mtd/maps/dilnetpc.c
@@ -14,7 +14,7 @@
14 * along with this program; if not, write to the Free Software 14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
16 * 16 *
17 * $Id: dilnetpc.c,v 1.17 2004/11/28 09:40:39 dwmw2 Exp $ 17 * $Id: dilnetpc.c,v 1.20 2005/11/07 11:14:26 gleixner Exp $
18 * 18 *
19 * The DIL/Net PC is a tiny embedded PC board made by SSV Embedded Systems 19 * The DIL/Net PC is a tiny embedded PC board made by SSV Embedded Systems
20 * featuring the AMD Elan SC410 processor. There are two variants of this 20 * featuring the AMD Elan SC410 processor. There are two variants of this
@@ -272,13 +272,13 @@ static struct map_info dnpc_map = {
272 272
273static struct mtd_partition partition_info[]= 273static struct mtd_partition partition_info[]=
274{ 274{
275 { 275 {
276 .name = "ADNP boot", 276 .name = "ADNP boot",
277 .offset = 0, 277 .offset = 0,
278 .size = 0xf0000, 278 .size = 0xf0000,
279 }, 279 },
280 { 280 {
281 .name = "ADNP system BIOS", 281 .name = "ADNP system BIOS",
282 .offset = MTDPART_OFS_NXTBLK, 282 .offset = MTDPART_OFS_NXTBLK,
283 .size = 0x10000, 283 .size = 0x10000,
284#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED 284#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
@@ -291,7 +291,7 @@ static struct mtd_partition partition_info[]=
291 .size = 0x2f0000, 291 .size = 0x2f0000,
292 }, 292 },
293 { 293 {
294 .name = "ADNP system BIOS entry", 294 .name = "ADNP system BIOS entry",
295 .offset = MTDPART_OFS_NXTBLK, 295 .offset = MTDPART_OFS_NXTBLK,
296 .size = MTDPART_SIZ_FULL, 296 .size = MTDPART_SIZ_FULL,
297#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED 297#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
@@ -325,9 +325,9 @@ static struct mtd_info *merged_mtd;
325 325
326static struct mtd_partition higlvl_partition_info[]= 326static struct mtd_partition higlvl_partition_info[]=
327{ 327{
328 { 328 {
329 .name = "ADNP boot block", 329 .name = "ADNP boot block",
330 .offset = 0, 330 .offset = 0,
331 .size = CONFIG_MTD_DILNETPC_BOOTSIZE, 331 .size = CONFIG_MTD_DILNETPC_BOOTSIZE,
332 }, 332 },
333 { 333 {
@@ -335,8 +335,8 @@ static struct mtd_partition higlvl_partition_info[]=
335 .offset = MTDPART_OFS_NXTBLK, 335 .offset = MTDPART_OFS_NXTBLK,
336 .size = ADNP_WINDOW_SIZE-CONFIG_MTD_DILNETPC_BOOTSIZE-0x20000, 336 .size = ADNP_WINDOW_SIZE-CONFIG_MTD_DILNETPC_BOOTSIZE-0x20000,
337 }, 337 },
338 { 338 {
339 .name = "ADNP system BIOS + BIOS Entry", 339 .name = "ADNP system BIOS + BIOS Entry",
340 .offset = MTDPART_OFS_NXTBLK, 340 .offset = MTDPART_OFS_NXTBLK,
341 .size = MTDPART_SIZ_FULL, 341 .size = MTDPART_SIZ_FULL,
342#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED 342#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
@@ -371,7 +371,7 @@ static int __init init_dnpc(void)
371 371
372 /* 372 /*
373 ** determine hardware (DNP/ADNP/invalid) 373 ** determine hardware (DNP/ADNP/invalid)
374 */ 374 */
375 if((is_dnp = dnp_adnp_probe()) < 0) 375 if((is_dnp = dnp_adnp_probe()) < 0)
376 return -ENXIO; 376 return -ENXIO;
377 377
@@ -397,13 +397,13 @@ static int __init init_dnpc(void)
397 ++dnpc_map.name; 397 ++dnpc_map.name;
398 for(i = 0; i < NUM_PARTITIONS; i++) 398 for(i = 0; i < NUM_PARTITIONS; i++)
399 ++partition_info[i].name; 399 ++partition_info[i].name;
400 higlvl_partition_info[1].size = DNP_WINDOW_SIZE - 400 higlvl_partition_info[1].size = DNP_WINDOW_SIZE -
401 CONFIG_MTD_DILNETPC_BOOTSIZE - 0x20000; 401 CONFIG_MTD_DILNETPC_BOOTSIZE - 0x20000;
402 for(i = 0; i < NUM_HIGHLVL_PARTITIONS; i++) 402 for(i = 0; i < NUM_HIGHLVL_PARTITIONS; i++)
403 ++higlvl_partition_info[i].name; 403 ++higlvl_partition_info[i].name;
404 } 404 }
405 405
406 printk(KERN_NOTICE "DIL/Net %s flash: 0x%lx at 0x%lx\n", 406 printk(KERN_NOTICE "DIL/Net %s flash: 0x%lx at 0x%lx\n",
407 is_dnp ? "DNPC" : "ADNP", dnpc_map.size, dnpc_map.phys); 407 is_dnp ? "DNPC" : "ADNP", dnpc_map.size, dnpc_map.phys);
408 408
409 dnpc_map.virt = ioremap_nocache(dnpc_map.phys, dnpc_map.size); 409 dnpc_map.virt = ioremap_nocache(dnpc_map.phys, dnpc_map.size);
@@ -436,7 +436,7 @@ static int __init init_dnpc(void)
436 iounmap(dnpc_map.virt); 436 iounmap(dnpc_map.virt);
437 return -ENXIO; 437 return -ENXIO;
438 } 438 }
439 439
440 mymtd->owner = THIS_MODULE; 440 mymtd->owner = THIS_MODULE;
441 441
442 /* 442 /*
diff --git a/drivers/mtd/maps/dmv182.c b/drivers/mtd/maps/dmv182.c
index b9bc63503e26..b993ac01a9a5 100644
--- a/drivers/mtd/maps/dmv182.c
+++ b/drivers/mtd/maps/dmv182.c
@@ -1,10 +1,10 @@
1 1
2/* 2/*
3 * drivers/mtd/maps/svme182.c 3 * drivers/mtd/maps/svme182.c
4 * 4 *
5 * Flash map driver for the Dy4 SVME182 board 5 * Flash map driver for the Dy4 SVME182 board
6 * 6 *
7 * $Id: dmv182.c,v 1.5 2004/11/04 13:24:14 gleixner Exp $ 7 * $Id: dmv182.c,v 1.6 2005/11/07 11:14:26 gleixner Exp $
8 * 8 *
9 * Copyright 2003-2004, TimeSys Corporation 9 * Copyright 2003-2004, TimeSys Corporation
10 * 10 *
@@ -104,7 +104,7 @@ static int __init init_svme182(void)
104 partitions = svme182_partitions; 104 partitions = svme182_partitions;
105 105
106 svme182_map.virt = ioremap(FLASH_BASE_ADDR, svme182_map.size); 106 svme182_map.virt = ioremap(FLASH_BASE_ADDR, svme182_map.size);
107 107
108 if (svme182_map.virt == 0) { 108 if (svme182_map.virt == 0) {
109 printk("Failed to ioremap FLASH memory area.\n"); 109 printk("Failed to ioremap FLASH memory area.\n");
110 return -EIO; 110 return -EIO;
diff --git a/drivers/mtd/maps/ebony.c b/drivers/mtd/maps/ebony.c
index b9d9cf4854b6..c0daf58357ca 100644
--- a/drivers/mtd/maps/ebony.c
+++ b/drivers/mtd/maps/ebony.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * $Id: ebony.c,v 1.15 2004/12/09 18:39:54 holindho Exp $ 2 * $Id: ebony.c,v 1.16 2005/11/07 11:14:26 gleixner Exp $
3 * 3 *
4 * Mapping for Ebony user flash 4 * Mapping for Ebony user flash
5 * 5 *
6 * Matt Porter <mporter@kernel.crashing.org> 6 * Matt Porter <mporter@kernel.crashing.org>
@@ -85,7 +85,7 @@ int __init init_ebony(void)
85 small_flash_base = EBONY_SMALL_FLASH_LOW2; 85 small_flash_base = EBONY_SMALL_FLASH_LOW2;
86 else 86 else
87 small_flash_base = EBONY_SMALL_FLASH_LOW1; 87 small_flash_base = EBONY_SMALL_FLASH_LOW1;
88 88
89 if (EBONY_BOOT_SMALL_FLASH(fpga0_reg) && 89 if (EBONY_BOOT_SMALL_FLASH(fpga0_reg) &&
90 !EBONY_ONBRD_FLASH_EN(fpga0_reg)) 90 !EBONY_ONBRD_FLASH_EN(fpga0_reg))
91 large_flash_base = EBONY_LARGE_FLASH_LOW; 91 large_flash_base = EBONY_LARGE_FLASH_LOW;
diff --git a/drivers/mtd/maps/edb7312.c b/drivers/mtd/maps/edb7312.c
index 8b0da394f3fa..b48a3473ffc1 100644
--- a/drivers/mtd/maps/edb7312.c
+++ b/drivers/mtd/maps/edb7312.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * $Id: edb7312.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $ 2 * $Id: edb7312.c,v 1.14 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * Handle mapping of the NOR flash on Cogent EDB7312 boards 4 * Handle mapping of the NOR flash on Cogent EDB7312 boards
5 * 5 *
6 * Copyright 2002 SYSGO Real-Time Solutions GmbH 6 * Copyright 2002 SYSGO Real-Time Solutions GmbH
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
@@ -46,7 +46,7 @@ struct map_info edb7312nor_map = {
46#ifdef CONFIG_MTD_PARTITIONS 46#ifdef CONFIG_MTD_PARTITIONS
47 47
48/* 48/*
49 * MTD partitioning stuff 49 * MTD partitioning stuff
50 */ 50 */
51static struct mtd_partition static_partitions[3] = 51static struct mtd_partition static_partitions[3] =
52{ 52{
@@ -80,7 +80,7 @@ int __init init_edb7312nor(void)
80 const char **type; 80 const char **type;
81 const char *part_type = 0; 81 const char *part_type = 0;
82 82
83 printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x\n", 83 printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x\n",
84 WINDOW_SIZE, WINDOW_ADDR); 84 WINDOW_SIZE, WINDOW_ADDR);
85 edb7312nor_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE); 85 edb7312nor_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
86 86
@@ -88,7 +88,7 @@ int __init init_edb7312nor(void)
88 printk(MSG_PREFIX "failed to ioremap\n"); 88 printk(MSG_PREFIX "failed to ioremap\n");
89 return -EIO; 89 return -EIO;
90 } 90 }
91 91
92 simple_map_init(&edb7312nor_map); 92 simple_map_init(&edb7312nor_map);
93 93
94 mymtd = 0; 94 mymtd = 0;
diff --git a/drivers/mtd/maps/epxa10db-flash.c b/drivers/mtd/maps/epxa10db-flash.c
index 1df6188926b3..265b079fe934 100644
--- a/drivers/mtd/maps/epxa10db-flash.c
+++ b/drivers/mtd/maps/epxa10db-flash.c
@@ -5,7 +5,7 @@
5 * Copyright (C) 2001 Altera Corporation 5 * Copyright (C) 2001 Altera Corporation
6 * Copyright (C) 2001 Red Hat, Inc. 6 * Copyright (C) 2001 Red Hat, Inc.
7 * 7 *
8 * $Id: epxa10db-flash.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $ 8 * $Id: epxa10db-flash.c,v 1.15 2005/11/07 11:14:27 gleixner Exp $
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
@@ -62,7 +62,7 @@ static const char *probes[] = { "RedBoot", "afs", NULL };
62static int __init epxa_mtd_init(void) 62static int __init epxa_mtd_init(void)
63{ 63{
64 int i; 64 int i;
65 65
66 printk(KERN_NOTICE "%s flash device: 0x%x at 0x%x\n", BOARD_NAME, FLASH_SIZE, FLASH_START); 66 printk(KERN_NOTICE "%s flash device: 0x%x at 0x%x\n", BOARD_NAME, FLASH_SIZE, FLASH_START);
67 67
68 epxa_map.virt = ioremap(FLASH_START, FLASH_SIZE); 68 epxa_map.virt = ioremap(FLASH_START, FLASH_SIZE);
@@ -126,8 +126,8 @@ static void __exit epxa_mtd_cleanup(void)
126} 126}
127 127
128 128
129/* 129/*
130 * This will do for now, once we decide which bootldr we're finally 130 * This will do for now, once we decide which bootldr we're finally
131 * going to use then we'll remove this function and do it properly 131 * going to use then we'll remove this function and do it properly
132 * 132 *
133 * Partions are currently (as offsets from base of flash): 133 * Partions are currently (as offsets from base of flash):
@@ -140,7 +140,7 @@ static int __init epxa_default_partitions(struct mtd_info *master, struct mtd_pa
140 struct mtd_partition *parts; 140 struct mtd_partition *parts;
141 int ret, i; 141 int ret, i;
142 int npartitions = 0; 142 int npartitions = 0;
143 char *names; 143 char *names;
144 const char *name = "jffs"; 144 const char *name = "jffs";
145 145
146 printk("Using default partitions for %s\n",BOARD_NAME); 146 printk("Using default partitions for %s\n",BOARD_NAME);
@@ -152,7 +152,7 @@ static int __init epxa_default_partitions(struct mtd_info *master, struct mtd_pa
152 goto out; 152 goto out;
153 } 153 }
154 i=0; 154 i=0;
155 names = (char *)&parts[npartitions]; 155 names = (char *)&parts[npartitions];
156 parts[i].name = names; 156 parts[i].name = names;
157 names += strlen(name) + 1; 157 names += strlen(name) + 1;
158 strcpy(parts[i].name, name); 158 strcpy(parts[i].name, name);
diff --git a/drivers/mtd/maps/fortunet.c b/drivers/mtd/maps/fortunet.c
index 00f7bbe5479e..c6bf4e1219ef 100644
--- a/drivers/mtd/maps/fortunet.c
+++ b/drivers/mtd/maps/fortunet.c
@@ -1,6 +1,6 @@
1/* fortunet.c memory map 1/* fortunet.c memory map
2 * 2 *
3 * $Id: fortunet.c,v 1.9 2004/11/04 13:24:14 gleixner Exp $ 3 * $Id: fortunet.c,v 1.11 2005/11/07 11:14:27 gleixner Exp $
4 */ 4 */
5 5
6#include <linux/module.h> 6#include <linux/module.h>
@@ -212,7 +212,7 @@ int __init init_fortunet(void)
212 212
213 map_regions[ix].map_info.phys = map_regions[ix].window_addr_physical, 213 map_regions[ix].map_info.phys = map_regions[ix].window_addr_physical,
214 214
215 map_regions[ix].map_info.virt = 215 map_regions[ix].map_info.virt =
216 ioremap_nocache( 216 ioremap_nocache(
217 map_regions[ix].window_addr_physical, 217 map_regions[ix].window_addr_physical,
218 map_regions[ix].map_info.size); 218 map_regions[ix].map_info.size);
diff --git a/drivers/mtd/maps/h720x-flash.c b/drivers/mtd/maps/h720x-flash.c
index c73828171d9b..319094821101 100644
--- a/drivers/mtd/maps/h720x-flash.c
+++ b/drivers/mtd/maps/h720x-flash.c
@@ -1,11 +1,11 @@
1/* 1/*
2 * Flash memory access on Hynix GMS30C7201/HMS30C7202 based 2 * Flash memory access on Hynix GMS30C7201/HMS30C7202 based
3 * evaluation boards 3 * evaluation boards
4 * 4 *
5 * $Id: h720x-flash.c,v 1.11 2004/11/04 13:24:14 gleixner Exp $ 5 * $Id: h720x-flash.c,v 1.12 2005/11/07 11:14:27 gleixner Exp $
6 * 6 *
7 * (C) 2002 Jungjun Kim <jungjun.kim@hynix.com> 7 * (C) 2002 Jungjun Kim <jungjun.kim@hynix.com>
8 * 2003 Thomas Gleixner <tglx@linutronix.de> 8 * 2003 Thomas Gleixner <tglx@linutronix.de>
9 */ 9 */
10 10
11#include <linux/config.h> 11#include <linux/config.h>
@@ -72,7 +72,7 @@ int __init h720x_mtd_init(void)
72{ 72{
73 73
74 char *part_type = NULL; 74 char *part_type = NULL;
75 75
76 h720x_map.virt = ioremap(FLASH_PHYS, FLASH_SIZE); 76 h720x_map.virt = ioremap(FLASH_PHYS, FLASH_SIZE);
77 77
78 if (!h720x_map.virt) { 78 if (!h720x_map.virt) {
@@ -91,7 +91,7 @@ int __init h720x_mtd_init(void)
91 h720x_map.bankwidth = 2; 91 h720x_map.bankwidth = 2;
92 mymtd = do_map_probe("cfi_probe", &h720x_map); 92 mymtd = do_map_probe("cfi_probe", &h720x_map);
93 } 93 }
94 94
95 if (mymtd) { 95 if (mymtd) {
96 mymtd->owner = THIS_MODULE; 96 mymtd->owner = THIS_MODULE;
97 97
@@ -124,11 +124,11 @@ static void __exit h720x_mtd_cleanup(void)
124 del_mtd_partitions(mymtd); 124 del_mtd_partitions(mymtd);
125 map_destroy(mymtd); 125 map_destroy(mymtd);
126 } 126 }
127 127
128 /* Free partition info, if commandline partition was used */ 128 /* Free partition info, if commandline partition was used */
129 if (mtd_parts && (mtd_parts != h720x_partitions)) 129 if (mtd_parts && (mtd_parts != h720x_partitions))
130 kfree (mtd_parts); 130 kfree (mtd_parts);
131 131
132 if (h720x_map.virt) { 132 if (h720x_map.virt) {
133 iounmap((void *)h720x_map.virt); 133 iounmap((void *)h720x_map.virt);
134 h720x_map.virt = 0; 134 h720x_map.virt = 0;
diff --git a/drivers/mtd/maps/ichxrom.c b/drivers/mtd/maps/ichxrom.c
index c5e2111ba146..ea5073781b3a 100644
--- a/drivers/mtd/maps/ichxrom.c
+++ b/drivers/mtd/maps/ichxrom.c
@@ -2,7 +2,7 @@
2 * ichxrom.c 2 * ichxrom.c
3 * 3 *
4 * Normal mappings of chips in physical memory 4 * Normal mappings of chips in physical memory
5 * $Id: ichxrom.c,v 1.18 2005/07/07 10:26:20 dwmw2 Exp $ 5 * $Id: ichxrom.c,v 1.19 2005/11/07 11:14:27 gleixner Exp $
6 */ 6 */
7 7
8#include <linux/module.h> 8#include <linux/module.h>
@@ -101,7 +101,7 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
101 * you can only really attach a FWH to an ICHX there 101 * you can only really attach a FWH to an ICHX there
102 * a number of simplifications you can make. 102 * a number of simplifications you can make.
103 * 103 *
104 * Also you can page firmware hubs if an 8MB window isn't enough 104 * Also you can page firmware hubs if an 8MB window isn't enough
105 * but don't currently handle that case either. 105 * but don't currently handle that case either.
106 */ 106 */
107 window->pdev = pdev; 107 window->pdev = pdev;
@@ -144,7 +144,7 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
144 window->phys = 0xfff00000; 144 window->phys = 0xfff00000;
145 } 145 }
146 else if ((byte & 0x80) == 0x80) { 146 else if ((byte & 0x80) == 0x80) {
147 window->phys = 0xfff80000; 147 window->phys = 0xfff80000;
148 } 148 }
149 149
150 if (window->phys == 0) { 150 if (window->phys == 0) {
@@ -233,7 +233,7 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
233 * in a factory setting. So in-place programming 233 * in a factory setting. So in-place programming
234 * needs to use a different method. 234 * needs to use a different method.
235 */ 235 */
236 for(map->map.bankwidth = 32; map->map.bankwidth; 236 for(map->map.bankwidth = 32; map->map.bankwidth;
237 map->map.bankwidth >>= 1) 237 map->map.bankwidth >>= 1)
238 { 238 {
239 char **probe_type; 239 char **probe_type;
@@ -286,7 +286,7 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
286 for(i = 0; i < cfi->numchips; i++) { 286 for(i = 0; i < cfi->numchips; i++) {
287 cfi->chips[i].start += offset; 287 cfi->chips[i].start += offset;
288 } 288 }
289 289
290 /* Now that the mtd devices is complete claim and export it */ 290 /* Now that the mtd devices is complete claim and export it */
291 map->mtd->owner = THIS_MODULE; 291 map->mtd->owner = THIS_MODULE;
292 if (add_mtd_device(map->mtd)) { 292 if (add_mtd_device(map->mtd)) {
@@ -324,11 +324,11 @@ static void __devexit ichxrom_remove_one (struct pci_dev *pdev)
324} 324}
325 325
326static struct pci_device_id ichxrom_pci_tbl[] __devinitdata = { 326static struct pci_device_id ichxrom_pci_tbl[] __devinitdata = {
327 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, 327 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0,
328 PCI_ANY_ID, PCI_ANY_ID, }, 328 PCI_ANY_ID, PCI_ANY_ID, },
329 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, 329 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0,
330 PCI_ANY_ID, PCI_ANY_ID, }, 330 PCI_ANY_ID, PCI_ANY_ID, },
331 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, 331 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,
332 PCI_ANY_ID, PCI_ANY_ID, }, 332 PCI_ANY_ID, PCI_ANY_ID, },
333 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, 333 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0,
334 PCI_ANY_ID, PCI_ANY_ID, }, 334 PCI_ANY_ID, PCI_ANY_ID, },
diff --git a/drivers/mtd/maps/impa7.c b/drivers/mtd/maps/impa7.c
index cb39172c81d2..ba7f40311a7e 100644
--- a/drivers/mtd/maps/impa7.c
+++ b/drivers/mtd/maps/impa7.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * $Id: impa7.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $ 2 * $Id: impa7.c,v 1.14 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * Handle mapping of the NOR flash on implementa A7 boards 4 * Handle mapping of the NOR flash on implementa A7 boards
5 * 5 *
6 * Copyright 2002 SYSGO Real-Time Solutions GmbH 6 * Copyright 2002 SYSGO Real-Time Solutions GmbH
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
@@ -55,7 +55,7 @@ static struct map_info impa7_map[NUM_FLASHBANKS] = {
55#ifdef CONFIG_MTD_PARTITIONS 55#ifdef CONFIG_MTD_PARTITIONS
56 56
57/* 57/*
58 * MTD partitioning stuff 58 * MTD partitioning stuff
59 */ 59 */
60static struct mtd_partition static_partitions[] = 60static struct mtd_partition static_partitions[] =
61{ 61{
@@ -108,9 +108,9 @@ int __init init_impa7(void)
108 impa7_mtd[i]->owner = THIS_MODULE; 108 impa7_mtd[i]->owner = THIS_MODULE;
109 devicesfound++; 109 devicesfound++;
110#ifdef CONFIG_MTD_PARTITIONS 110#ifdef CONFIG_MTD_PARTITIONS
111 mtd_parts_nb[i] = parse_mtd_partitions(impa7_mtd[i], 111 mtd_parts_nb[i] = parse_mtd_partitions(impa7_mtd[i],
112 probes, 112 probes,
113 &mtd_parts[i], 113 &mtd_parts[i],
114 0); 114 0);
115 if (mtd_parts_nb[i] > 0) { 115 if (mtd_parts_nb[i] > 0) {
116 part_type = "command line"; 116 part_type = "command line";
@@ -121,16 +121,16 @@ int __init init_impa7(void)
121 } 121 }
122 122
123 printk(KERN_NOTICE MSG_PREFIX 123 printk(KERN_NOTICE MSG_PREFIX
124 "using %s partition definition\n", 124 "using %s partition definition\n",
125 part_type); 125 part_type);
126 add_mtd_partitions(impa7_mtd[i], 126 add_mtd_partitions(impa7_mtd[i],
127 mtd_parts[i], mtd_parts_nb[i]); 127 mtd_parts[i], mtd_parts_nb[i]);
128#else 128#else
129 add_mtd_device(impa7_mtd[i]); 129 add_mtd_device(impa7_mtd[i]);
130 130
131#endif 131#endif
132 } 132 }
133 else 133 else
134 iounmap((void *)impa7_map[i].virt); 134 iounmap((void *)impa7_map[i].virt);
135 } 135 }
136 return devicesfound == 0 ? -ENXIO : 0; 136 return devicesfound == 0 ? -ENXIO : 0;
diff --git a/drivers/mtd/maps/integrator-flash.c b/drivers/mtd/maps/integrator-flash.c
index 93f50d6d5488..fe738fd8d6f8 100644
--- a/drivers/mtd/maps/integrator-flash.c
+++ b/drivers/mtd/maps/integrator-flash.c
@@ -1,28 +1,28 @@
1/*====================================================================== 1/*======================================================================
2 2
3 drivers/mtd/maps/integrator-flash.c: ARM Integrator flash map driver 3 drivers/mtd/maps/integrator-flash.c: ARM Integrator flash map driver
4 4
5 Copyright (C) 2000 ARM Limited 5 Copyright (C) 2000 ARM Limited
6 Copyright (C) 2003 Deep Blue Solutions Ltd. 6 Copyright (C) 2003 Deep Blue Solutions Ltd.
7 7
8 This program is free software; you can redistribute it and/or modify 8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by 9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or 10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version. 11 (at your option) any later version.
12 12
13 This program is distributed in the hope that it will be useful, 13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details. 16 GNU General Public License for more details.
17 17
18 You should have received a copy of the GNU General Public License 18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software 19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 21
22 This is access code for flashes using ARM's flash partitioning 22 This is access code for flashes using ARM's flash partitioning
23 standards. 23 standards.
24 24
25 $Id: integrator-flash.c,v 1.18 2004/11/01 13:26:15 rmk Exp $ 25 $Id: integrator-flash.c,v 1.20 2005/11/07 11:14:27 gleixner Exp $
26 26
27======================================================================*/ 27======================================================================*/
28 28
diff --git a/drivers/mtd/maps/ipaq-flash.c b/drivers/mtd/maps/ipaq-flash.c
index 70b0e0b82c34..35097c9bbf50 100644
--- a/drivers/mtd/maps/ipaq-flash.c
+++ b/drivers/mtd/maps/ipaq-flash.c
@@ -1,11 +1,11 @@
1/* 1/*
2 * Flash memory access on iPAQ Handhelds (either SA1100 or PXA250 based) 2 * Flash memory access on iPAQ Handhelds (either SA1100 or PXA250 based)
3 * 3 *
4 * (C) 2000 Nicolas Pitre <nico@cam.org> 4 * (C) 2000 Nicolas Pitre <nico@cam.org>
5 * (C) 2002 Hewlett-Packard Company <jamey.hicks@hp.com> 5 * (C) 2002 Hewlett-Packard Company <jamey.hicks@hp.com>
6 * (C) 2003 Christian Pellegrin <chri@ascensit.com>, <chri@infis.univ.ts.it>: concatenation of multiple flashes 6 * (C) 2003 Christian Pellegrin <chri@ascensit.com>, <chri@infis.univ.ts.it>: concatenation of multiple flashes
7 * 7 *
8 * $Id: ipaq-flash.c,v 1.3 2004/11/04 13:24:15 gleixner Exp $ 8 * $Id: ipaq-flash.c,v 1.5 2005/11/07 11:14:27 gleixner Exp $
9 */ 9 */
10 10
11#include <linux/config.h> 11#include <linux/config.h>
@@ -107,7 +107,7 @@ static struct mtd_partition h3xxx_partitions[] = {
107#ifndef CONFIG_LAB 107#ifndef CONFIG_LAB
108 mask_flags: MTD_WRITEABLE, /* force read-only */ 108 mask_flags: MTD_WRITEABLE, /* force read-only */
109#endif 109#endif
110 }, 110 },
111 { 111 {
112 name: "H3XXX root jffs2", 112 name: "H3XXX root jffs2",
113#ifndef CONFIG_LAB 113#ifndef CONFIG_LAB
@@ -148,7 +148,7 @@ static DEFINE_SPINLOCK(ipaq_vpp_lock);
148static void h3xxx_set_vpp(struct map_info *map, int vpp) 148static void h3xxx_set_vpp(struct map_info *map, int vpp)
149{ 149{
150 static int nest = 0; 150 static int nest = 0;
151 151
152 spin_lock(&ipaq_vpp_lock); 152 spin_lock(&ipaq_vpp_lock);
153 if (vpp) 153 if (vpp)
154 nest++; 154 nest++;
@@ -191,7 +191,7 @@ static unsigned long cs_phys[] = {
191 SA1100_CS3_PHYS, 191 SA1100_CS3_PHYS,
192 SA1100_CS4_PHYS, 192 SA1100_CS4_PHYS,
193 SA1100_CS5_PHYS, 193 SA1100_CS5_PHYS,
194#else 194#else
195 PXA_CS0_PHYS, 195 PXA_CS0_PHYS,
196 PXA_CS1_PHYS, 196 PXA_CS1_PHYS,
197 PXA_CS2_PHYS, 197 PXA_CS2_PHYS,
@@ -216,7 +216,7 @@ int __init ipaq_mtd_init(void)
216 216
217 /* Default flash bankwidth */ 217 /* Default flash bankwidth */
218 // ipaq_map.bankwidth = (MSC0 & MSC_RBW) ? 2 : 4; 218 // ipaq_map.bankwidth = (MSC0 & MSC_RBW) ? 2 : 4;
219 219
220 if (machine_is_h1900()) 220 if (machine_is_h1900())
221 { 221 {
222 /* For our intents, the h1900 is not a real iPAQ, so we special-case it. */ 222 /* For our intents, the h1900 is not a real iPAQ, so we special-case it. */
@@ -229,7 +229,7 @@ int __init ipaq_mtd_init(void)
229 else 229 else
230 for(i=0; i<MAX_IPAQ_CS; i++) 230 for(i=0; i<MAX_IPAQ_CS; i++)
231 ipaq_map[i].bankwidth = 4; 231 ipaq_map[i].bankwidth = 4;
232 232
233 /* 233 /*
234 * Static partition definition selection 234 * Static partition definition selection
235 */ 235 */
@@ -309,7 +309,7 @@ int __init ipaq_mtd_init(void)
309 return -ENXIO; 309 return -ENXIO;
310 } else 310 } else
311 printk(KERN_NOTICE "iPAQ flash: found %d bytes\n", my_sub_mtd[i]->size); 311 printk(KERN_NOTICE "iPAQ flash: found %d bytes\n", my_sub_mtd[i]->size);
312 312
313 /* do we really need this debugging? --joshua 20030703 */ 313 /* do we really need this debugging? --joshua 20030703 */
314 // printk("my_sub_mtd[%d]=%p\n", i, my_sub_mtd[i]); 314 // printk("my_sub_mtd[%d]=%p\n", i, my_sub_mtd[i]);
315 my_sub_mtd[i]->owner = THIS_MODULE; 315 my_sub_mtd[i]->owner = THIS_MODULE;
@@ -333,11 +333,11 @@ int __init ipaq_mtd_init(void)
333#else 333#else
334 mymtd = my_sub_mtd[0]; 334 mymtd = my_sub_mtd[0];
335 335
336 /* 336 /*
337 *In the very near future, command line partition parsing 337 *In the very near future, command line partition parsing
338 * will use the device name as 'mtd-id' instead of a value 338 * will use the device name as 'mtd-id' instead of a value
339 * passed to the parse_cmdline_partitions() routine. Since 339 * passed to the parse_cmdline_partitions() routine. Since
340 * the bootldr says 'ipaq', make sure it continues to work. 340 * the bootldr says 'ipaq', make sure it continues to work.
341 */ 341 */
342 mymtd->name = "ipaq"; 342 mymtd->name = "ipaq";
343 343
@@ -385,7 +385,7 @@ int __init ipaq_mtd_init(void)
385 */ 385 */
386 386
387 i = parse_mtd_partitions(mymtd, part_probes, &parsed_parts, 0); 387 i = parse_mtd_partitions(mymtd, part_probes, &parsed_parts, 0);
388 388
389 if (i > 0) { 389 if (i > 0) {
390 nb_parts = parsed_nr_parts = i; 390 nb_parts = parsed_nr_parts = i;
391 parts = parsed_parts; 391 parts = parsed_parts;
@@ -423,10 +423,10 @@ static void __exit ipaq_mtd_cleanup(void)
423#endif 423#endif
424 map_destroy(mymtd); 424 map_destroy(mymtd);
425#ifdef CONFIG_MTD_CONCAT 425#ifdef CONFIG_MTD_CONCAT
426 for(i=0; i<MAX_IPAQ_CS; i++) 426 for(i=0; i<MAX_IPAQ_CS; i++)
427#else 427#else
428 for(i=1; i<MAX_IPAQ_CS; i++) 428 for(i=1; i<MAX_IPAQ_CS; i++)
429#endif 429#endif
430 { 430 {
431 if (my_sub_mtd[i]) 431 if (my_sub_mtd[i])
432 map_destroy(my_sub_mtd[i]); 432 map_destroy(my_sub_mtd[i]);
@@ -444,14 +444,14 @@ static int __init h1900_special_case(void)
444 ipaq_map[0].phys = 0x0; 444 ipaq_map[0].phys = 0x0;
445 ipaq_map[0].virt = __ioremap(0x0, 0x04000000, 0, 1); 445 ipaq_map[0].virt = __ioremap(0x0, 0x04000000, 0, 1);
446 ipaq_map[0].bankwidth = 2; 446 ipaq_map[0].bankwidth = 2;
447 447
448 printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with JEDEC.\n", ipaq_map[0].bankwidth*8, ipaq_map[0].virt); 448 printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with JEDEC.\n", ipaq_map[0].bankwidth*8, ipaq_map[0].virt);
449 mymtd = do_map_probe("jedec_probe", &ipaq_map[0]); 449 mymtd = do_map_probe("jedec_probe", &ipaq_map[0]);
450 if (!mymtd) 450 if (!mymtd)
451 return -ENODEV; 451 return -ENODEV;
452 add_mtd_device(mymtd); 452 add_mtd_device(mymtd);
453 printk(KERN_NOTICE "iPAQ flash: registered h1910 flash\n"); 453 printk(KERN_NOTICE "iPAQ flash: registered h1910 flash\n");
454 454
455 return 0; 455 return 0;
456} 456}
457 457
diff --git a/drivers/mtd/maps/iq80310.c b/drivers/mtd/maps/iq80310.c
index 2e7577492a2c..62d9e87d84e2 100644
--- a/drivers/mtd/maps/iq80310.c
+++ b/drivers/mtd/maps/iq80310.c
@@ -1,11 +1,11 @@
1/* 1/*
2 * $Id: iq80310.c,v 1.20 2004/11/04 13:24:15 gleixner Exp $ 2 * $Id: iq80310.c,v 1.21 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * Mapping for the Intel XScale IQ80310 evaluation board 4 * Mapping for the Intel XScale IQ80310 evaluation board
5 * 5 *
6 * Author: Nicolas Pitre 6 * Author: Nicolas Pitre
7 * Copyright: (C) 2001 MontaVista Software Inc. 7 * Copyright: (C) 2001 MontaVista Software Inc.
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
diff --git a/drivers/mtd/maps/ixp2000.c b/drivers/mtd/maps/ixp2000.c
index 6f36497022d1..641eb2b55e9f 100644
--- a/drivers/mtd/maps/ixp2000.c
+++ b/drivers/mtd/maps/ixp2000.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: ixp2000.c,v 1.6 2005/03/18 14:07:46 gleixner Exp $ 2 * $Id: ixp2000.c,v 1.9 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * drivers/mtd/maps/ixp2000.c 4 * drivers/mtd/maps/ixp2000.c
5 * 5 *
@@ -14,7 +14,7 @@
14 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as 15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation. 16 * published by the Free Software Foundation.
17 * 17 *
18 */ 18 */
19 19
20#include <linux/module.h> 20#include <linux/module.h>
@@ -46,8 +46,8 @@ struct ixp2000_flash_info {
46}; 46};
47 47
48static inline unsigned long flash_bank_setup(struct map_info *map, unsigned long ofs) 48static inline unsigned long flash_bank_setup(struct map_info *map, unsigned long ofs)
49{ 49{
50 unsigned long (*set_bank)(unsigned long) = 50 unsigned long (*set_bank)(unsigned long) =
51 (unsigned long(*)(unsigned long))map->map_priv_2; 51 (unsigned long(*)(unsigned long))map->map_priv_2;
52 52
53 return (set_bank ? set_bank(ofs) : ofs); 53 return (set_bank ? set_bank(ofs) : ofs);
@@ -55,8 +55,8 @@ static inline unsigned long flash_bank_setup(struct map_info *map, unsigned long
55 55
56#ifdef __ARMEB__ 56#ifdef __ARMEB__
57/* 57/*
58 * Rev A0 and A1 of IXP2400 silicon have a broken addressing unit which 58 * Rev A0 and A1 of IXP2400 silicon have a broken addressing unit which
59 * causes the lower address bits to be XORed with 0x11 on 8 bit accesses 59 * causes the lower address bits to be XORed with 0x11 on 8 bit accesses
60 * and XORed with 0x10 on 16 bit accesses. See the spec update, erratum 44. 60 * and XORed with 0x10 on 16 bit accesses. See the spec update, erratum 44.
61 */ 61 */
62static int erratum44_workaround = 0; 62static int erratum44_workaround = 0;
@@ -90,7 +90,7 @@ static void ixp2000_flash_copy_from(struct map_info *map, void *to,
90 unsigned long from, ssize_t len) 90 unsigned long from, ssize_t len)
91{ 91{
92 from = flash_bank_setup(map, from); 92 from = flash_bank_setup(map, from);
93 while(len--) 93 while(len--)
94 *(__u8 *) to++ = *(__u8 *)(map->map_priv_1 + from++); 94 *(__u8 *) to++ = *(__u8 *)(map->map_priv_1 + from++);
95} 95}
96 96
@@ -148,11 +148,11 @@ static int ixp2000_flash_probe(struct device *_dev)
148 static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; 148 static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
149 struct platform_device *dev = to_platform_device(_dev); 149 struct platform_device *dev = to_platform_device(_dev);
150 struct ixp2000_flash_data *ixp_data = dev->dev.platform_data; 150 struct ixp2000_flash_data *ixp_data = dev->dev.platform_data;
151 struct flash_platform_data *plat; 151 struct flash_platform_data *plat;
152 struct ixp2000_flash_info *info; 152 struct ixp2000_flash_info *info;
153 unsigned long window_size; 153 unsigned long window_size;
154 int err = -1; 154 int err = -1;
155 155
156 if (!ixp_data) 156 if (!ixp_data)
157 return -ENODEV; 157 return -ENODEV;
158 158
@@ -161,7 +161,7 @@ static int ixp2000_flash_probe(struct device *_dev)
161 return -ENODEV; 161 return -ENODEV;
162 162
163 window_size = dev->resource->end - dev->resource->start + 1; 163 window_size = dev->resource->end - dev->resource->start + 1;
164 dev_info(_dev, "Probe of IXP2000 flash(%d banks x %dMiB)\n", 164 dev_info(_dev, "Probe of IXP2000 flash(%d banks x %dMiB)\n",
165 ixp_data->nr_banks, ((u32)window_size >> 20)); 165 ixp_data->nr_banks, ((u32)window_size >> 20));
166 166
167 if (plat->width != 1) { 167 if (plat->width != 1) {
@@ -174,7 +174,7 @@ static int ixp2000_flash_probe(struct device *_dev)
174 if(!info) { 174 if(!info) {
175 err = -ENOMEM; 175 err = -ENOMEM;
176 goto Error; 176 goto Error;
177 } 177 }
178 memzero(info, sizeof(struct ixp2000_flash_info)); 178 memzero(info, sizeof(struct ixp2000_flash_info));
179 179
180 dev_set_drvdata(&dev->dev, info); 180 dev_set_drvdata(&dev->dev, info);
@@ -184,7 +184,7 @@ static int ixp2000_flash_probe(struct device *_dev)
184 * not attempt to do a direct access on us. 184 * not attempt to do a direct access on us.
185 */ 185 */
186 info->map.phys = NO_XIP; 186 info->map.phys = NO_XIP;
187 187
188 info->nr_banks = ixp_data->nr_banks; 188 info->nr_banks = ixp_data->nr_banks;
189 info->map.size = ixp_data->nr_banks * window_size; 189 info->map.size = ixp_data->nr_banks * window_size;
190 info->map.bankwidth = 1; 190 info->map.bankwidth = 1;
@@ -192,7 +192,7 @@ static int ixp2000_flash_probe(struct device *_dev)
192 /* 192 /*
193 * map_priv_2 is used to store a ptr to to the bank_setup routine 193 * map_priv_2 is used to store a ptr to to the bank_setup routine
194 */ 194 */
195 info->map.map_priv_2 = (void __iomem *) ixp_data->bank_setup; 195 info->map.map_priv_2 = (unsigned long) ixp_data->bank_setup;
196 196
197 info->map.name = dev->dev.bus_id; 197 info->map.name = dev->dev.bus_id;
198 info->map.read = ixp2000_flash_read8; 198 info->map.read = ixp2000_flash_read8;
@@ -200,8 +200,8 @@ static int ixp2000_flash_probe(struct device *_dev)
200 info->map.copy_from = ixp2000_flash_copy_from; 200 info->map.copy_from = ixp2000_flash_copy_from;
201 info->map.copy_to = ixp2000_flash_copy_to; 201 info->map.copy_to = ixp2000_flash_copy_to;
202 202
203 info->res = request_mem_region(dev->resource->start, 203 info->res = request_mem_region(dev->resource->start,
204 dev->resource->end - dev->resource->start + 1, 204 dev->resource->end - dev->resource->start + 1,
205 dev->dev.bus_id); 205 dev->dev.bus_id);
206 if (!info->res) { 206 if (!info->res) {
207 dev_err(_dev, "Could not reserve memory region\n"); 207 dev_err(_dev, "Could not reserve memory region\n");
@@ -209,7 +209,7 @@ static int ixp2000_flash_probe(struct device *_dev)
209 goto Error; 209 goto Error;
210 } 210 }
211 211
212 info->map.map_priv_1 = ioremap(dev->resource->start, 212 info->map.map_priv_1 = (unsigned long) ioremap(dev->resource->start,
213 dev->resource->end - dev->resource->start + 1); 213 dev->resource->end - dev->resource->start + 1);
214 if (!info->map.map_priv_1) { 214 if (!info->map.map_priv_1) {
215 dev_err(_dev, "Failed to ioremap flash region\n"); 215 dev_err(_dev, "Failed to ioremap flash region\n");
diff --git a/drivers/mtd/maps/ixp4xx.c b/drivers/mtd/maps/ixp4xx.c
index 0d87c02dee04..56b3a355bf7b 100644
--- a/drivers/mtd/maps/ixp4xx.c
+++ b/drivers/mtd/maps/ixp4xx.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: ixp4xx.c,v 1.7 2004/11/04 13:24:15 gleixner Exp $ 2 * $Id: ixp4xx.c,v 1.12 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * drivers/mtd/maps/ixp4xx.c 4 * drivers/mtd/maps/ixp4xx.c
5 * 5 *
@@ -45,7 +45,7 @@
45static map_word ixp4xx_read16(struct map_info *map, unsigned long ofs) 45static map_word ixp4xx_read16(struct map_info *map, unsigned long ofs)
46{ 46{
47 map_word val; 47 map_word val;
48 val.x[0] = *(__u16 *) (map->map_priv_1 + ofs); 48 val.x[0] = le16_to_cpu(readw(map->virt + ofs));
49 return val; 49 return val;
50} 50}
51 51
@@ -59,35 +59,35 @@ static void ixp4xx_copy_from(struct map_info *map, void *to,
59{ 59{
60 int i; 60 int i;
61 u8 *dest = (u8 *) to; 61 u8 *dest = (u8 *) to;
62 u16 *src = (u16 *) (map->map_priv_1 + from); 62 void __iomem *src = map->virt + from;
63 u16 data; 63 u16 data;
64 64
65 for (i = 0; i < (len / 2); i++) { 65 for (i = 0; i < (len / 2); i++) {
66 data = src[i]; 66 data = le16_to_cpu(readw(src + 2*i));
67 dest[i * 2] = BYTE0(data); 67 dest[i * 2] = BYTE0(data);
68 dest[i * 2 + 1] = BYTE1(data); 68 dest[i * 2 + 1] = BYTE1(data);
69 } 69 }
70 70
71 if (len & 1) 71 if (len & 1)
72 dest[len - 1] = BYTE0(src[i]); 72 dest[len - 1] = BYTE0(le16_to_cpu(readw(src + 2*i)));
73} 73}
74 74
75/* 75/*
76 * Unaligned writes are ignored, causing the 8-bit 76 * Unaligned writes are ignored, causing the 8-bit
77 * probe to fail and proceed to the 16-bit probe (which succeeds). 77 * probe to fail and proceed to the 16-bit probe (which succeeds).
78 */ 78 */
79static void ixp4xx_probe_write16(struct map_info *map, map_word d, unsigned long adr) 79static void ixp4xx_probe_write16(struct map_info *map, map_word d, unsigned long adr)
80{ 80{
81 if (!(adr & 1)) 81 if (!(adr & 1))
82 *(__u16 *) (map->map_priv_1 + adr) = d.x[0]; 82 writew(cpu_to_le16(d.x[0]), map->virt + adr);
83} 83}
84 84
85/* 85/*
86 * Fast write16 function without the probing check above 86 * Fast write16 function without the probing check above
87 */ 87 */
88static void ixp4xx_write16(struct map_info *map, map_word d, unsigned long adr) 88static void ixp4xx_write16(struct map_info *map, map_word d, unsigned long adr)
89{ 89{
90 *(__u16 *) (map->map_priv_1 + adr) = d.x[0]; 90 writew(cpu_to_le16(d.x[0]), map->virt + adr);
91} 91}
92 92
93struct ixp4xx_flash_info { 93struct ixp4xx_flash_info {
@@ -104,25 +104,18 @@ static int ixp4xx_flash_remove(struct device *_dev)
104 struct platform_device *dev = to_platform_device(_dev); 104 struct platform_device *dev = to_platform_device(_dev);
105 struct flash_platform_data *plat = dev->dev.platform_data; 105 struct flash_platform_data *plat = dev->dev.platform_data;
106 struct ixp4xx_flash_info *info = dev_get_drvdata(&dev->dev); 106 struct ixp4xx_flash_info *info = dev_get_drvdata(&dev->dev);
107 map_word d;
108 107
109 dev_set_drvdata(&dev->dev, NULL); 108 dev_set_drvdata(&dev->dev, NULL);
110 109
111 if(!info) 110 if(!info)
112 return 0; 111 return 0;
113 112
114 /*
115 * This is required for a soft reboot to work.
116 */
117 d.x[0] = 0xff;
118 ixp4xx_write16(&info->map, d, 0x55 * 0x2);
119
120 if (info->mtd) { 113 if (info->mtd) {
121 del_mtd_partitions(info->mtd); 114 del_mtd_partitions(info->mtd);
122 map_destroy(info->mtd); 115 map_destroy(info->mtd);
123 } 116 }
124 if (info->map.map_priv_1) 117 if (info->map.virt)
125 iounmap((void *) info->map.map_priv_1); 118 iounmap(info->map.virt);
126 119
127 kfree(info->partitions); 120 kfree(info->partitions);
128 121
@@ -134,9 +127,6 @@ static int ixp4xx_flash_remove(struct device *_dev)
134 if (plat->exit) 127 if (plat->exit)
135 plat->exit(); 128 plat->exit();
136 129
137 /* Disable flash write */
138 *IXP4XX_EXP_CS0 &= ~IXP4XX_FLASH_WRITABLE;
139
140 return 0; 130 return 0;
141} 131}
142 132
@@ -160,17 +150,11 @@ static int ixp4xx_flash_probe(struct device *_dev)
160 if(!info) { 150 if(!info) {
161 err = -ENOMEM; 151 err = -ENOMEM;
162 goto Error; 152 goto Error;
163 } 153 }
164 memzero(info, sizeof(struct ixp4xx_flash_info)); 154 memzero(info, sizeof(struct ixp4xx_flash_info));
165 155
166 dev_set_drvdata(&dev->dev, info); 156 dev_set_drvdata(&dev->dev, info);
167 157
168 /*
169 * Enable flash write
170 * TODO: Move this out to board specific code
171 */
172 *IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
173
174 /* 158 /*
175 * Tell the MTD layer we're not 1:1 mapped so that it does 159 * Tell the MTD layer we're not 1:1 mapped so that it does
176 * not attempt to do a direct access on us. 160 * not attempt to do a direct access on us.
@@ -189,8 +173,8 @@ static int ixp4xx_flash_probe(struct device *_dev)
189 info->map.write = ixp4xx_probe_write16, 173 info->map.write = ixp4xx_probe_write16,
190 info->map.copy_from = ixp4xx_copy_from, 174 info->map.copy_from = ixp4xx_copy_from,
191 175
192 info->res = request_mem_region(dev->resource->start, 176 info->res = request_mem_region(dev->resource->start,
193 dev->resource->end - dev->resource->start + 1, 177 dev->resource->end - dev->resource->start + 1,
194 "IXP4XXFlash"); 178 "IXP4XXFlash");
195 if (!info->res) { 179 if (!info->res) {
196 printk(KERN_ERR "IXP4XXFlash: Could not reserve memory region\n"); 180 printk(KERN_ERR "IXP4XXFlash: Could not reserve memory region\n");
@@ -198,9 +182,9 @@ static int ixp4xx_flash_probe(struct device *_dev)
198 goto Error; 182 goto Error;
199 } 183 }
200 184
201 info->map.map_priv_1 = ioremap(dev->resource->start, 185 info->map.virt = ioremap(dev->resource->start,
202 dev->resource->end - dev->resource->start + 1); 186 dev->resource->end - dev->resource->start + 1);
203 if (!info->map.map_priv_1) { 187 if (!info->map.virt) {
204 printk(KERN_ERR "IXP4XXFlash: Failed to ioremap region\n"); 188 printk(KERN_ERR "IXP4XXFlash: Failed to ioremap region\n");
205 err = -EIO; 189 err = -EIO;
206 goto Error; 190 goto Error;
@@ -213,7 +197,7 @@ static int ixp4xx_flash_probe(struct device *_dev)
213 goto Error; 197 goto Error;
214 } 198 }
215 info->mtd->owner = THIS_MODULE; 199 info->mtd->owner = THIS_MODULE;
216 200
217 /* Use the fast version */ 201 /* Use the fast version */
218 info->map.write = ixp4xx_write16, 202 info->map.write = ixp4xx_write16,
219 203
@@ -258,4 +242,3 @@ module_exit(ixp4xx_flash_exit);
258MODULE_LICENSE("GPL"); 242MODULE_LICENSE("GPL");
259MODULE_DESCRIPTION("MTD map driver for Intel IXP4xx systems"); 243MODULE_DESCRIPTION("MTD map driver for Intel IXP4xx systems");
260MODULE_AUTHOR("Deepak Saxena"); 244MODULE_AUTHOR("Deepak Saxena");
261
diff --git a/drivers/mtd/maps/l440gx.c b/drivers/mtd/maps/l440gx.c
index b08668212ab7..851bf9576052 100644
--- a/drivers/mtd/maps/l440gx.c
+++ b/drivers/mtd/maps/l440gx.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: l440gx.c,v 1.17 2004/11/28 09:40:39 dwmw2 Exp $ 2 * $Id: l440gx.c,v 1.18 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * BIOS Flash chip on Intel 440GX board. 4 * BIOS Flash chip on Intel 440GX board.
5 * 5 *
@@ -49,7 +49,7 @@ static struct map_info l440gx_map = {
49 .bankwidth = BUSWIDTH, 49 .bankwidth = BUSWIDTH,
50 .phys = WINDOW_ADDR, 50 .phys = WINDOW_ADDR,
51#if 0 51#if 0
52 /* FIXME verify that this is the 52 /* FIXME verify that this is the
53 * appripriate code for vpp enable/disable 53 * appripriate code for vpp enable/disable
54 */ 54 */
55 .set_vpp = l440gx_set_vpp 55 .set_vpp = l440gx_set_vpp
@@ -62,10 +62,10 @@ static int __init init_l440gx(void)
62 struct resource *pm_iobase; 62 struct resource *pm_iobase;
63 __u16 word; 63 __u16 word;
64 64
65 dev = pci_find_device(PCI_VENDOR_ID_INTEL, 65 dev = pci_find_device(PCI_VENDOR_ID_INTEL,
66 PCI_DEVICE_ID_INTEL_82371AB_0, NULL); 66 PCI_DEVICE_ID_INTEL_82371AB_0, NULL);
67 67
68 pm_dev = pci_find_device(PCI_VENDOR_ID_INTEL, 68 pm_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
69 PCI_DEVICE_ID_INTEL_82371AB_3, NULL); 69 PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
70 70
71 if (!dev || !pm_dev) { 71 if (!dev || !pm_dev) {
@@ -82,10 +82,10 @@ static int __init init_l440gx(void)
82 simple_map_init(&l440gx_map); 82 simple_map_init(&l440gx_map);
83 printk(KERN_NOTICE "window_addr = 0x%08lx\n", (unsigned long)l440gx_map.virt); 83 printk(KERN_NOTICE "window_addr = 0x%08lx\n", (unsigned long)l440gx_map.virt);
84 84
85 /* Setup the pm iobase resource 85 /* Setup the pm iobase resource
86 * This code should move into some kind of generic bridge 86 * This code should move into some kind of generic bridge
87 * driver but for the moment I'm content with getting the 87 * driver but for the moment I'm content with getting the
88 * allocation correct. 88 * allocation correct.
89 */ 89 */
90 pm_iobase = &pm_dev->resource[PIIXE_IOBASE_RESOURCE]; 90 pm_iobase = &pm_dev->resource[PIIXE_IOBASE_RESOURCE];
91 if (!(pm_iobase->flags & IORESOURCE_IO)) { 91 if (!(pm_iobase->flags & IORESOURCE_IO)) {
@@ -110,7 +110,7 @@ static int __init init_l440gx(void)
110 /* Set the iobase */ 110 /* Set the iobase */
111 iobase = pm_iobase->start; 111 iobase = pm_iobase->start;
112 pci_write_config_dword(pm_dev, 0x40, iobase | 1); 112 pci_write_config_dword(pm_dev, 0x40, iobase | 1);
113 113
114 114
115 /* Set XBCS# */ 115 /* Set XBCS# */
116 pci_read_config_word(dev, 0x4e, &word); 116 pci_read_config_word(dev, 0x4e, &word);
@@ -122,7 +122,7 @@ static int __init init_l440gx(void)
122 122
123 /* Enable the gate on the WE line */ 123 /* Enable the gate on the WE line */
124 outb(inb(TRIBUF_PORT) & ~1, TRIBUF_PORT); 124 outb(inb(TRIBUF_PORT) & ~1, TRIBUF_PORT);
125 125
126 printk(KERN_NOTICE "Enabled WE line to L440GX BIOS flash chip.\n"); 126 printk(KERN_NOTICE "Enabled WE line to L440GX BIOS flash chip.\n");
127 127
128 mymtd = do_map_probe("jedec_probe", &l440gx_map); 128 mymtd = do_map_probe("jedec_probe", &l440gx_map);
@@ -145,7 +145,7 @@ static void __exit cleanup_l440gx(void)
145{ 145{
146 del_mtd_device(mymtd); 146 del_mtd_device(mymtd);
147 map_destroy(mymtd); 147 map_destroy(mymtd);
148 148
149 iounmap(l440gx_map.virt); 149 iounmap(l440gx_map.virt);
150} 150}
151 151
diff --git a/drivers/mtd/maps/lubbock-flash.c b/drivers/mtd/maps/lubbock-flash.c
index 2b4c5058787d..1aa0447c5e66 100644
--- a/drivers/mtd/maps/lubbock-flash.c
+++ b/drivers/mtd/maps/lubbock-flash.c
@@ -1,11 +1,11 @@
1/* 1/*
2 * $Id: lubbock-flash.c,v 1.19 2004/11/04 13:24:15 gleixner Exp $ 2 * $Id: lubbock-flash.c,v 1.21 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * Map driver for the Lubbock developer platform. 4 * Map driver for the Lubbock developer platform.
5 * 5 *
6 * Author: Nicolas Pitre 6 * Author: Nicolas Pitre
7 * Copyright: (C) 2001 MontaVista Software Inc. 7 * Copyright: (C) 2001 MontaVista Software Inc.
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
@@ -76,7 +76,7 @@ static int __init init_lubbock(void)
76 int flashboot = (LUB_CONF_SWITCHES & 1); 76 int flashboot = (LUB_CONF_SWITCHES & 1);
77 int ret = 0, i; 77 int ret = 0, i;
78 78
79 lubbock_maps[0].bankwidth = lubbock_maps[1].bankwidth = 79 lubbock_maps[0].bankwidth = lubbock_maps[1].bankwidth =
80 (BOOT_DEF & 1) ? 2 : 4; 80 (BOOT_DEF & 1) ? 2 : 4;
81 81
82 /* Compensate for the nROMBT switch which swaps the flash banks */ 82 /* Compensate for the nROMBT switch which swaps the flash banks */
@@ -100,11 +100,11 @@ static int __init init_lubbock(void)
100 simple_map_init(&lubbock_maps[i]); 100 simple_map_init(&lubbock_maps[i]);
101 101
102 printk(KERN_NOTICE "Probing %s at physical address 0x%08lx (%d-bit bankwidth)\n", 102 printk(KERN_NOTICE "Probing %s at physical address 0x%08lx (%d-bit bankwidth)\n",
103 lubbock_maps[i].name, lubbock_maps[i].phys, 103 lubbock_maps[i].name, lubbock_maps[i].phys,
104 lubbock_maps[i].bankwidth * 8); 104 lubbock_maps[i].bankwidth * 8);
105 105
106 mymtds[i] = do_map_probe("cfi_probe", &lubbock_maps[i]); 106 mymtds[i] = do_map_probe("cfi_probe", &lubbock_maps[i]);
107 107
108 if (!mymtds[i]) { 108 if (!mymtds[i]) {
109 iounmap((void *)lubbock_maps[i].virt); 109 iounmap((void *)lubbock_maps[i].virt);
110 if (lubbock_maps[i].cached) 110 if (lubbock_maps[i].cached)
@@ -124,7 +124,7 @@ static int __init init_lubbock(void)
124 124
125 if (!mymtds[0] && !mymtds[1]) 125 if (!mymtds[0] && !mymtds[1])
126 return ret; 126 return ret;
127 127
128 for (i = 0; i < 2; i++) { 128 for (i = 0; i < 2; i++) {
129 if (!mymtds[i]) { 129 if (!mymtds[i]) {
130 printk(KERN_WARNING "%s is absent. Skipping\n", lubbock_maps[i].name); 130 printk(KERN_WARNING "%s is absent. Skipping\n", lubbock_maps[i].name);
@@ -151,7 +151,7 @@ static void __exit cleanup_lubbock(void)
151 if (nr_parsed_parts[i] || !i) 151 if (nr_parsed_parts[i] || !i)
152 del_mtd_partitions(mymtds[i]); 152 del_mtd_partitions(mymtds[i]);
153 else 153 else
154 del_mtd_device(mymtds[i]); 154 del_mtd_device(mymtds[i]);
155 155
156 map_destroy(mymtds[i]); 156 map_destroy(mymtds[i]);
157 iounmap((void *)lubbock_maps[i].virt); 157 iounmap((void *)lubbock_maps[i].virt);
diff --git a/drivers/mtd/maps/mainstone-flash.c b/drivers/mtd/maps/mainstone-flash.c
index da0f8a692628..eaa4bbb868a3 100644
--- a/drivers/mtd/maps/mainstone-flash.c
+++ b/drivers/mtd/maps/mainstone-flash.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * Author: Nicolas Pitre 6 * Author: Nicolas Pitre
7 * Copyright: (C) 2001 MontaVista Software Inc. 7 * Copyright: (C) 2001 MontaVista Software Inc.
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
@@ -91,27 +91,27 @@ static int __init init_mainstone(void)
91 mainstone_maps[i].virt = ioremap(mainstone_maps[i].phys, 91 mainstone_maps[i].virt = ioremap(mainstone_maps[i].phys,
92 WINDOW_SIZE); 92 WINDOW_SIZE);
93 if (!mainstone_maps[i].virt) { 93 if (!mainstone_maps[i].virt) {
94 printk(KERN_WARNING "Failed to ioremap %s\n", 94 printk(KERN_WARNING "Failed to ioremap %s\n",
95 mainstone_maps[i].name); 95 mainstone_maps[i].name);
96 if (!ret) 96 if (!ret)
97 ret = -ENOMEM; 97 ret = -ENOMEM;
98 continue; 98 continue;
99 } 99 }
100 mainstone_maps[i].cached = 100 mainstone_maps[i].cached =
101 ioremap_cached(mainstone_maps[i].phys, WINDOW_SIZE); 101 ioremap_cached(mainstone_maps[i].phys, WINDOW_SIZE);
102 if (!mainstone_maps[i].cached) 102 if (!mainstone_maps[i].cached)
103 printk(KERN_WARNING "Failed to ioremap cached %s\n", 103 printk(KERN_WARNING "Failed to ioremap cached %s\n",
104 mainstone_maps[i].name); 104 mainstone_maps[i].name);
105 simple_map_init(&mainstone_maps[i]); 105 simple_map_init(&mainstone_maps[i]);
106 106
107 printk(KERN_NOTICE 107 printk(KERN_NOTICE
108 "Probing %s at physical address 0x%08lx" 108 "Probing %s at physical address 0x%08lx"
109 " (%d-bit bankwidth)\n", 109 " (%d-bit bankwidth)\n",
110 mainstone_maps[i].name, mainstone_maps[i].phys, 110 mainstone_maps[i].name, mainstone_maps[i].phys,
111 mainstone_maps[i].bankwidth * 8); 111 mainstone_maps[i].bankwidth * 8);
112 112
113 mymtds[i] = do_map_probe("cfi_probe", &mainstone_maps[i]); 113 mymtds[i] = do_map_probe("cfi_probe", &mainstone_maps[i]);
114 114
115 if (!mymtds[i]) { 115 if (!mymtds[i]) {
116 iounmap((void *)mainstone_maps[i].virt); 116 iounmap((void *)mainstone_maps[i].virt);
117 if (mainstone_maps[i].cached) 117 if (mainstone_maps[i].cached)
@@ -131,21 +131,21 @@ static int __init init_mainstone(void)
131 131
132 if (!mymtds[0] && !mymtds[1]) 132 if (!mymtds[0] && !mymtds[1])
133 return ret; 133 return ret;
134 134
135 for (i = 0; i < 2; i++) { 135 for (i = 0; i < 2; i++) {
136 if (!mymtds[i]) { 136 if (!mymtds[i]) {
137 printk(KERN_WARNING "%s is absent. Skipping\n", 137 printk(KERN_WARNING "%s is absent. Skipping\n",
138 mainstone_maps[i].name); 138 mainstone_maps[i].name);
139 } else if (nr_parsed_parts[i]) { 139 } else if (nr_parsed_parts[i]) {
140 add_mtd_partitions(mymtds[i], parsed_parts[i], 140 add_mtd_partitions(mymtds[i], parsed_parts[i],
141 nr_parsed_parts[i]); 141 nr_parsed_parts[i]);
142 } else if (!i) { 142 } else if (!i) {
143 printk("Using static partitions on %s\n", 143 printk("Using static partitions on %s\n",
144 mainstone_maps[i].name); 144 mainstone_maps[i].name);
145 add_mtd_partitions(mymtds[i], mainstone_partitions, 145 add_mtd_partitions(mymtds[i], mainstone_partitions,
146 ARRAY_SIZE(mainstone_partitions)); 146 ARRAY_SIZE(mainstone_partitions));
147 } else { 147 } else {
148 printk("Registering %s as whole device\n", 148 printk("Registering %s as whole device\n",
149 mainstone_maps[i].name); 149 mainstone_maps[i].name);
150 add_mtd_device(mymtds[i]); 150 add_mtd_device(mymtds[i]);
151 } 151 }
diff --git a/drivers/mtd/maps/mbx860.c b/drivers/mtd/maps/mbx860.c
index c5c6901a4763..06b118727846 100644
--- a/drivers/mtd/maps/mbx860.c
+++ b/drivers/mtd/maps/mbx860.c
@@ -1,11 +1,11 @@
1/* 1/*
2 * $Id: mbx860.c,v 1.8 2004/11/04 13:24:15 gleixner Exp $ 2 * $Id: mbx860.c,v 1.9 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * Handle mapping of the flash on MBX860 boards 4 * Handle mapping of the flash on MBX860 boards
5 * 5 *
6 * Author: Anton Todorov 6 * Author: Anton Todorov
7 * Copyright: (C) 2001 Emness Technology 7 * Copyright: (C) 2001 Emness Technology
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
@@ -46,7 +46,7 @@ static struct mtd_partition partition_info[]={
46 { .name = "MBX flash APPLICATION partition", 46 { .name = "MBX flash APPLICATION partition",
47 .offset = (BOOT_PARTITION_SIZE_KiB+KERNEL_PARTITION_SIZE_KiB)*1024 } 47 .offset = (BOOT_PARTITION_SIZE_KiB+KERNEL_PARTITION_SIZE_KiB)*1024 }
48}; 48};
49 49
50 50
51static struct mtd_info *mymtd; 51static struct mtd_info *mymtd;
52 52
diff --git a/drivers/mtd/maps/mtx-1_flash.c b/drivers/mtd/maps/mtx-1_flash.c
new file mode 100644
index 000000000000..d1e66e186746
--- /dev/null
+++ b/drivers/mtd/maps/mtx-1_flash.c
@@ -0,0 +1,96 @@
1/*
2 * Flash memory access on 4G Systems MTX-1 boards
3 *
4 * $Id: mtx-1_flash.c,v 1.2 2005/11/07 11:14:27 gleixner Exp $
5 *
6 * (C) 2005 Bruno Randolf <bruno.randolf@4g-systems.biz>
7 * (C) 2005 Jörn Engel <joern@wohnheim.fh-wedel.de>
8 *
9 */
10
11#include <linux/config.h>
12#include <linux/module.h>
13#include <linux/types.h>
14#include <linux/init.h>
15#include <linux/kernel.h>
16
17#include <linux/mtd/mtd.h>
18#include <linux/mtd/map.h>
19#include <linux/mtd/partitions.h>
20
21#include <asm/io.h>
22
23static struct map_info mtx1_map = {
24 .name = "MTX-1 flash",
25 .bankwidth = 4,
26 .size = 0x2000000,
27 .phys = 0x1E000000,
28};
29
30static struct mtd_partition mtx1_partitions[] = {
31 {
32 .name = "filesystem",
33 .size = 0x01C00000,
34 .offset = 0,
35 },{
36 .name = "yamon",
37 .size = 0x00100000,
38 .offset = MTDPART_OFS_APPEND,
39 .mask_flags = MTD_WRITEABLE,
40 },{
41 .name = "kernel",
42 .size = 0x002c0000,
43 .offset = MTDPART_OFS_APPEND,
44 },{
45 .name = "yamon env",
46 .size = 0x00040000,
47 .offset = MTDPART_OFS_APPEND,
48 }
49};
50
51static struct mtd_info *mtx1_mtd;
52
53int __init mtx1_mtd_init(void)
54{
55 int ret = -ENXIO;
56
57 simple_map_init(&mtx1_map);
58
59 mtx1_map.virt = ioremap(mtx1_map.phys, mtx1_map.size);
60 if (!mtx1_map.virt)
61 return -EIO;
62
63 mtx1_mtd = do_map_probe("cfi_probe", &mtx1_map);
64 if (!mtx1_mtd)
65 goto err;
66
67 mtx1_mtd->owner = THIS_MODULE;
68
69 ret = add_mtd_partitions(mtx1_mtd, mtx1_partitions,
70 ARRAY_SIZE(mtx1_partitions));
71 if (ret)
72 goto err;
73
74 return 0;
75
76err:
77 iounmap(mtx1_map.virt);
78 return ret;
79}
80
81static void __exit mtx1_mtd_cleanup(void)
82{
83 if (mtx1_mtd) {
84 del_mtd_partitions(mtx1_mtd);
85 map_destroy(mtx1_mtd);
86 }
87 if (mtx1_map.virt)
88 iounmap(mtx1_map.virt);
89}
90
91module_init(mtx1_mtd_init);
92module_exit(mtx1_mtd_cleanup);
93
94MODULE_AUTHOR("Bruno Randolf <bruno.randolf@4g-systems.biz>");
95MODULE_DESCRIPTION("MTX-1 flash map");
96MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/maps/netsc520.c b/drivers/mtd/maps/netsc520.c
index ab7e6358d281..33060a315722 100644
--- a/drivers/mtd/maps/netsc520.c
+++ b/drivers/mtd/maps/netsc520.c
@@ -3,7 +3,7 @@
3 * Copyright (C) 2001 Mark Langsdorf (mark.langsdorf@amd.com) 3 * Copyright (C) 2001 Mark Langsdorf (mark.langsdorf@amd.com)
4 * based on sc520cdp.c by Sysgo Real-Time Solutions GmbH 4 * based on sc520cdp.c by Sysgo Real-Time Solutions GmbH
5 * 5 *
6 * $Id: netsc520.c,v 1.13 2004/11/28 09:40:40 dwmw2 Exp $ 6 * $Id: netsc520.c,v 1.14 2005/11/07 11:14:27 gleixner Exp $
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
@@ -38,7 +38,7 @@
38** The single, 16 megabyte flash bank is divided into four virtual 38** The single, 16 megabyte flash bank is divided into four virtual
39** partitions. The first partition is 768 KiB and is intended to 39** partitions. The first partition is 768 KiB and is intended to
40** store the kernel image loaded by the bootstrap loader. The second 40** store the kernel image loaded by the bootstrap loader. The second
41** partition is 256 KiB and holds the BIOS image. The third 41** partition is 256 KiB and holds the BIOS image. The third
42** partition is 14.5 MiB and is intended for the flash file system 42** partition is 14.5 MiB and is intended for the flash file system
43** image. The last partition is 512 KiB and contains another copy 43** image. The last partition is 512 KiB and contains another copy
44** of the BIOS image and the reset vector. 44** of the BIOS image and the reset vector.
@@ -51,28 +51,28 @@
51** recoverable afterwards. 51** recoverable afterwards.
52*/ 52*/
53 53
54/* partition_info gives details on the logical partitions that the split the 54/* partition_info gives details on the logical partitions that the split the
55 * single flash device into. If the size if zero we use up to the end of the 55 * single flash device into. If the size if zero we use up to the end of the
56 * device. */ 56 * device. */
57static struct mtd_partition partition_info[]={ 57static struct mtd_partition partition_info[]={
58 { 58 {
59 .name = "NetSc520 boot kernel", 59 .name = "NetSc520 boot kernel",
60 .offset = 0, 60 .offset = 0,
61 .size = 0xc0000 61 .size = 0xc0000
62 }, 62 },
63 { 63 {
64 .name = "NetSc520 Low BIOS", 64 .name = "NetSc520 Low BIOS",
65 .offset = 0xc0000, 65 .offset = 0xc0000,
66 .size = 0x40000 66 .size = 0x40000
67 }, 67 },
68 { 68 {
69 .name = "NetSc520 file system", 69 .name = "NetSc520 file system",
70 .offset = 0x100000, 70 .offset = 0x100000,
71 .size = 0xe80000 71 .size = 0xe80000
72 }, 72 },
73 { 73 {
74 .name = "NetSc520 High BIOS", 74 .name = "NetSc520 High BIOS",
75 .offset = 0xf80000, 75 .offset = 0xf80000,
76 .size = 0x80000 76 .size = 0x80000
77 }, 77 },
78}; 78};
@@ -114,7 +114,7 @@ static int __init init_netsc520(void)
114 iounmap(netsc520_map.virt); 114 iounmap(netsc520_map.virt);
115 return -ENXIO; 115 return -ENXIO;
116 } 116 }
117 117
118 mymtd->owner = THIS_MODULE; 118 mymtd->owner = THIS_MODULE;
119 add_mtd_partitions( mymtd, partition_info, NUM_PARTITIONS ); 119 add_mtd_partitions( mymtd, partition_info, NUM_PARTITIONS );
120 return 0; 120 return 0;
diff --git a/drivers/mtd/maps/nettel.c b/drivers/mtd/maps/nettel.c
index 61be5a4148c9..f00ee7e54dba 100644
--- a/drivers/mtd/maps/nettel.c
+++ b/drivers/mtd/maps/nettel.c
@@ -6,7 +6,7 @@
6 * (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com) 6 * (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com)
7 * (C) Copyright 2001-2002, SnapGear (www.snapgear.com) 7 * (C) Copyright 2001-2002, SnapGear (www.snapgear.com)
8 * 8 *
9 * $Id: nettel.c,v 1.10 2005/01/05 17:11:29 dwmw2 Exp $ 9 * $Id: nettel.c,v 1.11 2005/11/07 11:14:27 gleixner Exp $
10 */ 10 */
11 11
12/****************************************************************************/ 12/****************************************************************************/
@@ -143,7 +143,7 @@ static int nettel_reboot_notifier(struct notifier_block *nb, unsigned long val,
143{ 143{
144 struct cfi_private *cfi = nettel_intel_map.fldrv_priv; 144 struct cfi_private *cfi = nettel_intel_map.fldrv_priv;
145 unsigned long b; 145 unsigned long b;
146 146
147 /* Make sure all FLASH chips are put back into read mode */ 147 /* Make sure all FLASH chips are put back into read mode */
148 for (b = 0; (b < nettel_intel_partitions[3].size); b += 0x100000) { 148 for (b = 0; (b < nettel_intel_partitions[3].size); b += 0x100000) {
149 cfi_send_gen_cmd(0xff, 0x55, b, &nettel_intel_map, cfi, 149 cfi_send_gen_cmd(0xff, 0x55, b, &nettel_intel_map, cfi,
@@ -199,7 +199,7 @@ int nettel_eraseconfig(void)
199 199
200 schedule(); /* Wait for erase to finish. */ 200 schedule(); /* Wait for erase to finish. */
201 remove_wait_queue(&wait_q, &wait); 201 remove_wait_queue(&wait_q, &wait);
202 202
203 put_mtd_device(mtd); 203 put_mtd_device(mtd);
204 } 204 }
205 205
@@ -430,7 +430,7 @@ int __init nettel_init(void)
430 nettel_intel_partitions[1].size = (intel0size + intel1size) - 430 nettel_intel_partitions[1].size = (intel0size + intel1size) -
431 (1024*1024 + intel_mtd->erasesize); 431 (1024*1024 + intel_mtd->erasesize);
432 nettel_intel_partitions[3].size = intel0size + intel1size; 432 nettel_intel_partitions[3].size = intel0size + intel1size;
433 nettel_intel_partitions[4].offset = 433 nettel_intel_partitions[4].offset =
434 (intel0size + intel1size) - intel_mtd->erasesize; 434 (intel0size + intel1size) - intel_mtd->erasesize;
435 nettel_intel_partitions[4].size = intel_mtd->erasesize; 435 nettel_intel_partitions[4].size = intel_mtd->erasesize;
436 nettel_intel_partitions[5].offset = 436 nettel_intel_partitions[5].offset =
diff --git a/drivers/mtd/maps/ocelot.c b/drivers/mtd/maps/ocelot.c
index 82c3070678c5..6977963d7897 100644
--- a/drivers/mtd/maps/ocelot.c
+++ b/drivers/mtd/maps/ocelot.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: ocelot.c,v 1.16 2005/01/05 18:05:13 dwmw2 Exp $ 2 * $Id: ocelot.c,v 1.17 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * Flash on Momenco Ocelot 4 * Flash on Momenco Ocelot
5 */ 5 */
@@ -31,7 +31,7 @@ static void ocelot_ram_write(struct mtd_info *mtd, loff_t to, size_t len, size_t
31 struct map_info *map = mtd->priv; 31 struct map_info *map = mtd->priv;
32 size_t done = 0; 32 size_t done = 0;
33 33
34 /* If we use memcpy, it does word-wide writes. Even though we told the 34 /* If we use memcpy, it does word-wide writes. Even though we told the
35 GT64120A that it's an 8-bit wide region, word-wide writes don't work. 35 GT64120A that it's an 8-bit wide region, word-wide writes don't work.
36 We end up just writing the first byte of the four to all four bytes. 36 We end up just writing the first byte of the four to all four bytes.
37 So we have this loop instead */ 37 So we have this loop instead */
@@ -68,7 +68,7 @@ static int __init init_ocelot_maps(void)
68 int nr_parts; 68 int nr_parts;
69 unsigned char brd_status; 69 unsigned char brd_status;
70 70
71 printk(KERN_INFO "Momenco Ocelot MTD mappings: Flash 0x%x at 0x%x, NVRAM 0x%x at 0x%x\n", 71 printk(KERN_INFO "Momenco Ocelot MTD mappings: Flash 0x%x at 0x%x, NVRAM 0x%x at 0x%x\n",
72 FLASH_WINDOW_SIZE, FLASH_WINDOW_ADDR, NVRAM_WINDOW_SIZE, NVRAM_WINDOW_ADDR); 72 FLASH_WINDOW_SIZE, FLASH_WINDOW_ADDR, NVRAM_WINDOW_SIZE, NVRAM_WINDOW_ADDR);
73 73
74 /* First check whether the flash jumper is present */ 74 /* First check whether the flash jumper is present */
@@ -138,8 +138,8 @@ static int __init init_ocelot_maps(void)
138 add_mtd_device(flash_mtd); 138 add_mtd_device(flash_mtd);
139 139
140 return 0; 140 return 0;
141 141
142 fail3: 142 fail3:
143 iounmap((void *)ocelot_flash_map.virt); 143 iounmap((void *)ocelot_flash_map.virt);
144 if (ocelot_flash_map.cached) 144 if (ocelot_flash_map.cached)
145 iounmap((void *)ocelot_flash_map.cached); 145 iounmap((void *)ocelot_flash_map.cached);
diff --git a/drivers/mtd/maps/octagon-5066.c b/drivers/mtd/maps/octagon-5066.c
index e5ff83de420e..a6642db3d325 100644
--- a/drivers/mtd/maps/octagon-5066.c
+++ b/drivers/mtd/maps/octagon-5066.c
@@ -1,12 +1,12 @@
1// $Id: octagon-5066.c,v 1.26 2004/07/12 22:38:29 dwmw2 Exp $ 1// $Id: octagon-5066.c,v 1.28 2005/11/07 11:14:27 gleixner Exp $
2/* ###################################################################### 2/* ######################################################################
3 3
4 Octagon 5066 MTD Driver. 4 Octagon 5066 MTD Driver.
5 5
6 The Octagon 5066 is a SBC based on AMD's 586-WB running at 133 MHZ. It 6 The Octagon 5066 is a SBC based on AMD's 586-WB running at 133 MHZ. It
7 comes with a builtin AMD 29F016 flash chip and a socketed EEPROM that 7 comes with a builtin AMD 29F016 flash chip and a socketed EEPROM that
8 is replacable by flash. Both units are mapped through a multiplexer 8 is replacable by flash. Both units are mapped through a multiplexer
9 into a 32k memory window at 0xe8000. The control register for the 9 into a 32k memory window at 0xe8000. The control register for the
10 multiplexing unit is located at IO 0x208 with a bit map of 10 multiplexing unit is located at IO 0x208 with a bit map of
11 0-5 Page Selection in 32k increments 11 0-5 Page Selection in 32k increments
12 6-7 Device selection: 12 6-7 Device selection:
@@ -14,14 +14,14 @@
14 01 SSD 0 (Socket) 14 01 SSD 0 (Socket)
15 10 SSD 1 (Flash chip) 15 10 SSD 1 (Flash chip)
16 11 undefined 16 11 undefined
17 17
18 On each SSD, the first 128k is reserved for use by the bios 18 On each SSD, the first 128k is reserved for use by the bios
19 (actually it IS the bios..) This only matters if you are booting off the 19 (actually it IS the bios..) This only matters if you are booting off the
20 flash, you must not put a file system starting there. 20 flash, you must not put a file system starting there.
21 21
22 The driver tries to do a detection algorithm to guess what sort of devices 22 The driver tries to do a detection algorithm to guess what sort of devices
23 are plugged into the sockets. 23 are plugged into the sockets.
24 24
25 ##################################################################### */ 25 ##################################################################### */
26 26
27#include <linux/module.h> 27#include <linux/module.h>
@@ -56,7 +56,7 @@ static void __oct5066_page(struct map_info *map, __u8 byte)
56static inline void oct5066_page(struct map_info *map, unsigned long ofs) 56static inline void oct5066_page(struct map_info *map, unsigned long ofs)
57{ 57{
58 __u8 byte = map->map_priv_1 | (ofs >> WINDOW_SHIFT); 58 __u8 byte = map->map_priv_1 | (ofs >> WINDOW_SHIFT);
59 59
60 if (page_n_dev != byte) 60 if (page_n_dev != byte)
61 __oct5066_page(map, byte); 61 __oct5066_page(map, byte);
62} 62}
@@ -78,7 +78,7 @@ static void oct5066_copy_from(struct map_info *map, void *to, unsigned long from
78 unsigned long thislen = len; 78 unsigned long thislen = len;
79 if (len > (WINDOW_LENGTH - (from & WINDOW_MASK))) 79 if (len > (WINDOW_LENGTH - (from & WINDOW_MASK)))
80 thislen = WINDOW_LENGTH-(from & WINDOW_MASK); 80 thislen = WINDOW_LENGTH-(from & WINDOW_MASK);
81 81
82 spin_lock(&oct5066_spin); 82 spin_lock(&oct5066_spin);
83 oct5066_page(map, from); 83 oct5066_page(map, from);
84 memcpy_fromio(to, iomapadr + from, thislen); 84 memcpy_fromio(to, iomapadr + from, thislen);
@@ -103,7 +103,7 @@ static void oct5066_copy_to(struct map_info *map, unsigned long to, const void *
103 unsigned long thislen = len; 103 unsigned long thislen = len;
104 if (len > (WINDOW_LENGTH - (to & WINDOW_MASK))) 104 if (len > (WINDOW_LENGTH - (to & WINDOW_MASK)))
105 thislen = WINDOW_LENGTH-(to & WINDOW_MASK); 105 thislen = WINDOW_LENGTH-(to & WINDOW_MASK);
106 106
107 spin_lock(&oct5066_spin); 107 spin_lock(&oct5066_spin);
108 oct5066_page(map, to); 108 oct5066_page(map, to);
109 memcpy_toio(iomapadr + to, from, thislen); 109 memcpy_toio(iomapadr + to, from, thislen);
@@ -144,7 +144,7 @@ static struct mtd_info *oct5066_mtd[2] = {NULL, NULL};
144// OctProbe - Sense if this is an octagon card 144// OctProbe - Sense if this is an octagon card
145// --------------------------------------------------------------------- 145// ---------------------------------------------------------------------
146/* Perform a simple validity test, we map the window select SSD0 and 146/* Perform a simple validity test, we map the window select SSD0 and
147 change pages while monitoring the window. A change in the window, 147 change pages while monitoring the window. A change in the window,
148 controlled by the PAGE_IO port is a functioning 5066 board. This will 148 controlled by the PAGE_IO port is a functioning 5066 board. This will
149 fail if the thing in the socket is set to a uniform value. */ 149 fail if the thing in the socket is set to a uniform value. */
150static int __init OctProbe(void) 150static int __init OctProbe(void)
@@ -161,13 +161,13 @@ static int __init OctProbe(void)
161 Values[I%10] = readl(iomapadr); 161 Values[I%10] = readl(iomapadr);
162 if (I > 0 && Values[I%10] == Values[0]) 162 if (I > 0 && Values[I%10] == Values[0])
163 return -EAGAIN; 163 return -EAGAIN;
164 } 164 }
165 else 165 else
166 { 166 {
167 // Make sure we get the same values on the second pass 167 // Make sure we get the same values on the second pass
168 if (Values[I%10] != readl(iomapadr)) 168 if (Values[I%10] != readl(iomapadr))
169 return -EAGAIN; 169 return -EAGAIN;
170 } 170 }
171 } 171 }
172 return 0; 172 return 0;
173} 173}
@@ -207,11 +207,11 @@ int __init init_oct5066(void)
207 ret = -EAGAIN; 207 ret = -EAGAIN;
208 goto out_unmap; 208 goto out_unmap;
209 } 209 }
210 210
211 // Print out our little header.. 211 // Print out our little header..
212 printk("Octagon 5066 SSD IO:0x%x MEM:0x%x-0x%x\n",PAGE_IO,WINDOW_START, 212 printk("Octagon 5066 SSD IO:0x%x MEM:0x%x-0x%x\n",PAGE_IO,WINDOW_START,
213 WINDOW_START+WINDOW_LENGTH); 213 WINDOW_START+WINDOW_LENGTH);
214 214
215 for (i=0; i<2; i++) { 215 for (i=0; i<2; i++) {
216 oct5066_mtd[i] = do_map_probe("cfi_probe", &oct5066_map[i]); 216 oct5066_mtd[i] = do_map_probe("cfi_probe", &oct5066_map[i]);
217 if (!oct5066_mtd[i]) 217 if (!oct5066_mtd[i])
@@ -225,11 +225,11 @@ int __init init_oct5066(void)
225 add_mtd_device(oct5066_mtd[i]); 225 add_mtd_device(oct5066_mtd[i]);
226 } 226 }
227 } 227 }
228 228
229 if (!oct5066_mtd[0] && !oct5066_mtd[1]) { 229 if (!oct5066_mtd[0] && !oct5066_mtd[1]) {
230 cleanup_oct5066(); 230 cleanup_oct5066();
231 return -ENXIO; 231 return -ENXIO;
232 } 232 }
233 233
234 return 0; 234 return 0;
235 235
diff --git a/drivers/mtd/maps/omap-toto-flash.c b/drivers/mtd/maps/omap-toto-flash.c
index 763304154a92..dc3765270057 100644
--- a/drivers/mtd/maps/omap-toto-flash.c
+++ b/drivers/mtd/maps/omap-toto-flash.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * (C) 2002 MontVista Software, Inc. 6 * (C) 2002 MontVista Software, Inc.
7 * 7 *
8 * $Id: omap-toto-flash.c,v 1.3 2004/09/16 23:27:13 gleixner Exp $ 8 * $Id: omap-toto-flash.c,v 1.5 2005/11/07 11:14:27 gleixner Exp $
9 */ 9 */
10 10
11#include <linux/config.h> 11#include <linux/config.h>
@@ -38,7 +38,7 @@ static struct map_info omap_toto_map_flash = {
38 .virt = (void __iomem *)OMAP_TOTO_FLASH_BASE, 38 .virt = (void __iomem *)OMAP_TOTO_FLASH_BASE,
39}; 39};
40 40
41 41
42static struct mtd_partition toto_flash_partitions[] = { 42static struct mtd_partition toto_flash_partitions[] = {
43 { 43 {
44 .name = "BootLoader", 44 .name = "BootLoader",
@@ -54,21 +54,21 @@ static struct mtd_partition toto_flash_partitions[] = {
54 .name = "EnvArea", /* bottom 64KiB for env vars */ 54 .name = "EnvArea", /* bottom 64KiB for env vars */
55 .size = MTDPART_SIZ_FULL, 55 .size = MTDPART_SIZ_FULL,
56 .offset = MTDPART_OFS_APPEND, 56 .offset = MTDPART_OFS_APPEND,
57 } 57 }
58}; 58};
59 59
60static struct mtd_partition *parsed_parts; 60static struct mtd_partition *parsed_parts;
61 61
62static struct mtd_info *flash_mtd; 62static struct mtd_info *flash_mtd;
63 63
64static int __init init_flash (void) 64static int __init init_flash (void)
65{ 65{
66 66
67 struct mtd_partition *parts; 67 struct mtd_partition *parts;
68 int nb_parts = 0; 68 int nb_parts = 0;
69 int parsed_nr_parts = 0; 69 int parsed_nr_parts = 0;
70 const char *part_type; 70 const char *part_type;
71 71
72 /* 72 /*
73 * Static partition definition selection 73 * Static partition definition selection
74 */ 74 */
@@ -89,7 +89,7 @@ static int __init init_flash (void)
89 flash_mtd = do_map_probe("jedec_probe", &omap_toto_map_flash); 89 flash_mtd = do_map_probe("jedec_probe", &omap_toto_map_flash);
90 if (!flash_mtd) 90 if (!flash_mtd)
91 return -ENXIO; 91 return -ENXIO;
92 92
93 if (parsed_nr_parts > 0) { 93 if (parsed_nr_parts > 0) {
94 parts = parsed_parts; 94 parts = parsed_parts;
95 nb_parts = parsed_nr_parts; 95 nb_parts = parsed_nr_parts;
@@ -108,8 +108,8 @@ static int __init init_flash (void)
108 } 108 }
109 return 0; 109 return 0;
110} 110}
111 111
112int __init omap_toto_mtd_init(void) 112int __init omap_toto_mtd_init(void)
113{ 113{
114 int status; 114 int status;
115 115
@@ -119,7 +119,7 @@ int __init omap_toto_mtd_init(void)
119 return status; 119 return status;
120} 120}
121 121
122static void __exit omap_toto_mtd_cleanup(void) 122static void __exit omap_toto_mtd_cleanup(void)
123{ 123{
124 if (flash_mtd) { 124 if (flash_mtd) {
125 del_mtd_partitions(flash_mtd); 125 del_mtd_partitions(flash_mtd);
diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c
index 7f370bb794fe..fd3b4a5fc207 100644
--- a/drivers/mtd/maps/omap_nor.c
+++ b/drivers/mtd/maps/omap_nor.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2001-2002 MontaVista Software Inc. 4 * Copyright (C) 2001-2002 MontaVista Software Inc.
5 * Copyright (C) 2003-2004 Texas Instruments 5 * Copyright (C) 2003-2004 Texas Instruments
6 * Copyright (C) 2004 Nokia Corporation 6 * Copyright (C) 2004 Nokia Corporation
7 * 7 *
8 * Assembled using driver code copyright the companies above 8 * Assembled using driver code copyright the companies above
9 * and written by David Brownell, Jian Zhang <jzhang@ti.com>, 9 * and written by David Brownell, Jian Zhang <jzhang@ti.com>,
diff --git a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c
index d9c64e99ee32..8b3570b09095 100644
--- a/drivers/mtd/maps/pci.c
+++ b/drivers/mtd/maps/pci.c
@@ -7,8 +7,8 @@
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 * 9 *
10 * $Id: pci.c,v 1.10 2005/03/18 14:04:35 gleixner Exp $ 10 * $Id: pci.c,v 1.13 2005/11/07 11:14:27 gleixner Exp $
11 * 11 *
12 * Generic PCI memory map driver. We support the following boards: 12 * Generic PCI memory map driver. We support the following boards:
13 * - Intel IQ80310 ATU. 13 * - Intel IQ80310 ATU.
14 * - Intel EBSA285 (blank rom programming mode). Tested working 27/09/2001 14 * - Intel EBSA285 (blank rom programming mode). Tested working 27/09/2001
@@ -38,7 +38,7 @@ struct map_pci_info {
38 void (*exit)(struct pci_dev *dev, struct map_pci_info *map); 38 void (*exit)(struct pci_dev *dev, struct map_pci_info *map);
39 unsigned long (*translate)(struct map_pci_info *map, unsigned long ofs); 39 unsigned long (*translate)(struct map_pci_info *map, unsigned long ofs);
40 struct pci_dev *dev; 40 struct pci_dev *dev;
41}; 41};
42 42
43static map_word mtd_pci_read8(struct map_info *_map, unsigned long ofs) 43static map_word mtd_pci_read8(struct map_info *_map, unsigned long ofs)
44{ 44{
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c
index ff7c50d10180..af24216a0626 100644
--- a/drivers/mtd/maps/pcmciamtd.c
+++ b/drivers/mtd/maps/pcmciamtd.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: pcmciamtd.c,v 1.51 2004/07/12 22:38:29 dwmw2 Exp $ 2 * $Id: pcmciamtd.c,v 1.55 2005/11/07 11:14:28 gleixner Exp $
3 * 3 *
4 * pcmciamtd.c - MTD driver for PCMCIA flash memory cards 4 * pcmciamtd.c - MTD driver for PCMCIA flash memory cards
5 * 5 *
@@ -48,7 +48,7 @@ static const int debug = 0;
48 48
49 49
50#define DRIVER_DESC "PCMCIA Flash memory card driver" 50#define DRIVER_DESC "PCMCIA Flash memory card driver"
51#define DRIVER_VERSION "$Revision: 1.51 $" 51#define DRIVER_VERSION "$Revision: 1.55 $"
52 52
53/* Size of the PCMCIA address space: 26 bits = 64 MB */ 53/* Size of the PCMCIA address space: 26 bits = 64 MB */
54#define MAX_PCMCIA_ADDR 0x4000000 54#define MAX_PCMCIA_ADDR 0x4000000
@@ -176,7 +176,7 @@ static void pcmcia_copy_from_remap(struct map_info *map, void *to, unsigned long
176 176
177 if(toread > len) 177 if(toread > len)
178 toread = len; 178 toread = len;
179 179
180 addr = remap_window(map, from); 180 addr = remap_window(map, from);
181 if(!addr) 181 if(!addr)
182 return; 182 return;
@@ -386,7 +386,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
386 cs_error(link->handle, ParseTuple, rc); 386 cs_error(link->handle, ParseTuple, rc);
387 break; 387 break;
388 } 388 }
389 389
390 switch(tuple.TupleCode) { 390 switch(tuple.TupleCode) {
391 case CISTPL_FORMAT: { 391 case CISTPL_FORMAT: {
392 cistpl_format_t *t = &parse.format; 392 cistpl_format_t *t = &parse.format;
@@ -394,9 +394,9 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
394 DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u", 394 DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u",
395 t->type, t->edc, t->offset, t->length); 395 t->type, t->edc, t->offset, t->length);
396 break; 396 break;
397 397
398 } 398 }
399 399
400 case CISTPL_DEVICE: { 400 case CISTPL_DEVICE: {
401 cistpl_device_t *t = &parse.device; 401 cistpl_device_t *t = &parse.device;
402 int i; 402 int i;
@@ -410,7 +410,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
410 } 410 }
411 break; 411 break;
412 } 412 }
413 413
414 case CISTPL_VERS_1: { 414 case CISTPL_VERS_1: {
415 cistpl_vers_1_t *t = &parse.version_1; 415 cistpl_vers_1_t *t = &parse.version_1;
416 int i; 416 int i;
@@ -425,7 +425,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
425 DEBUG(2, "Found name: %s", dev->mtd_name); 425 DEBUG(2, "Found name: %s", dev->mtd_name);
426 break; 426 break;
427 } 427 }
428 428
429 case CISTPL_JEDEC_C: { 429 case CISTPL_JEDEC_C: {
430 cistpl_jedec_t *t = &parse.jedec; 430 cistpl_jedec_t *t = &parse.jedec;
431 int i; 431 int i;
@@ -434,7 +434,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
434 } 434 }
435 break; 435 break;
436 } 436 }
437 437
438 case CISTPL_DEVICE_GEO: { 438 case CISTPL_DEVICE_GEO: {
439 cistpl_device_geo_t *t = &parse.device_geo; 439 cistpl_device_geo_t *t = &parse.device_geo;
440 int i; 440 int i;
@@ -449,11 +449,11 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
449 } 449 }
450 break; 450 break;
451 } 451 }
452 452
453 default: 453 default:
454 DEBUG(2, "Unknown tuple code %d", tuple.TupleCode); 454 DEBUG(2, "Unknown tuple code %d", tuple.TupleCode);
455 } 455 }
456 456
457 rc = pcmcia_get_next_tuple(link->handle, &tuple); 457 rc = pcmcia_get_next_tuple(link->handle, &tuple);
458 } 458 }
459 if(!dev->pcmcia_map.size) 459 if(!dev->pcmcia_map.size)
@@ -470,7 +470,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
470 if(bankwidth) { 470 if(bankwidth) {
471 dev->pcmcia_map.bankwidth = bankwidth; 471 dev->pcmcia_map.bankwidth = bankwidth;
472 DEBUG(2, "bankwidth forced to %d", bankwidth); 472 DEBUG(2, "bankwidth forced to %d", bankwidth);
473 } 473 }
474 474
475 dev->pcmcia_map.name = dev->mtd_name; 475 dev->pcmcia_map.name = dev->mtd_name;
476 if(!dev->mtd_name[0]) { 476 if(!dev->mtd_name[0]) {
@@ -568,7 +568,7 @@ static void pcmciamtd_config(dev_link_t *link)
568 return; 568 return;
569 } 569 }
570 DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10); 570 DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10);
571 571
572 /* Get write protect status */ 572 /* Get write protect status */
573 CS_CHECK(GetStatus, pcmcia_get_status(link->handle, &status)); 573 CS_CHECK(GetStatus, pcmcia_get_status(link->handle, &status));
574 DEBUG(2, "status value: 0x%x window handle = 0x%8.8lx", 574 DEBUG(2, "status value: 0x%x window handle = 0x%8.8lx",
@@ -624,11 +624,11 @@ static void pcmciamtd_config(dev_link_t *link)
624 mtd = do_map_probe(probes[i], &dev->pcmcia_map); 624 mtd = do_map_probe(probes[i], &dev->pcmcia_map);
625 if(mtd) 625 if(mtd)
626 break; 626 break;
627 627
628 DEBUG(1, "FAILED: %s", probes[i]); 628 DEBUG(1, "FAILED: %s", probes[i]);
629 } 629 }
630 } 630 }
631 631
632 if(!mtd) { 632 if(!mtd) {
633 DEBUG(1, "Cant find an MTD"); 633 DEBUG(1, "Cant find an MTD");
634 pcmciamtd_release(link); 634 pcmciamtd_release(link);
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c
index b853670bfb81..9ee760f97bc6 100644
--- a/drivers/mtd/maps/physmap.c
+++ b/drivers/mtd/maps/physmap.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: physmap.c,v 1.37 2004/11/28 09:40:40 dwmw2 Exp $ 2 * $Id: physmap.c,v 1.38 2005/11/07 11:14:28 gleixner Exp $
3 * 3 *
4 * Normal mappings of chips in physical memory 4 * Normal mappings of chips in physical memory
5 * 5 *
@@ -69,7 +69,7 @@ static int __init init_physmap(void)
69 mymtd->owner = THIS_MODULE; 69 mymtd->owner = THIS_MODULE;
70 70
71#ifdef CONFIG_MTD_PARTITIONS 71#ifdef CONFIG_MTD_PARTITIONS
72 mtd_parts_nb = parse_mtd_partitions(mymtd, part_probes, 72 mtd_parts_nb = parse_mtd_partitions(mymtd, part_probes,
73 &mtd_parts, 0); 73 &mtd_parts, 0);
74 74
75 if (mtd_parts_nb > 0) 75 if (mtd_parts_nb > 0)
@@ -78,9 +78,9 @@ static int __init init_physmap(void)
78 return 0; 78 return 0;
79 } 79 }
80 80
81 if (num_physmap_partitions != 0) 81 if (num_physmap_partitions != 0)
82 { 82 {
83 printk(KERN_NOTICE 83 printk(KERN_NOTICE
84 "Using physmap partition definition\n"); 84 "Using physmap partition definition\n");
85 add_mtd_partitions (mymtd, physmap_partitions, num_physmap_partitions); 85 add_mtd_partitions (mymtd, physmap_partitions, num_physmap_partitions);
86 return 0; 86 return 0;
diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c
index 104576b5be34..a02eed94a231 100644
--- a/drivers/mtd/maps/plat-ram.c
+++ b/drivers/mtd/maps/plat-ram.c
@@ -6,7 +6,7 @@
6 * 6 *
7 * Generic platfrom device based RAM map 7 * Generic platfrom device based RAM map
8 * 8 *
9 * $Id: plat-ram.c,v 1.3 2005/03/19 22:41:27 gleixner Exp $ 9 * $Id: plat-ram.c,v 1.7 2005/11/07 11:14:28 gleixner Exp $
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by 12 * it under the terms of the GNU General Public License as published by
@@ -91,7 +91,7 @@ static int platram_remove(struct device *dev)
91 91
92 dev_dbg(dev, "removing device\n"); 92 dev_dbg(dev, "removing device\n");
93 93
94 if (info == NULL) 94 if (info == NULL)
95 return 0; 95 return 0;
96 96
97 if (info->mtd) { 97 if (info->mtd) {
@@ -118,7 +118,7 @@ static int platram_remove(struct device *dev)
118 118
119 if (info->map.virt != NULL) 119 if (info->map.virt != NULL)
120 iounmap(info->map.virt); 120 iounmap(info->map.virt);
121 121
122 kfree(info); 122 kfree(info);
123 123
124 return 0; 124 return 0;
@@ -139,7 +139,7 @@ static int platram_probe(struct device *dev)
139 int err = 0; 139 int err = 0;
140 140
141 dev_dbg(dev, "probe entered\n"); 141 dev_dbg(dev, "probe entered\n");
142 142
143 if (dev->platform_data == NULL) { 143 if (dev->platform_data == NULL) {
144 dev_err(dev, "no platform data supplied\n"); 144 dev_err(dev, "no platform data supplied\n");
145 err = -ENOENT; 145 err = -ENOENT;
@@ -177,7 +177,7 @@ static int platram_probe(struct device *dev)
177 177
178 info->map.phys = res->start; 178 info->map.phys = res->start;
179 info->map.size = (res->end - res->start) + 1; 179 info->map.size = (res->end - res->start) + 1;
180 info->map.name = pdata->mapname != NULL ? pdata->mapname : pd->name; 180 info->map.name = pdata->mapname != NULL ? pdata->mapname : (char *)pd->name;
181 info->map.bankwidth = pdata->bankwidth; 181 info->map.bankwidth = pdata->bankwidth;
182 182
183 /* register our usage of the memory area */ 183 /* register our usage of the memory area */
@@ -240,7 +240,7 @@ static int platram_probe(struct device *dev)
240 dev_err(dev, "add_mtd_device() failed\n"); 240 dev_err(dev, "add_mtd_device() failed\n");
241 err = -ENOMEM; 241 err = -ENOMEM;
242 } 242 }
243 243
244 dev_info(dev, "registered mtd device\n"); 244 dev_info(dev, "registered mtd device\n");
245 return err; 245 return err;
246 246
@@ -254,6 +254,7 @@ static int platram_probe(struct device *dev)
254 254
255static struct device_driver platram_driver = { 255static struct device_driver platram_driver = {
256 .name = "mtd-ram", 256 .name = "mtd-ram",
257 .owner = THIS_MODULE,
257 .bus = &platform_bus_type, 258 .bus = &platform_bus_type,
258 .probe = platram_probe, 259 .probe = platram_probe,
259 .remove = platram_remove, 260 .remove = platram_remove,
diff --git a/drivers/mtd/maps/pnc2000.c b/drivers/mtd/maps/pnc2000.c
index a0f43dad8985..d7e16c2d5c44 100644
--- a/drivers/mtd/maps/pnc2000.c
+++ b/drivers/mtd/maps/pnc2000.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * This code is GPL 6 * This code is GPL
7 * 7 *
8 * $Id: pnc2000.c,v 1.17 2004/11/16 18:29:02 dwmw2 Exp $ 8 * $Id: pnc2000.c,v 1.18 2005/11/07 11:14:28 gleixner Exp $
9 */ 9 */
10 10
11#include <linux/module.h> 11#include <linux/module.h>
@@ -21,7 +21,7 @@
21#define WINDOW_ADDR 0xbf000000 21#define WINDOW_ADDR 0xbf000000
22#define WINDOW_SIZE 0x00400000 22#define WINDOW_SIZE 0x00400000
23 23
24/* 24/*
25 * MAP DRIVER STUFF 25 * MAP DRIVER STUFF
26 */ 26 */
27 27
@@ -36,7 +36,7 @@ static struct map_info pnc_map = {
36 36
37 37
38/* 38/*
39 * MTD 'PARTITIONING' STUFF 39 * MTD 'PARTITIONING' STUFF
40 */ 40 */
41static struct mtd_partition pnc_partitions[3] = { 41static struct mtd_partition pnc_partitions[3] = {
42 { 42 {
@@ -56,7 +56,7 @@ static struct mtd_partition pnc_partitions[3] = {
56 } 56 }
57}; 57};
58 58
59/* 59/*
60 * This is the master MTD device for which all the others are just 60 * This is the master MTD device for which all the others are just
61 * auto-relocating aliases. 61 * auto-relocating aliases.
62 */ 62 */
diff --git a/drivers/mtd/maps/pq2fads.c b/drivers/mtd/maps/pq2fads.c
new file mode 100644
index 000000000000..fb78d87cc130
--- /dev/null
+++ b/drivers/mtd/maps/pq2fads.c
@@ -0,0 +1,88 @@
1/*
2 * drivers/mtd/maps/pq2fads.c
3 *
4 * Mapping for the flash SIMM on 8272ADS and PQ2FADS board
5 *
6 * Author: Vitaly Bordug <vbordug@ru.mvista.com>
7 *
8 * 2005 (c) MontaVista Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14#include <linux/module.h>
15#include <linux/types.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <asm/io.h>
19#include <asm/ppcboot.h>
20#include <linux/mtd/mtd.h>
21#include <linux/mtd/map.h>
22#include <linux/mtd/partitions.h>
23#include <linux/mtd/physmap.h>
24
25/*
26 NOTE: bank width and interleave relative to the installed flash
27 should have been chosen within MTD_CFI_GEOMETRY options.
28 */
29#define PQ2FADS_BANK_WIDTH 4
30
31static struct mtd_partition pq2fads_partitions[] = {
32 {
33#ifdef CONFIG_ADS8272
34 .name = "HRCW",
35 .size = 0x40000,
36 .offset = 0,
37 .mask_flags = MTD_WRITEABLE, /* force read-only */
38 }, {
39 .name = "User FS",
40 .size = 0x5c0000,
41 .offset = 0x40000,
42#else
43 .name = "User FS",
44 .size = 0x600000,
45 .offset = 0,
46#endif
47 }, {
48 .name = "uImage",
49 .size = 0x100000,
50 .offset = 0x600000,
51 .mask_flags = MTD_WRITEABLE, /* force read-only */
52 }, {
53 .name = "bootloader",
54 .size = 0x40000,
55 .offset = 0x700000,
56 .mask_flags = MTD_WRITEABLE, /* force read-only */
57 }, {
58 .name = "bootloader env",
59 .size = 0x40000,
60 .offset = 0x740000,
61 .mask_flags = MTD_WRITEABLE, /* force read-only */
62 }
63};
64
65
66/* pointer to MPC885ADS board info data */
67extern unsigned char __res[];
68
69static int __init init_pq2fads_mtd(void)
70{
71 bd_t *bd = (bd_t *)__res;
72 physmap_configure(bd->bi_flashstart, bd->bi_flashsize, PQ2FADS_BANK_WIDTH, NULL);
73
74 physmap_set_partitions(pq2fads_partitions,
75 sizeof (pq2fads_partitions) /
76 sizeof (pq2fads_partitions[0]));
77 return 0;
78}
79
80static void __exit cleanup_pq2fads_mtd(void)
81{
82}
83
84module_init(init_pq2fads_mtd);
85module_exit(cleanup_pq2fads_mtd);
86
87MODULE_LICENSE("GPL");
88MODULE_DESCRIPTION("MTD map and partitions for MPC8272ADS boards");
diff --git a/drivers/mtd/maps/redwood.c b/drivers/mtd/maps/redwood.c
index edd01ee4f90b..5b76ed886185 100644
--- a/drivers/mtd/maps/redwood.c
+++ b/drivers/mtd/maps/redwood.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: redwood.c,v 1.10 2004/11/04 13:24:15 gleixner Exp $ 2 * $Id: redwood.c,v 1.11 2005/11/07 11:14:28 gleixner Exp $
3 * 3 *
4 * drivers/mtd/maps/redwood.c 4 * drivers/mtd/maps/redwood.c
5 * 5 *
@@ -79,7 +79,7 @@ static struct mtd_partition redwood_flash_partitions[] = {
79 79
80#define RW_PART0_OF 0 80#define RW_PART0_OF 0
81#define RW_PART0_SZ 0x400000 /* 4 MiB data */ 81#define RW_PART0_SZ 0x400000 /* 4 MiB data */
82#define RW_PART1_OF RW_PART0_OF + RW_PART0_SZ 82#define RW_PART1_OF RW_PART0_OF + RW_PART0_SZ
83#define RW_PART1_SZ 0x10000 /* 64K VPD */ 83#define RW_PART1_SZ 0x10000 /* 64K VPD */
84#define RW_PART2_OF RW_PART1_OF + RW_PART1_SZ 84#define RW_PART2_OF RW_PART1_OF + RW_PART1_SZ
85#define RW_PART2_SZ 0x400000 - (0x10000 + 0x20000) 85#define RW_PART2_SZ 0x400000 - (0x10000 + 0x20000)
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
index a31f6ee8a4be..9e8bb1782be0 100644
--- a/drivers/mtd/maps/sa1100-flash.c
+++ b/drivers/mtd/maps/sa1100-flash.c
@@ -1,9 +1,9 @@
1/* 1/*
2 * Flash memory access on SA11x0 based devices 2 * Flash memory access on SA11x0 based devices
3 * 3 *
4 * (C) 2000 Nicolas Pitre <nico@cam.org> 4 * (C) 2000 Nicolas Pitre <nico@cam.org>
5 * 5 *
6 * $Id: sa1100-flash.c,v 1.47 2004/11/01 13:44:36 rmk Exp $ 6 * $Id: sa1100-flash.c,v 1.51 2005/11/07 11:14:28 gleixner Exp $
7 */ 7 */
8#include <linux/config.h> 8#include <linux/config.h>
9#include <linux/module.h> 9#include <linux/module.h>
diff --git a/drivers/mtd/maps/sbc8240.c b/drivers/mtd/maps/sbc8240.c
index da684d3384e9..225cdd9ba5b2 100644
--- a/drivers/mtd/maps/sbc8240.c
+++ b/drivers/mtd/maps/sbc8240.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * This code is GPLed 6 * This code is GPLed
7 * 7 *
8 * $Id: sbc8240.c,v 1.4 2004/07/12 22:38:29 dwmw2 Exp $ 8 * $Id: sbc8240.c,v 1.5 2005/11/07 11:14:28 gleixner Exp $
9 * 9 *
10 */ 10 */
11 11
@@ -205,7 +205,7 @@ int __init init_sbc8240_mtd (void)
205 } else { 205 } else {
206 printk (KERN_NOTICE MSG_PREFIX 206 printk (KERN_NOTICE MSG_PREFIX
207 "Using %s partition definition\n", sbc8240_part_banks[i].mtd_part->name); 207 "Using %s partition definition\n", sbc8240_part_banks[i].mtd_part->name);
208 add_mtd_partitions (sbc8240_mtd[i], 208 add_mtd_partitions (sbc8240_mtd[i],
209 sbc8240_part_banks[i].mtd_part, 209 sbc8240_part_banks[i].mtd_part,
210 sbc8240_part_banks[i].nums); 210 sbc8240_part_banks[i].nums);
211 } 211 }
diff --git a/drivers/mtd/maps/sbc_gxx.c b/drivers/mtd/maps/sbc_gxx.c
index 65add28bde14..7cc4041d096d 100644
--- a/drivers/mtd/maps/sbc_gxx.c
+++ b/drivers/mtd/maps/sbc_gxx.c
@@ -1,35 +1,35 @@
1/* sbc_gxx.c -- MTD map driver for Arcom Control Systems SBC-MediaGX, 1/* sbc_gxx.c -- MTD map driver for Arcom Control Systems SBC-MediaGX,
2 SBC-GXm and SBC-GX1 series boards. 2 SBC-GXm and SBC-GX1 series boards.
3 3
4 Copyright (C) 2001 Arcom Control System Ltd 4 Copyright (C) 2001 Arcom Control System Ltd
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by 7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or 8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version. 9 (at your option) any later version.
10 10
11 This program is distributed in the hope that it will be useful, 11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details. 14 GNU General Public License for more details.
15 15
16 You should have received a copy of the GNU General Public License 16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software 17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 19
20 $Id: sbc_gxx.c,v 1.33 2004/11/28 09:40:40 dwmw2 Exp $ 20 $Id: sbc_gxx.c,v 1.35 2005/11/07 11:14:28 gleixner Exp $
21 21
22The SBC-MediaGX / SBC-GXx has up to 16 MiB of 22The SBC-MediaGX / SBC-GXx has up to 16 MiB of
23Intel StrataFlash (28F320/28F640) in x8 mode. 23Intel StrataFlash (28F320/28F640) in x8 mode.
24 24
25This driver uses the CFI probe and Intel Extended Command Set drivers. 25This driver uses the CFI probe and Intel Extended Command Set drivers.
26 26
27The flash is accessed as follows: 27The flash is accessed as follows:
28 28
29 16 KiB memory window at 0xdc000-0xdffff 29 16 KiB memory window at 0xdc000-0xdffff
30 30
31 Two IO address locations for paging 31 Two IO address locations for paging
32 32
33 0x258 33 0x258
34 bit 0-7: address bit 14-21 34 bit 0-7: address bit 14-21
35 0x259 35 0x259
@@ -37,7 +37,7 @@ The flash is accessed as follows:
37 bit 7: 0 - reset/powered down 37 bit 7: 0 - reset/powered down
38 1 - device enabled 38 1 - device enabled
39 39
40The single flash device is divided into 3 partition which appear as 40The single flash device is divided into 3 partition which appear as
41separate MTD devices. 41separate MTD devices.
42 42
4325/04/2001 AJL (Arcom) Modified signon strings and partition sizes 4325/04/2001 AJL (Arcom) Modified signon strings and partition sizes
@@ -87,17 +87,17 @@ static volatile int page_in_window = -1; // Current page in window.
87static void __iomem *iomapadr; 87static void __iomem *iomapadr;
88static DEFINE_SPINLOCK(sbc_gxx_spin); 88static DEFINE_SPINLOCK(sbc_gxx_spin);
89 89
90/* partition_info gives details on the logical partitions that the split the 90/* partition_info gives details on the logical partitions that the split the
91 * single flash device into. If the size if zero we use up to the end of the 91 * single flash device into. If the size if zero we use up to the end of the
92 * device. */ 92 * device. */
93static struct mtd_partition partition_info[]={ 93static struct mtd_partition partition_info[]={
94 { .name = "SBC-GXx flash boot partition", 94 { .name = "SBC-GXx flash boot partition",
95 .offset = 0, 95 .offset = 0,
96 .size = BOOT_PARTITION_SIZE_KiB*1024 }, 96 .size = BOOT_PARTITION_SIZE_KiB*1024 },
97 { .name = "SBC-GXx flash data partition", 97 { .name = "SBC-GXx flash data partition",
98 .offset = BOOT_PARTITION_SIZE_KiB*1024, 98 .offset = BOOT_PARTITION_SIZE_KiB*1024,
99 .size = (DATA_PARTITION_SIZE_KiB)*1024 }, 99 .size = (DATA_PARTITION_SIZE_KiB)*1024 },
100 { .name = "SBC-GXx flash application partition", 100 { .name = "SBC-GXx flash application partition",
101 .offset = (BOOT_PARTITION_SIZE_KiB+DATA_PARTITION_SIZE_KiB)*1024 } 101 .offset = (BOOT_PARTITION_SIZE_KiB+DATA_PARTITION_SIZE_KiB)*1024 }
102}; 102};
103 103
@@ -130,7 +130,7 @@ static void sbc_gxx_copy_from(struct map_info *map, void *to, unsigned long from
130 unsigned long thislen = len; 130 unsigned long thislen = len;
131 if (len > (WINDOW_LENGTH - (from & WINDOW_MASK))) 131 if (len > (WINDOW_LENGTH - (from & WINDOW_MASK)))
132 thislen = WINDOW_LENGTH-(from & WINDOW_MASK); 132 thislen = WINDOW_LENGTH-(from & WINDOW_MASK);
133 133
134 spin_lock(&sbc_gxx_spin); 134 spin_lock(&sbc_gxx_spin);
135 sbc_gxx_page(map, from); 135 sbc_gxx_page(map, from);
136 memcpy_fromio(to, iomapadr + (from & WINDOW_MASK), thislen); 136 memcpy_fromio(to, iomapadr + (from & WINDOW_MASK), thislen);
@@ -150,12 +150,12 @@ static void sbc_gxx_write8(struct map_info *map, map_word d, unsigned long adr)
150} 150}
151 151
152static void sbc_gxx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) 152static void sbc_gxx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
153{ 153{
154 while(len) { 154 while(len) {
155 unsigned long thislen = len; 155 unsigned long thislen = len;
156 if (len > (WINDOW_LENGTH - (to & WINDOW_MASK))) 156 if (len > (WINDOW_LENGTH - (to & WINDOW_MASK)))
157 thislen = WINDOW_LENGTH-(to & WINDOW_MASK); 157 thislen = WINDOW_LENGTH-(to & WINDOW_MASK);
158 158
159 spin_lock(&sbc_gxx_spin); 159 spin_lock(&sbc_gxx_spin);
160 sbc_gxx_page(map, to); 160 sbc_gxx_page(map, to);
161 memcpy_toio(iomapadr + (to & WINDOW_MASK), from, thislen); 161 memcpy_toio(iomapadr + (to & WINDOW_MASK), from, thislen);
@@ -201,7 +201,7 @@ static int __init init_sbc_gxx(void)
201 sbc_gxx_map.name ); 201 sbc_gxx_map.name );
202 return -EIO; 202 return -EIO;
203 } 203 }
204 204
205 if (!request_region( PAGE_IO, PAGE_IO_SIZE, "SBC-GXx flash")) { 205 if (!request_region( PAGE_IO, PAGE_IO_SIZE, "SBC-GXx flash")) {
206 printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n", 206 printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n",
207 sbc_gxx_map.name, 207 sbc_gxx_map.name,
@@ -209,8 +209,8 @@ static int __init init_sbc_gxx(void)
209 iounmap(iomapadr); 209 iounmap(iomapadr);
210 return -EAGAIN; 210 return -EAGAIN;
211 } 211 }
212 212
213 213
214 printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n", 214 printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n",
215 sbc_gxx_map.name, 215 sbc_gxx_map.name,
216 PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1, 216 PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1,
@@ -222,7 +222,7 @@ static int __init init_sbc_gxx(void)
222 cleanup_sbc_gxx(); 222 cleanup_sbc_gxx();
223 return -ENXIO; 223 return -ENXIO;
224 } 224 }
225 225
226 all_mtd->owner = THIS_MODULE; 226 all_mtd->owner = THIS_MODULE;
227 227
228 /* Create MTD devices for each partition. */ 228 /* Create MTD devices for each partition. */
diff --git a/drivers/mtd/maps/sc520cdp.c b/drivers/mtd/maps/sc520cdp.c
index a06ed21e7ed1..6fb9f3c57aab 100644
--- a/drivers/mtd/maps/sc520cdp.c
+++ b/drivers/mtd/maps/sc520cdp.c
@@ -16,7 +16,7 @@
16 * along with this program; if not, write to the Free Software 16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
18 * 18 *
19 * $Id: sc520cdp.c,v 1.21 2004/12/13 10:27:08 dedekind Exp $ 19 * $Id: sc520cdp.c,v 1.22 2005/11/07 11:14:28 gleixner Exp $
20 * 20 *
21 * 21 *
22 * The SC520CDP is an evaluation board for the Elan SC520 processor available 22 * The SC520CDP is an evaluation board for the Elan SC520 processor available
@@ -231,7 +231,7 @@ static void sc520cdp_setup_par(void)
231static int __init init_sc520cdp(void) 231static int __init init_sc520cdp(void)
232{ 232{
233 int i, devices_found = 0; 233 int i, devices_found = 0;
234 234
235#ifdef REPROGRAM_PAR 235#ifdef REPROGRAM_PAR
236 /* reprogram PAR registers so flash appears at the desired addresses */ 236 /* reprogram PAR registers so flash appears at the desired addresses */
237 sc520cdp_setup_par(); 237 sc520cdp_setup_par();
@@ -278,7 +278,7 @@ static int __init init_sc520cdp(void)
278static void __exit cleanup_sc520cdp(void) 278static void __exit cleanup_sc520cdp(void)
279{ 279{
280 int i; 280 int i;
281 281
282 if (merged_mtd) { 282 if (merged_mtd) {
283 del_mtd_device(merged_mtd); 283 del_mtd_device(merged_mtd);
284 mtd_concat_destroy(merged_mtd); 284 mtd_concat_destroy(merged_mtd);
diff --git a/drivers/mtd/maps/scx200_docflash.c b/drivers/mtd/maps/scx200_docflash.c
index 0ece3786d6ea..2c91dff8bb60 100644
--- a/drivers/mtd/maps/scx200_docflash.c
+++ b/drivers/mtd/maps/scx200_docflash.c
@@ -1,8 +1,8 @@
1/* linux/drivers/mtd/maps/scx200_docflash.c 1/* linux/drivers/mtd/maps/scx200_docflash.c
2 2
3 Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> 3 Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
4 4
5 $Id: scx200_docflash.c,v 1.10 2004/11/28 09:40:40 dwmw2 Exp $ 5 $Id: scx200_docflash.c,v 1.12 2005/11/07 11:14:28 gleixner Exp $
6 6
7 National Semiconductor SCx200 flash mapped with DOCCS 7 National Semiconductor SCx200 flash mapped with DOCCS
8*/ 8*/
@@ -49,23 +49,23 @@ static struct mtd_info *mymtd;
49 49
50#ifdef CONFIG_MTD_PARTITIONS 50#ifdef CONFIG_MTD_PARTITIONS
51static struct mtd_partition partition_info[] = { 51static struct mtd_partition partition_info[] = {
52 { 52 {
53 .name = "DOCCS Boot kernel", 53 .name = "DOCCS Boot kernel",
54 .offset = 0, 54 .offset = 0,
55 .size = 0xc0000 55 .size = 0xc0000
56 }, 56 },
57 { 57 {
58 .name = "DOCCS Low BIOS", 58 .name = "DOCCS Low BIOS",
59 .offset = 0xc0000, 59 .offset = 0xc0000,
60 .size = 0x40000 60 .size = 0x40000
61 }, 61 },
62 { 62 {
63 .name = "DOCCS File system", 63 .name = "DOCCS File system",
64 .offset = 0x100000, 64 .offset = 0x100000,
65 .size = ~0 /* calculate from flash size */ 65 .size = ~0 /* calculate from flash size */
66 }, 66 },
67 { 67 {
68 .name = "DOCCS High BIOS", 68 .name = "DOCCS High BIOS",
69 .offset = ~0, /* calculate from flash size */ 69 .offset = ~0, /* calculate from flash size */
70 .size = 0x80000 70 .size = 0x80000
71 }, 71 },
@@ -88,7 +88,7 @@ static int __init init_scx200_docflash(void)
88 88
89 printk(KERN_DEBUG NAME ": NatSemi SCx200 DOCCS Flash Driver\n"); 89 printk(KERN_DEBUG NAME ": NatSemi SCx200 DOCCS Flash Driver\n");
90 90
91 if ((bridge = pci_find_device(PCI_VENDOR_ID_NS, 91 if ((bridge = pci_find_device(PCI_VENDOR_ID_NS,
92 PCI_DEVICE_ID_NS_SCx200_BRIDGE, 92 PCI_DEVICE_ID_NS_SCx200_BRIDGE,
93 NULL)) == NULL) 93 NULL)) == NULL)
94 return -ENODEV; 94 return -ENODEV;
@@ -134,28 +134,28 @@ static int __init init_scx200_docflash(void)
134 printk(KERN_ERR NAME ": invalid size for flash mapping\n"); 134 printk(KERN_ERR NAME ": invalid size for flash mapping\n");
135 return -EINVAL; 135 return -EINVAL;
136 } 136 }
137 137
138 if (width != 8 && width != 16) { 138 if (width != 8 && width != 16) {
139 printk(KERN_ERR NAME ": invalid bus width for flash mapping\n"); 139 printk(KERN_ERR NAME ": invalid bus width for flash mapping\n");
140 return -EINVAL; 140 return -EINVAL;
141 } 141 }
142 142
143 if (allocate_resource(&iomem_resource, &docmem, 143 if (allocate_resource(&iomem_resource, &docmem,
144 size, 144 size,
145 0xc0000000, 0xffffffff, 145 0xc0000000, 0xffffffff,
146 size, NULL, NULL)) { 146 size, NULL, NULL)) {
147 printk(KERN_ERR NAME ": unable to allocate memory for flash mapping\n"); 147 printk(KERN_ERR NAME ": unable to allocate memory for flash mapping\n");
148 return -ENOMEM; 148 return -ENOMEM;
149 } 149 }
150 150
151 ctrl = 0x07000000 | ((size-1) >> 13); 151 ctrl = 0x07000000 | ((size-1) >> 13);
152 152
153 printk(KERN_INFO "DOCCS BASE=0x%08lx, CTRL=0x%08lx\n", (long)docmem.start, (long)ctrl); 153 printk(KERN_INFO "DOCCS BASE=0x%08lx, CTRL=0x%08lx\n", (long)docmem.start, (long)ctrl);
154 154
155 pci_write_config_dword(bridge, SCx200_DOCCS_BASE, docmem.start); 155 pci_write_config_dword(bridge, SCx200_DOCCS_BASE, docmem.start);
156 pci_write_config_dword(bridge, SCx200_DOCCS_CTRL, ctrl); 156 pci_write_config_dword(bridge, SCx200_DOCCS_CTRL, ctrl);
157 pmr = inl(scx200_cb_base + SCx200_PMR); 157 pmr = inl(scx200_cb_base + SCx200_PMR);
158 158
159 if (width == 8) { 159 if (width == 8) {
160 pmr &= ~(1<<6); 160 pmr &= ~(1<<6);
161 } else { 161 } else {
@@ -163,8 +163,8 @@ static int __init init_scx200_docflash(void)
163 } 163 }
164 outl(pmr, scx200_cb_base + SCx200_PMR); 164 outl(pmr, scx200_cb_base + SCx200_PMR);
165 } 165 }
166 166
167 printk(KERN_INFO NAME ": DOCCS mapped at 0x%lx-0x%lx, width %d\n", 167 printk(KERN_INFO NAME ": DOCCS mapped at 0x%lx-0x%lx, width %d\n",
168 docmem.start, docmem.end, width); 168 docmem.start, docmem.end, width);
169 169
170 scx200_docflash_map.size = size; 170 scx200_docflash_map.size = size;
diff --git a/drivers/mtd/maps/sharpsl-flash.c b/drivers/mtd/maps/sharpsl-flash.c
index b7f093fbf9b0..999f4bb3d845 100644
--- a/drivers/mtd/maps/sharpsl-flash.c
+++ b/drivers/mtd/maps/sharpsl-flash.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * sharpsl-flash.c 2 * sharpsl-flash.c
3 * 3 *
4 * Copyright (C) 2001 Lineo Japan, Inc. 4 * Copyright (C) 2001 Lineo Japan, Inc.
5 * Copyright (C) 2002 SHARP 5 * Copyright (C) 2002 SHARP
6 * 6 *
7 * $Id: sharpsl-flash.c,v 1.5 2005/03/21 08:42:11 rpurdie Exp $ 7 * $Id: sharpsl-flash.c,v 1.7 2005/11/07 11:14:28 gleixner Exp $
8 * 8 *
9 * based on rpxlite.c,v 1.15 2001/10/02 15:05:14 dwmw2 Exp 9 * based on rpxlite.c,v 1.15 2001/10/02 15:05:14 dwmw2 Exp
10 * Handle mapping of the flash on the RPX Lite and CLLF boards 10 * Handle mapping of the flash on the RPX Lite and CLLF boards
@@ -57,7 +57,7 @@ int __init init_sharpsl(void)
57 int nb_parts = 0; 57 int nb_parts = 0;
58 char *part_type = "static"; 58 char *part_type = "static";
59 59
60 printk(KERN_NOTICE "Sharp SL series flash device: %x at %x\n", 60 printk(KERN_NOTICE "Sharp SL series flash device: %x at %x\n",
61 WINDOW_SIZE, WINDOW_ADDR); 61 WINDOW_SIZE, WINDOW_ADDR);
62 sharpsl_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE); 62 sharpsl_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
63 if (!sharpsl_map.virt) { 63 if (!sharpsl_map.virt) {
@@ -75,7 +75,7 @@ int __init init_sharpsl(void)
75 75
76 mymtd->owner = THIS_MODULE; 76 mymtd->owner = THIS_MODULE;
77 77
78 if (machine_is_corgi() || machine_is_shepherd() || machine_is_husky() 78 if (machine_is_corgi() || machine_is_shepherd() || machine_is_husky()
79 || machine_is_poodle()) { 79 || machine_is_poodle()) {
80 sharpsl_partitions[0].size=0x006d0000; 80 sharpsl_partitions[0].size=0x006d0000;
81 sharpsl_partitions[0].offset=0x00120000; 81 sharpsl_partitions[0].offset=0x00120000;
@@ -87,10 +87,10 @@ int __init init_sharpsl(void)
87 sharpsl_partitions[0].offset=0x00140000; 87 sharpsl_partitions[0].offset=0x00140000;
88 } else { 88 } else {
89 map_destroy(mymtd); 89 map_destroy(mymtd);
90 iounmap(sharpsl_map.virt); 90 iounmap(sharpsl_map.virt);
91 return -ENODEV; 91 return -ENODEV;
92 } 92 }
93 93
94 parts = sharpsl_partitions; 94 parts = sharpsl_partitions;
95 nb_parts = NB_OF(sharpsl_partitions); 95 nb_parts = NB_OF(sharpsl_partitions);
96 96
diff --git a/drivers/mtd/maps/solutionengine.c b/drivers/mtd/maps/solutionengine.c
index 8ce5d897645c..c53c2c369c9d 100644
--- a/drivers/mtd/maps/solutionengine.c
+++ b/drivers/mtd/maps/solutionengine.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: solutionengine.c,v 1.14 2004/09/16 23:27:14 gleixner Exp $ 2 * $Id: solutionengine.c,v 1.15 2005/11/07 11:14:28 gleixner Exp $
3 * 3 *
4 * Flash and EPROM on Hitachi Solution Engine and similar boards. 4 * Flash and EPROM on Hitachi Solution Engine and similar boards.
5 * 5 *
@@ -67,7 +67,7 @@ static int __init init_soleng_maps(void)
67 soleng_eprom_map.virt = (void __iomem *)P1SEGADDR(0x01000000); 67 soleng_eprom_map.virt = (void __iomem *)P1SEGADDR(0x01000000);
68 simple_map_init(&soleng_eprom_map); 68 simple_map_init(&soleng_eprom_map);
69 simple_map_init(&soleng_flash_map); 69 simple_map_init(&soleng_flash_map);
70 70
71 printk(KERN_NOTICE "Probing for flash chips at 0x00000000:\n"); 71 printk(KERN_NOTICE "Probing for flash chips at 0x00000000:\n");
72 flash_mtd = do_map_probe("cfi_probe", &soleng_flash_map); 72 flash_mtd = do_map_probe("cfi_probe", &soleng_flash_map);
73 if (!flash_mtd) { 73 if (!flash_mtd) {
diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c
index 1355c28f90a4..0758cb1d0105 100644
--- a/drivers/mtd/maps/sun_uflash.c
+++ b/drivers/mtd/maps/sun_uflash.c
@@ -1,4 +1,4 @@
1/* $Id: sun_uflash.c,v 1.11 2004/11/04 13:24:15 gleixner Exp $ 1/* $Id: sun_uflash.c,v 1.13 2005/11/07 11:14:28 gleixner Exp $
2 * 2 *
3 * sun_uflash - Driver implementation for user-programmable flash 3 * sun_uflash - Driver implementation for user-programmable flash
4 * present on many Sun Microsystems SME boardsets. 4 * present on many Sun Microsystems SME boardsets.
@@ -63,7 +63,7 @@ int uflash_devinit(struct linux_ebus_device* edev)
63 iTmp = prom_getproperty( 63 iTmp = prom_getproperty(
64 edev->prom_node, "reg", (void *)regs, sizeof(regs)); 64 edev->prom_node, "reg", (void *)regs, sizeof(regs));
65 if ((iTmp % sizeof(regs[0])) != 0) { 65 if ((iTmp % sizeof(regs[0])) != 0) {
66 printk("%s: Strange reg property size %d\n", 66 printk("%s: Strange reg property size %d\n",
67 UFLASH_DEVNAME, iTmp); 67 UFLASH_DEVNAME, iTmp);
68 return -ENODEV; 68 return -ENODEV;
69 } 69 }
@@ -75,7 +75,7 @@ int uflash_devinit(struct linux_ebus_device* edev)
75 * can work on supporting it. 75 * can work on supporting it.
76 */ 76 */
77 printk("%s: unsupported device at 0x%lx (%d regs): " \ 77 printk("%s: unsupported device at 0x%lx (%d regs): " \
78 "email ebrower@usa.net\n", 78 "email ebrower@usa.net\n",
79 UFLASH_DEVNAME, edev->resource[0].start, nregs); 79 UFLASH_DEVNAME, edev->resource[0].start, nregs);
80 return -ENODEV; 80 return -ENODEV;
81 } 81 }
@@ -84,7 +84,7 @@ int uflash_devinit(struct linux_ebus_device* edev)
84 printk("%s: unable to kmalloc new device\n", UFLASH_DEVNAME); 84 printk("%s: unable to kmalloc new device\n", UFLASH_DEVNAME);
85 return(-ENOMEM); 85 return(-ENOMEM);
86 } 86 }
87 87
88 /* copy defaults and tweak parameters */ 88 /* copy defaults and tweak parameters */
89 memcpy(&pdev->map, &uflash_map_templ, sizeof(uflash_map_templ)); 89 memcpy(&pdev->map, &uflash_map_templ, sizeof(uflash_map_templ));
90 pdev->map.size = regs[0].reg_size; 90 pdev->map.size = regs[0].reg_size;
@@ -155,7 +155,7 @@ static void __exit uflash_cleanup(void)
155 155
156 list_for_each(udevlist, &device_list) { 156 list_for_each(udevlist, &device_list) {
157 udev = list_entry(udevlist, struct uflash_dev, list); 157 udev = list_entry(udevlist, struct uflash_dev, list);
158 DEBUG(2, "%s: removing device %s\n", 158 DEBUG(2, "%s: removing device %s\n",
159 UFLASH_DEVNAME, udev->name); 159 UFLASH_DEVNAME, udev->name);
160 160
161 if(0 != udev->mtd) { 161 if(0 != udev->mtd) {
@@ -168,7 +168,7 @@ static void __exit uflash_cleanup(void)
168 } 168 }
169 kfree(udev->name); 169 kfree(udev->name);
170 kfree(udev); 170 kfree(udev);
171 } 171 }
172} 172}
173 173
174module_init(uflash_init); 174module_init(uflash_init);
diff --git a/drivers/mtd/maps/tqm834x.c b/drivers/mtd/maps/tqm834x.c
new file mode 100644
index 000000000000..c7ae9a515c1a
--- /dev/null
+++ b/drivers/mtd/maps/tqm834x.c
@@ -0,0 +1,291 @@
1/*
2 * drivers/mtd/maps/tqm834x.c
3 *
4 * MTD mapping driver for TQM834x boards
5 *
6 * Copyright 2005 Wolfgang Denk, DENX Software Engineering, <wd@denx.de>.
7 *
8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
11 *
12 */
13
14#include <linux/config.h>
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/types.h>
18#include <linux/kernel.h>
19#include <linux/slab.h>
20#include <asm/io.h>
21#include <asm/ppcboot.h>
22
23#include <linux/mtd/mtd.h>
24#include <linux/mtd/map.h>
25#include <linux/mtd/partitions.h>
26
27#define FLASH_BANK_MAX 2
28
29extern unsigned char __res[];
30
31/* trivial struct to describe partition information */
32struct mtd_part_def
33{
34 int nums;
35 unsigned char *type;
36 struct mtd_partition* mtd_part;
37};
38
39static struct mtd_info* mtd_banks[FLASH_BANK_MAX];
40static struct map_info* map_banks[FLASH_BANK_MAX];
41static struct mtd_part_def part_banks[FLASH_BANK_MAX];
42
43static unsigned long num_banks;
44static unsigned long start_scan_addr;
45
46#ifdef CONFIG_MTD_PARTITIONS
47/*
48 * The following defines the partition layout of TQM834x boards.
49 *
50 * See include/linux/mtd/partitions.h for definition of the
51 * mtd_partition structure.
52 *
53 * Assume minimal initial size of 4 MiB per bank, will be updated
54 * later in init_tqm834x_mtd() routine.
55 */
56
57/* Partition definition for the first flash bank which is always present. */
58static struct mtd_partition tqm834x_partitions_bank1[] = {
59 {
60 .name = "u-boot", /* u-boot firmware */
61 .offset = 0x00000000,
62 .size = 0x00040000, /* 256 KiB */
63 /*mask_flags: MTD_WRITEABLE, * force read-only */
64 },
65 {
66 .name = "env", /* u-boot environment */
67 .offset = 0x00040000,
68 .size = 0x00020000, /* 128 KiB */
69 /*mask_flags: MTD_WRITEABLE, * force read-only */
70 },
71 {
72 .name = "kernel", /* linux kernel image */
73 .offset = 0x00060000,
74 .size = 0x00100000, /* 1 MiB */
75 /*mask_flags: MTD_WRITEABLE, * force read-only */
76 },
77 {
78 .name = "initrd", /* ramdisk image */
79 .offset = 0x00160000,
80 .size = 0x00200000, /* 2 MiB */
81 },
82 {
83 .name = "user", /* user data */
84 .offset = 0x00360000,
85 .size = 0x000a0000, /* remaining space */
86 /* NOTE: this parttion size is re-calcated in */
87 /* init_tqm834x_mtd() to cover actual remaining space. */
88 },
89};
90
91/* Partition definition for the second flash bank which may be present on some
92 * TQM834x boards.
93 */
94static struct mtd_partition tqm834x_partitions_bank2[] = {
95 {
96 .name = "jffs2", /* jffs2 filesystem */
97 .offset = 0x00000000,
98 .size = 0x00400000, /* whole device */
99 /* NOTE: this parttion size is re-calcated in */
100 /* init_tqm834x_mtd() to cover actual device size. */
101 },
102};
103
104#endif /* CONFIG_MTD_PARTITIONS */
105
106static int __init init_tqm834x_mtd(void)
107{
108 int idx = 0, ret = 0;
109 unsigned long flash_addr, flash_size, mtd_size = 0;
110
111 /* pointer to TQM834x board info data */
112 bd_t *bd = (bd_t *)__res;
113#ifdef CONFIG_MTD_CMDLINE_PARTS
114 int n;
115 char mtdid[4];
116 const char *part_probes[] = { "cmdlinepart", NULL };
117#endif
118
119 flash_addr = bd->bi_flashstart;
120 flash_size = bd->bi_flashsize;
121
122 /* request maximum flash size address space */
123 start_scan_addr = (unsigned long)ioremap(flash_addr, flash_size);
124 if (!start_scan_addr) {
125 printk("%s: Failed to ioremap address: 0x%lx\n",
126 __FUNCTION__, flash_addr);
127 return -EIO;
128 }
129
130 for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
131 if (mtd_size >= flash_size)
132 break;
133
134 pr_debug("%s: chip probing count %d\n", __FUNCTION__, idx);
135
136 map_banks[idx] =
137 (struct map_info *)kmalloc(sizeof(struct map_info),
138 GFP_KERNEL);
139 if (map_banks[idx] == NULL) {
140 ret = -ENOMEM;
141 goto error_mem;
142 }
143 memset((void *)map_banks[idx], 0, sizeof(struct map_info));
144 map_banks[idx]->name = (char *)kmalloc(16, GFP_KERNEL);
145 if (map_banks[idx]->name == NULL) {
146 ret = -ENOMEM;
147 goto error_mem;
148 }
149 memset((void *)map_banks[idx]->name, 0, 16);
150
151 sprintf(map_banks[idx]->name, "TQM834x-%d", idx);
152 map_banks[idx]->size = flash_size;
153 map_banks[idx]->bankwidth = 4;
154
155 simple_map_init(map_banks[idx]);
156
157 map_banks[idx]->virt = (void __iomem *)
158 (start_scan_addr + ((idx > 0) ?
159 (mtd_banks[idx-1] ? mtd_banks[idx-1]->size : 0) : 0));
160 map_banks[idx]->phys =
161 flash_addr + ((idx > 0) ?
162 (mtd_banks[idx-1] ? mtd_banks[idx-1]->size : 0) : 0);
163
164 /* start to probe flash chips */
165 mtd_banks[idx] = do_map_probe("cfi_probe", map_banks[idx]);
166 if (mtd_banks[idx]) {
167 mtd_banks[idx]->owner = THIS_MODULE;
168 mtd_size += mtd_banks[idx]->size;
169 num_banks++;
170 pr_debug("%s: bank %ld, name: %s, size: %d bytes \n",
171 __FUNCTION__, num_banks,
172 mtd_banks[idx]->name, mtd_banks[idx]->size);
173 }
174 }
175
176 /* no supported flash chips found */
177 if (!num_banks) {
178 printk("TQM834x: No supported flash chips found!\n");
179 ret = -ENXIO;
180 goto error_mem;
181 }
182
183#ifdef CONFIG_MTD_PARTITIONS
184 /*
185 * Select static partition definitions
186 */
187 n = ARRAY_SIZE(tqm834x_partitions_bank1);
188 part_banks[0].mtd_part = tqm834x_partitions_bank1;
189 part_banks[0].type = "static image bank1";
190 part_banks[0].nums = n;
191
192 /* update last partition size to cover actual remaining space */
193 tqm834x_partitions_bank1[n - 1].size =
194 mtd_banks[0]->size -
195 tqm834x_partitions_bank1[n - 1].offset;
196
197 /* check if we have second bank? */
198 if (num_banks == 2) {
199 n = ARRAY_SIZE(tqm834x_partitions_bank2);
200 part_banks[1].mtd_part = tqm834x_partitions_bank2;
201 part_banks[1].type = "static image bank2";
202 part_banks[1].nums = n;
203
204 /* update last partition size to cover actual remaining space */
205 tqm834x_partitions_bank2[n - 1].size =
206 mtd_banks[1]->size -
207 tqm834x_partitions_bank2[n - 1].offset;
208 }
209
210 for(idx = 0; idx < num_banks ; idx++) {
211#ifdef CONFIG_MTD_CMDLINE_PARTS
212 sprintf(mtdid, "%d", idx);
213 n = parse_mtd_partitions(mtd_banks[idx],
214 part_probes,
215 &part_banks[idx].mtd_part,
216 0);
217 pr_debug("%s: %d command line partitions on bank %s\n",
218 __FUNCTION__, n, mtdid);
219 if (n > 0) {
220 part_banks[idx].type = "command line";
221 part_banks[idx].nums = n;
222 }
223#endif /* CONFIG_MTD_CMDLINE_PARTS */
224 if (part_banks[idx].nums == 0) {
225 printk(KERN_NOTICE
226 "TQM834x flash bank %d: no partition info "
227 "available, registering whole device\n", idx);
228 add_mtd_device(mtd_banks[idx]);
229 } else {
230 printk(KERN_NOTICE
231 "TQM834x flash bank %d: Using %s partition "
232 "definition\n", idx, part_banks[idx].type);
233 add_mtd_partitions(mtd_banks[idx],
234 part_banks[idx].mtd_part,
235 part_banks[idx].nums);
236 }
237 }
238#else /* ! CONFIG_MTD_PARTITIONS */
239 printk(KERN_NOTICE "TQM834x flash: registering %d flash banks "
240 "at once\n", num_banks);
241
242 for(idx = 0 ; idx < num_banks ; idx++)
243 add_mtd_device(mtd_banks[idx]);
244
245#endif /* CONFIG_MTD_PARTITIONS */
246
247 return 0;
248error_mem:
249 for (idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
250 if (map_banks[idx] != NULL) {
251 if (map_banks[idx]->name != NULL) {
252 kfree(map_banks[idx]->name);
253 map_banks[idx]->name = NULL;
254 }
255 kfree(map_banks[idx]);
256 map_banks[idx] = NULL;
257 }
258 }
259
260 iounmap((void *)start_scan_addr);
261
262 return ret;
263}
264
265static void __exit cleanup_tqm834x_mtd(void)
266{
267 unsigned int idx = 0;
268 for(idx = 0 ; idx < num_banks ; idx++) {
269 /* destroy mtd_info previously allocated */
270 if (mtd_banks[idx]) {
271 del_mtd_partitions(mtd_banks[idx]);
272 map_destroy(mtd_banks[idx]);
273 }
274
275 /* release map_info not used anymore */
276 kfree(map_banks[idx]->name);
277 kfree(map_banks[idx]);
278 }
279
280 if (start_scan_addr) {
281 iounmap((void *)start_scan_addr);
282 start_scan_addr = 0;
283 }
284}
285
286module_init(init_tqm834x_mtd);
287module_exit(cleanup_tqm834x_mtd);
288
289MODULE_LICENSE("GPL");
290MODULE_AUTHOR("Wolfgang Denk <wd@denx.de>");
291MODULE_DESCRIPTION("MTD map driver for TQM834x boards");
diff --git a/drivers/mtd/maps/tqm8xxl.c b/drivers/mtd/maps/tqm8xxl.c
index 0aca8179f27f..a43517053e7c 100644
--- a/drivers/mtd/maps/tqm8xxl.c
+++ b/drivers/mtd/maps/tqm8xxl.c
@@ -1,15 +1,15 @@
1/* 1/*
2 * Handle mapping of the flash memory access routines 2 * Handle mapping of the flash memory access routines
3 * on TQM8xxL based devices. 3 * on TQM8xxL based devices.
4 * 4 *
5 * $Id: tqm8xxl.c,v 1.13 2004/10/20 22:21:53 dwmw2 Exp $ 5 * $Id: tqm8xxl.c,v 1.15 2005/11/07 11:14:28 gleixner Exp $
6 * 6 *
7 * based on rpxlite.c 7 * based on rpxlite.c
8 * 8 *
9 * Copyright(C) 2001 Kirk Lee <kirk@hpc.ee.ntu.edu.tw> 9 * Copyright(C) 2001 Kirk Lee <kirk@hpc.ee.ntu.edu.tw>
10 * 10 *
11 * This code is GPLed 11 * This code is GPLed
12 * 12 *
13 */ 13 */
14 14
15/* 15/*
@@ -19,7 +19,7 @@
19 * 2MiB 512Kx16 2MiB 0 19 * 2MiB 512Kx16 2MiB 0
20 * 4MiB 1Mx16 4MiB 0 20 * 4MiB 1Mx16 4MiB 0
21 * 8MiB 1Mx16 4MiB 4MiB 21 * 8MiB 1Mx16 4MiB 4MiB
22 * Thus, we choose CONFIG_MTD_CFI_I2 & CONFIG_MTD_CFI_B4 at 22 * Thus, we choose CONFIG_MTD_CFI_I2 & CONFIG_MTD_CFI_B4 at
23 * kernel configuration. 23 * kernel configuration.
24 */ 24 */
25#include <linux/config.h> 25#include <linux/config.h>
@@ -58,9 +58,9 @@ static void __iomem *start_scan_addr;
58 * Here are partition information for all known TQM8xxL series devices. 58 * Here are partition information for all known TQM8xxL series devices.
59 * See include/linux/mtd/partitions.h for definition of the mtd_partition 59 * See include/linux/mtd/partitions.h for definition of the mtd_partition
60 * structure. 60 * structure.
61 * 61 *
62 * The *_max_flash_size is the maximum possible mapped flash size which 62 * The *_max_flash_size is the maximum possible mapped flash size which
63 * is not necessarily the actual flash size. It must correspond to the 63 * is not necessarily the actual flash size. It must correspond to the
64 * value specified in the mapping definition defined by the 64 * value specified in the mapping definition defined by the
65 * "struct map_desc *_io_desc" for the corresponding machine. 65 * "struct map_desc *_io_desc" for the corresponding machine.
66 */ 66 */
@@ -132,9 +132,9 @@ int __init init_tqm_mtd(void)
132 for (idx = 0 ; idx < FLASH_BANK_MAX ; idx++) { 132 for (idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
133 if(mtd_size >= flash_size) 133 if(mtd_size >= flash_size)
134 break; 134 break;
135 135
136 printk(KERN_INFO "%s: chip probing count %d\n", __FUNCTION__, idx); 136 printk(KERN_INFO "%s: chip probing count %d\n", __FUNCTION__, idx);
137 137
138 map_banks[idx] = (struct map_info *)kmalloc(sizeof(struct map_info), GFP_KERNEL); 138 map_banks[idx] = (struct map_info *)kmalloc(sizeof(struct map_info), GFP_KERNEL);
139 if(map_banks[idx] == NULL) { 139 if(map_banks[idx] == NULL) {
140 ret = -ENOMEM; 140 ret = -ENOMEM;
@@ -180,7 +180,7 @@ int __init init_tqm_mtd(void)
180 mtd_size += mtd_banks[idx]->size; 180 mtd_size += mtd_banks[idx]->size;
181 num_banks++; 181 num_banks++;
182 182
183 printk(KERN_INFO "%s: bank%d, name:%s, size:%dbytes \n", __FUNCTION__, num_banks, 183 printk(KERN_INFO "%s: bank%d, name:%s, size:%dbytes \n", __FUNCTION__, num_banks,
184 mtd_banks[idx]->name, mtd_banks[idx]->size); 184 mtd_banks[idx]->name, mtd_banks[idx]->size);
185 } 185 }
186 } 186 }
@@ -211,7 +211,7 @@ int __init init_tqm_mtd(void)
211 } else { 211 } else {
212 printk(KERN_NOTICE "TQM flash%d: Using %s partition definition\n", 212 printk(KERN_NOTICE "TQM flash%d: Using %s partition definition\n",
213 idx, part_banks[idx].type); 213 idx, part_banks[idx].type);
214 add_mtd_partitions(mtd_banks[idx], part_banks[idx].mtd_part, 214 add_mtd_partitions(mtd_banks[idx], part_banks[idx].mtd_part,
215 part_banks[idx].nums); 215 part_banks[idx].nums);
216 } 216 }
217 } 217 }
diff --git a/drivers/mtd/maps/ts5500_flash.c b/drivers/mtd/maps/ts5500_flash.c
index 3ebd90f56503..4b372bcb17f1 100644
--- a/drivers/mtd/maps/ts5500_flash.c
+++ b/drivers/mtd/maps/ts5500_flash.c
@@ -19,26 +19,22 @@
19 * 19 *
20 * Note: 20 * Note:
21 * - In order for detection to work, jumper 3 must be set. 21 * - In order for detection to work, jumper 3 must be set.
22 * - Drive A and B use a proprietary FTL from General Software which isn't 22 * - Drive A and B use the resident flash disk (RFD) flash translation layer.
23 * supported as of yet so standard drives can't be mounted; you can create 23 * - If you have created your own jffs file system and the bios overwrites
24 * your own (e.g. jffs) file system.
25 * - If you have created your own jffs file system and the bios overwrites
26 * it during boot, try disabling Drive A: and B: in the boot order. 24 * it during boot, try disabling Drive A: and B: in the boot order.
27 * 25 *
28 * $Id: ts5500_flash.c,v 1.2 2004/11/28 09:40:40 dwmw2 Exp $ 26 * $Id: ts5500_flash.c,v 1.5 2005/11/07 11:14:28 gleixner Exp $
29 */ 27 */
30 28
31#include <linux/config.h> 29#include <linux/config.h>
30#include <linux/init.h>
32#include <linux/module.h> 31#include <linux/module.h>
33#include <linux/types.h>
34#include <linux/kernel.h> 32#include <linux/kernel.h>
35#include <linux/init.h>
36#include <linux/mtd/mtd.h>
37#include <linux/mtd/map.h> 33#include <linux/mtd/map.h>
38 34#include <linux/mtd/mtd.h>
39#ifdef CONFIG_MTD_PARTITIONS
40#include <linux/mtd/partitions.h> 35#include <linux/mtd/partitions.h>
41#endif 36#include <linux/types.h>
37
42 38
43#define WINDOW_ADDR 0x09400000 39#define WINDOW_ADDR 0x09400000
44#define WINDOW_SIZE 0x00200000 40#define WINDOW_SIZE 0x00200000
@@ -50,7 +46,6 @@ static struct map_info ts5500_map = {
50 .phys = WINDOW_ADDR 46 .phys = WINDOW_ADDR
51}; 47};
52 48
53#ifdef CONFIG_MTD_PARTITIONS
54static struct mtd_partition ts5500_partitions[] = { 49static struct mtd_partition ts5500_partitions[] = {
55 { 50 {
56 .name = "Drive A", 51 .name = "Drive A",
@@ -71,8 +66,6 @@ static struct mtd_partition ts5500_partitions[] = {
71 66
72#define NUM_PARTITIONS (sizeof(ts5500_partitions)/sizeof(struct mtd_partition)) 67#define NUM_PARTITIONS (sizeof(ts5500_partitions)/sizeof(struct mtd_partition))
73 68
74#endif
75
76static struct mtd_info *mymtd; 69static struct mtd_info *mymtd;
77 70
78static int __init init_ts5500_map(void) 71static int __init init_ts5500_map(void)
@@ -81,48 +74,39 @@ static int __init init_ts5500_map(void)
81 74
82 ts5500_map.virt = ioremap_nocache(ts5500_map.phys, ts5500_map.size); 75 ts5500_map.virt = ioremap_nocache(ts5500_map.phys, ts5500_map.size);
83 76
84 if(!ts5500_map.virt) { 77 if (!ts5500_map.virt) {
85 printk(KERN_ERR "Failed to ioremap_nocache\n"); 78 printk(KERN_ERR "Failed to ioremap_nocache\n");
86 rc = -EIO; 79 rc = -EIO;
87 goto err_out_ioremap; 80 goto err2;
88 } 81 }
89 82
90 simple_map_init(&ts5500_map); 83 simple_map_init(&ts5500_map);
91 84
92 mymtd = do_map_probe("jedec_probe", &ts5500_map); 85 mymtd = do_map_probe("jedec_probe", &ts5500_map);
93 if(!mymtd) 86 if (!mymtd)
94 mymtd = do_map_probe("map_rom", &ts5500_map); 87 mymtd = do_map_probe("map_rom", &ts5500_map);
95 88
96 if(!mymtd) { 89 if (!mymtd) {
97 rc = -ENXIO; 90 rc = -ENXIO;
98 goto err_out_map; 91 goto err1;
99 } 92 }
100 93
101 mymtd->owner = THIS_MODULE; 94 mymtd->owner = THIS_MODULE;
102#ifdef CONFIG_MTD_PARTITIONS
103 add_mtd_partitions(mymtd, ts5500_partitions, NUM_PARTITIONS); 95 add_mtd_partitions(mymtd, ts5500_partitions, NUM_PARTITIONS);
104#else
105 add_mtd_device(mymtd);
106#endif
107 96
108 return 0; 97 return 0;
109 98
110err_out_map: 99err1:
111 map_destroy(mymtd); 100 map_destroy(mymtd);
112err_out_ioremap:
113 iounmap(ts5500_map.virt); 101 iounmap(ts5500_map.virt);
114 102err2:
115 return rc; 103 return rc;
116} 104}
117 105
118static void __exit cleanup_ts5500_map(void) 106static void __exit cleanup_ts5500_map(void)
119{ 107{
120 if (mymtd) { 108 if (mymtd) {
121#ifdef CONFIG_MTD_PARTITIONS
122 del_mtd_partitions(mymtd); 109 del_mtd_partitions(mymtd);
123#else
124 del_mtd_device(mymtd);
125#endif
126 map_destroy(mymtd); 110 map_destroy(mymtd);
127 } 111 }
128 112
diff --git a/drivers/mtd/maps/tsunami_flash.c b/drivers/mtd/maps/tsunami_flash.c
index 170d71239e5e..9e21e6c02f80 100644
--- a/drivers/mtd/maps/tsunami_flash.c
+++ b/drivers/mtd/maps/tsunami_flash.c
@@ -2,7 +2,7 @@
2 * tsunami_flash.c 2 * tsunami_flash.c
3 * 3 *
4 * flash chip on alpha ds10... 4 * flash chip on alpha ds10...
5 * $Id: tsunami_flash.c,v 1.9 2004/07/14 09:52:55 dwmw2 Exp $ 5 * $Id: tsunami_flash.c,v 1.10 2005/11/07 11:14:29 gleixner Exp $
6 */ 6 */
7#include <asm/io.h> 7#include <asm/io.h>
8#include <asm/core_tsunami.h> 8#include <asm/core_tsunami.h>
@@ -41,7 +41,7 @@ static void tsunami_flash_copy_from(
41} 41}
42 42
43static void tsunami_flash_copy_to( 43static void tsunami_flash_copy_to(
44 struct map_info *map, unsigned long offset, 44 struct map_info *map, unsigned long offset,
45 const void *addr, ssize_t len) 45 const void *addr, ssize_t len)
46{ 46{
47 const unsigned char *src; 47 const unsigned char *src;
@@ -90,7 +90,7 @@ static int __init init_tsunami_flash(void)
90 char **type; 90 char **type;
91 91
92 tsunami_tig_writeb(FLASH_ENABLE_BYTE, FLASH_ENABLE_PORT); 92 tsunami_tig_writeb(FLASH_ENABLE_BYTE, FLASH_ENABLE_PORT);
93 93
94 tsunami_flash_mtd = 0; 94 tsunami_flash_mtd = 0;
95 type = rom_probe_types; 95 type = rom_probe_types;
96 for(; !tsunami_flash_mtd && *type; type++) { 96 for(; !tsunami_flash_mtd && *type; type++) {
diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c
index cc372136e852..79d92808b766 100644
--- a/drivers/mtd/maps/uclinux.c
+++ b/drivers/mtd/maps/uclinux.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) 6 * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
7 * 7 *
8 * $Id: uclinux.c,v 1.10 2005/01/05 18:05:13 dwmw2 Exp $ 8 * $Id: uclinux.c,v 1.12 2005/11/07 11:14:29 gleixner Exp $
9 */ 9 */
10 10
11/****************************************************************************/ 11/****************************************************************************/
@@ -82,7 +82,7 @@ int __init uclinux_mtd_init(void)
82 iounmap(mapp->virt); 82 iounmap(mapp->virt);
83 return(-ENXIO); 83 return(-ENXIO);
84 } 84 }
85 85
86 mtd->owner = THIS_MODULE; 86 mtd->owner = THIS_MODULE;
87 mtd->point = uclinux_point; 87 mtd->point = uclinux_point;
88 mtd->priv = mapp; 88 mtd->priv = mapp;
diff --git a/drivers/mtd/maps/vmax301.c b/drivers/mtd/maps/vmax301.c
index c8c74110ed1b..e0063941c0df 100644
--- a/drivers/mtd/maps/vmax301.c
+++ b/drivers/mtd/maps/vmax301.c
@@ -1,19 +1,19 @@
1// $Id: vmax301.c,v 1.30 2004/07/12 22:38:29 dwmw2 Exp $ 1// $Id: vmax301.c,v 1.32 2005/11/07 11:14:29 gleixner Exp $
2/* ###################################################################### 2/* ######################################################################
3 3
4 Tempustech VMAX SBC301 MTD Driver. 4 Tempustech VMAX SBC301 MTD Driver.
5 5
6 The VMAx 301 is a SBC based on . It 6 The VMAx 301 is a SBC based on . It
7 comes with three builtin AMD 29F016B flash chips and a socket for SRAM or 7 comes with three builtin AMD 29F016B flash chips and a socket for SRAM or
8 more flash. Each unit has it's own 8k mapping into a settable region 8 more flash. Each unit has it's own 8k mapping into a settable region
9 (0xD8000). There are two 8k mappings for each MTD, the first is always set 9 (0xD8000). There are two 8k mappings for each MTD, the first is always set
10 to the lower 8k of the device the second is paged. Writing a 16 bit page 10 to the lower 8k of the device the second is paged. Writing a 16 bit page
11 value to anywhere in the first 8k will cause the second 8k to page around. 11 value to anywhere in the first 8k will cause the second 8k to page around.
12 12
13 To boot the device a bios extension must be installed into the first 8k 13 To boot the device a bios extension must be installed into the first 8k
14 of flash that is smart enough to copy itself down, page in the rest of 14 of flash that is smart enough to copy itself down, page in the rest of
15 itself and begin executing. 15 itself and begin executing.
16 16
17 ##################################################################### */ 17 ##################################################################### */
18 18
19#include <linux/module.h> 19#include <linux/module.h>
@@ -35,7 +35,7 @@
35/* Actually we could use two spinlocks, but we'd have to have 35/* Actually we could use two spinlocks, but we'd have to have
36 more private space in the struct map_info. We lose a little 36 more private space in the struct map_info. We lose a little
37 performance like this, but we'd probably lose more by having 37 performance like this, but we'd probably lose more by having
38 the extra indirection from having one of the map->map_priv 38 the extra indirection from having one of the map->map_priv
39 fields pointing to yet another private struct. 39 fields pointing to yet another private struct.
40*/ 40*/
41static DEFINE_SPINLOCK(vmax301_spin); 41static DEFINE_SPINLOCK(vmax301_spin);
@@ -98,7 +98,7 @@ static void vmax301_copy_to(struct map_info *map, unsigned long to, const void *
98 spin_lock(&vmax301_spin); 98 spin_lock(&vmax301_spin);
99 vmax301_page(map, to); 99 vmax301_page(map, to);
100 memcpy_toio(map->map_priv_2 + to, from, thislen); 100 memcpy_toio(map->map_priv_2 + to, from, thislen);
101 spin_unlock(&vmax301_spin); 101 spin_unlock(&vmax301_spin);
102 to += thislen; 102 to += thislen;
103 from += thislen; 103 from += thislen;
104 len -= thislen; 104 len -= thislen;
@@ -137,7 +137,7 @@ static struct mtd_info *vmax_mtd[2] = {NULL, NULL};
137static void __exit cleanup_vmax301(void) 137static void __exit cleanup_vmax301(void)
138{ 138{
139 int i; 139 int i;
140 140
141 for (i=0; i<2; i++) { 141 for (i=0; i<2; i++) {
142 if (vmax_mtd[i]) { 142 if (vmax_mtd[i]) {
143 del_mtd_device(vmax_mtd[i]); 143 del_mtd_device(vmax_mtd[i]);
@@ -161,13 +161,13 @@ int __init init_vmax301(void)
161 return -EIO; 161 return -EIO;
162 } 162 }
163 /* Put the address in the map's private data area. 163 /* Put the address in the map's private data area.
164 We store the actual MTD IO address rather than the 164 We store the actual MTD IO address rather than the
165 address of the first half, because it's used more 165 address of the first half, because it's used more
166 often. 166 often.
167 */ 167 */
168 vmax_map[0].map_priv_2 = iomapadr + WINDOW_START; 168 vmax_map[0].map_priv_2 = iomapadr + WINDOW_START;
169 vmax_map[1].map_priv_2 = iomapadr + (3*WINDOW_START); 169 vmax_map[1].map_priv_2 = iomapadr + (3*WINDOW_START);
170 170
171 for (i=0; i<2; i++) { 171 for (i=0; i<2; i++) {
172 vmax_mtd[i] = do_map_probe("cfi_probe", &vmax_map[i]); 172 vmax_mtd[i] = do_map_probe("cfi_probe", &vmax_map[i]);
173 if (!vmax_mtd[i]) 173 if (!vmax_mtd[i])
diff --git a/drivers/mtd/maps/walnut.c b/drivers/mtd/maps/walnut.c
index d6137b1b5670..5c17bca3a37e 100644
--- a/drivers/mtd/maps/walnut.c
+++ b/drivers/mtd/maps/walnut.c
@@ -1,12 +1,12 @@
1/* 1/*
2 * $Id: walnut.c,v 1.2 2004/12/10 12:07:42 holindho Exp $ 2 * $Id: walnut.c,v 1.3 2005/11/07 11:14:29 gleixner Exp $
3 * 3 *
4 * Mapping for Walnut flash 4 * Mapping for Walnut flash
5 * (used ebony.c as a "framework") 5 * (used ebony.c as a "framework")
6 * 6 *
7 * Heikki Lindholm <holindho@infradead.org> 7 * Heikki Lindholm <holindho@infradead.org>
8 * 8 *
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the 11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your 12 * Free Software Foundation; either version 2 of the License, or (at your
@@ -48,7 +48,7 @@ static struct mtd_partition walnut_partitions[] = {
48 .name = "OpenBIOS", 48 .name = "OpenBIOS",
49 .offset = 0x0, 49 .offset = 0x0,
50 .size = WALNUT_FLASH_SIZE, 50 .size = WALNUT_FLASH_SIZE,
51 /*.mask_flags = MTD_WRITEABLE, */ /* force read-only */ 51 /*.mask_flags = MTD_WRITEABLE, */ /* force read-only */
52 } 52 }
53}; 53};
54 54
@@ -72,11 +72,11 @@ int __init init_walnut(void)
72 printk("The on-board flash is disabled (U79 sw 5)!"); 72 printk("The on-board flash is disabled (U79 sw 5)!");
73 return -EIO; 73 return -EIO;
74 } 74 }
75 if (WALNUT_FLASH_SRAM_SEL(fpga_brds1)) 75 if (WALNUT_FLASH_SRAM_SEL(fpga_brds1))
76 flash_base = WALNUT_FLASH_LOW; 76 flash_base = WALNUT_FLASH_LOW;
77 else 77 else
78 flash_base = WALNUT_FLASH_HIGH; 78 flash_base = WALNUT_FLASH_HIGH;
79 79
80 walnut_map.phys = flash_base; 80 walnut_map.phys = flash_base;
81 walnut_map.virt = 81 walnut_map.virt =
82 (void __iomem *)ioremap(flash_base, walnut_map.size); 82 (void __iomem *)ioremap(flash_base, walnut_map.size);
diff --git a/drivers/mtd/maps/wr_sbc82xx_flash.c b/drivers/mtd/maps/wr_sbc82xx_flash.c
index 82b887b05707..60c197ec455b 100644
--- a/drivers/mtd/maps/wr_sbc82xx_flash.c
+++ b/drivers/mtd/maps/wr_sbc82xx_flash.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: wr_sbc82xx_flash.c,v 1.7 2004/11/04 13:24:15 gleixner Exp $ 2 * $Id: wr_sbc82xx_flash.c,v 1.8 2005/11/07 11:14:29 gleixner Exp $
3 * 3 *
4 * Map for flash chips on Wind River PowerQUICC II SBC82xx board. 4 * Map for flash chips on Wind River PowerQUICC II SBC82xx board.
5 * 5 *
@@ -163,10 +163,10 @@ static void __exit cleanup_sbc82xx_flash(void)
163 del_mtd_partitions(sbcmtd[i]); 163 del_mtd_partitions(sbcmtd[i]);
164 else 164 else
165 del_mtd_device(sbcmtd[i]); 165 del_mtd_device(sbcmtd[i]);
166 166
167 kfree(sbcmtd_parts[i]); 167 kfree(sbcmtd_parts[i]);
168 map_destroy(sbcmtd[i]); 168 map_destroy(sbcmtd[i]);
169 169
170 iounmap((void *)sbc82xx_flash_map[i].virt); 170 iounmap((void *)sbc82xx_flash_map[i].virt);
171 sbc82xx_flash_map[i].virt = 0; 171 sbc82xx_flash_map[i].virt = 0;
172 } 172 }
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index f8d2185819e7..339cb1218eaa 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: mtd_blkdevs.c,v 1.24 2004/11/16 18:28:59 dwmw2 Exp $ 2 * $Id: mtd_blkdevs.c,v 1.27 2005/11/07 11:14:20 gleixner Exp $
3 * 3 *
4 * (C) 2003 David Woodhouse <dwmw2@infradead.org> 4 * (C) 2003 David Woodhouse <dwmw2@infradead.org>
5 * 5 *
@@ -21,7 +21,6 @@
21#include <linux/init.h> 21#include <linux/init.h>
22#include <asm/semaphore.h> 22#include <asm/semaphore.h>
23#include <asm/uaccess.h> 23#include <asm/uaccess.h>
24#include <linux/devfs_fs_kernel.h>
25 24
26static LIST_HEAD(blktrans_majors); 25static LIST_HEAD(blktrans_majors);
27 26
@@ -86,7 +85,7 @@ static int mtd_blktrans_thread(void *arg)
86 daemonize("%sd", tr->name); 85 daemonize("%sd", tr->name);
87 86
88 /* daemonize() doesn't do this for us since some kernel threads 87 /* daemonize() doesn't do this for us since some kernel threads
89 actually want to deal with signals. We can't just call 88 actually want to deal with signals. We can't just call
90 exit_sighand() since that'll cause an oops when we finally 89 exit_sighand() since that'll cause an oops when we finally
91 do exit. */ 90 do exit. */
92 spin_lock_irq(&current->sighand->siglock); 91 spin_lock_irq(&current->sighand->siglock);
@@ -95,7 +94,7 @@ static int mtd_blktrans_thread(void *arg)
95 spin_unlock_irq(&current->sighand->siglock); 94 spin_unlock_irq(&current->sighand->siglock);
96 95
97 spin_lock_irq(rq->queue_lock); 96 spin_lock_irq(rq->queue_lock);
98 97
99 while (!tr->blkcore_priv->exiting) { 98 while (!tr->blkcore_priv->exiting) {
100 struct request *req; 99 struct request *req;
101 struct mtd_blktrans_dev *dev; 100 struct mtd_blktrans_dev *dev;
@@ -158,7 +157,7 @@ static int blktrans_open(struct inode *i, struct file *f)
158 if (!try_module_get(tr->owner)) 157 if (!try_module_get(tr->owner))
159 goto out_tr; 158 goto out_tr;
160 159
161 /* FIXME: Locking. A hot pluggable device can go away 160 /* FIXME: Locking. A hot pluggable device can go away
162 (del_mtd_device can be called for it) without its module 161 (del_mtd_device can be called for it) without its module
163 being unloaded. */ 162 being unloaded. */
164 dev->mtd->usecount++; 163 dev->mtd->usecount++;
@@ -196,7 +195,7 @@ static int blktrans_release(struct inode *i, struct file *f)
196} 195}
197 196
198 197
199static int blktrans_ioctl(struct inode *inode, struct file *file, 198static int blktrans_ioctl(struct inode *inode, struct file *file,
200 unsigned int cmd, unsigned long arg) 199 unsigned int cmd, unsigned long arg)
201{ 200{
202 struct mtd_blktrans_dev *dev = inode->i_bdev->bd_disk->private_data; 201 struct mtd_blktrans_dev *dev = inode->i_bdev->bd_disk->private_data;
@@ -265,7 +264,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
265 /* Required number was free */ 264 /* Required number was free */
266 list_add_tail(&new->list, &d->list); 265 list_add_tail(&new->list, &d->list);
267 goto added; 266 goto added;
268 } 267 }
269 last_devnum = d->devnum; 268 last_devnum = d->devnum;
270 } 269 }
271 if (new->devnum == -1) 270 if (new->devnum == -1)
@@ -289,11 +288,19 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
289 gd->major = tr->major; 288 gd->major = tr->major;
290 gd->first_minor = (new->devnum) << tr->part_bits; 289 gd->first_minor = (new->devnum) << tr->part_bits;
291 gd->fops = &mtd_blktrans_ops; 290 gd->fops = &mtd_blktrans_ops;
292 291
293 snprintf(gd->disk_name, sizeof(gd->disk_name), 292 if (tr->part_bits)
294 "%s%c", tr->name, (tr->part_bits?'a':'0') + new->devnum); 293 if (new->devnum < 26)
295 snprintf(gd->devfs_name, sizeof(gd->devfs_name), 294 snprintf(gd->disk_name, sizeof(gd->disk_name),
296 "%s/%c", tr->name, (tr->part_bits?'a':'0') + new->devnum); 295 "%s%c", tr->name, 'a' + new->devnum);
296 else
297 snprintf(gd->disk_name, sizeof(gd->disk_name),
298 "%s%c%c", tr->name,
299 'a' - 1 + new->devnum / 26,
300 'a' + new->devnum % 26);
301 else
302 snprintf(gd->disk_name, sizeof(gd->disk_name),
303 "%s%d", tr->name, new->devnum);
297 304
298 /* 2.5 has capacity in units of 512 bytes while still 305 /* 2.5 has capacity in units of 512 bytes while still
299 having BLOCK_SIZE_BITS set to 10. Just to keep us amused. */ 306 having BLOCK_SIZE_BITS set to 10. Just to keep us amused. */
@@ -307,7 +314,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
307 set_disk_ro(gd, 1); 314 set_disk_ro(gd, 1);
308 315
309 add_disk(gd); 316 add_disk(gd);
310 317
311 return 0; 318 return 0;
312} 319}
313 320
@@ -322,7 +329,7 @@ int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
322 329
323 del_gendisk(old->blkcore_priv); 330 del_gendisk(old->blkcore_priv);
324 put_disk(old->blkcore_priv); 331 put_disk(old->blkcore_priv);
325 332
326 return 0; 333 return 0;
327} 334}
328 335
@@ -361,12 +368,12 @@ static struct mtd_notifier blktrans_notifier = {
361 .add = blktrans_notify_add, 368 .add = blktrans_notify_add,
362 .remove = blktrans_notify_remove, 369 .remove = blktrans_notify_remove,
363}; 370};
364 371
365int register_mtd_blktrans(struct mtd_blktrans_ops *tr) 372int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
366{ 373{
367 int ret, i; 374 int ret, i;
368 375
369 /* Register the notifier if/when the first device type is 376 /* Register the notifier if/when the first device type is
370 registered, to prevent the link/init ordering from fucking 377 registered, to prevent the link/init ordering from fucking
371 us over. */ 378 us over. */
372 if (!blktrans_notifier.list.next) 379 if (!blktrans_notifier.list.next)
@@ -409,9 +416,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
409 kfree(tr->blkcore_priv); 416 kfree(tr->blkcore_priv);
410 up(&mtd_table_mutex); 417 up(&mtd_table_mutex);
411 return ret; 418 return ret;
412 } 419 }
413
414 devfs_mk_dir(tr->name);
415 420
416 INIT_LIST_HEAD(&tr->devs); 421 INIT_LIST_HEAD(&tr->devs);
417 list_add(&tr->list, &blktrans_majors); 422 list_add(&tr->list, &blktrans_majors);
@@ -445,7 +450,6 @@ int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr)
445 tr->remove_dev(dev); 450 tr->remove_dev(dev);
446 } 451 }
447 452
448 devfs_remove(tr->name);
449 blk_cleanup_queue(tr->blkcore_priv->rq); 453 blk_cleanup_queue(tr->blkcore_priv->rq);
450 unregister_blkdev(tr->major, tr->name); 454 unregister_blkdev(tr->major, tr->name);
451 455
diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
index 400dd9c89883..e84756644fd1 100644
--- a/drivers/mtd/mtdblock.c
+++ b/drivers/mtd/mtdblock.c
@@ -1,21 +1,22 @@
1/* 1/*
2 * Direct MTD block device access 2 * Direct MTD block device access
3 * 3 *
4 * $Id: mtdblock.c,v 1.66 2004/11/25 13:52:52 joern Exp $ 4 * $Id: mtdblock.c,v 1.68 2005/11/07 11:14:20 gleixner Exp $
5 * 5 *
6 * (C) 2000-2003 Nicolas Pitre <nico@cam.org> 6 * (C) 2000-2003 Nicolas Pitre <nico@cam.org>
7 * (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> 7 * (C) 1999-2003 David Woodhouse <dwmw2@infradead.org>
8 */ 8 */
9 9
10#include <linux/config.h> 10#include <linux/config.h>
11#include <linux/types.h>
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/fs.h> 11#include <linux/fs.h>
15#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/sched.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/types.h>
17#include <linux/vmalloc.h> 18#include <linux/vmalloc.h>
18#include <linux/sched.h> /* TASK_* */ 19
19#include <linux/mtd/mtd.h> 20#include <linux/mtd/mtd.h>
20#include <linux/mtd/blktrans.h> 21#include <linux/mtd/blktrans.h>
21 22
@@ -31,7 +32,7 @@ static struct mtdblk_dev {
31 32
32/* 33/*
33 * Cache stuff... 34 * Cache stuff...
34 * 35 *
35 * Since typical flash erasable sectors are much larger than what Linux's 36 * Since typical flash erasable sectors are much larger than what Linux's
36 * buffer cache can handle, we must implement read-modify-write on flash 37 * buffer cache can handle, we must implement read-modify-write on flash
37 * sectors for each block write requests. To avoid over-erasing flash sectors 38 * sectors for each block write requests. To avoid over-erasing flash sectors
@@ -45,7 +46,7 @@ static void erase_callback(struct erase_info *done)
45 wake_up(wait_q); 46 wake_up(wait_q);
46} 47}
47 48
48static int erase_write (struct mtd_info *mtd, unsigned long pos, 49static int erase_write (struct mtd_info *mtd, unsigned long pos,
49 int len, const char *buf) 50 int len, const char *buf)
50{ 51{
51 struct erase_info erase; 52 struct erase_info erase;
@@ -103,18 +104,18 @@ static int write_cached_data (struct mtdblk_dev *mtdblk)
103 return 0; 104 return 0;
104 105
105 DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: writing cached data for \"%s\" " 106 DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: writing cached data for \"%s\" "
106 "at 0x%lx, size 0x%x\n", mtd->name, 107 "at 0x%lx, size 0x%x\n", mtd->name,
107 mtdblk->cache_offset, mtdblk->cache_size); 108 mtdblk->cache_offset, mtdblk->cache_size);
108 109
109 ret = erase_write (mtd, mtdblk->cache_offset, 110 ret = erase_write (mtd, mtdblk->cache_offset,
110 mtdblk->cache_size, mtdblk->cache_data); 111 mtdblk->cache_size, mtdblk->cache_data);
111 if (ret) 112 if (ret)
112 return ret; 113 return ret;
113 114
114 /* 115 /*
115 * Here we could argubly set the cache state to STATE_CLEAN. 116 * Here we could argubly set the cache state to STATE_CLEAN.
116 * However this could lead to inconsistency since we will not 117 * However this could lead to inconsistency since we will not
117 * be notified if this content is altered on the flash by other 118 * be notified if this content is altered on the flash by other
118 * means. Let's declare it empty and leave buffering tasks to 119 * means. Let's declare it empty and leave buffering tasks to
119 * the buffer cache instead. 120 * the buffer cache instead.
120 */ 121 */
@@ -123,7 +124,7 @@ static int write_cached_data (struct mtdblk_dev *mtdblk)
123} 124}
124 125
125 126
126static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos, 127static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
127 int len, const char *buf) 128 int len, const char *buf)
128{ 129{
129 struct mtd_info *mtd = mtdblk->mtd; 130 struct mtd_info *mtd = mtdblk->mtd;
@@ -133,7 +134,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
133 134
134 DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: write on \"%s\" at 0x%lx, size 0x%x\n", 135 DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: write on \"%s\" at 0x%lx, size 0x%x\n",
135 mtd->name, pos, len); 136 mtd->name, pos, len);
136 137
137 if (!sect_size) 138 if (!sect_size)
138 return MTD_WRITE (mtd, pos, len, &retlen, buf); 139 return MTD_WRITE (mtd, pos, len, &retlen, buf);
139 140
@@ -141,11 +142,11 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
141 unsigned long sect_start = (pos/sect_size)*sect_size; 142 unsigned long sect_start = (pos/sect_size)*sect_size;
142 unsigned int offset = pos - sect_start; 143 unsigned int offset = pos - sect_start;
143 unsigned int size = sect_size - offset; 144 unsigned int size = sect_size - offset;
144 if( size > len ) 145 if( size > len )
145 size = len; 146 size = len;
146 147
147 if (size == sect_size) { 148 if (size == sect_size) {
148 /* 149 /*
149 * We are covering a whole sector. Thus there is no 150 * We are covering a whole sector. Thus there is no
150 * need to bother with the cache while it may still be 151 * need to bother with the cache while it may still be
151 * useful for other partial writes. 152 * useful for other partial writes.
@@ -159,7 +160,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
159 if (mtdblk->cache_state == STATE_DIRTY && 160 if (mtdblk->cache_state == STATE_DIRTY &&
160 mtdblk->cache_offset != sect_start) { 161 mtdblk->cache_offset != sect_start) {
161 ret = write_cached_data(mtdblk); 162 ret = write_cached_data(mtdblk);
162 if (ret) 163 if (ret)
163 return ret; 164 return ret;
164 } 165 }
165 166
@@ -192,7 +193,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
192} 193}
193 194
194 195
195static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos, 196static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
196 int len, char *buf) 197 int len, char *buf)
197{ 198{
198 struct mtd_info *mtd = mtdblk->mtd; 199 struct mtd_info *mtd = mtdblk->mtd;
@@ -200,9 +201,9 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
200 size_t retlen; 201 size_t retlen;
201 int ret; 202 int ret;
202 203
203 DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n", 204 DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n",
204 mtd->name, pos, len); 205 mtd->name, pos, len);
205 206
206 if (!sect_size) 207 if (!sect_size)
207 return MTD_READ (mtd, pos, len, &retlen, buf); 208 return MTD_READ (mtd, pos, len, &retlen, buf);
208 209
@@ -210,7 +211,7 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
210 unsigned long sect_start = (pos/sect_size)*sect_size; 211 unsigned long sect_start = (pos/sect_size)*sect_size;
211 unsigned int offset = pos - sect_start; 212 unsigned int offset = pos - sect_start;
212 unsigned int size = sect_size - offset; 213 unsigned int size = sect_size - offset;
213 if (size > len) 214 if (size > len)
214 size = len; 215 size = len;
215 216
216 /* 217 /*
@@ -268,12 +269,12 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
268 int dev = mbd->devnum; 269 int dev = mbd->devnum;
269 270
270 DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n"); 271 DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n");
271 272
272 if (mtdblks[dev]) { 273 if (mtdblks[dev]) {
273 mtdblks[dev]->count++; 274 mtdblks[dev]->count++;
274 return 0; 275 return 0;
275 } 276 }
276 277
277 /* OK, it's not open. Create cache info for it */ 278 /* OK, it's not open. Create cache info for it */
278 mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL); 279 mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL);
279 if (!mtdblk) 280 if (!mtdblk)
@@ -292,7 +293,7 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
292 } 293 }
293 294
294 mtdblks[dev] = mtdblk; 295 mtdblks[dev] = mtdblk;
295 296
296 DEBUG(MTD_DEBUG_LEVEL1, "ok\n"); 297 DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
297 298
298 return 0; 299 return 0;
@@ -320,7 +321,7 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd)
320 DEBUG(MTD_DEBUG_LEVEL1, "ok\n"); 321 DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
321 322
322 return 0; 323 return 0;
323} 324}
324 325
325static int mtdblock_flush(struct mtd_blktrans_dev *dev) 326static int mtdblock_flush(struct mtd_blktrans_dev *dev)
326{ 327{
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 16df1e4fb0e9..6f044584bdc6 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -1,22 +1,23 @@
1/* 1/*
2 * $Id: mtdchar.c,v 1.73 2005/07/04 17:36:41 gleixner Exp $ 2 * $Id: mtdchar.c,v 1.76 2005/11/07 11:14:20 gleixner Exp $
3 * 3 *
4 * Character-device access to raw MTD devices. 4 * Character-device access to raw MTD devices.
5 * 5 *
6 */ 6 */
7 7
8#include <linux/config.h> 8#include <linux/config.h>
9#include <linux/device.h>
10#include <linux/fs.h>
11#include <linux/init.h>
9#include <linux/kernel.h> 12#include <linux/kernel.h>
10#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/slab.h>
15#include <linux/sched.h>
16
11#include <linux/mtd/mtd.h> 17#include <linux/mtd/mtd.h>
12#include <linux/mtd/compatmac.h> 18#include <linux/mtd/compatmac.h>
13#include <linux/slab.h>
14#include <linux/init.h>
15#include <linux/fs.h>
16#include <linux/sched.h> /* TASK_* */
17#include <asm/uaccess.h>
18 19
19#include <linux/device.h> 20#include <asm/uaccess.h>
20 21
21static struct class *mtd_class; 22static struct class *mtd_class;
22 23
@@ -27,7 +28,7 @@ static void mtd_notify_add(struct mtd_info* mtd)
27 28
28 class_device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2), 29 class_device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
29 NULL, "mtd%d", mtd->index); 30 NULL, "mtd%d", mtd->index);
30 31
31 class_device_create(mtd_class, NULL, 32 class_device_create(mtd_class, NULL,
32 MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1), 33 MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
33 NULL, "mtd%dro", mtd->index); 34 NULL, "mtd%dro", mtd->index);
@@ -70,26 +71,23 @@ static loff_t mtd_lseek (struct file *file, loff_t offset, int orig)
70 switch (orig) { 71 switch (orig) {
71 case 0: 72 case 0:
72 /* SEEK_SET */ 73 /* SEEK_SET */
73 file->f_pos = offset;
74 break; 74 break;
75 case 1: 75 case 1:
76 /* SEEK_CUR */ 76 /* SEEK_CUR */
77 file->f_pos += offset; 77 offset += file->f_pos;
78 break; 78 break;
79 case 2: 79 case 2:
80 /* SEEK_END */ 80 /* SEEK_END */
81 file->f_pos =mtd->size + offset; 81 offset += mtd->size;
82 break; 82 break;
83 default: 83 default:
84 return -EINVAL; 84 return -EINVAL;
85 } 85 }
86 86
87 if (file->f_pos < 0) 87 if (offset >= 0 && offset < mtd->size)
88 file->f_pos = 0; 88 return file->f_pos = offset;
89 else if (file->f_pos >= mtd->size)
90 file->f_pos = mtd->size - 1;
91 89
92 return file->f_pos; 90 return -EINVAL;
93} 91}
94 92
95 93
@@ -110,23 +108,23 @@ static int mtd_open(struct inode *inode, struct file *file)
110 return -EACCES; 108 return -EACCES;
111 109
112 mtd = get_mtd_device(NULL, devnum); 110 mtd = get_mtd_device(NULL, devnum);
113 111
114 if (!mtd) 112 if (!mtd)
115 return -ENODEV; 113 return -ENODEV;
116 114
117 if (MTD_ABSENT == mtd->type) { 115 if (MTD_ABSENT == mtd->type) {
118 put_mtd_device(mtd); 116 put_mtd_device(mtd);
119 return -ENODEV; 117 return -ENODEV;
120 } 118 }
121 119
122 file->private_data = mtd; 120 file->private_data = mtd;
123 121
124 /* You can't open it RW if it's not a writeable device */ 122 /* You can't open it RW if it's not a writeable device */
125 if ((file->f_mode & 2) && !(mtd->flags & MTD_WRITEABLE)) { 123 if ((file->f_mode & 2) && !(mtd->flags & MTD_WRITEABLE)) {
126 put_mtd_device(mtd); 124 put_mtd_device(mtd);
127 return -EACCES; 125 return -EACCES;
128 } 126 }
129 127
130 return 0; 128 return 0;
131} /* mtd_open */ 129} /* mtd_open */
132 130
@@ -139,10 +137,10 @@ static int mtd_close(struct inode *inode, struct file *file)
139 DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n"); 137 DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n");
140 138
141 mtd = TO_MTD(file); 139 mtd = TO_MTD(file);
142 140
143 if (mtd->sync) 141 if (mtd->sync)
144 mtd->sync(mtd); 142 mtd->sync(mtd);
145 143
146 put_mtd_device(mtd); 144 put_mtd_device(mtd);
147 145
148 return 0; 146 return 0;
@@ -161,7 +159,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
161 int ret=0; 159 int ret=0;
162 int len; 160 int len;
163 char *kbuf; 161 char *kbuf;
164 162
165 DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n"); 163 DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n");
166 164
167 if (*ppos + count > mtd->size) 165 if (*ppos + count > mtd->size)
@@ -169,11 +167,11 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
169 167
170 if (!count) 168 if (!count)
171 return 0; 169 return 0;
172 170
173 /* FIXME: Use kiovec in 2.5 to lock down the user's buffers 171 /* FIXME: Use kiovec in 2.5 to lock down the user's buffers
174 and pass them directly to the MTD functions */ 172 and pass them directly to the MTD functions */
175 while (count) { 173 while (count) {
176 if (count > MAX_KMALLOC_SIZE) 174 if (count > MAX_KMALLOC_SIZE)
177 len = MAX_KMALLOC_SIZE; 175 len = MAX_KMALLOC_SIZE;
178 else 176 else
179 len = count; 177 len = count;
@@ -181,7 +179,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
181 kbuf=kmalloc(len,GFP_KERNEL); 179 kbuf=kmalloc(len,GFP_KERNEL);
182 if (!kbuf) 180 if (!kbuf)
183 return -ENOMEM; 181 return -ENOMEM;
184 182
185 switch (MTD_MODE(file)) { 183 switch (MTD_MODE(file)) {
186 case MTD_MODE_OTP_FACT: 184 case MTD_MODE_OTP_FACT:
187 ret = mtd->read_fact_prot_reg(mtd, *ppos, len, &retlen, kbuf); 185 ret = mtd->read_fact_prot_reg(mtd, *ppos, len, &retlen, kbuf);
@@ -194,7 +192,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
194 } 192 }
195 /* Nand returns -EBADMSG on ecc errors, but it returns 193 /* Nand returns -EBADMSG on ecc errors, but it returns
196 * the data. For our userspace tools it is important 194 * the data. For our userspace tools it is important
197 * to dump areas with ecc errors ! 195 * to dump areas with ecc errors !
198 * Userspace software which accesses NAND this way 196 * Userspace software which accesses NAND this way
199 * must be aware of the fact that it deals with NAND 197 * must be aware of the fact that it deals with NAND
200 */ 198 */
@@ -216,7 +214,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
216 kfree(kbuf); 214 kfree(kbuf);
217 return ret; 215 return ret;
218 } 216 }
219 217
220 kfree(kbuf); 218 kfree(kbuf);
221 } 219 }
222 220
@@ -233,10 +231,10 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
233 int len; 231 int len;
234 232
235 DEBUG(MTD_DEBUG_LEVEL0,"MTD_write\n"); 233 DEBUG(MTD_DEBUG_LEVEL0,"MTD_write\n");
236 234
237 if (*ppos == mtd->size) 235 if (*ppos == mtd->size)
238 return -ENOSPC; 236 return -ENOSPC;
239 237
240 if (*ppos + count > mtd->size) 238 if (*ppos + count > mtd->size)
241 count = mtd->size - *ppos; 239 count = mtd->size - *ppos;
242 240
@@ -244,7 +242,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
244 return 0; 242 return 0;
245 243
246 while (count) { 244 while (count) {
247 if (count > MAX_KMALLOC_SIZE) 245 if (count > MAX_KMALLOC_SIZE)
248 len = MAX_KMALLOC_SIZE; 246 len = MAX_KMALLOC_SIZE;
249 else 247 else
250 len = count; 248 len = count;
@@ -259,7 +257,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
259 kfree(kbuf); 257 kfree(kbuf);
260 return -EFAULT; 258 return -EFAULT;
261 } 259 }
262 260
263 switch (MTD_MODE(file)) { 261 switch (MTD_MODE(file)) {
264 case MTD_MODE_OTP_FACT: 262 case MTD_MODE_OTP_FACT:
265 ret = -EROFS; 263 ret = -EROFS;
@@ -284,7 +282,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
284 kfree(kbuf); 282 kfree(kbuf);
285 return ret; 283 return ret;
286 } 284 }
287 285
288 kfree(kbuf); 286 kfree(kbuf);
289 } 287 }
290 288
@@ -308,7 +306,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
308 void __user *argp = (void __user *)arg; 306 void __user *argp = (void __user *)arg;
309 int ret = 0; 307 int ret = 0;
310 u_long size; 308 u_long size;
311 309
312 DEBUG(MTD_DEBUG_LEVEL0, "MTD_ioctl\n"); 310 DEBUG(MTD_DEBUG_LEVEL0, "MTD_ioctl\n");
313 311
314 size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT; 312 size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
@@ -320,7 +318,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
320 if (!access_ok(VERIFY_WRITE, argp, size)) 318 if (!access_ok(VERIFY_WRITE, argp, size))
321 return -EFAULT; 319 return -EFAULT;
322 } 320 }
323 321
324 switch (cmd) { 322 switch (cmd) {
325 case MEMGETREGIONCOUNT: 323 case MEMGETREGIONCOUNT:
326 if (copy_to_user(argp, &(mtd->numeraseregions), sizeof(int))) 324 if (copy_to_user(argp, &(mtd->numeraseregions), sizeof(int)))
@@ -372,11 +370,11 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
372 erase->mtd = mtd; 370 erase->mtd = mtd;
373 erase->callback = mtdchar_erase_callback; 371 erase->callback = mtdchar_erase_callback;
374 erase->priv = (unsigned long)&waitq; 372 erase->priv = (unsigned long)&waitq;
375 373
376 /* 374 /*
377 FIXME: Allow INTERRUPTIBLE. Which means 375 FIXME: Allow INTERRUPTIBLE. Which means
378 not having the wait_queue head on the stack. 376 not having the wait_queue head on the stack.
379 377
380 If the wq_head is on the stack, and we 378 If the wq_head is on the stack, and we
381 leave because we got interrupted, then the 379 leave because we got interrupted, then the
382 wq_head is no longer there when the 380 wq_head is no longer there when the
@@ -404,13 +402,13 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
404 struct mtd_oob_buf buf; 402 struct mtd_oob_buf buf;
405 void *databuf; 403 void *databuf;
406 ssize_t retlen; 404 ssize_t retlen;
407 405
408 if(!(file->f_mode & 2)) 406 if(!(file->f_mode & 2))
409 return -EPERM; 407 return -EPERM;
410 408
411 if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf))) 409 if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf)))
412 return -EFAULT; 410 return -EFAULT;
413 411
414 if (buf.length > 0x4096) 412 if (buf.length > 0x4096)
415 return -EINVAL; 413 return -EINVAL;
416 414
@@ -426,7 +424,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
426 databuf = kmalloc(buf.length, GFP_KERNEL); 424 databuf = kmalloc(buf.length, GFP_KERNEL);
427 if (!databuf) 425 if (!databuf)
428 return -ENOMEM; 426 return -ENOMEM;
429 427
430 if (copy_from_user(databuf, buf.ptr, buf.length)) { 428 if (copy_from_user(databuf, buf.ptr, buf.length)) {
431 kfree(databuf); 429 kfree(databuf);
432 return -EFAULT; 430 return -EFAULT;
@@ -450,7 +448,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
450 448
451 if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf))) 449 if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf)))
452 return -EFAULT; 450 return -EFAULT;
453 451
454 if (buf.length > 0x4096) 452 if (buf.length > 0x4096)
455 return -EINVAL; 453 return -EINVAL;
456 454
@@ -466,14 +464,14 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
466 databuf = kmalloc(buf.length, GFP_KERNEL); 464 databuf = kmalloc(buf.length, GFP_KERNEL);
467 if (!databuf) 465 if (!databuf)
468 return -ENOMEM; 466 return -ENOMEM;
469 467
470 ret = (mtd->read_oob)(mtd, buf.start, buf.length, &retlen, databuf); 468 ret = (mtd->read_oob)(mtd, buf.start, buf.length, &retlen, databuf);
471 469
472 if (put_user(retlen, (uint32_t __user *)argp)) 470 if (put_user(retlen, (uint32_t __user *)argp))
473 ret = -EFAULT; 471 ret = -EFAULT;
474 else if (retlen && copy_to_user(buf.ptr, databuf, retlen)) 472 else if (retlen && copy_to_user(buf.ptr, databuf, retlen))
475 ret = -EFAULT; 473 ret = -EFAULT;
476 474
477 kfree(databuf); 475 kfree(databuf);
478 break; 476 break;
479 } 477 }
@@ -523,7 +521,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
523 case MEMGETBADBLOCK: 521 case MEMGETBADBLOCK:
524 { 522 {
525 loff_t offs; 523 loff_t offs;
526 524
527 if (copy_from_user(&offs, argp, sizeof(loff_t))) 525 if (copy_from_user(&offs, argp, sizeof(loff_t)))
528 return -EFAULT; 526 return -EFAULT;
529 if (!mtd->block_isbad) 527 if (!mtd->block_isbad)
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index f3e65af33a9c..b1bf8c411de7 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -7,14 +7,15 @@
7 * 7 *
8 * This code is GPL 8 * This code is GPL
9 * 9 *
10 * $Id: mtdconcat.c,v 1.9 2004/06/30 15:17:41 dbrown Exp $ 10 * $Id: mtdconcat.c,v 1.11 2005/11/07 11:14:20 gleixner Exp $
11 */ 11 */
12 12
13#include <linux/module.h>
14#include <linux/types.h>
15#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/module.h>
16#include <linux/slab.h> 15#include <linux/slab.h>
17#include <linux/sched.h> /* TASK_* */ 16#include <linux/sched.h>
17#include <linux/types.h>
18
18#include <linux/mtd/mtd.h> 19#include <linux/mtd/mtd.h>
19#include <linux/mtd/concat.h> 20#include <linux/mtd/concat.h>
20 21
@@ -43,7 +44,7 @@ struct mtd_concat {
43 */ 44 */
44#define CONCAT(x) ((struct mtd_concat *)(x)) 45#define CONCAT(x) ((struct mtd_concat *)(x))
45 46
46/* 47/*
47 * MTD methods which look up the relevant subdevice, translate the 48 * MTD methods which look up the relevant subdevice, translate the
48 * effective address and pass through to the subdevice. 49 * effective address and pass through to the subdevice.
49 */ 50 */
@@ -877,7 +878,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
877 return &concat->mtd; 878 return &concat->mtd;
878} 879}
879 880
880/* 881/*
881 * This function destroys an MTD object obtained from concat_mtd_devs() 882 * This function destroys an MTD object obtained from concat_mtd_devs()
882 */ 883 */
883 884
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index dc86df18e94b..dade02ab0687 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: mtdcore.c,v 1.45 2005/02/18 14:34:50 dedekind Exp $ 2 * $Id: mtdcore.c,v 1.47 2005/11/07 11:14:20 gleixner Exp $
3 * 3 *
4 * Core registration and callback routines for MTD 4 * Core registration and callback routines for MTD
5 * drivers and users. 5 * drivers and users.
@@ -25,7 +25,7 @@
25 25
26#include <linux/mtd/mtd.h> 26#include <linux/mtd/mtd.h>
27 27
28/* These are exported solely for the purpose of mtd_blkdevs.c. You 28/* These are exported solely for the purpose of mtd_blkdevs.c. You
29 should not use them for _anything_ else */ 29 should not use them for _anything_ else */
30DECLARE_MUTEX(mtd_table_mutex); 30DECLARE_MUTEX(mtd_table_mutex);
31struct mtd_info *mtd_table[MAX_MTD_DEVICES]; 31struct mtd_info *mtd_table[MAX_MTD_DEVICES];
@@ -66,7 +66,7 @@ int add_mtd_device(struct mtd_info *mtd)
66 struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list); 66 struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list);
67 not->add(mtd); 67 not->add(mtd);
68 } 68 }
69 69
70 up(&mtd_table_mutex); 70 up(&mtd_table_mutex);
71 /* We _know_ we aren't being removed, because 71 /* We _know_ we aren't being removed, because
72 our caller is still holding us here. So none 72 our caller is still holding us here. So none
@@ -75,7 +75,7 @@ int add_mtd_device(struct mtd_info *mtd)
75 __module_get(THIS_MODULE); 75 __module_get(THIS_MODULE);
76 return 0; 76 return 0;
77 } 77 }
78 78
79 up(&mtd_table_mutex); 79 up(&mtd_table_mutex);
80 return 1; 80 return 1;
81} 81}
@@ -93,13 +93,13 @@ int add_mtd_device(struct mtd_info *mtd)
93int del_mtd_device (struct mtd_info *mtd) 93int del_mtd_device (struct mtd_info *mtd)
94{ 94{
95 int ret; 95 int ret;
96 96
97 down(&mtd_table_mutex); 97 down(&mtd_table_mutex);
98 98
99 if (mtd_table[mtd->index] != mtd) { 99 if (mtd_table[mtd->index] != mtd) {
100 ret = -ENODEV; 100 ret = -ENODEV;
101 } else if (mtd->usecount) { 101 } else if (mtd->usecount) {
102 printk(KERN_NOTICE "Removing MTD device #%d (%s) with use count %d\n", 102 printk(KERN_NOTICE "Removing MTD device #%d (%s) with use count %d\n",
103 mtd->index, mtd->name, mtd->usecount); 103 mtd->index, mtd->name, mtd->usecount);
104 ret = -EBUSY; 104 ret = -EBUSY;
105 } else { 105 } else {
@@ -140,7 +140,7 @@ void register_mtd_user (struct mtd_notifier *new)
140 list_add(&new->list, &mtd_notifiers); 140 list_add(&new->list, &mtd_notifiers);
141 141
142 __module_get(THIS_MODULE); 142 __module_get(THIS_MODULE);
143 143
144 for (i=0; i< MAX_MTD_DEVICES; i++) 144 for (i=0; i< MAX_MTD_DEVICES; i++)
145 if (mtd_table[i]) 145 if (mtd_table[i])
146 new->add(mtd_table[i]); 146 new->add(mtd_table[i]);
@@ -169,7 +169,7 @@ int unregister_mtd_user (struct mtd_notifier *old)
169 for (i=0; i< MAX_MTD_DEVICES; i++) 169 for (i=0; i< MAX_MTD_DEVICES; i++)
170 if (mtd_table[i]) 170 if (mtd_table[i])
171 old->remove(mtd_table[i]); 171 old->remove(mtd_table[i]);
172 172
173 list_del(&old->list); 173 list_del(&old->list);
174 up(&mtd_table_mutex); 174 up(&mtd_table_mutex);
175 return 0; 175 return 0;
@@ -187,7 +187,7 @@ int unregister_mtd_user (struct mtd_notifier *old)
187 * both, return the num'th driver only if its address matches. Return NULL 187 * both, return the num'th driver only if its address matches. Return NULL
188 * if not. 188 * if not.
189 */ 189 */
190 190
191struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num) 191struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)
192{ 192{
193 struct mtd_info *ret = NULL; 193 struct mtd_info *ret = NULL;
@@ -297,39 +297,6 @@ EXPORT_SYMBOL(default_mtd_writev);
297EXPORT_SYMBOL(default_mtd_readv); 297EXPORT_SYMBOL(default_mtd_readv);
298 298
299/*====================================================================*/ 299/*====================================================================*/
300/* Power management code */
301
302#ifdef CONFIG_PM
303
304#include <linux/pm.h>
305
306static struct pm_dev *mtd_pm_dev = NULL;
307
308static int mtd_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
309{
310 int ret = 0, i;
311
312 if (down_trylock(&mtd_table_mutex))
313 return -EAGAIN;
314 if (rqst == PM_SUSPEND) {
315 for (i = 0; ret == 0 && i < MAX_MTD_DEVICES; i++) {
316 if (mtd_table[i] && mtd_table[i]->suspend)
317 ret = mtd_table[i]->suspend(mtd_table[i]);
318 }
319 } else i = MAX_MTD_DEVICES-1;
320
321 if (rqst == PM_RESUME || ret) {
322 for ( ; i >= 0; i--) {
323 if (mtd_table[i] && mtd_table[i]->resume)
324 mtd_table[i]->resume(mtd_table[i]);
325 }
326 }
327 up(&mtd_table_mutex);
328 return ret;
329}
330#endif
331
332/*====================================================================*/
333/* Support for /proc/mtd */ 300/* Support for /proc/mtd */
334 301
335#ifdef CONFIG_PROC_FS 302#ifdef CONFIG_PROC_FS
@@ -388,22 +355,11 @@ static int __init init_mtd(void)
388 if ((proc_mtd = create_proc_entry( "mtd", 0, NULL ))) 355 if ((proc_mtd = create_proc_entry( "mtd", 0, NULL )))
389 proc_mtd->read_proc = mtd_read_proc; 356 proc_mtd->read_proc = mtd_read_proc;
390#endif 357#endif
391
392#ifdef CONFIG_PM
393 mtd_pm_dev = pm_register(PM_UNKNOWN_DEV, 0, mtd_pm_callback);
394#endif
395 return 0; 358 return 0;
396} 359}
397 360
398static void __exit cleanup_mtd(void) 361static void __exit cleanup_mtd(void)
399{ 362{
400#ifdef CONFIG_PM
401 if (mtd_pm_dev) {
402 pm_unregister(mtd_pm_dev);
403 mtd_pm_dev = NULL;
404 }
405#endif
406
407#ifdef CONFIG_PROC_FS 363#ifdef CONFIG_PROC_FS
408 if (proc_mtd) 364 if (proc_mtd)
409 remove_proc_entry( "mtd", NULL); 365 remove_proc_entry( "mtd", NULL);
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index b92e6bfffaf2..99395911d26f 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -5,11 +5,11 @@
5 * 5 *
6 * This code is GPL 6 * This code is GPL
7 * 7 *
8 * $Id: mtdpart.c,v 1.53 2005/02/08 17:11:13 nico Exp $ 8 * $Id: mtdpart.c,v 1.55 2005/11/07 11:14:20 gleixner Exp $
9 * 9 *
10 * 02-21-2002 Thomas Gleixner <gleixner@autronix.de> 10 * 02-21-2002 Thomas Gleixner <gleixner@autronix.de>
11 * added support for read_oob, write_oob 11 * added support for read_oob, write_oob
12 */ 12 */
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/types.h> 15#include <linux/types.h>
@@ -41,13 +41,13 @@ struct mtd_part {
41 */ 41 */
42#define PART(x) ((struct mtd_part *)(x)) 42#define PART(x) ((struct mtd_part *)(x))
43 43
44 44
45/* 45/*
46 * MTD methods which simply translate the effective address and pass through 46 * MTD methods which simply translate the effective address and pass through
47 * to the _real_ device. 47 * to the _real_ device.
48 */ 48 */
49 49
50static int part_read (struct mtd_info *mtd, loff_t from, size_t len, 50static int part_read (struct mtd_info *mtd, loff_t from, size_t len,
51 size_t *retlen, u_char *buf) 51 size_t *retlen, u_char *buf)
52{ 52{
53 struct mtd_part *part = PART(mtd); 53 struct mtd_part *part = PART(mtd);
@@ -55,15 +55,15 @@ static int part_read (struct mtd_info *mtd, loff_t from, size_t len,
55 len = 0; 55 len = 0;
56 else if (from + len > mtd->size) 56 else if (from + len > mtd->size)
57 len = mtd->size - from; 57 len = mtd->size - from;
58 if (part->master->read_ecc == NULL) 58 if (part->master->read_ecc == NULL)
59 return part->master->read (part->master, from + part->offset, 59 return part->master->read (part->master, from + part->offset,
60 len, retlen, buf); 60 len, retlen, buf);
61 else 61 else
62 return part->master->read_ecc (part->master, from + part->offset, 62 return part->master->read_ecc (part->master, from + part->offset,
63 len, retlen, buf, NULL, &mtd->oobinfo); 63 len, retlen, buf, NULL, &mtd->oobinfo);
64} 64}
65 65
66static int part_point (struct mtd_info *mtd, loff_t from, size_t len, 66static int part_point (struct mtd_info *mtd, loff_t from, size_t len,
67 size_t *retlen, u_char **buf) 67 size_t *retlen, u_char **buf)
68{ 68{
69 struct mtd_part *part = PART(mtd); 69 struct mtd_part *part = PART(mtd);
@@ -71,7 +71,7 @@ static int part_point (struct mtd_info *mtd, loff_t from, size_t len,
71 len = 0; 71 len = 0;
72 else if (from + len > mtd->size) 72 else if (from + len > mtd->size)
73 len = mtd->size - from; 73 len = mtd->size - from;
74 return part->master->point (part->master, from + part->offset, 74 return part->master->point (part->master, from + part->offset,
75 len, retlen, buf); 75 len, retlen, buf);
76} 76}
77static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len) 77static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len)
@@ -82,7 +82,7 @@ static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_
82} 82}
83 83
84 84
85static int part_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, 85static int part_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
86 size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel) 86 size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel)
87{ 87{
88 struct mtd_part *part = PART(mtd); 88 struct mtd_part *part = PART(mtd);
@@ -92,11 +92,11 @@ static int part_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
92 len = 0; 92 len = 0;
93 else if (from + len > mtd->size) 93 else if (from + len > mtd->size)
94 len = mtd->size - from; 94 len = mtd->size - from;
95 return part->master->read_ecc (part->master, from + part->offset, 95 return part->master->read_ecc (part->master, from + part->offset,
96 len, retlen, buf, eccbuf, oobsel); 96 len, retlen, buf, eccbuf, oobsel);
97} 97}
98 98
99static int part_read_oob (struct mtd_info *mtd, loff_t from, size_t len, 99static int part_read_oob (struct mtd_info *mtd, loff_t from, size_t len,
100 size_t *retlen, u_char *buf) 100 size_t *retlen, u_char *buf)
101{ 101{
102 struct mtd_part *part = PART(mtd); 102 struct mtd_part *part = PART(mtd);
@@ -104,15 +104,15 @@ static int part_read_oob (struct mtd_info *mtd, loff_t from, size_t len,
104 len = 0; 104 len = 0;
105 else if (from + len > mtd->size) 105 else if (from + len > mtd->size)
106 len = mtd->size - from; 106 len = mtd->size - from;
107 return part->master->read_oob (part->master, from + part->offset, 107 return part->master->read_oob (part->master, from + part->offset,
108 len, retlen, buf); 108 len, retlen, buf);
109} 109}
110 110
111static int part_read_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, 111static int part_read_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len,
112 size_t *retlen, u_char *buf) 112 size_t *retlen, u_char *buf)
113{ 113{
114 struct mtd_part *part = PART(mtd); 114 struct mtd_part *part = PART(mtd);
115 return part->master->read_user_prot_reg (part->master, from, 115 return part->master->read_user_prot_reg (part->master, from,
116 len, retlen, buf); 116 len, retlen, buf);
117} 117}
118 118
@@ -123,11 +123,11 @@ static int part_get_user_prot_info (struct mtd_info *mtd,
123 return part->master->get_user_prot_info (part->master, buf, len); 123 return part->master->get_user_prot_info (part->master, buf, len);
124} 124}
125 125
126static int part_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, 126static int part_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t len,
127 size_t *retlen, u_char *buf) 127 size_t *retlen, u_char *buf)
128{ 128{
129 struct mtd_part *part = PART(mtd); 129 struct mtd_part *part = PART(mtd);
130 return part->master->read_fact_prot_reg (part->master, from, 130 return part->master->read_fact_prot_reg (part->master, from,
131 len, retlen, buf); 131 len, retlen, buf);
132} 132}
133 133
@@ -148,13 +148,13 @@ static int part_write (struct mtd_info *mtd, loff_t to, size_t len,
148 len = 0; 148 len = 0;
149 else if (to + len > mtd->size) 149 else if (to + len > mtd->size)
150 len = mtd->size - to; 150 len = mtd->size - to;
151 if (part->master->write_ecc == NULL) 151 if (part->master->write_ecc == NULL)
152 return part->master->write (part->master, to + part->offset, 152 return part->master->write (part->master, to + part->offset,
153 len, retlen, buf); 153 len, retlen, buf);
154 else 154 else
155 return part->master->write_ecc (part->master, to + part->offset, 155 return part->master->write_ecc (part->master, to + part->offset,
156 len, retlen, buf, NULL, &mtd->oobinfo); 156 len, retlen, buf, NULL, &mtd->oobinfo);
157 157
158} 158}
159 159
160static int part_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, 160static int part_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
@@ -170,7 +170,7 @@ static int part_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
170 len = 0; 170 len = 0;
171 else if (to + len > mtd->size) 171 else if (to + len > mtd->size)
172 len = mtd->size - to; 172 len = mtd->size - to;
173 return part->master->write_ecc (part->master, to + part->offset, 173 return part->master->write_ecc (part->master, to + part->offset,
174 len, retlen, buf, eccbuf, oobsel); 174 len, retlen, buf, eccbuf, oobsel);
175} 175}
176 176
@@ -184,19 +184,19 @@ static int part_write_oob (struct mtd_info *mtd, loff_t to, size_t len,
184 len = 0; 184 len = 0;
185 else if (to + len > mtd->size) 185 else if (to + len > mtd->size)
186 len = mtd->size - to; 186 len = mtd->size - to;
187 return part->master->write_oob (part->master, to + part->offset, 187 return part->master->write_oob (part->master, to + part->offset,
188 len, retlen, buf); 188 len, retlen, buf);
189} 189}
190 190
191static int part_write_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, 191static int part_write_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len,
192 size_t *retlen, u_char *buf) 192 size_t *retlen, u_char *buf)
193{ 193{
194 struct mtd_part *part = PART(mtd); 194 struct mtd_part *part = PART(mtd);
195 return part->master->write_user_prot_reg (part->master, from, 195 return part->master->write_user_prot_reg (part->master, from,
196 len, retlen, buf); 196 len, retlen, buf);
197} 197}
198 198
199static int part_lock_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len) 199static int part_lock_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len)
200{ 200{
201 struct mtd_part *part = PART(mtd); 201 struct mtd_part *part = PART(mtd);
202 return part->master->lock_user_prot_reg (part->master, from, len); 202 return part->master->lock_user_prot_reg (part->master, from, len);
@@ -208,7 +208,7 @@ static int part_writev (struct mtd_info *mtd, const struct kvec *vecs,
208 struct mtd_part *part = PART(mtd); 208 struct mtd_part *part = PART(mtd);
209 if (!(mtd->flags & MTD_WRITEABLE)) 209 if (!(mtd->flags & MTD_WRITEABLE))
210 return -EROFS; 210 return -EROFS;
211 if (part->master->writev_ecc == NULL) 211 if (part->master->writev_ecc == NULL)
212 return part->master->writev (part->master, vecs, count, 212 return part->master->writev (part->master, vecs, count,
213 to + part->offset, retlen); 213 to + part->offset, retlen);
214 else 214 else
@@ -221,12 +221,12 @@ static int part_readv (struct mtd_info *mtd, struct kvec *vecs,
221 unsigned long count, loff_t from, size_t *retlen) 221 unsigned long count, loff_t from, size_t *retlen)
222{ 222{
223 struct mtd_part *part = PART(mtd); 223 struct mtd_part *part = PART(mtd);
224 if (part->master->readv_ecc == NULL) 224 if (part->master->readv_ecc == NULL)
225 return part->master->readv (part->master, vecs, count, 225 return part->master->readv (part->master, vecs, count,
226 from + part->offset, retlen); 226 from + part->offset, retlen);
227 else 227 else
228 return part->master->readv_ecc (part->master, vecs, count, 228 return part->master->readv_ecc (part->master, vecs, count,
229 from + part->offset, retlen, 229 from + part->offset, retlen,
230 NULL, &mtd->oobinfo); 230 NULL, &mtd->oobinfo);
231} 231}
232 232
@@ -252,7 +252,7 @@ static int part_readv_ecc (struct mtd_info *mtd, struct kvec *vecs,
252 if (oobsel == NULL) 252 if (oobsel == NULL)
253 oobsel = &mtd->oobinfo; 253 oobsel = &mtd->oobinfo;
254 return part->master->readv_ecc (part->master, vecs, count, 254 return part->master->readv_ecc (part->master, vecs, count,
255 from + part->offset, retlen, 255 from + part->offset, retlen,
256 eccbuf, oobsel); 256 eccbuf, oobsel);
257} 257}
258 258
@@ -286,7 +286,7 @@ EXPORT_SYMBOL_GPL(mtd_erase_callback);
286static int part_lock (struct mtd_info *mtd, loff_t ofs, size_t len) 286static int part_lock (struct mtd_info *mtd, loff_t ofs, size_t len)
287{ 287{
288 struct mtd_part *part = PART(mtd); 288 struct mtd_part *part = PART(mtd);
289 if ((len + ofs) > mtd->size) 289 if ((len + ofs) > mtd->size)
290 return -EINVAL; 290 return -EINVAL;
291 return part->master->lock(part->master, ofs + part->offset, len); 291 return part->master->lock(part->master, ofs + part->offset, len);
292} 292}
@@ -294,7 +294,7 @@ static int part_lock (struct mtd_info *mtd, loff_t ofs, size_t len)
294static int part_unlock (struct mtd_info *mtd, loff_t ofs, size_t len) 294static int part_unlock (struct mtd_info *mtd, loff_t ofs, size_t len)
295{ 295{
296 struct mtd_part *part = PART(mtd); 296 struct mtd_part *part = PART(mtd);
297 if ((len + ofs) > mtd->size) 297 if ((len + ofs) > mtd->size)
298 return -EINVAL; 298 return -EINVAL;
299 return part->master->unlock(part->master, ofs + part->offset, len); 299 return part->master->unlock(part->master, ofs + part->offset, len);
300} 300}
@@ -337,8 +337,8 @@ static int part_block_markbad (struct mtd_info *mtd, loff_t ofs)
337 return part->master->block_markbad(part->master, ofs); 337 return part->master->block_markbad(part->master, ofs);
338} 338}
339 339
340/* 340/*
341 * This function unregisters and destroy all slave MTD objects which are 341 * This function unregisters and destroy all slave MTD objects which are
342 * attached to the given master MTD object. 342 * attached to the given master MTD object.
343 */ 343 */
344 344
@@ -371,7 +371,7 @@ int del_mtd_partitions(struct mtd_info *master)
371 * (Q: should we register the master MTD object as well?) 371 * (Q: should we register the master MTD object as well?)
372 */ 372 */
373 373
374int add_mtd_partitions(struct mtd_info *master, 374int add_mtd_partitions(struct mtd_info *master,
375 const struct mtd_partition *parts, 375 const struct mtd_partition *parts,
376 int nbparts) 376 int nbparts)
377{ 377{
@@ -414,7 +414,7 @@ int add_mtd_partitions(struct mtd_info *master,
414 slave->mtd.point = part_point; 414 slave->mtd.point = part_point;
415 slave->mtd.unpoint = part_unpoint; 415 slave->mtd.unpoint = part_unpoint;
416 } 416 }
417 417
418 if (master->read_ecc) 418 if (master->read_ecc)
419 slave->mtd.read_ecc = part_read_ecc; 419 slave->mtd.read_ecc = part_read_ecc;
420 if (master->write_ecc) 420 if (master->write_ecc)
@@ -465,9 +465,10 @@ int add_mtd_partitions(struct mtd_info *master,
465 if (slave->offset == MTDPART_OFS_APPEND) 465 if (slave->offset == MTDPART_OFS_APPEND)
466 slave->offset = cur_offset; 466 slave->offset = cur_offset;
467 if (slave->offset == MTDPART_OFS_NXTBLK) { 467 if (slave->offset == MTDPART_OFS_NXTBLK) {
468 u_int32_t emask = master->erasesize-1; 468 slave->offset = cur_offset;
469 slave->offset = (cur_offset + emask) & ~emask; 469 if ((cur_offset % master->erasesize) != 0) {
470 if (slave->offset != cur_offset) { 470 /* Round up to next erasesize */
471 slave->offset = ((cur_offset / master->erasesize) + 1) * master->erasesize;
471 printk(KERN_NOTICE "Moving partition %d: " 472 printk(KERN_NOTICE "Moving partition %d: "
472 "0x%08x -> 0x%08x\n", i, 473 "0x%08x -> 0x%08x\n", i,
473 cur_offset, slave->offset); 474 cur_offset, slave->offset);
@@ -476,8 +477,8 @@ int add_mtd_partitions(struct mtd_info *master,
476 if (slave->mtd.size == MTDPART_SIZ_FULL) 477 if (slave->mtd.size == MTDPART_SIZ_FULL)
477 slave->mtd.size = master->size - slave->offset; 478 slave->mtd.size = master->size - slave->offset;
478 cur_offset = slave->offset + slave->mtd.size; 479 cur_offset = slave->offset + slave->mtd.size;
479 480
480 printk (KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset, 481 printk (KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset,
481 slave->offset + slave->mtd.size, slave->mtd.name); 482 slave->offset + slave->mtd.size, slave->mtd.name);
482 483
483 /* let's do some sanity checks */ 484 /* let's do some sanity checks */
@@ -497,7 +498,7 @@ int add_mtd_partitions(struct mtd_info *master,
497 /* Deal with variable erase size stuff */ 498 /* Deal with variable erase size stuff */
498 int i; 499 int i;
499 struct mtd_erase_region_info *regions = master->eraseregions; 500 struct mtd_erase_region_info *regions = master->eraseregions;
500 501
501 /* Find the first erase regions which is part of this partition. */ 502 /* Find the first erase regions which is part of this partition. */
502 for (i=0; i < master->numeraseregions && slave->offset >= regions[i].offset; i++) 503 for (i=0; i < master->numeraseregions && slave->offset >= regions[i].offset; i++)
503 ; 504 ;
@@ -512,7 +513,7 @@ int add_mtd_partitions(struct mtd_info *master,
512 slave->mtd.erasesize = master->erasesize; 513 slave->mtd.erasesize = master->erasesize;
513 } 514 }
514 515
515 if ((slave->mtd.flags & MTD_WRITEABLE) && 516 if ((slave->mtd.flags & MTD_WRITEABLE) &&
516 (slave->offset % slave->mtd.erasesize)) { 517 (slave->offset % slave->mtd.erasesize)) {
517 /* Doesn't start on a boundary of major erase size */ 518 /* Doesn't start on a boundary of major erase size */
518 /* FIXME: Let it be writable if it is on a boundary of _minor_ erase size though */ 519 /* FIXME: Let it be writable if it is on a boundary of _minor_ erase size though */
@@ -520,14 +521,14 @@ int add_mtd_partitions(struct mtd_info *master,
520 printk ("mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n", 521 printk ("mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n",
521 parts[i].name); 522 parts[i].name);
522 } 523 }
523 if ((slave->mtd.flags & MTD_WRITEABLE) && 524 if ((slave->mtd.flags & MTD_WRITEABLE) &&
524 (slave->mtd.size % slave->mtd.erasesize)) { 525 (slave->mtd.size % slave->mtd.erasesize)) {
525 slave->mtd.flags &= ~MTD_WRITEABLE; 526 slave->mtd.flags &= ~MTD_WRITEABLE;
526 printk ("mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n", 527 printk ("mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n",
527 parts[i].name); 528 parts[i].name);
528 } 529 }
529 530
530 /* copy oobinfo from master */ 531 /* copy oobinfo from master */
531 memcpy(&slave->mtd.oobinfo, &master->oobinfo, sizeof(slave->mtd.oobinfo)); 532 memcpy(&slave->mtd.oobinfo, &master->oobinfo, sizeof(slave->mtd.oobinfo));
532 533
533 if(parts[i].mtdp) 534 if(parts[i].mtdp)
@@ -588,12 +589,12 @@ int deregister_mtd_parser(struct mtd_part_parser *p)
588 return 0; 589 return 0;
589} 590}
590 591
591int parse_mtd_partitions(struct mtd_info *master, const char **types, 592int parse_mtd_partitions(struct mtd_info *master, const char **types,
592 struct mtd_partition **pparts, unsigned long origin) 593 struct mtd_partition **pparts, unsigned long origin)
593{ 594{
594 struct mtd_part_parser *parser; 595 struct mtd_part_parser *parser;
595 int ret = 0; 596 int ret = 0;
596 597
597 for ( ; ret <= 0 && *types; types++) { 598 for ( ; ret <= 0 && *types; types++) {
598 parser = get_partition_parser(*types); 599 parser = get_partition_parser(*types);
599#ifdef CONFIG_KMOD 600#ifdef CONFIG_KMOD
@@ -607,7 +608,7 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types,
607 } 608 }
608 ret = (*parser->parse_fn)(master, pparts, origin); 609 ret = (*parser->parse_fn)(master, pparts, origin);
609 if (ret > 0) { 610 if (ret > 0) {
610 printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n", 611 printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n",
611 ret, parser->name, master->name); 612 ret, parser->name, master->name);
612 } 613 }
613 put_partition_parser(parser); 614 put_partition_parser(parser);
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 36d34e5e5a5a..1fc4c134d939 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -1,5 +1,5 @@
1# drivers/mtd/nand/Kconfig 1# drivers/mtd/nand/Kconfig
2# $Id: Kconfig,v 1.31 2005/06/20 12:03:21 bjd Exp $ 2# $Id: Kconfig,v 1.35 2005/11/07 11:14:30 gleixner Exp $
3 3
4menu "NAND Flash Device Drivers" 4menu "NAND Flash Device Drivers"
5 depends on MTD!=n 5 depends on MTD!=n
@@ -25,33 +25,33 @@ config MTD_NAND_VERIFY_WRITE
25 25
26config MTD_NAND_AUTCPU12 26config MTD_NAND_AUTCPU12
27 tristate "SmartMediaCard on autronix autcpu12 board" 27 tristate "SmartMediaCard on autronix autcpu12 board"
28 depends on ARM && MTD_NAND && ARCH_AUTCPU12 28 depends on MTD_NAND && ARCH_AUTCPU12
29 help 29 help
30 This enables the driver for the autronix autcpu12 board to 30 This enables the driver for the autronix autcpu12 board to
31 access the SmartMediaCard. 31 access the SmartMediaCard.
32 32
33config MTD_NAND_EDB7312 33config MTD_NAND_EDB7312
34 tristate "Support for Cirrus Logic EBD7312 evaluation board" 34 tristate "Support for Cirrus Logic EBD7312 evaluation board"
35 depends on ARM && MTD_NAND && ARCH_EDB7312 35 depends on MTD_NAND && ARCH_EDB7312
36 help 36 help
37 This enables the driver for the Cirrus Logic EBD7312 evaluation 37 This enables the driver for the Cirrus Logic EBD7312 evaluation
38 board to access the onboard NAND Flash. 38 board to access the onboard NAND Flash.
39 39
40config MTD_NAND_H1900 40config MTD_NAND_H1900
41 tristate "iPAQ H1900 flash" 41 tristate "iPAQ H1900 flash"
42 depends on ARM && MTD_NAND && ARCH_PXA && MTD_PARTITIONS 42 depends on MTD_NAND && ARCH_PXA && MTD_PARTITIONS
43 help 43 help
44 This enables the driver for the iPAQ h1900 flash. 44 This enables the driver for the iPAQ h1900 flash.
45 45
46config MTD_NAND_SPIA 46config MTD_NAND_SPIA
47 tristate "NAND Flash device on SPIA board" 47 tristate "NAND Flash device on SPIA board"
48 depends on ARM && ARCH_P720T && MTD_NAND 48 depends on ARCH_P720T && MTD_NAND
49 help 49 help
50 If you had to ask, you don't have one. Say 'N'. 50 If you had to ask, you don't have one. Say 'N'.
51 51
52config MTD_NAND_TOTO 52config MTD_NAND_TOTO
53 tristate "NAND Flash device on TOTO board" 53 tristate "NAND Flash device on TOTO board"
54 depends on ARM && ARCH_OMAP && MTD_NAND 54 depends on ARCH_OMAP && MTD_NAND
55 help 55 help
56 Support for NAND flash on Texas Instruments Toto platform. 56 Support for NAND flash on Texas Instruments Toto platform.
57 57
@@ -59,8 +59,8 @@ config MTD_NAND_IDS
59 tristate 59 tristate
60 60
61config MTD_NAND_AU1550 61config MTD_NAND_AU1550
62 tristate "Au1550 NAND support" 62 tristate "Au1550/1200 NAND support"
63 depends on SOC_AU1550 && MTD_NAND 63 depends on (SOC_AU1200 || SOC_AU1550) && MTD_NAND
64 help 64 help
65 This enables the driver for the NAND flash controller on the 65 This enables the driver for the NAND flash controller on the
66 AMD/Alchemy 1550 SOC. 66 AMD/Alchemy 1550 SOC.
@@ -71,7 +71,7 @@ config MTD_NAND_RTC_FROM4
71 select REED_SOLOMON 71 select REED_SOLOMON
72 select REED_SOLOMON_DEC8 72 select REED_SOLOMON_DEC8
73 help 73 help
74 This enables the driver for the Renesas Technology AG-AND 74 This enables the driver for the Renesas Technology AG-AND
75 flash interface board (FROM_BOARD4) 75 flash interface board (FROM_BOARD4)
76 76
77config MTD_NAND_PPCHAMELEONEVB 77config MTD_NAND_PPCHAMELEONEVB
@@ -88,7 +88,7 @@ config MTD_NAND_S3C2410
88 SoCs 88 SoCs
89 89
90 No board specfic support is done by this driver, each board 90 No board specfic support is done by this driver, each board
91 must advertise a platform_device for the driver to attach. 91 must advertise a platform_device for the driver to attach.
92 92
93config MTD_NAND_S3C2410_DEBUG 93config MTD_NAND_S3C2410_DEBUG
94 bool "S3C2410 NAND driver debug" 94 bool "S3C2410 NAND driver debug"
@@ -181,7 +181,7 @@ config MTD_NAND_DISKONCHIP_BBTWRITE
181 181
182 config MTD_NAND_SHARPSL 182 config MTD_NAND_SHARPSL
183 bool "Support for NAND Flash on Sharp SL Series (C7xx + others)" 183 bool "Support for NAND Flash on Sharp SL Series (C7xx + others)"
184 depends on MTD_NAND && ARCH_PXA 184 depends on MTD_NAND && ARCH_PXA
185 185
186 config MTD_NAND_NANDSIM 186 config MTD_NAND_NANDSIM
187 bool "Support for NAND Flash Simulator" 187 bool "Support for NAND Flash Simulator"
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c
index 4c7719ce3f48..3cafcdf28aed 100644
--- a/drivers/mtd/nand/au1550nd.c
+++ b/drivers/mtd/nand/au1550nd.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2004 Embedded Edge, LLC 4 * Copyright (C) 2004 Embedded Edge, LLC
5 * 5 *
6 * $Id: au1550nd.c,v 1.11 2004/11/04 12:53:10 gleixner Exp $ 6 * $Id: au1550nd.c,v 1.13 2005/11/07 11:14:30 gleixner Exp $
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -21,20 +21,14 @@
21 21
22/* fixme: this is ugly */ 22/* fixme: this is ugly */
23#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 0) 23#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 0)
24#include <asm/mach-au1x00/au1000.h> 24#include <asm/mach-au1x00/au1xxx.h>
25#ifdef CONFIG_MIPS_PB1550
26#include <asm/mach-pb1x00/pb1550.h>
27#endif
28#ifdef CONFIG_MIPS_DB1550
29#include <asm/mach-db1x00/db1x00.h>
30#endif
31#else 25#else
32#include <asm/au1000.h> 26#include <asm/au1000.h>
33#ifdef CONFIG_MIPS_PB1550 27#ifdef CONFIG_MIPS_PB1550
34#include <asm/pb1550.h> 28#include <asm/pb1550.h>
35#endif 29#endif
36#ifdef CONFIG_MIPS_DB1550 30#ifdef CONFIG_MIPS_DB1550
37#include <asm/db1x00.h> 31#include <asm/db1x00.h>
38#endif 32#endif
39#endif 33#endif
40 34
@@ -45,39 +39,22 @@ static struct mtd_info *au1550_mtd = NULL;
45static void __iomem *p_nand; 39static void __iomem *p_nand;
46static int nand_width = 1; /* default x8*/ 40static int nand_width = 1; /* default x8*/
47 41
48#define NAND_CS 1
49
50/* 42/*
51 * Define partitions for flash device 43 * Define partitions for flash device
52 */ 44 */
53const static struct mtd_partition partition_info[] = { 45const static struct mtd_partition partition_info[] = {
54#ifdef CONFIG_MIPS_PB1550 46 {
55#define NUM_PARTITIONS 2 47 .name = "NAND FS 0",
56 {
57 .name = "Pb1550 NAND FS 0",
58 .offset = 0, 48 .offset = 0,
59 .size = 8*1024*1024 49 .size = 8*1024*1024
60 }, 50 },
61 { 51 {
62 .name = "Pb1550 NAND FS 1", 52 .name = "NAND FS 1",
63 .offset = MTDPART_OFS_APPEND, 53 .offset = MTDPART_OFS_APPEND,
64 .size = MTDPART_SIZ_FULL 54 .size = MTDPART_SIZ_FULL
65 } 55 }
66#endif
67#ifdef CONFIG_MIPS_DB1550
68#define NUM_PARTITIONS 2
69 {
70 .name = "Db1550 NAND FS 0",
71 .offset = 0,
72 .size = 8*1024*1024
73 },
74 {
75 .name = "Db1550 NAND FS 1",
76 .offset = MTDPART_OFS_APPEND,
77 .size = MTDPART_SIZ_FULL
78 }
79#endif
80}; 56};
57#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
81 58
82 59
83/** 60/**
@@ -112,7 +89,7 @@ static void au_write_byte(struct mtd_info *mtd, u_char byte)
112 * au_read_byte16 - read one byte endianess aware from the chip 89 * au_read_byte16 - read one byte endianess aware from the chip
113 * @mtd: MTD device structure 90 * @mtd: MTD device structure
114 * 91 *
115 * read function for 16bit buswith with 92 * read function for 16bit buswith with
116 * endianess conversion 93 * endianess conversion
117 */ 94 */
118static u_char au_read_byte16(struct mtd_info *mtd) 95static u_char au_read_byte16(struct mtd_info *mtd)
@@ -142,7 +119,7 @@ static void au_write_byte16(struct mtd_info *mtd, u_char byte)
142 * au_read_word - read one word from the chip 119 * au_read_word - read one word from the chip
143 * @mtd: MTD device structure 120 * @mtd: MTD device structure
144 * 121 *
145 * read function for 16bit buswith without 122 * read function for 16bit buswith without
146 * endianess conversion 123 * endianess conversion
147 */ 124 */
148static u16 au_read_word(struct mtd_info *mtd) 125static u16 au_read_word(struct mtd_info *mtd)
@@ -158,7 +135,7 @@ static u16 au_read_word(struct mtd_info *mtd)
158 * @mtd: MTD device structure 135 * @mtd: MTD device structure
159 * @word: data word to write 136 * @word: data word to write
160 * 137 *
161 * write function for 16bit buswith without 138 * write function for 16bit buswith without
162 * endianess conversion 139 * endianess conversion
163 */ 140 */
164static void au_write_word(struct mtd_info *mtd, u16 word) 141static void au_write_word(struct mtd_info *mtd, u16 word)
@@ -188,7 +165,7 @@ static void au_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
188} 165}
189 166
190/** 167/**
191 * au_read_buf - read chip data into buffer 168 * au_read_buf - read chip data into buffer
192 * @mtd: MTD device structure 169 * @mtd: MTD device structure
193 * @buf: buffer to store date 170 * @buf: buffer to store date
194 * @len: number of bytes to read 171 * @len: number of bytes to read
@@ -202,12 +179,12 @@ static void au_read_buf(struct mtd_info *mtd, u_char *buf, int len)
202 179
203 for (i=0; i<len; i++) { 180 for (i=0; i<len; i++) {
204 buf[i] = readb(this->IO_ADDR_R); 181 buf[i] = readb(this->IO_ADDR_R);
205 au_sync(); 182 au_sync();
206 } 183 }
207} 184}
208 185
209/** 186/**
210 * au_verify_buf - Verify chip data against buffer 187 * au_verify_buf - Verify chip data against buffer
211 * @mtd: MTD device structure 188 * @mtd: MTD device structure
212 * @buf: buffer containing the data to compare 189 * @buf: buffer containing the data to compare
213 * @len: number of bytes to compare 190 * @len: number of bytes to compare
@@ -242,16 +219,16 @@ static void au_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
242 struct nand_chip *this = mtd->priv; 219 struct nand_chip *this = mtd->priv;
243 u16 *p = (u16 *) buf; 220 u16 *p = (u16 *) buf;
244 len >>= 1; 221 len >>= 1;
245 222
246 for (i=0; i<len; i++) { 223 for (i=0; i<len; i++) {
247 writew(p[i], this->IO_ADDR_W); 224 writew(p[i], this->IO_ADDR_W);
248 au_sync(); 225 au_sync();
249 } 226 }
250 227
251} 228}
252 229
253/** 230/**
254 * au_read_buf16 - read chip data into buffer 231 * au_read_buf16 - read chip data into buffer
255 * @mtd: MTD device structure 232 * @mtd: MTD device structure
256 * @buf: buffer to store date 233 * @buf: buffer to store date
257 * @len: number of bytes to read 234 * @len: number of bytes to read
@@ -272,7 +249,7 @@ static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
272} 249}
273 250
274/** 251/**
275 * au_verify_buf16 - Verify chip data against buffer 252 * au_verify_buf16 - Verify chip data against buffer
276 * @mtd: MTD device structure 253 * @mtd: MTD device structure
277 * @buf: buffer containing the data to compare 254 * @buf: buffer containing the data to compare
278 * @len: number of bytes to compare 255 * @len: number of bytes to compare
@@ -305,26 +282,26 @@ static void au1550_hwcontrol(struct mtd_info *mtd, int cmd)
305 case NAND_CTL_CLRCLE: this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; break; 282 case NAND_CTL_CLRCLE: this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; break;
306 283
307 case NAND_CTL_SETALE: this->IO_ADDR_W = p_nand + MEM_STNAND_ADDR; break; 284 case NAND_CTL_SETALE: this->IO_ADDR_W = p_nand + MEM_STNAND_ADDR; break;
308 case NAND_CTL_CLRALE: 285 case NAND_CTL_CLRALE:
309 this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; 286 this->IO_ADDR_W = p_nand + MEM_STNAND_DATA;
310 /* FIXME: Nobody knows why this is neccecary, 287 /* FIXME: Nobody knows why this is neccecary,
311 * but it works only that way */ 288 * but it works only that way */
312 udelay(1); 289 udelay(1);
313 break; 290 break;
314 291
315 case NAND_CTL_SETNCE: 292 case NAND_CTL_SETNCE:
316 /* assert (force assert) chip enable */ 293 /* assert (force assert) chip enable */
317 au_writel((1<<(4+NAND_CS)) , MEM_STNDCTL); break; 294 au_writel((1<<(4+NAND_CS)) , MEM_STNDCTL); break;
318 break; 295 break;
319 296
320 case NAND_CTL_CLRNCE: 297 case NAND_CTL_CLRNCE:
321 /* deassert chip enable */ 298 /* deassert chip enable */
322 au_writel(0, MEM_STNDCTL); break; 299 au_writel(0, MEM_STNDCTL); break;
323 break; 300 break;
324 } 301 }
325 302
326 this->IO_ADDR_R = this->IO_ADDR_W; 303 this->IO_ADDR_R = this->IO_ADDR_W;
327 304
328 /* Drain the writebuffer */ 305 /* Drain the writebuffer */
329 au_sync(); 306 au_sync();
330} 307}
@@ -339,14 +316,16 @@ int au1550_device_ready(struct mtd_info *mtd)
339/* 316/*
340 * Main initialization routine 317 * Main initialization routine
341 */ 318 */
342int __init au1550_init (void) 319int __init au1xxx_nand_init (void)
343{ 320{
344 struct nand_chip *this; 321 struct nand_chip *this;
345 u16 boot_swapboot = 0; /* default value */ 322 u16 boot_swapboot = 0; /* default value */
346 int retval; 323 int retval;
324 u32 mem_staddr;
325 u32 nand_phys;
347 326
348 /* Allocate memory for MTD device structure and private data */ 327 /* Allocate memory for MTD device structure and private data */
349 au1550_mtd = kmalloc (sizeof(struct mtd_info) + 328 au1550_mtd = kmalloc (sizeof(struct mtd_info) +
350 sizeof (struct nand_chip), GFP_KERNEL); 329 sizeof (struct nand_chip), GFP_KERNEL);
351 if (!au1550_mtd) { 330 if (!au1550_mtd) {
352 printk ("Unable to allocate NAND MTD dev structure.\n"); 331 printk ("Unable to allocate NAND MTD dev structure.\n");
@@ -364,14 +343,17 @@ int __init au1550_init (void)
364 au1550_mtd->priv = this; 343 au1550_mtd->priv = this;
365 344
366 345
367 /* MEM_STNDCTL: disable ints, disable nand boot */ 346 /* disable interrupts */
368 au_writel(0, MEM_STNDCTL); 347 au_writel(au_readl(MEM_STNDCTL) & ~(1<<8), MEM_STNDCTL);
348
349 /* disable NAND boot */
350 au_writel(au_readl(MEM_STNDCTL) & ~(1<<0), MEM_STNDCTL);
369 351
370#ifdef CONFIG_MIPS_PB1550 352#ifdef CONFIG_MIPS_PB1550
371 /* set gpio206 high */ 353 /* set gpio206 high */
372 au_writel(au_readl(GPIO2_DIR) & ~(1<<6), GPIO2_DIR); 354 au_writel(au_readl(GPIO2_DIR) & ~(1<<6), GPIO2_DIR);
373 355
374 boot_swapboot = (au_readl(MEM_STSTAT) & (0x7<<1)) | 356 boot_swapboot = (au_readl(MEM_STSTAT) & (0x7<<1)) |
375 ((bcsr->status >> 6) & 0x1); 357 ((bcsr->status >> 6) & 0x1);
376 switch (boot_swapboot) { 358 switch (boot_swapboot) {
377 case 0: 359 case 0:
@@ -397,25 +379,66 @@ int __init au1550_init (void)
397 } 379 }
398#endif 380#endif
399 381
400 /* Configure RCE1 - should be done by YAMON */ 382 /* Configure chip-select; normally done by boot code, e.g. YAMON */
401 au_writel(0x5 | (nand_width << 22), 0xB4001010); /* MEM_STCFG1 */ 383#ifdef NAND_STCFG
402 au_writel(NAND_TIMING, 0xB4001014); /* MEM_STTIME1 */ 384 if (NAND_CS == 0) {
403 au_sync(); 385 au_writel(NAND_STCFG, MEM_STCFG0);
386 au_writel(NAND_STTIME, MEM_STTIME0);
387 au_writel(NAND_STADDR, MEM_STADDR0);
388 }
389 if (NAND_CS == 1) {
390 au_writel(NAND_STCFG, MEM_STCFG1);
391 au_writel(NAND_STTIME, MEM_STTIME1);
392 au_writel(NAND_STADDR, MEM_STADDR1);
393 }
394 if (NAND_CS == 2) {
395 au_writel(NAND_STCFG, MEM_STCFG2);
396 au_writel(NAND_STTIME, MEM_STTIME2);
397 au_writel(NAND_STADDR, MEM_STADDR2);
398 }
399 if (NAND_CS == 3) {
400 au_writel(NAND_STCFG, MEM_STCFG3);
401 au_writel(NAND_STTIME, MEM_STTIME3);
402 au_writel(NAND_STADDR, MEM_STADDR3);
403 }
404#endif
404 405
405 /* setup and enable chip select, MEM_STADDR1 */ 406 /* Locate NAND chip-select in order to determine NAND phys address */
406 /* we really need to decode offsets only up till 0x20 */ 407 mem_staddr = 0x00000000;
407 au_writel((1<<28) | (NAND_PHYS_ADDR>>4) | 408 if (((au_readl(MEM_STCFG0) & 0x7) == 0x5) && (NAND_CS == 0))
408 (((NAND_PHYS_ADDR + 0x1000)-1) & (0x3fff<<18)>>18), 409 mem_staddr = au_readl(MEM_STADDR0);
409 MEM_STADDR1); 410 else if (((au_readl(MEM_STCFG1) & 0x7) == 0x5) && (NAND_CS == 1))
410 au_sync(); 411 mem_staddr = au_readl(MEM_STADDR1);
412 else if (((au_readl(MEM_STCFG2) & 0x7) == 0x5) && (NAND_CS == 2))
413 mem_staddr = au_readl(MEM_STADDR2);
414 else if (((au_readl(MEM_STCFG3) & 0x7) == 0x5) && (NAND_CS == 3))
415 mem_staddr = au_readl(MEM_STADDR3);
416
417 if (mem_staddr == 0x00000000) {
418 printk("Au1xxx NAND: ERROR WITH NAND CHIP-SELECT\n");
419 kfree(au1550_mtd);
420 return 1;
421 }
422 nand_phys = (mem_staddr << 4) & 0xFFFC0000;
423
424 p_nand = (void __iomem *)ioremap(nand_phys, 0x1000);
425
426 /* make controller and MTD agree */
427 if (NAND_CS == 0)
428 nand_width = au_readl(MEM_STCFG0) & (1<<22);
429 if (NAND_CS == 1)
430 nand_width = au_readl(MEM_STCFG1) & (1<<22);
431 if (NAND_CS == 2)
432 nand_width = au_readl(MEM_STCFG2) & (1<<22);
433 if (NAND_CS == 3)
434 nand_width = au_readl(MEM_STCFG3) & (1<<22);
411 435
412 p_nand = ioremap(NAND_PHYS_ADDR, 0x1000);
413 436
414 /* Set address of hardware control function */ 437 /* Set address of hardware control function */
415 this->hwcontrol = au1550_hwcontrol; 438 this->hwcontrol = au1550_hwcontrol;
416 this->dev_ready = au1550_device_ready; 439 this->dev_ready = au1550_device_ready;
417 /* 30 us command delay time */ 440 /* 30 us command delay time */
418 this->chip_delay = 30; 441 this->chip_delay = 30;
419 this->eccmode = NAND_ECC_SOFT; 442 this->eccmode = NAND_ECC_SOFT;
420 443
421 this->options = NAND_NO_AUTOINCR; 444 this->options = NAND_NO_AUTOINCR;
@@ -438,19 +461,19 @@ int __init au1550_init (void)
438 } 461 }
439 462
440 /* Register the partitions */ 463 /* Register the partitions */
441 add_mtd_partitions(au1550_mtd, partition_info, NUM_PARTITIONS); 464 add_mtd_partitions(au1550_mtd, partition_info, NB_OF(partition_info));
442 465
443 return 0; 466 return 0;
444 467
445 outio: 468 outio:
446 iounmap ((void *)p_nand); 469 iounmap ((void *)p_nand);
447 470
448 outmem: 471 outmem:
449 kfree (au1550_mtd); 472 kfree (au1550_mtd);
450 return retval; 473 return retval;
451} 474}
452 475
453module_init(au1550_init); 476module_init(au1xxx_nand_init);
454 477
455/* 478/*
456 * Clean up routine 479 * Clean up routine
diff --git a/drivers/mtd/nand/autcpu12.c b/drivers/mtd/nand/autcpu12.c
index 4afa8ced05ad..056dfc17a075 100644
--- a/drivers/mtd/nand/autcpu12.c
+++ b/drivers/mtd/nand/autcpu12.c
@@ -5,8 +5,8 @@
5 * 5 *
6 * Derived from drivers/mtd/spia.c 6 * Derived from drivers/mtd/spia.c
7 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) 7 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
8 * 8 *
9 * $Id: autcpu12.c,v 1.22 2004/11/04 12:53:10 gleixner Exp $ 9 * $Id: autcpu12.c,v 1.23 2005/11/07 11:14:30 gleixner Exp $
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as 12 * it under the terms of the GNU General Public License version 2 as
@@ -14,7 +14,7 @@
14 * 14 *
15 * Overview: 15 * Overview:
16 * This is a device driver for the NAND flash device found on the 16 * This is a device driver for the NAND flash device found on the
17 * autronix autcpu12 board, which is a SmartMediaCard. It supports 17 * autronix autcpu12 board, which is a SmartMediaCard. It supports
18 * 16MiB, 32MiB and 64MiB cards. 18 * 16MiB, 32MiB and 64MiB cards.
19 * 19 *
20 * 20 *
@@ -93,7 +93,7 @@ static struct mtd_partition partition_info128k[] = {
93#define NUM_PARTITIONS32K 2 93#define NUM_PARTITIONS32K 2
94#define NUM_PARTITIONS64K 2 94#define NUM_PARTITIONS64K 2
95#define NUM_PARTITIONS128K 2 95#define NUM_PARTITIONS128K 2
96/* 96/*
97 * hardware specific access to control-lines 97 * hardware specific access to control-lines
98*/ 98*/
99static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd) 99static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd)
@@ -163,7 +163,7 @@ int __init autcpu12_init (void)
163 this->hwcontrol = autcpu12_hwcontrol; 163 this->hwcontrol = autcpu12_hwcontrol;
164 this->dev_ready = autcpu12_device_ready; 164 this->dev_ready = autcpu12_device_ready;
165 /* 20 us command delay time */ 165 /* 20 us command delay time */
166 this->chip_delay = 20; 166 this->chip_delay = 20;
167 this->eccmode = NAND_ECC_SOFT; 167 this->eccmode = NAND_ECC_SOFT;
168 168
169 /* Enable the following for a flash based bad block table */ 169 /* Enable the following for a flash based bad block table */
@@ -171,21 +171,21 @@ int __init autcpu12_init (void)
171 this->options = NAND_USE_FLASH_BBT; 171 this->options = NAND_USE_FLASH_BBT;
172 */ 172 */
173 this->options = NAND_USE_FLASH_BBT; 173 this->options = NAND_USE_FLASH_BBT;
174 174
175 /* Scan to find existance of the device */ 175 /* Scan to find existance of the device */
176 if (nand_scan (autcpu12_mtd, 1)) { 176 if (nand_scan (autcpu12_mtd, 1)) {
177 err = -ENXIO; 177 err = -ENXIO;
178 goto out_ior; 178 goto out_ior;
179 } 179 }
180 180
181 /* Register the partitions */ 181 /* Register the partitions */
182 switch(autcpu12_mtd->size){ 182 switch(autcpu12_mtd->size){
183 case SZ_16M: add_mtd_partitions(autcpu12_mtd, partition_info16k, NUM_PARTITIONS16K); break; 183 case SZ_16M: add_mtd_partitions(autcpu12_mtd, partition_info16k, NUM_PARTITIONS16K); break;
184 case SZ_32M: add_mtd_partitions(autcpu12_mtd, partition_info32k, NUM_PARTITIONS32K); break; 184 case SZ_32M: add_mtd_partitions(autcpu12_mtd, partition_info32k, NUM_PARTITIONS32K); break;
185 case SZ_64M: add_mtd_partitions(autcpu12_mtd, partition_info64k, NUM_PARTITIONS64K); break; 185 case SZ_64M: add_mtd_partitions(autcpu12_mtd, partition_info64k, NUM_PARTITIONS64K); break;
186 case SZ_128M: add_mtd_partitions(autcpu12_mtd, partition_info128k, NUM_PARTITIONS128K); break; 186 case SZ_128M: add_mtd_partitions(autcpu12_mtd, partition_info128k, NUM_PARTITIONS128K); break;
187 default: { 187 default: {
188 printk ("Unsupported SmartMedia device\n"); 188 printk ("Unsupported SmartMedia device\n");
189 err = -ENXIO; 189 err = -ENXIO;
190 goto out_ior; 190 goto out_ior;
191 } 191 }
@@ -213,7 +213,7 @@ static void __exit autcpu12_cleanup (void)
213 213
214 /* unmap physical adress */ 214 /* unmap physical adress */
215 iounmap((void *)autcpu12_fio_base); 215 iounmap((void *)autcpu12_fio_base);
216 216
217 /* Free the MTD device structure */ 217 /* Free the MTD device structure */
218 kfree (autcpu12_mtd); 218 kfree (autcpu12_mtd);
219} 219}
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index fdb5d4ad3d52..21d4e8f4b7af 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * drivers/mtd/nand/diskonchip.c 2 * drivers/mtd/nand/diskonchip.c
3 * 3 *
4 * (C) 2003 Red Hat, Inc. 4 * (C) 2003 Red Hat, Inc.
@@ -8,15 +8,15 @@
8 * Author: David Woodhouse <dwmw2@infradead.org> 8 * Author: David Woodhouse <dwmw2@infradead.org>
9 * Additional Diskonchip 2000 and Millennium support by Dan Brown <dan_brown@ieee.org> 9 * Additional Diskonchip 2000 and Millennium support by Dan Brown <dan_brown@ieee.org>
10 * Diskonchip Millennium Plus support by Kalev Lember <kalev@smartlink.ee> 10 * Diskonchip Millennium Plus support by Kalev Lember <kalev@smartlink.ee>
11 * 11 *
12 * Error correction code lifted from the old docecc code 12 * Error correction code lifted from the old docecc code
13 * Author: Fabrice Bellard (fabrice.bellard@netgem.com) 13 * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
14 * Copyright (C) 2000 Netgem S.A. 14 * Copyright (C) 2000 Netgem S.A.
15 * converted to the generic Reed-Solomon library by Thomas Gleixner <tglx@linutronix.de> 15 * converted to the generic Reed-Solomon library by Thomas Gleixner <tglx@linutronix.de>
16 * 16 *
17 * Interface to generic NAND code for M-Systems DiskOnChip devices 17 * Interface to generic NAND code for M-Systems DiskOnChip devices
18 * 18 *
19 * $Id: diskonchip.c,v 1.54 2005/04/07 14:22:55 dbrown Exp $ 19 * $Id: diskonchip.c,v 1.55 2005/11/07 11:14:30 gleixner Exp $
20 */ 20 */
21 21
22#include <linux/kernel.h> 22#include <linux/kernel.h>
@@ -42,16 +42,16 @@
42static unsigned long __initdata doc_locations[] = { 42static unsigned long __initdata doc_locations[] = {
43#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__) 43#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__)
44#ifdef CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH 44#ifdef CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH
45 0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000, 45 0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,
46 0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000, 46 0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000,
47 0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000, 47 0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000,
48 0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000, 48 0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000,
49 0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000, 49 0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000,
50#else /* CONFIG_MTD_DOCPROBE_HIGH */ 50#else /* CONFIG_MTD_DOCPROBE_HIGH */
51 0xc8000, 0xca000, 0xcc000, 0xce000, 51 0xc8000, 0xca000, 0xcc000, 0xce000,
52 0xd0000, 0xd2000, 0xd4000, 0xd6000, 52 0xd0000, 0xd2000, 0xd4000, 0xd6000,
53 0xd8000, 0xda000, 0xdc000, 0xde000, 53 0xd8000, 0xda000, 0xdc000, 0xde000,
54 0xe0000, 0xe2000, 0xe4000, 0xe6000, 54 0xe0000, 0xe2000, 0xe4000, 0xe6000,
55 0xe8000, 0xea000, 0xec000, 0xee000, 55 0xe8000, 0xea000, 0xec000, 0xee000,
56#endif /* CONFIG_MTD_DOCPROBE_HIGH */ 56#endif /* CONFIG_MTD_DOCPROBE_HIGH */
57#elif defined(__PPC__) 57#elif defined(__PPC__)
@@ -138,7 +138,7 @@ MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe
138/* the Reed Solomon control structure */ 138/* the Reed Solomon control structure */
139static struct rs_control *rs_decoder; 139static struct rs_control *rs_decoder;
140 140
141/* 141/*
142 * The HW decoder in the DoC ASIC's provides us a error syndrome, 142 * The HW decoder in the DoC ASIC's provides us a error syndrome,
143 * which we must convert to a standard syndrom usable by the generic 143 * which we must convert to a standard syndrom usable by the generic
144 * Reed-Solomon library code. 144 * Reed-Solomon library code.
@@ -163,8 +163,8 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
163 /* Initialize the syndrom buffer */ 163 /* Initialize the syndrom buffer */
164 for (i = 0; i < NROOTS; i++) 164 for (i = 0; i < NROOTS; i++)
165 s[i] = ds[0]; 165 s[i] = ds[0];
166 /* 166 /*
167 * Evaluate 167 * Evaluate
168 * s[i] = ds[3]x^3 + ds[2]x^2 + ds[1]x^1 + ds[0] 168 * s[i] = ds[3]x^3 + ds[2]x^2 + ds[1]x^1 + ds[0]
169 * where x = alpha^(FCR + i) 169 * where x = alpha^(FCR + i)
170 */ 170 */
@@ -188,7 +188,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
188 if (nerr < 0) 188 if (nerr < 0)
189 return nerr; 189 return nerr;
190 190
191 /* 191 /*
192 * Correct the errors. The bitpositions are a bit of magic, 192 * Correct the errors. The bitpositions are a bit of magic,
193 * but they are given by the design of the de/encoder circuit 193 * but they are given by the design of the de/encoder circuit
194 * in the DoC ASIC's. 194 * in the DoC ASIC's.
@@ -205,7 +205,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
205 can be modified since pos is even */ 205 can be modified since pos is even */
206 index = (pos >> 3) ^ 1; 206 index = (pos >> 3) ^ 1;
207 bitpos = pos & 7; 207 bitpos = pos & 7;
208 if ((index >= 0 && index < SECTOR_SIZE) || 208 if ((index >= 0 && index < SECTOR_SIZE) ||
209 index == (SECTOR_SIZE + 1)) { 209 index == (SECTOR_SIZE + 1)) {
210 val = (uint8_t) (errval[i] >> (2 + bitpos)); 210 val = (uint8_t) (errval[i] >> (2 + bitpos));
211 parity ^= val; 211 parity ^= val;
@@ -216,7 +216,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
216 bitpos = (bitpos + 10) & 7; 216 bitpos = (bitpos + 10) & 7;
217 if (bitpos == 0) 217 if (bitpos == 0)
218 bitpos = 8; 218 bitpos = 8;
219 if ((index >= 0 && index < SECTOR_SIZE) || 219 if ((index >= 0 && index < SECTOR_SIZE) ||
220 index == (SECTOR_SIZE + 1)) { 220 index == (SECTOR_SIZE + 1)) {
221 val = (uint8_t)(errval[i] << (8 - bitpos)); 221 val = (uint8_t)(errval[i] << (8 - bitpos));
222 parity ^= val; 222 parity ^= val;
@@ -233,7 +233,7 @@ static void DoC_Delay(struct doc_priv *doc, unsigned short cycles)
233{ 233{
234 volatile char dummy; 234 volatile char dummy;
235 int i; 235 int i;
236 236
237 for (i = 0; i < cycles; i++) { 237 for (i = 0; i < cycles; i++) {
238 if (DoC_is_Millennium(doc)) 238 if (DoC_is_Millennium(doc))
239 dummy = ReadDOC(doc->virtadr, NOP); 239 dummy = ReadDOC(doc->virtadr, NOP);
@@ -242,7 +242,7 @@ static void DoC_Delay(struct doc_priv *doc, unsigned short cycles)
242 else 242 else
243 dummy = ReadDOC(doc->virtadr, DOCStatus); 243 dummy = ReadDOC(doc->virtadr, DOCStatus);
244 } 244 }
245 245
246} 246}
247 247
248#define CDSN_CTRL_FR_B_MASK (CDSN_CTRL_FR_B0 | CDSN_CTRL_FR_B1) 248#define CDSN_CTRL_FR_B_MASK (CDSN_CTRL_FR_B0 | CDSN_CTRL_FR_B1)
@@ -327,7 +327,7 @@ static u_char doc2000_read_byte(struct mtd_info *mtd)
327 return ret; 327 return ret;
328} 328}
329 329
330static void doc2000_writebuf(struct mtd_info *mtd, 330static void doc2000_writebuf(struct mtd_info *mtd,
331 const u_char *buf, int len) 331 const u_char *buf, int len)
332{ 332{
333 struct nand_chip *this = mtd->priv; 333 struct nand_chip *this = mtd->priv;
@@ -343,7 +343,7 @@ static void doc2000_writebuf(struct mtd_info *mtd,
343 if (debug) printk("\n"); 343 if (debug) printk("\n");
344} 344}
345 345
346static void doc2000_readbuf(struct mtd_info *mtd, 346static void doc2000_readbuf(struct mtd_info *mtd,
347 u_char *buf, int len) 347 u_char *buf, int len)
348{ 348{
349 struct nand_chip *this = mtd->priv; 349 struct nand_chip *this = mtd->priv;
@@ -358,7 +358,7 @@ static void doc2000_readbuf(struct mtd_info *mtd,
358 } 358 }
359} 359}
360 360
361static void doc2000_readbuf_dword(struct mtd_info *mtd, 361static void doc2000_readbuf_dword(struct mtd_info *mtd,
362 u_char *buf, int len) 362 u_char *buf, int len)
363{ 363{
364 struct nand_chip *this = mtd->priv; 364 struct nand_chip *this = mtd->priv;
@@ -379,7 +379,7 @@ static void doc2000_readbuf_dword(struct mtd_info *mtd,
379 } 379 }
380} 380}
381 381
382static int doc2000_verifybuf(struct mtd_info *mtd, 382static int doc2000_verifybuf(struct mtd_info *mtd,
383 const u_char *buf, int len) 383 const u_char *buf, int len)
384{ 384{
385 struct nand_chip *this = mtd->priv; 385 struct nand_chip *this = mtd->priv;
@@ -406,12 +406,12 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
406 doc200x_hwcontrol(mtd, NAND_CTL_SETALE); 406 doc200x_hwcontrol(mtd, NAND_CTL_SETALE);
407 this->write_byte(mtd, 0); 407 this->write_byte(mtd, 0);
408 doc200x_hwcontrol(mtd, NAND_CTL_CLRALE); 408 doc200x_hwcontrol(mtd, NAND_CTL_CLRALE);
409 409
410 /* We cant' use dev_ready here, but at least we wait for the 410 /* We cant' use dev_ready here, but at least we wait for the
411 * command to complete 411 * command to complete
412 */ 412 */
413 udelay(50); 413 udelay(50);
414 414
415 ret = this->read_byte(mtd) << 8; 415 ret = this->read_byte(mtd) << 8;
416 ret |= this->read_byte(mtd); 416 ret |= this->read_byte(mtd);
417 417
@@ -438,7 +438,7 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
438 this->read_buf = &doc2000_readbuf_dword; 438 this->read_buf = &doc2000_readbuf_dword;
439 } 439 }
440 } 440 }
441 441
442 return ret; 442 return ret;
443} 443}
444 444
@@ -469,7 +469,7 @@ static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
469 struct doc_priv *doc = this->priv; 469 struct doc_priv *doc = this->priv;
470 470
471 int status; 471 int status;
472 472
473 DoC_WaitReady(doc); 473 DoC_WaitReady(doc);
474 this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); 474 this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
475 DoC_WaitReady(doc); 475 DoC_WaitReady(doc);
@@ -503,7 +503,7 @@ static u_char doc2001_read_byte(struct mtd_info *mtd)
503 return ReadDOC(docptr, LastDataRead); 503 return ReadDOC(docptr, LastDataRead);
504} 504}
505 505
506static void doc2001_writebuf(struct mtd_info *mtd, 506static void doc2001_writebuf(struct mtd_info *mtd,
507 const u_char *buf, int len) 507 const u_char *buf, int len)
508{ 508{
509 struct nand_chip *this = mtd->priv; 509 struct nand_chip *this = mtd->priv;
@@ -517,7 +517,7 @@ static void doc2001_writebuf(struct mtd_info *mtd,
517 WriteDOC(0x00, docptr, WritePipeTerm); 517 WriteDOC(0x00, docptr, WritePipeTerm);
518} 518}
519 519
520static void doc2001_readbuf(struct mtd_info *mtd, 520static void doc2001_readbuf(struct mtd_info *mtd,
521 u_char *buf, int len) 521 u_char *buf, int len)
522{ 522{
523 struct nand_chip *this = mtd->priv; 523 struct nand_chip *this = mtd->priv;
@@ -535,7 +535,7 @@ static void doc2001_readbuf(struct mtd_info *mtd,
535 buf[i] = ReadDOC(docptr, LastDataRead); 535 buf[i] = ReadDOC(docptr, LastDataRead);
536} 536}
537 537
538static int doc2001_verifybuf(struct mtd_info *mtd, 538static int doc2001_verifybuf(struct mtd_info *mtd,
539 const u_char *buf, int len) 539 const u_char *buf, int len)
540{ 540{
541 struct nand_chip *this = mtd->priv; 541 struct nand_chip *this = mtd->priv;
@@ -570,7 +570,7 @@ static u_char doc2001plus_read_byte(struct mtd_info *mtd)
570 return ret; 570 return ret;
571} 571}
572 572
573static void doc2001plus_writebuf(struct mtd_info *mtd, 573static void doc2001plus_writebuf(struct mtd_info *mtd,
574 const u_char *buf, int len) 574 const u_char *buf, int len)
575{ 575{
576 struct nand_chip *this = mtd->priv; 576 struct nand_chip *this = mtd->priv;
@@ -587,7 +587,7 @@ static void doc2001plus_writebuf(struct mtd_info *mtd,
587 if (debug) printk("\n"); 587 if (debug) printk("\n");
588} 588}
589 589
590static void doc2001plus_readbuf(struct mtd_info *mtd, 590static void doc2001plus_readbuf(struct mtd_info *mtd,
591 u_char *buf, int len) 591 u_char *buf, int len)
592{ 592{
593 struct nand_chip *this = mtd->priv; 593 struct nand_chip *this = mtd->priv;
@@ -617,7 +617,7 @@ static void doc2001plus_readbuf(struct mtd_info *mtd,
617 if (debug) printk("\n"); 617 if (debug) printk("\n");
618} 618}
619 619
620static int doc2001plus_verifybuf(struct mtd_info *mtd, 620static int doc2001plus_verifybuf(struct mtd_info *mtd,
621 const u_char *buf, int len) 621 const u_char *buf, int len)
622{ 622{
623 struct nand_chip *this = mtd->priv; 623 struct nand_chip *this = mtd->priv;
@@ -797,7 +797,7 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col
797 WriteDOC(0, docptr, Mplus_FlashControl); 797 WriteDOC(0, docptr, Mplus_FlashControl);
798 } 798 }
799 799
800 /* 800 /*
801 * program and erase have their own busy handlers 801 * program and erase have their own busy handlers
802 * status and sequential in needs no delay 802 * status and sequential in needs no delay
803 */ 803 */
@@ -822,7 +822,7 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col
822 822
823 /* This applies to read commands */ 823 /* This applies to read commands */
824 default: 824 default:
825 /* 825 /*
826 * If we don't have access to the busy pin, we apply the given 826 * If we don't have access to the busy pin, we apply the given
827 * command delay 827 * command delay
828 */ 828 */
@@ -945,7 +945,7 @@ static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
945 for (i = 0; i < 6; i++) { 945 for (i = 0; i < 6; i++) {
946 if (DoC_is_MillenniumPlus(doc)) 946 if (DoC_is_MillenniumPlus(doc))
947 ecc_code[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i); 947 ecc_code[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i);
948 else 948 else
949 ecc_code[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i); 949 ecc_code[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i);
950 if (ecc_code[i] != empty_write_ecc[i]) 950 if (ecc_code[i] != empty_write_ecc[i])
951 emptymatch = 0; 951 emptymatch = 0;
@@ -982,7 +982,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
982 void __iomem *docptr = doc->virtadr; 982 void __iomem *docptr = doc->virtadr;
983 volatile u_char dummy; 983 volatile u_char dummy;
984 int emptymatch = 1; 984 int emptymatch = 1;
985 985
986 /* flush the pipeline */ 986 /* flush the pipeline */
987 if (DoC_is_2000(doc)) { 987 if (DoC_is_2000(doc)) {
988 dummy = ReadDOC(docptr, 2k_ECCStatus); 988 dummy = ReadDOC(docptr, 2k_ECCStatus);
@@ -997,7 +997,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
997 dummy = ReadDOC(docptr, ECCConf); 997 dummy = ReadDOC(docptr, ECCConf);
998 dummy = ReadDOC(docptr, ECCConf); 998 dummy = ReadDOC(docptr, ECCConf);
999 } 999 }
1000 1000
1001 /* Error occured ? */ 1001 /* Error occured ? */
1002 if (dummy & 0x80) { 1002 if (dummy & 0x80) {
1003 for (i = 0; i < 6; i++) { 1003 for (i = 0; i < 6; i++) {
@@ -1035,7 +1035,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
1035 if (!emptymatch) ret = doc_ecc_decode (rs_decoder, dat, calc_ecc); 1035 if (!emptymatch) ret = doc_ecc_decode (rs_decoder, dat, calc_ecc);
1036 if (ret > 0) 1036 if (ret > 0)
1037 printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret); 1037 printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret);
1038 } 1038 }
1039 if (DoC_is_MillenniumPlus(doc)) 1039 if (DoC_is_MillenniumPlus(doc))
1040 WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf); 1040 WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
1041 else 1041 else
@@ -1046,7 +1046,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
1046 } 1046 }
1047 return ret; 1047 return ret;
1048} 1048}
1049 1049
1050//u_char mydatabuf[528]; 1050//u_char mydatabuf[528];
1051 1051
1052/* The strange out-of-order .oobfree list below is a (possibly unneeded) 1052/* The strange out-of-order .oobfree list below is a (possibly unneeded)
@@ -1065,7 +1065,7 @@ static struct nand_oobinfo doc200x_oobinfo = {
1065 .eccpos = {0, 1, 2, 3, 4, 5}, 1065 .eccpos = {0, 1, 2, 3, 4, 5},
1066 .oobfree = { {8, 8}, {6, 2} } 1066 .oobfree = { {8, 8}, {6, 2} }
1067}; 1067};
1068 1068
1069/* Find the (I)NFTL Media Header, and optionally also the mirror media header. 1069/* Find the (I)NFTL Media Header, and optionally also the mirror media header.
1070 On sucessful return, buf will contain a copy of the media header for 1070 On sucessful return, buf will contain a copy of the media header for
1071 further processing. id is the string to scan for, and will presumably be 1071 further processing. id is the string to scan for, and will presumably be
@@ -1251,7 +1251,7 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
1251 mh->BlockMultiplierBits = le32_to_cpu(mh->BlockMultiplierBits); 1251 mh->BlockMultiplierBits = le32_to_cpu(mh->BlockMultiplierBits);
1252 mh->FormatFlags = le32_to_cpu(mh->FormatFlags); 1252 mh->FormatFlags = le32_to_cpu(mh->FormatFlags);
1253 mh->PercentUsed = le32_to_cpu(mh->PercentUsed); 1253 mh->PercentUsed = le32_to_cpu(mh->PercentUsed);
1254 1254
1255 printk(KERN_INFO " bootRecordID = %s\n" 1255 printk(KERN_INFO " bootRecordID = %s\n"
1256 " NoOfBootImageBlocks = %d\n" 1256 " NoOfBootImageBlocks = %d\n"
1257 " NoOfBinaryPartitions = %d\n" 1257 " NoOfBinaryPartitions = %d\n"
@@ -1468,7 +1468,7 @@ static inline int __init doc2001_init(struct mtd_info *mtd)
1468 ReadDOC(doc->virtadr, ChipID); 1468 ReadDOC(doc->virtadr, ChipID);
1469 if (ReadDOC(doc->virtadr, ChipID) != DOC_ChipID_DocMil) { 1469 if (ReadDOC(doc->virtadr, ChipID) != DOC_ChipID_DocMil) {
1470 /* It's not a Millennium; it's one of the newer 1470 /* It's not a Millennium; it's one of the newer
1471 DiskOnChip 2000 units with a similar ASIC. 1471 DiskOnChip 2000 units with a similar ASIC.
1472 Treat it like a Millennium, except that it 1472 Treat it like a Millennium, except that it
1473 can have multiple chips. */ 1473 can have multiple chips. */
1474 doc2000_count_chips(mtd); 1474 doc2000_count_chips(mtd);
@@ -1530,20 +1530,20 @@ static inline int __init doc_probe(unsigned long physadr)
1530 * to the DOCControl register. So we store the current contents 1530 * to the DOCControl register. So we store the current contents
1531 * of the DOCControl register's location, in case we later decide 1531 * of the DOCControl register's location, in case we later decide
1532 * that it's not a DiskOnChip, and want to put it back how we 1532 * that it's not a DiskOnChip, and want to put it back how we
1533 * found it. 1533 * found it.
1534 */ 1534 */
1535 save_control = ReadDOC(virtadr, DOCControl); 1535 save_control = ReadDOC(virtadr, DOCControl);
1536 1536
1537 /* Reset the DiskOnChip ASIC */ 1537 /* Reset the DiskOnChip ASIC */
1538 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, 1538 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
1539 virtadr, DOCControl); 1539 virtadr, DOCControl);
1540 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, 1540 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
1541 virtadr, DOCControl); 1541 virtadr, DOCControl);
1542 1542
1543 /* Enable the DiskOnChip ASIC */ 1543 /* Enable the DiskOnChip ASIC */
1544 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, 1544 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
1545 virtadr, DOCControl); 1545 virtadr, DOCControl);
1546 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, 1546 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
1547 virtadr, DOCControl); 1547 virtadr, DOCControl);
1548 1548
1549 ChipID = ReadDOC(virtadr, ChipID); 1549 ChipID = ReadDOC(virtadr, ChipID);
@@ -1738,7 +1738,7 @@ static int __init init_nanddoc(void)
1738 int i, ret = 0; 1738 int i, ret = 0;
1739 1739
1740 /* We could create the decoder on demand, if memory is a concern. 1740 /* We could create the decoder on demand, if memory is a concern.
1741 * This way we have it handy, if an error happens 1741 * This way we have it handy, if an error happens
1742 * 1742 *
1743 * Symbolsize is 10 (bits) 1743 * Symbolsize is 10 (bits)
1744 * Primitve polynomial is x^10+x^3+1 1744 * Primitve polynomial is x^10+x^3+1
diff --git a/drivers/mtd/nand/edb7312.c b/drivers/mtd/nand/edb7312.c
index 5549681ccdce..9b1fd2f387fa 100644
--- a/drivers/mtd/nand/edb7312.c
+++ b/drivers/mtd/nand/edb7312.c
@@ -6,7 +6,7 @@
6 * Derived from drivers/mtd/nand/autcpu12.c 6 * Derived from drivers/mtd/nand/autcpu12.c
7 * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) 7 * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
8 * 8 *
9 * $Id: edb7312.c,v 1.11 2004/11/04 12:53:10 gleixner Exp $ 9 * $Id: edb7312.c,v 1.12 2005/11/07 11:14:30 gleixner Exp $
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as 12 * it under the terms of the GNU General Public License version 2 as
@@ -71,27 +71,27 @@ static struct mtd_partition partition_info[] = {
71#endif 71#endif
72 72
73 73
74/* 74/*
75 * hardware specific access to control-lines 75 * hardware specific access to control-lines
76 */ 76 */
77static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd) 77static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd)
78{ 78{
79 switch(cmd) { 79 switch(cmd) {
80 80
81 case NAND_CTL_SETCLE: 81 case NAND_CTL_SETCLE:
82 clps_writeb(clps_readb(ep7312_pxdr) | 0x10, ep7312_pxdr); 82 clps_writeb(clps_readb(ep7312_pxdr) | 0x10, ep7312_pxdr);
83 break; 83 break;
84 case NAND_CTL_CLRCLE: 84 case NAND_CTL_CLRCLE:
85 clps_writeb(clps_readb(ep7312_pxdr) & ~0x10, ep7312_pxdr); 85 clps_writeb(clps_readb(ep7312_pxdr) & ~0x10, ep7312_pxdr);
86 break; 86 break;
87 87
88 case NAND_CTL_SETALE: 88 case NAND_CTL_SETALE:
89 clps_writeb(clps_readb(ep7312_pxdr) | 0x20, ep7312_pxdr); 89 clps_writeb(clps_readb(ep7312_pxdr) | 0x20, ep7312_pxdr);
90 break; 90 break;
91 case NAND_CTL_CLRALE: 91 case NAND_CTL_CLRALE:
92 clps_writeb(clps_readb(ep7312_pxdr) & ~0x20, ep7312_pxdr); 92 clps_writeb(clps_readb(ep7312_pxdr) & ~0x20, ep7312_pxdr);
93 break; 93 break;
94 94
95 case NAND_CTL_SETNCE: 95 case NAND_CTL_SETNCE:
96 clps_writeb((clps_readb(ep7312_pxdr) | 0x80) & ~0x40, ep7312_pxdr); 96 clps_writeb((clps_readb(ep7312_pxdr) | 0x80) & ~0x40, ep7312_pxdr);
97 break; 97 break;
@@ -122,16 +122,16 @@ static int __init ep7312_init (void)
122 int mtd_parts_nb = 0; 122 int mtd_parts_nb = 0;
123 struct mtd_partition *mtd_parts = 0; 123 struct mtd_partition *mtd_parts = 0;
124 void __iomem * ep7312_fio_base; 124 void __iomem * ep7312_fio_base;
125 125
126 /* Allocate memory for MTD device structure and private data */ 126 /* Allocate memory for MTD device structure and private data */
127 ep7312_mtd = kmalloc(sizeof(struct mtd_info) + 127 ep7312_mtd = kmalloc(sizeof(struct mtd_info) +
128 sizeof(struct nand_chip), 128 sizeof(struct nand_chip),
129 GFP_KERNEL); 129 GFP_KERNEL);
130 if (!ep7312_mtd) { 130 if (!ep7312_mtd) {
131 printk("Unable to allocate EDB7312 NAND MTD device structure.\n"); 131 printk("Unable to allocate EDB7312 NAND MTD device structure.\n");
132 return -ENOMEM; 132 return -ENOMEM;
133 } 133 }
134 134
135 /* map physical adress */ 135 /* map physical adress */
136 ep7312_fio_base = ioremap(ep7312_fio_pbase, SZ_1K); 136 ep7312_fio_base = ioremap(ep7312_fio_pbase, SZ_1K);
137 if(!ep7312_fio_base) { 137 if(!ep7312_fio_base) {
@@ -139,23 +139,23 @@ static int __init ep7312_init (void)
139 kfree(ep7312_mtd); 139 kfree(ep7312_mtd);
140 return -EIO; 140 return -EIO;
141 } 141 }
142 142
143 /* Get pointer to private data */ 143 /* Get pointer to private data */
144 this = (struct nand_chip *) (&ep7312_mtd[1]); 144 this = (struct nand_chip *) (&ep7312_mtd[1]);
145 145
146 /* Initialize structures */ 146 /* Initialize structures */
147 memset((char *) ep7312_mtd, 0, sizeof(struct mtd_info)); 147 memset((char *) ep7312_mtd, 0, sizeof(struct mtd_info));
148 memset((char *) this, 0, sizeof(struct nand_chip)); 148 memset((char *) this, 0, sizeof(struct nand_chip));
149 149
150 /* Link the private data with the MTD structure */ 150 /* Link the private data with the MTD structure */
151 ep7312_mtd->priv = this; 151 ep7312_mtd->priv = this;
152 152
153 /* 153 /*
154 * Set GPIO Port B control register so that the pins are configured 154 * Set GPIO Port B control register so that the pins are configured
155 * to be outputs for controlling the NAND flash. 155 * to be outputs for controlling the NAND flash.
156 */ 156 */
157 clps_writeb(0xf0, ep7312_pxddr); 157 clps_writeb(0xf0, ep7312_pxddr);
158 158
159 /* insert callbacks */ 159 /* insert callbacks */
160 this->IO_ADDR_R = ep7312_fio_base; 160 this->IO_ADDR_R = ep7312_fio_base;
161 this->IO_ADDR_W = ep7312_fio_base; 161 this->IO_ADDR_W = ep7312_fio_base;
@@ -163,14 +163,14 @@ static int __init ep7312_init (void)
163 this->dev_ready = ep7312_device_ready; 163 this->dev_ready = ep7312_device_ready;
164 /* 15 us command delay time */ 164 /* 15 us command delay time */
165 this->chip_delay = 15; 165 this->chip_delay = 15;
166 166
167 /* Scan to find existence of the device */ 167 /* Scan to find existence of the device */
168 if (nand_scan (ep7312_mtd, 1)) { 168 if (nand_scan (ep7312_mtd, 1)) {
169 iounmap((void *)ep7312_fio_base); 169 iounmap((void *)ep7312_fio_base);
170 kfree (ep7312_mtd); 170 kfree (ep7312_mtd);
171 return -ENXIO; 171 return -ENXIO;
172 } 172 }
173 173
174#ifdef CONFIG_MTD_PARTITIONS 174#ifdef CONFIG_MTD_PARTITIONS
175 ep7312_mtd->name = "edb7312-nand"; 175 ep7312_mtd->name = "edb7312-nand";
176 mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes, 176 mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes,
@@ -185,11 +185,11 @@ static int __init ep7312_init (void)
185 mtd_parts_nb = NUM_PARTITIONS; 185 mtd_parts_nb = NUM_PARTITIONS;
186 part_type = "static"; 186 part_type = "static";
187 } 187 }
188 188
189 /* Register the partitions */ 189 /* Register the partitions */
190 printk(KERN_NOTICE "Using %s partition definition\n", part_type); 190 printk(KERN_NOTICE "Using %s partition definition\n", part_type);
191 add_mtd_partitions(ep7312_mtd, mtd_parts, mtd_parts_nb); 191 add_mtd_partitions(ep7312_mtd, mtd_parts, mtd_parts_nb);
192 192
193 /* Return happy */ 193 /* Return happy */
194 return 0; 194 return 0;
195} 195}
@@ -201,13 +201,13 @@ module_init(ep7312_init);
201static void __exit ep7312_cleanup (void) 201static void __exit ep7312_cleanup (void)
202{ 202{
203 struct nand_chip *this = (struct nand_chip *) &ep7312_mtd[1]; 203 struct nand_chip *this = (struct nand_chip *) &ep7312_mtd[1];
204 204
205 /* Release resources, unregister device */ 205 /* Release resources, unregister device */
206 nand_release (ap7312_mtd); 206 nand_release (ap7312_mtd);
207 207
208 /* Free internal data buffer */ 208 /* Free internal data buffer */
209 kfree (this->data_buf); 209 kfree (this->data_buf);
210 210
211 /* Free the MTD device structure */ 211 /* Free the MTD device structure */
212 kfree (ep7312_mtd); 212 kfree (ep7312_mtd);
213} 213}
diff --git a/drivers/mtd/nand/h1910.c b/drivers/mtd/nand/h1910.c
index 3825a7a0900c..041e4b3358fb 100644
--- a/drivers/mtd/nand/h1910.c
+++ b/drivers/mtd/nand/h1910.c
@@ -7,7 +7,7 @@
7 * Copyright (C) 2002 Marius Gröger (mag@sysgo.de) 7 * Copyright (C) 2002 Marius Gröger (mag@sysgo.de)
8 * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) 8 * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
9 * 9 *
10 * $Id: h1910.c,v 1.5 2004/11/04 12:53:10 gleixner Exp $ 10 * $Id: h1910.c,v 1.6 2005/11/07 11:14:30 gleixner Exp $
11 * 11 *
12 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as 13 * it under the terms of the GNU General Public License version 2 as
@@ -54,24 +54,24 @@ static struct mtd_partition partition_info[] = {
54#endif 54#endif
55 55
56 56
57/* 57/*
58 * hardware specific access to control-lines 58 * hardware specific access to control-lines
59 */ 59 */
60static void h1910_hwcontrol(struct mtd_info *mtd, int cmd) 60static void h1910_hwcontrol(struct mtd_info *mtd, int cmd)
61{ 61{
62 struct nand_chip* this = (struct nand_chip *) (mtd->priv); 62 struct nand_chip* this = (struct nand_chip *) (mtd->priv);
63 63
64 switch(cmd) { 64 switch(cmd) {
65 65
66 case NAND_CTL_SETCLE: 66 case NAND_CTL_SETCLE:
67 this->IO_ADDR_R |= (1 << 2); 67 this->IO_ADDR_R |= (1 << 2);
68 this->IO_ADDR_W |= (1 << 2); 68 this->IO_ADDR_W |= (1 << 2);
69 break; 69 break;
70 case NAND_CTL_CLRCLE: 70 case NAND_CTL_CLRCLE:
71 this->IO_ADDR_R &= ~(1 << 2); 71 this->IO_ADDR_R &= ~(1 << 2);
72 this->IO_ADDR_W &= ~(1 << 2); 72 this->IO_ADDR_W &= ~(1 << 2);
73 break; 73 break;
74 74
75 case NAND_CTL_SETALE: 75 case NAND_CTL_SETALE:
76 this->IO_ADDR_R |= (1 << 3); 76 this->IO_ADDR_R |= (1 << 3);
77 this->IO_ADDR_W |= (1 << 3); 77 this->IO_ADDR_W |= (1 << 3);
@@ -80,7 +80,7 @@ static void h1910_hwcontrol(struct mtd_info *mtd, int cmd)
80 this->IO_ADDR_R &= ~(1 << 3); 80 this->IO_ADDR_R &= ~(1 << 3);
81 this->IO_ADDR_W &= ~(1 << 3); 81 this->IO_ADDR_W &= ~(1 << 3);
82 break; 82 break;
83 83
84 case NAND_CTL_SETNCE: 84 case NAND_CTL_SETNCE:
85 break; 85 break;
86 case NAND_CTL_CLRNCE: 86 case NAND_CTL_CLRNCE:
@@ -108,18 +108,18 @@ static int __init h1910_init (void)
108 int mtd_parts_nb = 0; 108 int mtd_parts_nb = 0;
109 struct mtd_partition *mtd_parts = 0; 109 struct mtd_partition *mtd_parts = 0;
110 void __iomem *nandaddr; 110 void __iomem *nandaddr;
111 111
112 if (!machine_is_h1900()) 112 if (!machine_is_h1900())
113 return -ENODEV; 113 return -ENODEV;
114 114
115 nandaddr = __ioremap(0x08000000, 0x1000, 0, 1); 115 nandaddr = __ioremap(0x08000000, 0x1000, 0, 1);
116 if (!nandaddr) { 116 if (!nandaddr) {
117 printk("Failed to ioremap nand flash.\n"); 117 printk("Failed to ioremap nand flash.\n");
118 return -ENOMEM; 118 return -ENOMEM;
119 } 119 }
120 120
121 /* Allocate memory for MTD device structure and private data */ 121 /* Allocate memory for MTD device structure and private data */
122 h1910_nand_mtd = kmalloc(sizeof(struct mtd_info) + 122 h1910_nand_mtd = kmalloc(sizeof(struct mtd_info) +
123 sizeof(struct nand_chip), 123 sizeof(struct nand_chip),
124 GFP_KERNEL); 124 GFP_KERNEL);
125 if (!h1910_nand_mtd) { 125 if (!h1910_nand_mtd) {
@@ -127,22 +127,22 @@ static int __init h1910_init (void)
127 iounmap ((void *) nandaddr); 127 iounmap ((void *) nandaddr);
128 return -ENOMEM; 128 return -ENOMEM;
129 } 129 }
130 130
131 /* Get pointer to private data */ 131 /* Get pointer to private data */
132 this = (struct nand_chip *) (&h1910_nand_mtd[1]); 132 this = (struct nand_chip *) (&h1910_nand_mtd[1]);
133 133
134 /* Initialize structures */ 134 /* Initialize structures */
135 memset((char *) h1910_nand_mtd, 0, sizeof(struct mtd_info)); 135 memset((char *) h1910_nand_mtd, 0, sizeof(struct mtd_info));
136 memset((char *) this, 0, sizeof(struct nand_chip)); 136 memset((char *) this, 0, sizeof(struct nand_chip));
137 137
138 /* Link the private data with the MTD structure */ 138 /* Link the private data with the MTD structure */
139 h1910_nand_mtd->priv = this; 139 h1910_nand_mtd->priv = this;
140 140
141 /* 141 /*
142 * Enable VPEN 142 * Enable VPEN
143 */ 143 */
144 GPSR(37) = GPIO_bit(37); 144 GPSR(37) = GPIO_bit(37);
145 145
146 /* insert callbacks */ 146 /* insert callbacks */
147 this->IO_ADDR_R = nandaddr; 147 this->IO_ADDR_R = nandaddr;
148 this->IO_ADDR_W = nandaddr; 148 this->IO_ADDR_W = nandaddr;
@@ -152,7 +152,7 @@ static int __init h1910_init (void)
152 this->chip_delay = 50; 152 this->chip_delay = 50;
153 this->eccmode = NAND_ECC_SOFT; 153 this->eccmode = NAND_ECC_SOFT;
154 this->options = NAND_NO_AUTOINCR; 154 this->options = NAND_NO_AUTOINCR;
155 155
156 /* Scan to find existence of the device */ 156 /* Scan to find existence of the device */
157 if (nand_scan (h1910_nand_mtd, 1)) { 157 if (nand_scan (h1910_nand_mtd, 1)) {
158 printk(KERN_NOTICE "No NAND device - returning -ENXIO\n"); 158 printk(KERN_NOTICE "No NAND device - returning -ENXIO\n");
@@ -160,9 +160,9 @@ static int __init h1910_init (void)
160 iounmap ((void *) nandaddr); 160 iounmap ((void *) nandaddr);
161 return -ENXIO; 161 return -ENXIO;
162 } 162 }
163 163
164#ifdef CONFIG_MTD_CMDLINE_PARTS 164#ifdef CONFIG_MTD_CMDLINE_PARTS
165 mtd_parts_nb = parse_cmdline_partitions(h1910_nand_mtd, &mtd_parts, 165 mtd_parts_nb = parse_cmdline_partitions(h1910_nand_mtd, &mtd_parts,
166 "h1910-nand"); 166 "h1910-nand");
167 if (mtd_parts_nb > 0) 167 if (mtd_parts_nb > 0)
168 part_type = "command line"; 168 part_type = "command line";
@@ -175,11 +175,11 @@ static int __init h1910_init (void)
175 mtd_parts_nb = NUM_PARTITIONS; 175 mtd_parts_nb = NUM_PARTITIONS;
176 part_type = "static"; 176 part_type = "static";
177 } 177 }
178 178
179 /* Register the partitions */ 179 /* Register the partitions */
180 printk(KERN_NOTICE "Using %s partition definition\n", part_type); 180 printk(KERN_NOTICE "Using %s partition definition\n", part_type);
181 add_mtd_partitions(h1910_nand_mtd, mtd_parts, mtd_parts_nb); 181 add_mtd_partitions(h1910_nand_mtd, mtd_parts, mtd_parts_nb);
182 182
183 /* Return happy */ 183 /* Return happy */
184 return 0; 184 return 0;
185} 185}
@@ -191,7 +191,7 @@ module_init(h1910_init);
191static void __exit h1910_cleanup (void) 191static void __exit h1910_cleanup (void)
192{ 192{
193 struct nand_chip *this = (struct nand_chip *) &h1910_nand_mtd[1]; 193 struct nand_chip *this = (struct nand_chip *) &h1910_nand_mtd[1];
194 194
195 /* Release resources, unregister device */ 195 /* Release resources, unregister device */
196 nand_release (h1910_nand_mtd); 196 nand_release (h1910_nand_mtd);
197 197
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 8e78d7b96a56..5d222460b42a 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -5,14 +5,14 @@
5 * This is the generic MTD driver for NAND flash devices. It should be 5 * This is the generic MTD driver for NAND flash devices. It should be
6 * capable of working with almost all NAND chips currently available. 6 * capable of working with almost all NAND chips currently available.
7 * Basic support for AG-AND chips is provided. 7 * Basic support for AG-AND chips is provided.
8 * 8 *
9 * Additional technical information is available on 9 * Additional technical information is available on
10 * http://www.linux-mtd.infradead.org/tech/nand.html 10 * http://www.linux-mtd.infradead.org/tech/nand.html
11 * 11 *
12 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) 12 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
13 * 2002 Thomas Gleixner (tglx@linutronix.de) 13 * 2002 Thomas Gleixner (tglx@linutronix.de)
14 * 14 *
15 * 02-08-2004 tglx: support for strange chips, which cannot auto increment 15 * 02-08-2004 tglx: support for strange chips, which cannot auto increment
16 * pages on read / read_oob 16 * pages on read / read_oob
17 * 17 *
18 * 03-17-2004 tglx: Check ready before auto increment check. Simon Bayes 18 * 03-17-2004 tglx: Check ready before auto increment check. Simon Bayes
@@ -21,7 +21,7 @@
21 * Make reads over block boundaries work too 21 * Make reads over block boundaries work too
22 * 22 *
23 * 04-14-2004 tglx: first working version for 2k page size chips 23 * 04-14-2004 tglx: first working version for 2k page size chips
24 * 24 *
25 * 05-19-2004 tglx: Basic support for Renesas AG-AND chips 25 * 05-19-2004 tglx: Basic support for Renesas AG-AND chips
26 * 26 *
27 * 09-24-2004 tglx: add support for hardware controllers (e.g. ECC) shared 27 * 09-24-2004 tglx: add support for hardware controllers (e.g. ECC) shared
@@ -30,25 +30,27 @@
30 * 30 *
31 * 12-05-2004 dmarlin: add workaround for Renesas AG-AND chips "disturb" issue. 31 * 12-05-2004 dmarlin: add workaround for Renesas AG-AND chips "disturb" issue.
32 * Basically, any block not rewritten may lose data when surrounding blocks 32 * Basically, any block not rewritten may lose data when surrounding blocks
33 * are rewritten many times. JFFS2 ensures this doesn't happen for blocks 33 * are rewritten many times. JFFS2 ensures this doesn't happen for blocks
34 * it uses, but the Bad Block Table(s) may not be rewritten. To ensure they 34 * it uses, but the Bad Block Table(s) may not be rewritten. To ensure they
35 * do not lose data, force them to be rewritten when some of the surrounding 35 * do not lose data, force them to be rewritten when some of the surrounding
36 * blocks are erased. Rather than tracking a specific nearby block (which 36 * blocks are erased. Rather than tracking a specific nearby block (which
37 * could itself go bad), use a page address 'mask' to select several blocks 37 * could itself go bad), use a page address 'mask' to select several blocks
38 * in the same area, and rewrite the BBT when any of them are erased. 38 * in the same area, and rewrite the BBT when any of them are erased.
39 * 39 *
40 * 01-03-2005 dmarlin: added support for the device recovery command sequence for Renesas 40 * 01-03-2005 dmarlin: added support for the device recovery command sequence for Renesas
41 * AG-AND chips. If there was a sudden loss of power during an erase operation, 41 * AG-AND chips. If there was a sudden loss of power during an erase operation,
42 * a "device recovery" operation must be performed when power is restored 42 * a "device recovery" operation must be performed when power is restored
43 * to ensure correct operation. 43 * to ensure correct operation.
44 * 44 *
45 * 01-20-2005 dmarlin: added support for optional hardware specific callback routine to 45 * 01-20-2005 dmarlin: added support for optional hardware specific callback routine to
46 * perform extra error status checks on erase and write failures. This required 46 * perform extra error status checks on erase and write failures. This required
47 * adding a wrapper function for nand_read_ecc. 47 * adding a wrapper function for nand_read_ecc.
48 * 48 *
49 * 08-20-2005 vwool: suspend/resume added
50 *
49 * Credits: 51 * Credits:
50 * David Woodhouse for adding multichip support 52 * David Woodhouse for adding multichip support
51 * 53 *
52 * Aleph One Ltd. and Toby Churchill Ltd. for supporting the 54 * Aleph One Ltd. and Toby Churchill Ltd. for supporting the
53 * rework for 2K page size chips 55 * rework for 2K page size chips
54 * 56 *
@@ -59,7 +61,7 @@
59 * The AG-AND chips have nice features for speed improvement, 61 * The AG-AND chips have nice features for speed improvement,
60 * which are not supported yet. Read / program 4 pages in one go. 62 * which are not supported yet. Read / program 4 pages in one go.
61 * 63 *
62 * $Id: nand_base.c,v 1.147 2005/07/15 07:18:06 gleixner Exp $ 64 * $Id: nand_base.c,v 1.150 2005/09/15 13:58:48 vwool Exp $
63 * 65 *
64 * This program is free software; you can redistribute it and/or modify 66 * This program is free software; you can redistribute it and/or modify
65 * it under the terms of the GNU General Public License version 2 as 67 * it under the terms of the GNU General Public License version 2 as
@@ -103,8 +105,8 @@ static struct nand_oobinfo nand_oob_64 = {
103 .useecc = MTD_NANDECC_AUTOPLACE, 105 .useecc = MTD_NANDECC_AUTOPLACE,
104 .eccbytes = 24, 106 .eccbytes = 24,
105 .eccpos = { 107 .eccpos = {
106 40, 41, 42, 43, 44, 45, 46, 47, 108 40, 41, 42, 43, 44, 45, 46, 47,
107 48, 49, 50, 51, 52, 53, 54, 55, 109 48, 49, 50, 51, 52, 53, 54, 55,
108 56, 57, 58, 59, 60, 61, 62, 63}, 110 56, 57, 58, 59, 60, 61, 62, 63},
109 .oobfree = { {2, 38} } 111 .oobfree = { {2, 38} }
110}; 112};
@@ -147,19 +149,19 @@ static void nand_sync (struct mtd_info *mtd);
147static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf, 149static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf,
148 struct nand_oobinfo *oobsel, int mode); 150 struct nand_oobinfo *oobsel, int mode);
149#ifdef CONFIG_MTD_NAND_VERIFY_WRITE 151#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
150static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages, 152static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
151 u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode); 153 u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode);
152#else 154#else
153#define nand_verify_pages(...) (0) 155#define nand_verify_pages(...) (0)
154#endif 156#endif
155 157
156static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state); 158static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state);
157 159
158/** 160/**
159 * nand_release_device - [GENERIC] release chip 161 * nand_release_device - [GENERIC] release chip
160 * @mtd: MTD device structure 162 * @mtd: MTD device structure
161 * 163 *
162 * Deselect, release chip lock and wake up anyone waiting on the device 164 * Deselect, release chip lock and wake up anyone waiting on the device
163 */ 165 */
164static void nand_release_device (struct mtd_info *mtd) 166static void nand_release_device (struct mtd_info *mtd)
165{ 167{
@@ -213,7 +215,7 @@ static void nand_write_byte(struct mtd_info *mtd, u_char byte)
213 * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip 215 * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip
214 * @mtd: MTD device structure 216 * @mtd: MTD device structure
215 * 217 *
216 * Default read function for 16bit buswith with 218 * Default read function for 16bit buswith with
217 * endianess conversion 219 * endianess conversion
218 */ 220 */
219static u_char nand_read_byte16(struct mtd_info *mtd) 221static u_char nand_read_byte16(struct mtd_info *mtd)
@@ -240,7 +242,7 @@ static void nand_write_byte16(struct mtd_info *mtd, u_char byte)
240 * nand_read_word - [DEFAULT] read one word from the chip 242 * nand_read_word - [DEFAULT] read one word from the chip
241 * @mtd: MTD device structure 243 * @mtd: MTD device structure
242 * 244 *
243 * Default read function for 16bit buswith without 245 * Default read function for 16bit buswith without
244 * endianess conversion 246 * endianess conversion
245 */ 247 */
246static u16 nand_read_word(struct mtd_info *mtd) 248static u16 nand_read_word(struct mtd_info *mtd)
@@ -254,7 +256,7 @@ static u16 nand_read_word(struct mtd_info *mtd)
254 * @mtd: MTD device structure 256 * @mtd: MTD device structure
255 * @word: data word to write 257 * @word: data word to write
256 * 258 *
257 * Default write function for 16bit buswith without 259 * Default write function for 16bit buswith without
258 * endianess conversion 260 * endianess conversion
259 */ 261 */
260static void nand_write_word(struct mtd_info *mtd, u16 word) 262static void nand_write_word(struct mtd_info *mtd, u16 word)
@@ -275,7 +277,7 @@ static void nand_select_chip(struct mtd_info *mtd, int chip)
275 struct nand_chip *this = mtd->priv; 277 struct nand_chip *this = mtd->priv;
276 switch(chip) { 278 switch(chip) {
277 case -1: 279 case -1:
278 this->hwcontrol(mtd, NAND_CTL_CLRNCE); 280 this->hwcontrol(mtd, NAND_CTL_CLRNCE);
279 break; 281 break;
280 case 0: 282 case 0:
281 this->hwcontrol(mtd, NAND_CTL_SETNCE); 283 this->hwcontrol(mtd, NAND_CTL_SETNCE);
@@ -304,7 +306,7 @@ static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
304} 306}
305 307
306/** 308/**
307 * nand_read_buf - [DEFAULT] read chip data into buffer 309 * nand_read_buf - [DEFAULT] read chip data into buffer
308 * @mtd: MTD device structure 310 * @mtd: MTD device structure
309 * @buf: buffer to store date 311 * @buf: buffer to store date
310 * @len: number of bytes to read 312 * @len: number of bytes to read
@@ -321,7 +323,7 @@ static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
321} 323}
322 324
323/** 325/**
324 * nand_verify_buf - [DEFAULT] Verify chip data against buffer 326 * nand_verify_buf - [DEFAULT] Verify chip data against buffer
325 * @mtd: MTD device structure 327 * @mtd: MTD device structure
326 * @buf: buffer containing the data to compare 328 * @buf: buffer containing the data to compare
327 * @len: number of bytes to compare 329 * @len: number of bytes to compare
@@ -354,14 +356,14 @@ static void nand_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
354 struct nand_chip *this = mtd->priv; 356 struct nand_chip *this = mtd->priv;
355 u16 *p = (u16 *) buf; 357 u16 *p = (u16 *) buf;
356 len >>= 1; 358 len >>= 1;
357 359
358 for (i=0; i<len; i++) 360 for (i=0; i<len; i++)
359 writew(p[i], this->IO_ADDR_W); 361 writew(p[i], this->IO_ADDR_W);
360 362
361} 363}
362 364
363/** 365/**
364 * nand_read_buf16 - [DEFAULT] read chip data into buffer 366 * nand_read_buf16 - [DEFAULT] read chip data into buffer
365 * @mtd: MTD device structure 367 * @mtd: MTD device structure
366 * @buf: buffer to store date 368 * @buf: buffer to store date
367 * @len: number of bytes to read 369 * @len: number of bytes to read
@@ -380,7 +382,7 @@ static void nand_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
380} 382}
381 383
382/** 384/**
383 * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer 385 * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer
384 * @mtd: MTD device structure 386 * @mtd: MTD device structure
385 * @buf: buffer containing the data to compare 387 * @buf: buffer containing the data to compare
386 * @len: number of bytes to compare 388 * @len: number of bytes to compare
@@ -407,7 +409,7 @@ static int nand_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
407 * @ofs: offset from device start 409 * @ofs: offset from device start
408 * @getchip: 0, if the chip is already selected 410 * @getchip: 0, if the chip is already selected
409 * 411 *
410 * Check, if the block is bad. 412 * Check, if the block is bad.
411 */ 413 */
412static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) 414static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
413{ 415{
@@ -424,14 +426,14 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
424 426
425 /* Select the NAND device */ 427 /* Select the NAND device */
426 this->select_chip(mtd, chipnr); 428 this->select_chip(mtd, chipnr);
427 } else 429 } else
428 page = (int) ofs; 430 page = (int) ofs;
429 431
430 if (this->options & NAND_BUSWIDTH_16) { 432 if (this->options & NAND_BUSWIDTH_16) {
431 this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page & this->pagemask); 433 this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page & this->pagemask);
432 bad = cpu_to_le16(this->read_word(mtd)); 434 bad = cpu_to_le16(this->read_word(mtd));
433 if (this->badblockpos & 0x1) 435 if (this->badblockpos & 0x1)
434 bad >>= 1; 436 bad >>= 8;
435 if ((bad & 0xFF) != 0xff) 437 if ((bad & 0xFF) != 0xff)
436 res = 1; 438 res = 1;
437 } else { 439 } else {
@@ -439,12 +441,12 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
439 if (this->read_byte(mtd) != 0xff) 441 if (this->read_byte(mtd) != 0xff)
440 res = 1; 442 res = 1;
441 } 443 }
442 444
443 if (getchip) { 445 if (getchip) {
444 /* Deselect and wake up anyone waiting on the device */ 446 /* Deselect and wake up anyone waiting on the device */
445 nand_release_device(mtd); 447 nand_release_device(mtd);
446 } 448 }
447 449
448 return res; 450 return res;
449} 451}
450 452
@@ -462,7 +464,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
462 u_char buf[2] = {0, 0}; 464 u_char buf[2] = {0, 0};
463 size_t retlen; 465 size_t retlen;
464 int block; 466 int block;
465 467
466 /* Get block number */ 468 /* Get block number */
467 block = ((int) ofs) >> this->bbt_erase_shift; 469 block = ((int) ofs) >> this->bbt_erase_shift;
468 if (this->bbt) 470 if (this->bbt)
@@ -471,25 +473,25 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
471 /* Do we have a flash based bad block table ? */ 473 /* Do we have a flash based bad block table ? */
472 if (this->options & NAND_USE_FLASH_BBT) 474 if (this->options & NAND_USE_FLASH_BBT)
473 return nand_update_bbt (mtd, ofs); 475 return nand_update_bbt (mtd, ofs);
474 476
475 /* We write two bytes, so we dont have to mess with 16 bit access */ 477 /* We write two bytes, so we dont have to mess with 16 bit access */
476 ofs += mtd->oobsize + (this->badblockpos & ~0x01); 478 ofs += mtd->oobsize + (this->badblockpos & ~0x01);
477 return nand_write_oob (mtd, ofs , 2, &retlen, buf); 479 return nand_write_oob (mtd, ofs , 2, &retlen, buf);
478} 480}
479 481
480/** 482/**
481 * nand_check_wp - [GENERIC] check if the chip is write protected 483 * nand_check_wp - [GENERIC] check if the chip is write protected
482 * @mtd: MTD device structure 484 * @mtd: MTD device structure
483 * Check, if the device is write protected 485 * Check, if the device is write protected
484 * 486 *
485 * The function expects, that the device is already selected 487 * The function expects, that the device is already selected
486 */ 488 */
487static int nand_check_wp (struct mtd_info *mtd) 489static int nand_check_wp (struct mtd_info *mtd)
488{ 490{
489 struct nand_chip *this = mtd->priv; 491 struct nand_chip *this = mtd->priv;
490 /* Check the WP bit */ 492 /* Check the WP bit */
491 this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); 493 this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
492 return (this->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1; 494 return (this->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1;
493} 495}
494 496
495/** 497/**
@@ -505,15 +507,15 @@ static int nand_check_wp (struct mtd_info *mtd)
505static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt) 507static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt)
506{ 508{
507 struct nand_chip *this = mtd->priv; 509 struct nand_chip *this = mtd->priv;
508 510
509 if (!this->bbt) 511 if (!this->bbt)
510 return this->block_bad(mtd, ofs, getchip); 512 return this->block_bad(mtd, ofs, getchip);
511 513
512 /* Return info from the table */ 514 /* Return info from the table */
513 return nand_isbad_bbt (mtd, ofs, allowbbt); 515 return nand_isbad_bbt (mtd, ofs, allowbbt);
514} 516}
515 517
516/* 518/*
517 * Wait for the ready pin, after a command 519 * Wait for the ready pin, after a command
518 * The timeout is catched later. 520 * The timeout is catched later.
519 */ 521 */
@@ -527,7 +529,7 @@ static void nand_wait_ready(struct mtd_info *mtd)
527 if (this->dev_ready(mtd)) 529 if (this->dev_ready(mtd))
528 return; 530 return;
529 touch_softlockup_watchdog(); 531 touch_softlockup_watchdog();
530 } while (time_before(jiffies, timeo)); 532 } while (time_before(jiffies, timeo));
531} 533}
532 534
533/** 535/**
@@ -590,13 +592,13 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
590 /* Latch in address */ 592 /* Latch in address */
591 this->hwcontrol(mtd, NAND_CTL_CLRALE); 593 this->hwcontrol(mtd, NAND_CTL_CLRALE);
592 } 594 }
593 595
594 /* 596 /*
595 * program and erase have their own busy handlers 597 * program and erase have their own busy handlers
596 * status and sequential in needs no delay 598 * status and sequential in needs no delay
597 */ 599 */
598 switch (command) { 600 switch (command) {
599 601
600 case NAND_CMD_PAGEPROG: 602 case NAND_CMD_PAGEPROG:
601 case NAND_CMD_ERASE1: 603 case NAND_CMD_ERASE1:
602 case NAND_CMD_ERASE2: 604 case NAND_CMD_ERASE2:
@@ -605,7 +607,7 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
605 return; 607 return;
606 608
607 case NAND_CMD_RESET: 609 case NAND_CMD_RESET:
608 if (this->dev_ready) 610 if (this->dev_ready)
609 break; 611 break;
610 udelay(this->chip_delay); 612 udelay(this->chip_delay);
611 this->hwcontrol(mtd, NAND_CTL_SETCLE); 613 this->hwcontrol(mtd, NAND_CTL_SETCLE);
@@ -614,16 +616,16 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
614 while ( !(this->read_byte(mtd) & NAND_STATUS_READY)); 616 while ( !(this->read_byte(mtd) & NAND_STATUS_READY));
615 return; 617 return;
616 618
617 /* This applies to read commands */ 619 /* This applies to read commands */
618 default: 620 default:
619 /* 621 /*
620 * If we don't have access to the busy pin, we apply the given 622 * If we don't have access to the busy pin, we apply the given
621 * command delay 623 * command delay
622 */ 624 */
623 if (!this->dev_ready) { 625 if (!this->dev_ready) {
624 udelay (this->chip_delay); 626 udelay (this->chip_delay);
625 return; 627 return;
626 } 628 }
627 } 629 }
628 /* Apply this short delay always to ensure that we do wait tWB in 630 /* Apply this short delay always to ensure that we do wait tWB in
629 * any case on any machine. */ 631 * any case on any machine. */
@@ -653,8 +655,8 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
653 column += mtd->oobblock; 655 column += mtd->oobblock;
654 command = NAND_CMD_READ0; 656 command = NAND_CMD_READ0;
655 } 657 }
656 658
657 659
658 /* Begin command latch cycle */ 660 /* Begin command latch cycle */
659 this->hwcontrol(mtd, NAND_CTL_SETCLE); 661 this->hwcontrol(mtd, NAND_CTL_SETCLE);
660 /* Write out the command to the device. */ 662 /* Write out the command to the device. */
@@ -672,7 +674,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
672 column >>= 1; 674 column >>= 1;
673 this->write_byte(mtd, column & 0xff); 675 this->write_byte(mtd, column & 0xff);
674 this->write_byte(mtd, column >> 8); 676 this->write_byte(mtd, column >> 8);
675 } 677 }
676 if (page_addr != -1) { 678 if (page_addr != -1) {
677 this->write_byte(mtd, (unsigned char) (page_addr & 0xff)); 679 this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
678 this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff)); 680 this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
@@ -683,13 +685,13 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
683 /* Latch in address */ 685 /* Latch in address */
684 this->hwcontrol(mtd, NAND_CTL_CLRALE); 686 this->hwcontrol(mtd, NAND_CTL_CLRALE);
685 } 687 }
686 688
687 /* 689 /*
688 * program and erase have their own busy handlers 690 * program and erase have their own busy handlers
689 * status, sequential in, and deplete1 need no delay 691 * status, sequential in, and deplete1 need no delay
690 */ 692 */
691 switch (command) { 693 switch (command) {
692 694
693 case NAND_CMD_CACHEDPROG: 695 case NAND_CMD_CACHEDPROG:
694 case NAND_CMD_PAGEPROG: 696 case NAND_CMD_PAGEPROG:
695 case NAND_CMD_ERASE1: 697 case NAND_CMD_ERASE1:
@@ -699,7 +701,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
699 case NAND_CMD_DEPLETE1: 701 case NAND_CMD_DEPLETE1:
700 return; 702 return;
701 703
702 /* 704 /*
703 * read error status commands require only a short delay 705 * read error status commands require only a short delay
704 */ 706 */
705 case NAND_CMD_STATUS_ERROR: 707 case NAND_CMD_STATUS_ERROR:
@@ -711,7 +713,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
711 return; 713 return;
712 714
713 case NAND_CMD_RESET: 715 case NAND_CMD_RESET:
714 if (this->dev_ready) 716 if (this->dev_ready)
715 break; 717 break;
716 udelay(this->chip_delay); 718 udelay(this->chip_delay);
717 this->hwcontrol(mtd, NAND_CTL_SETCLE); 719 this->hwcontrol(mtd, NAND_CTL_SETCLE);
@@ -728,17 +730,17 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
728 /* End command latch cycle */ 730 /* End command latch cycle */
729 this->hwcontrol(mtd, NAND_CTL_CLRCLE); 731 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
730 /* Fall through into ready check */ 732 /* Fall through into ready check */
731 733
732 /* This applies to read commands */ 734 /* This applies to read commands */
733 default: 735 default:
734 /* 736 /*
735 * If we don't have access to the busy pin, we apply the given 737 * If we don't have access to the busy pin, we apply the given
736 * command delay 738 * command delay
737 */ 739 */
738 if (!this->dev_ready) { 740 if (!this->dev_ready) {
739 udelay (this->chip_delay); 741 udelay (this->chip_delay);
740 return; 742 return;
741 } 743 }
742 } 744 }
743 745
744 /* Apply this short delay always to ensure that we do wait tWB in 746 /* Apply this short delay always to ensure that we do wait tWB in
@@ -752,11 +754,11 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
752 * nand_get_device - [GENERIC] Get chip for selected access 754 * nand_get_device - [GENERIC] Get chip for selected access
753 * @this: the nand chip descriptor 755 * @this: the nand chip descriptor
754 * @mtd: MTD device structure 756 * @mtd: MTD device structure
755 * @new_state: the state which is requested 757 * @new_state: the state which is requested
756 * 758 *
757 * Get the device and lock it for exclusive access 759 * Get the device and lock it for exclusive access
758 */ 760 */
759static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state) 761static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state)
760{ 762{
761 struct nand_chip *active; 763 struct nand_chip *active;
762 spinlock_t *lock; 764 spinlock_t *lock;
@@ -779,7 +781,11 @@ retry:
779 if (active == this && this->state == FL_READY) { 781 if (active == this && this->state == FL_READY) {
780 this->state = new_state; 782 this->state = new_state;
781 spin_unlock(lock); 783 spin_unlock(lock);
782 return; 784 return 0;
785 }
786 if (new_state == FL_PM_SUSPENDED) {
787 spin_unlock(lock);
788 return (this->state == FL_PM_SUSPENDED) ? 0 : -EAGAIN;
783 } 789 }
784 set_current_state(TASK_UNINTERRUPTIBLE); 790 set_current_state(TASK_UNINTERRUPTIBLE);
785 add_wait_queue(wq, &wait); 791 add_wait_queue(wq, &wait);
@@ -796,7 +802,7 @@ retry:
796 * @state: state to select the max. timeout value 802 * @state: state to select the max. timeout value
797 * 803 *
798 * Wait for command done. This applies to erase and program only 804 * Wait for command done. This applies to erase and program only
799 * Erase can take up to 400ms and program up to 20ms according to 805 * Erase can take up to 400ms and program up to 20ms according to
800 * general NAND and SmartMedia specs 806 * general NAND and SmartMedia specs
801 * 807 *
802*/ 808*/
@@ -805,7 +811,7 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
805 811
806 unsigned long timeo = jiffies; 812 unsigned long timeo = jiffies;
807 int status; 813 int status;
808 814
809 if (state == FL_ERASING) 815 if (state == FL_ERASING)
810 timeo += (HZ * 400) / 1000; 816 timeo += (HZ * 400) / 1000;
811 else 817 else
@@ -817,17 +823,17 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
817 823
818 if ((state == FL_ERASING) && (this->options & NAND_IS_AND)) 824 if ((state == FL_ERASING) && (this->options & NAND_IS_AND))
819 this->cmdfunc (mtd, NAND_CMD_STATUS_MULTI, -1, -1); 825 this->cmdfunc (mtd, NAND_CMD_STATUS_MULTI, -1, -1);
820 else 826 else
821 this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); 827 this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
822 828
823 while (time_before(jiffies, timeo)) { 829 while (time_before(jiffies, timeo)) {
824 /* Check, if we were interrupted */ 830 /* Check, if we were interrupted */
825 if (this->state != state) 831 if (this->state != state)
826 return 0; 832 return 0;
827 833
828 if (this->dev_ready) { 834 if (this->dev_ready) {
829 if (this->dev_ready(mtd)) 835 if (this->dev_ready(mtd))
830 break; 836 break;
831 } else { 837 } else {
832 if (this->read_byte(mtd) & NAND_STATUS_READY) 838 if (this->read_byte(mtd) & NAND_STATUS_READY)
833 break; 839 break;
@@ -853,7 +859,7 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
853 * 859 *
854 * Cached programming is not supported yet. 860 * Cached programming is not supported yet.
855 */ 861 */
856static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, 862static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page,
857 u_char *oob_buf, struct nand_oobinfo *oobsel, int cached) 863 u_char *oob_buf, struct nand_oobinfo *oobsel, int cached)
858{ 864{
859 int i, status; 865 int i, status;
@@ -862,10 +868,10 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
862 int *oob_config = oobsel->eccpos; 868 int *oob_config = oobsel->eccpos;
863 int datidx = 0, eccidx = 0, eccsteps = this->eccsteps; 869 int datidx = 0, eccidx = 0, eccsteps = this->eccsteps;
864 int eccbytes = 0; 870 int eccbytes = 0;
865 871
866 /* FIXME: Enable cached programming */ 872 /* FIXME: Enable cached programming */
867 cached = 0; 873 cached = 0;
868 874
869 /* Send command to begin auto page programming */ 875 /* Send command to begin auto page programming */
870 this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page); 876 this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page);
871 877
@@ -876,7 +882,7 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
876 printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n"); 882 printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n");
877 this->write_buf(mtd, this->data_poi, mtd->oobblock); 883 this->write_buf(mtd, this->data_poi, mtd->oobblock);
878 break; 884 break;
879 885
880 /* Software ecc 3/256, write all */ 886 /* Software ecc 3/256, write all */
881 case NAND_ECC_SOFT: 887 case NAND_ECC_SOFT:
882 for (; eccsteps; eccsteps--) { 888 for (; eccsteps; eccsteps--) {
@@ -905,11 +911,11 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
905 } 911 }
906 break; 912 break;
907 } 913 }
908 914
909 /* Write out OOB data */ 915 /* Write out OOB data */
910 if (this->options & NAND_HWECC_SYNDROME) 916 if (this->options & NAND_HWECC_SYNDROME)
911 this->write_buf(mtd, &oob_buf[oobsel->eccbytes], mtd->oobsize - oobsel->eccbytes); 917 this->write_buf(mtd, &oob_buf[oobsel->eccbytes], mtd->oobsize - oobsel->eccbytes);
912 else 918 else
913 this->write_buf(mtd, oob_buf, mtd->oobsize); 919 this->write_buf(mtd, oob_buf, mtd->oobsize);
914 920
915 /* Send command to actually program the data */ 921 /* Send command to actually program the data */
@@ -934,7 +940,7 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
934 /* wait until cache is ready*/ 940 /* wait until cache is ready*/
935 // status = this->waitfunc (mtd, this, FL_CACHEDRPG); 941 // status = this->waitfunc (mtd, this, FL_CACHEDRPG);
936 } 942 }
937 return 0; 943 return 0;
938} 944}
939 945
940#ifdef CONFIG_MTD_NAND_VERIFY_WRITE 946#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
@@ -950,19 +956,19 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
950 * @oobmode: 1 = full buffer verify, 0 = ecc only 956 * @oobmode: 1 = full buffer verify, 0 = ecc only
951 * 957 *
952 * The NAND device assumes that it is always writing to a cleanly erased page. 958 * The NAND device assumes that it is always writing to a cleanly erased page.
953 * Hence, it performs its internal write verification only on bits that 959 * Hence, it performs its internal write verification only on bits that
954 * transitioned from 1 to 0. The device does NOT verify the whole page on a 960 * transitioned from 1 to 0. The device does NOT verify the whole page on a
955 * byte by byte basis. It is possible that the page was not completely erased 961 * byte by byte basis. It is possible that the page was not completely erased
956 * or the page is becoming unusable due to wear. The read with ECC would catch 962 * or the page is becoming unusable due to wear. The read with ECC would catch
957 * the error later when the ECC page check fails, but we would rather catch 963 * the error later when the ECC page check fails, but we would rather catch
958 * it early in the page write stage. Better to write no data than invalid data. 964 * it early in the page write stage. Better to write no data than invalid data.
959 */ 965 */
960static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages, 966static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
961 u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode) 967 u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode)
962{ 968{
963 int i, j, datidx = 0, oobofs = 0, res = -EIO; 969 int i, j, datidx = 0, oobofs = 0, res = -EIO;
964 int eccsteps = this->eccsteps; 970 int eccsteps = this->eccsteps;
965 int hweccbytes; 971 int hweccbytes;
966 u_char oobdata[64]; 972 u_char oobdata[64];
967 973
968 hweccbytes = (this->options & NAND_HWECC_SYNDROME) ? (oobsel->eccbytes / eccsteps) : 0; 974 hweccbytes = (this->options & NAND_HWECC_SYNDROME) ? (oobsel->eccbytes / eccsteps) : 0;
@@ -1002,7 +1008,7 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int
1002 1008
1003 if (oobsel->useecc != MTD_NANDECC_OFF && !hweccbytes) { 1009 if (oobsel->useecc != MTD_NANDECC_OFF && !hweccbytes) {
1004 int ecccnt = oobsel->eccbytes; 1010 int ecccnt = oobsel->eccbytes;
1005 1011
1006 for (i = 0; i < ecccnt; i++) { 1012 for (i = 0; i < ecccnt; i++) {
1007 int idx = oobsel->eccpos[i]; 1013 int idx = oobsel->eccpos[i];
1008 if (oobdata[idx] != oob_buf[oobofs + idx] ) { 1014 if (oobdata[idx] != oob_buf[oobofs + idx] ) {
@@ -1012,20 +1018,20 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int
1012 goto out; 1018 goto out;
1013 } 1019 }
1014 } 1020 }
1015 } 1021 }
1016 } 1022 }
1017 oobofs += mtd->oobsize - hweccbytes * eccsteps; 1023 oobofs += mtd->oobsize - hweccbytes * eccsteps;
1018 page++; 1024 page++;
1019 numpages--; 1025 numpages--;
1020 1026
1021 /* Apply delay or wait for ready/busy pin 1027 /* Apply delay or wait for ready/busy pin
1022 * Do this before the AUTOINCR check, so no problems 1028 * Do this before the AUTOINCR check, so no problems
1023 * arise if a chip which does auto increment 1029 * arise if a chip which does auto increment
1024 * is marked as NOAUTOINCR by the board driver. 1030 * is marked as NOAUTOINCR by the board driver.
1025 * Do this also before returning, so the chip is 1031 * Do this also before returning, so the chip is
1026 * ready for the next command. 1032 * ready for the next command.
1027 */ 1033 */
1028 if (!this->dev_ready) 1034 if (!this->dev_ready)
1029 udelay (this->chip_delay); 1035 udelay (this->chip_delay);
1030 else 1036 else
1031 nand_wait_ready(mtd); 1037 nand_wait_ready(mtd);
@@ -1033,17 +1039,17 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int
1033 /* All done, return happy */ 1039 /* All done, return happy */
1034 if (!numpages) 1040 if (!numpages)
1035 return 0; 1041 return 0;
1036 1042
1037 1043
1038 /* Check, if the chip supports auto page increment */ 1044 /* Check, if the chip supports auto page increment */
1039 if (!NAND_CANAUTOINCR(this)) 1045 if (!NAND_CANAUTOINCR(this))
1040 this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page); 1046 this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
1041 } 1047 }
1042 /* 1048 /*
1043 * Terminate the read command. We come here in case of an error 1049 * Terminate the read command. We come here in case of an error
1044 * So we must issue a reset command. 1050 * So we must issue a reset command.
1045 */ 1051 */
1046out: 1052out:
1047 this->cmdfunc (mtd, NAND_CMD_RESET, -1, -1); 1053 this->cmdfunc (mtd, NAND_CMD_RESET, -1, -1);
1048 return res; 1054 return res;
1049} 1055}
@@ -1105,7 +1111,7 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1105 * NAND read with ECC 1111 * NAND read with ECC
1106 */ 1112 */
1107int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, 1113int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1108 size_t * retlen, u_char * buf, u_char * oob_buf, 1114 size_t * retlen, u_char * buf, u_char * oob_buf,
1109 struct nand_oobinfo *oobsel, int flags) 1115 struct nand_oobinfo *oobsel, int flags)
1110{ 1116{
1111 1117
@@ -1139,7 +1145,7 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1139 /* Autoplace of oob data ? Use the default placement scheme */ 1145 /* Autoplace of oob data ? Use the default placement scheme */
1140 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) 1146 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE)
1141 oobsel = this->autooob; 1147 oobsel = this->autooob;
1142 1148
1143 eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE; 1149 eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
1144 oob_config = oobsel->eccpos; 1150 oob_config = oobsel->eccpos;
1145 1151
@@ -1157,28 +1163,28 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1157 end = mtd->oobblock; 1163 end = mtd->oobblock;
1158 ecc = this->eccsize; 1164 ecc = this->eccsize;
1159 eccbytes = this->eccbytes; 1165 eccbytes = this->eccbytes;
1160 1166
1161 if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME)) 1167 if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME))
1162 compareecc = 0; 1168 compareecc = 0;
1163 1169
1164 oobreadlen = mtd->oobsize; 1170 oobreadlen = mtd->oobsize;
1165 if (this->options & NAND_HWECC_SYNDROME) 1171 if (this->options & NAND_HWECC_SYNDROME)
1166 oobreadlen -= oobsel->eccbytes; 1172 oobreadlen -= oobsel->eccbytes;
1167 1173
1168 /* Loop until all data read */ 1174 /* Loop until all data read */
1169 while (read < len) { 1175 while (read < len) {
1170 1176
1171 int aligned = (!col && (len - read) >= end); 1177 int aligned = (!col && (len - read) >= end);
1172 /* 1178 /*
1173 * If the read is not page aligned, we have to read into data buffer 1179 * If the read is not page aligned, we have to read into data buffer
1174 * due to ecc, else we read into return buffer direct 1180 * due to ecc, else we read into return buffer direct
1175 */ 1181 */
1176 if (aligned) 1182 if (aligned)
1177 data_poi = &buf[read]; 1183 data_poi = &buf[read];
1178 else 1184 else
1179 data_poi = this->data_buf; 1185 data_poi = this->data_buf;
1180 1186
1181 /* Check, if we have this page in the buffer 1187 /* Check, if we have this page in the buffer
1182 * 1188 *
1183 * FIXME: Make it work when we must provide oob data too, 1189 * FIXME: Make it work when we must provide oob data too,
1184 * check the usage of data_buf oob field 1190 * check the usage of data_buf oob field
@@ -1194,7 +1200,7 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1194 if (sndcmd) { 1200 if (sndcmd) {
1195 this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page); 1201 this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
1196 sndcmd = 0; 1202 sndcmd = 0;
1197 } 1203 }
1198 1204
1199 /* get oob area, if we have no oob buffer from fs-driver */ 1205 /* get oob area, if we have no oob buffer from fs-driver */
1200 if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE || 1206 if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE ||
@@ -1202,7 +1208,7 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1202 oob_data = &this->data_buf[end]; 1208 oob_data = &this->data_buf[end];
1203 1209
1204 eccsteps = this->eccsteps; 1210 eccsteps = this->eccsteps;
1205 1211
1206 switch (eccmode) { 1212 switch (eccmode) {
1207 case NAND_ECC_NONE: { /* No ECC, Read in a page */ 1213 case NAND_ECC_NONE: { /* No ECC, Read in a page */
1208 static unsigned long lastwhinge = 0; 1214 static unsigned long lastwhinge = 0;
@@ -1213,12 +1219,12 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1213 this->read_buf(mtd, data_poi, end); 1219 this->read_buf(mtd, data_poi, end);
1214 break; 1220 break;
1215 } 1221 }
1216 1222
1217 case NAND_ECC_SOFT: /* Software ECC 3/256: Read in a page + oob data */ 1223 case NAND_ECC_SOFT: /* Software ECC 3/256: Read in a page + oob data */
1218 this->read_buf(mtd, data_poi, end); 1224 this->read_buf(mtd, data_poi, end);
1219 for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc) 1225 for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc)
1220 this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]); 1226 this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
1221 break; 1227 break;
1222 1228
1223 default: 1229 default:
1224 for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) { 1230 for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) {
@@ -1237,15 +1243,15 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1237 * does the error correction on the fly */ 1243 * does the error correction on the fly */
1238 ecc_status = this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]); 1244 ecc_status = this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]);
1239 if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) { 1245 if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
1240 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " 1246 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: "
1241 "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr); 1247 "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr);
1242 ecc_failed++; 1248 ecc_failed++;
1243 } 1249 }
1244 } else { 1250 } else {
1245 this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]); 1251 this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
1246 } 1252 }
1247 } 1253 }
1248 break; 1254 break;
1249 } 1255 }
1250 1256
1251 /* read oobdata */ 1257 /* read oobdata */
@@ -1253,8 +1259,8 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1253 1259
1254 /* Skip ECC check, if not requested (ECC_NONE or HW_ECC with syndromes) */ 1260 /* Skip ECC check, if not requested (ECC_NONE or HW_ECC with syndromes) */
1255 if (!compareecc) 1261 if (!compareecc)
1256 goto readoob; 1262 goto readoob;
1257 1263
1258 /* Pick the ECC bytes out of the oob data */ 1264 /* Pick the ECC bytes out of the oob data */
1259 for (j = 0; j < oobsel->eccbytes; j++) 1265 for (j = 0; j < oobsel->eccbytes; j++)
1260 ecc_code[j] = oob_data[oob_config[j]]; 1266 ecc_code[j] = oob_data[oob_config[j]];
@@ -1262,24 +1268,24 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1262 /* correct data, if neccecary */ 1268 /* correct data, if neccecary */
1263 for (i = 0, j = 0, datidx = 0; i < this->eccsteps; i++, datidx += ecc) { 1269 for (i = 0, j = 0, datidx = 0; i < this->eccsteps; i++, datidx += ecc) {
1264 ecc_status = this->correct_data(mtd, &data_poi[datidx], &ecc_code[j], &ecc_calc[j]); 1270 ecc_status = this->correct_data(mtd, &data_poi[datidx], &ecc_code[j], &ecc_calc[j]);
1265 1271
1266 /* Get next chunk of ecc bytes */ 1272 /* Get next chunk of ecc bytes */
1267 j += eccbytes; 1273 j += eccbytes;
1268 1274
1269 /* Check, if we have a fs supplied oob-buffer, 1275 /* Check, if we have a fs supplied oob-buffer,
1270 * This is the legacy mode. Used by YAFFS1 1276 * This is the legacy mode. Used by YAFFS1
1271 * Should go away some day 1277 * Should go away some day
1272 */ 1278 */
1273 if (oob_buf && oobsel->useecc == MTD_NANDECC_PLACE) { 1279 if (oob_buf && oobsel->useecc == MTD_NANDECC_PLACE) {
1274 int *p = (int *)(&oob_data[mtd->oobsize]); 1280 int *p = (int *)(&oob_data[mtd->oobsize]);
1275 p[i] = ecc_status; 1281 p[i] = ecc_status;
1276 } 1282 }
1277 1283
1278 if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) { 1284 if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
1279 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page); 1285 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page);
1280 ecc_failed++; 1286 ecc_failed++;
1281 } 1287 }
1282 } 1288 }
1283 1289
1284 readoob: 1290 readoob:
1285 /* check, if we have a fs supplied oob-buffer */ 1291 /* check, if we have a fs supplied oob-buffer */
@@ -1305,25 +1311,25 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1305 } 1311 }
1306 readdata: 1312 readdata:
1307 /* Partial page read, transfer data into fs buffer */ 1313 /* Partial page read, transfer data into fs buffer */
1308 if (!aligned) { 1314 if (!aligned) {
1309 for (j = col; j < end && read < len; j++) 1315 for (j = col; j < end && read < len; j++)
1310 buf[read++] = data_poi[j]; 1316 buf[read++] = data_poi[j];
1311 this->pagebuf = realpage; 1317 this->pagebuf = realpage;
1312 } else 1318 } else
1313 read += mtd->oobblock; 1319 read += mtd->oobblock;
1314 1320
1315 /* Apply delay or wait for ready/busy pin 1321 /* Apply delay or wait for ready/busy pin
1316 * Do this before the AUTOINCR check, so no problems 1322 * Do this before the AUTOINCR check, so no problems
1317 * arise if a chip which does auto increment 1323 * arise if a chip which does auto increment
1318 * is marked as NOAUTOINCR by the board driver. 1324 * is marked as NOAUTOINCR by the board driver.
1319 */ 1325 */
1320 if (!this->dev_ready) 1326 if (!this->dev_ready)
1321 udelay (this->chip_delay); 1327 udelay (this->chip_delay);
1322 else 1328 else
1323 nand_wait_ready(mtd); 1329 nand_wait_ready(mtd);
1324 1330
1325 if (read == len) 1331 if (read == len)
1326 break; 1332 break;
1327 1333
1328 /* For subsequent reads align to page boundary. */ 1334 /* For subsequent reads align to page boundary. */
1329 col = 0; 1335 col = 0;
@@ -1337,11 +1343,11 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1337 this->select_chip(mtd, -1); 1343 this->select_chip(mtd, -1);
1338 this->select_chip(mtd, chipnr); 1344 this->select_chip(mtd, chipnr);
1339 } 1345 }
1340 /* Check, if the chip supports auto page increment 1346 /* Check, if the chip supports auto page increment
1341 * or if we have hit a block boundary. 1347 * or if we have hit a block boundary.
1342 */ 1348 */
1343 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) 1349 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
1344 sndcmd = 1; 1350 sndcmd = 1;
1345 } 1351 }
1346 1352
1347 /* Deselect and wake up anyone waiting on the device */ 1353 /* Deselect and wake up anyone waiting on the device */
@@ -1378,7 +1384,7 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
1378 /* Shift to get page */ 1384 /* Shift to get page */
1379 page = (int)(from >> this->page_shift); 1385 page = (int)(from >> this->page_shift);
1380 chipnr = (int)(from >> this->chip_shift); 1386 chipnr = (int)(from >> this->chip_shift);
1381 1387
1382 /* Mask to get column */ 1388 /* Mask to get column */
1383 col = from & (mtd->oobsize - 1); 1389 col = from & (mtd->oobsize - 1);
1384 1390
@@ -1400,7 +1406,7 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
1400 1406
1401 /* Send the read command */ 1407 /* Send the read command */
1402 this->cmdfunc (mtd, NAND_CMD_READOOB, col, page & this->pagemask); 1408 this->cmdfunc (mtd, NAND_CMD_READOOB, col, page & this->pagemask);
1403 /* 1409 /*
1404 * Read the data, if we read more than one page 1410 * Read the data, if we read more than one page
1405 * oob data, let the device transfer the data ! 1411 * oob data, let the device transfer the data !
1406 */ 1412 */
@@ -1422,20 +1428,20 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
1422 this->select_chip(mtd, -1); 1428 this->select_chip(mtd, -1);
1423 this->select_chip(mtd, chipnr); 1429 this->select_chip(mtd, chipnr);
1424 } 1430 }
1425 1431
1426 /* Apply delay or wait for ready/busy pin 1432 /* Apply delay or wait for ready/busy pin
1427 * Do this before the AUTOINCR check, so no problems 1433 * Do this before the AUTOINCR check, so no problems
1428 * arise if a chip which does auto increment 1434 * arise if a chip which does auto increment
1429 * is marked as NOAUTOINCR by the board driver. 1435 * is marked as NOAUTOINCR by the board driver.
1430 */ 1436 */
1431 if (!this->dev_ready) 1437 if (!this->dev_ready)
1432 udelay (this->chip_delay); 1438 udelay (this->chip_delay);
1433 else 1439 else
1434 nand_wait_ready(mtd); 1440 nand_wait_ready(mtd);
1435 1441
1436 /* Check, if the chip supports auto page increment 1442 /* Check, if the chip supports auto page increment
1437 * or if we have hit a block boundary. 1443 * or if we have hit a block boundary.
1438 */ 1444 */
1439 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) { 1445 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) {
1440 /* For subsequent page reads set offset to 0 */ 1446 /* For subsequent page reads set offset to 0 */
1441 this->cmdfunc (mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask); 1447 this->cmdfunc (mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask);
@@ -1481,27 +1487,27 @@ int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len,
1481 nand_get_device (this, mtd , FL_READING); 1487 nand_get_device (this, mtd , FL_READING);
1482 1488
1483 this->select_chip (mtd, chip); 1489 this->select_chip (mtd, chip);
1484 1490
1485 /* Add requested oob length */ 1491 /* Add requested oob length */
1486 len += ooblen; 1492 len += ooblen;
1487 1493
1488 while (len) { 1494 while (len) {
1489 if (sndcmd) 1495 if (sndcmd)
1490 this->cmdfunc (mtd, NAND_CMD_READ0, 0, page & this->pagemask); 1496 this->cmdfunc (mtd, NAND_CMD_READ0, 0, page & this->pagemask);
1491 sndcmd = 0; 1497 sndcmd = 0;
1492 1498
1493 this->read_buf (mtd, &buf[cnt], pagesize); 1499 this->read_buf (mtd, &buf[cnt], pagesize);
1494 1500
1495 len -= pagesize; 1501 len -= pagesize;
1496 cnt += pagesize; 1502 cnt += pagesize;
1497 page++; 1503 page++;
1498 1504
1499 if (!this->dev_ready) 1505 if (!this->dev_ready)
1500 udelay (this->chip_delay); 1506 udelay (this->chip_delay);
1501 else 1507 else
1502 nand_wait_ready(mtd); 1508 nand_wait_ready(mtd);
1503 1509
1504 /* Check, if the chip supports auto page increment */ 1510 /* Check, if the chip supports auto page increment */
1505 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) 1511 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
1506 sndcmd = 1; 1512 sndcmd = 1;
1507 } 1513 }
@@ -1512,8 +1518,8 @@ int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len,
1512} 1518}
1513 1519
1514 1520
1515/** 1521/**
1516 * nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer 1522 * nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer
1517 * @mtd: MTD device structure 1523 * @mtd: MTD device structure
1518 * @fsbuf: buffer given by fs driver 1524 * @fsbuf: buffer given by fs driver
1519 * @oobsel: out of band selection structre 1525 * @oobsel: out of band selection structre
@@ -1542,20 +1548,20 @@ static u_char * nand_prepare_oobbuf (struct mtd_info *mtd, u_char *fsbuf, struct
1542 int i, len, ofs; 1548 int i, len, ofs;
1543 1549
1544 /* Zero copy fs supplied buffer */ 1550 /* Zero copy fs supplied buffer */
1545 if (fsbuf && !autoplace) 1551 if (fsbuf && !autoplace)
1546 return fsbuf; 1552 return fsbuf;
1547 1553
1548 /* Check, if the buffer must be filled with ff again */ 1554 /* Check, if the buffer must be filled with ff again */
1549 if (this->oobdirty) { 1555 if (this->oobdirty) {
1550 memset (this->oob_buf, 0xff, 1556 memset (this->oob_buf, 0xff,
1551 mtd->oobsize << (this->phys_erase_shift - this->page_shift)); 1557 mtd->oobsize << (this->phys_erase_shift - this->page_shift));
1552 this->oobdirty = 0; 1558 this->oobdirty = 0;
1553 } 1559 }
1554 1560
1555 /* If we have no autoplacement or no fs buffer use the internal one */ 1561 /* If we have no autoplacement or no fs buffer use the internal one */
1556 if (!autoplace || !fsbuf) 1562 if (!autoplace || !fsbuf)
1557 return this->oob_buf; 1563 return this->oob_buf;
1558 1564
1559 /* Walk through the pages and place the data */ 1565 /* Walk through the pages and place the data */
1560 this->oobdirty = 1; 1566 this->oobdirty = 1;
1561 ofs = 0; 1567 ofs = 0;
@@ -1589,7 +1595,7 @@ static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * ret
1589{ 1595{
1590 return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, NULL)); 1596 return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, NULL));
1591} 1597}
1592 1598
1593/** 1599/**
1594 * nand_write_ecc - [MTD Interface] NAND write with ECC 1600 * nand_write_ecc - [MTD Interface] NAND write with ECC
1595 * @mtd: MTD device structure 1601 * @mtd: MTD device structure
@@ -1622,7 +1628,7 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
1622 return -EINVAL; 1628 return -EINVAL;
1623 } 1629 }
1624 1630
1625 /* reject writes, which are not page aligned */ 1631 /* reject writes, which are not page aligned */
1626 if (NOTALIGNED (to) || NOTALIGNED(len)) { 1632 if (NOTALIGNED (to) || NOTALIGNED(len)) {
1627 printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n"); 1633 printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n");
1628 return -EINVAL; 1634 return -EINVAL;
@@ -1641,14 +1647,14 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
1641 goto out; 1647 goto out;
1642 1648
1643 /* if oobsel is NULL, use chip defaults */ 1649 /* if oobsel is NULL, use chip defaults */
1644 if (oobsel == NULL) 1650 if (oobsel == NULL)
1645 oobsel = &mtd->oobinfo; 1651 oobsel = &mtd->oobinfo;
1646 1652
1647 /* Autoplace of oob data ? Use the default placement scheme */ 1653 /* Autoplace of oob data ? Use the default placement scheme */
1648 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) { 1654 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) {
1649 oobsel = this->autooob; 1655 oobsel = this->autooob;
1650 autoplace = 1; 1656 autoplace = 1;
1651 } 1657 }
1652 if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR) 1658 if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
1653 autoplace = 1; 1659 autoplace = 1;
1654 1660
@@ -1656,9 +1662,9 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
1656 totalpages = len >> this->page_shift; 1662 totalpages = len >> this->page_shift;
1657 page = (int) (to >> this->page_shift); 1663 page = (int) (to >> this->page_shift);
1658 /* Invalidate the page cache, if we write to the cached page */ 1664 /* Invalidate the page cache, if we write to the cached page */
1659 if (page <= this->pagebuf && this->pagebuf < (page + totalpages)) 1665 if (page <= this->pagebuf && this->pagebuf < (page + totalpages))
1660 this->pagebuf = -1; 1666 this->pagebuf = -1;
1661 1667
1662 /* Set it relative to chip */ 1668 /* Set it relative to chip */
1663 page &= this->pagemask; 1669 page &= this->pagemask;
1664 startpage = page; 1670 startpage = page;
@@ -1680,14 +1686,14 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
1680 if (ret) { 1686 if (ret) {
1681 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: write_page failed %d\n", ret); 1687 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: write_page failed %d\n", ret);
1682 goto out; 1688 goto out;
1683 } 1689 }
1684 /* Next oob page */ 1690 /* Next oob page */
1685 oob += mtd->oobsize; 1691 oob += mtd->oobsize;
1686 /* Update written bytes count */ 1692 /* Update written bytes count */
1687 written += mtd->oobblock; 1693 written += mtd->oobblock;
1688 if (written == len) 1694 if (written == len)
1689 goto cmp; 1695 goto cmp;
1690 1696
1691 /* Increment page address */ 1697 /* Increment page address */
1692 page++; 1698 page++;
1693 1699
@@ -1698,13 +1704,13 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
1698 if (!(page & (ppblock - 1))){ 1704 if (!(page & (ppblock - 1))){
1699 int ofs; 1705 int ofs;
1700 this->data_poi = bufstart; 1706 this->data_poi = bufstart;
1701 ret = nand_verify_pages (mtd, this, startpage, 1707 ret = nand_verify_pages (mtd, this, startpage,
1702 page - startpage, 1708 page - startpage,
1703 oobbuf, oobsel, chipnr, (eccbuf != NULL)); 1709 oobbuf, oobsel, chipnr, (eccbuf != NULL));
1704 if (ret) { 1710 if (ret) {
1705 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret); 1711 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
1706 goto out; 1712 goto out;
1707 } 1713 }
1708 *retlen = written; 1714 *retlen = written;
1709 1715
1710 ofs = autoplace ? mtd->oobavail : mtd->oobsize; 1716 ofs = autoplace ? mtd->oobavail : mtd->oobsize;
@@ -1714,8 +1720,9 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
1714 numpages = min (totalpages, ppblock); 1720 numpages = min (totalpages, ppblock);
1715 page &= this->pagemask; 1721 page &= this->pagemask;
1716 startpage = page; 1722 startpage = page;
1717 oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel, 1723 oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel,
1718 autoplace, numpages); 1724 autoplace, numpages);
1725 oob = 0;
1719 /* Check, if we cross a chip boundary */ 1726 /* Check, if we cross a chip boundary */
1720 if (!page) { 1727 if (!page) {
1721 chipnr++; 1728 chipnr++;
@@ -1731,7 +1738,7 @@ cmp:
1731 oobbuf, oobsel, chipnr, (eccbuf != NULL)); 1738 oobbuf, oobsel, chipnr, (eccbuf != NULL));
1732 if (!ret) 1739 if (!ret)
1733 *retlen = written; 1740 *retlen = written;
1734 else 1741 else
1735 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret); 1742 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
1736 1743
1737out: 1744out:
@@ -1791,7 +1798,7 @@ static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t *
1791 /* Check, if it is write protected */ 1798 /* Check, if it is write protected */
1792 if (nand_check_wp(mtd)) 1799 if (nand_check_wp(mtd))
1793 goto out; 1800 goto out;
1794 1801
1795 /* Invalidate the page cache, if we write to the cached page */ 1802 /* Invalidate the page cache, if we write to the cached page */
1796 if (page == this->pagebuf) 1803 if (page == this->pagebuf)
1797 this->pagebuf = -1; 1804 this->pagebuf = -1;
@@ -1854,10 +1861,10 @@ out:
1854 * 1861 *
1855 * NAND write with kvec. This just calls the ecc function 1862 * NAND write with kvec. This just calls the ecc function
1856 */ 1863 */
1857static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, 1864static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
1858 loff_t to, size_t * retlen) 1865 loff_t to, size_t * retlen)
1859{ 1866{
1860 return (nand_writev_ecc (mtd, vecs, count, to, retlen, NULL, NULL)); 1867 return (nand_writev_ecc (mtd, vecs, count, to, retlen, NULL, NULL));
1861} 1868}
1862 1869
1863/** 1870/**
@@ -1872,7 +1879,7 @@ static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned
1872 * 1879 *
1873 * NAND write with iovec with ecc 1880 * NAND write with iovec with ecc
1874 */ 1881 */
1875static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, 1882static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
1876 loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel) 1883 loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel)
1877{ 1884{
1878 int i, page, len, total_len, ret = -EIO, written = 0, chipnr; 1885 int i, page, len, total_len, ret = -EIO, written = 0, chipnr;
@@ -1898,7 +1905,7 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
1898 return -EINVAL; 1905 return -EINVAL;
1899 } 1906 }
1900 1907
1901 /* reject writes, which are not page aligned */ 1908 /* reject writes, which are not page aligned */
1902 if (NOTALIGNED (to) || NOTALIGNED(total_len)) { 1909 if (NOTALIGNED (to) || NOTALIGNED(total_len)) {
1903 printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n"); 1910 printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n");
1904 return -EINVAL; 1911 return -EINVAL;
@@ -1917,21 +1924,21 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
1917 goto out; 1924 goto out;
1918 1925
1919 /* if oobsel is NULL, use chip defaults */ 1926 /* if oobsel is NULL, use chip defaults */
1920 if (oobsel == NULL) 1927 if (oobsel == NULL)
1921 oobsel = &mtd->oobinfo; 1928 oobsel = &mtd->oobinfo;
1922 1929
1923 /* Autoplace of oob data ? Use the default placement scheme */ 1930 /* Autoplace of oob data ? Use the default placement scheme */
1924 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) { 1931 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) {
1925 oobsel = this->autooob; 1932 oobsel = this->autooob;
1926 autoplace = 1; 1933 autoplace = 1;
1927 } 1934 }
1928 if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR) 1935 if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
1929 autoplace = 1; 1936 autoplace = 1;
1930 1937
1931 /* Setup start page */ 1938 /* Setup start page */
1932 page = (int) (to >> this->page_shift); 1939 page = (int) (to >> this->page_shift);
1933 /* Invalidate the page cache, if we write to the cached page */ 1940 /* Invalidate the page cache, if we write to the cached page */
1934 if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift)) 1941 if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift))
1935 this->pagebuf = -1; 1942 this->pagebuf = -1;
1936 1943
1937 startpage = page & this->pagemask; 1944 startpage = page & this->pagemask;
@@ -1955,10 +1962,10 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
1955 oob = 0; 1962 oob = 0;
1956 for (i = 1; i <= numpages; i++) { 1963 for (i = 1; i <= numpages; i++) {
1957 /* Write one page. If this is the last page to write 1964 /* Write one page. If this is the last page to write
1958 * then use the real pageprogram command, else select 1965 * then use the real pageprogram command, else select
1959 * cached programming if supported by the chip. 1966 * cached programming if supported by the chip.
1960 */ 1967 */
1961 ret = nand_write_page (mtd, this, page & this->pagemask, 1968 ret = nand_write_page (mtd, this, page & this->pagemask,
1962 &oobbuf[oob], oobsel, i != numpages); 1969 &oobbuf[oob], oobsel, i != numpages);
1963 if (ret) 1970 if (ret)
1964 goto out; 1971 goto out;
@@ -1974,12 +1981,12 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
1974 count--; 1981 count--;
1975 } 1982 }
1976 } else { 1983 } else {
1977 /* We must use the internal buffer, read data out of each 1984 /* We must use the internal buffer, read data out of each
1978 * tuple until we have a full page to write 1985 * tuple until we have a full page to write
1979 */ 1986 */
1980 int cnt = 0; 1987 int cnt = 0;
1981 while (cnt < mtd->oobblock) { 1988 while (cnt < mtd->oobblock) {
1982 if (vecs->iov_base != NULL && vecs->iov_len) 1989 if (vecs->iov_base != NULL && vecs->iov_len)
1983 this->data_buf[cnt++] = ((u_char *) vecs->iov_base)[len++]; 1990 this->data_buf[cnt++] = ((u_char *) vecs->iov_base)[len++];
1984 /* Check, if we have to switch to the next tuple */ 1991 /* Check, if we have to switch to the next tuple */
1985 if (len >= (int) vecs->iov_len) { 1992 if (len >= (int) vecs->iov_len) {
@@ -1988,10 +1995,10 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
1988 count--; 1995 count--;
1989 } 1996 }
1990 } 1997 }
1991 this->pagebuf = page; 1998 this->pagebuf = page;
1992 this->data_poi = this->data_buf; 1999 this->data_poi = this->data_buf;
1993 bufstart = this->data_poi; 2000 bufstart = this->data_poi;
1994 numpages = 1; 2001 numpages = 1;
1995 oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages); 2002 oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages);
1996 ret = nand_write_page (mtd, this, page & this->pagemask, 2003 ret = nand_write_page (mtd, this, page & this->pagemask,
1997 oobbuf, oobsel, 0); 2004 oobbuf, oobsel, 0);
@@ -2004,7 +2011,7 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
2004 ret = nand_verify_pages (mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0); 2011 ret = nand_verify_pages (mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0);
2005 if (ret) 2012 if (ret)
2006 goto out; 2013 goto out;
2007 2014
2008 written += mtd->oobblock * numpages; 2015 written += mtd->oobblock * numpages;
2009 /* All done ? */ 2016 /* All done ? */
2010 if (!count) 2017 if (!count)
@@ -2072,7 +2079,7 @@ static int nand_erase (struct mtd_info *mtd, struct erase_info *instr)
2072{ 2079{
2073 return nand_erase_nand (mtd, instr, 0); 2080 return nand_erase_nand (mtd, instr, 0);
2074} 2081}
2075 2082
2076#define BBT_PAGE_MASK 0xffffff3f 2083#define BBT_PAGE_MASK 0xffffff3f
2077/** 2084/**
2078 * nand_erase_intern - [NAND Interface] erase block(s) 2085 * nand_erase_intern - [NAND Interface] erase block(s)
@@ -2154,14 +2161,14 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
2154 instr->state = MTD_ERASE_FAILED; 2161 instr->state = MTD_ERASE_FAILED;
2155 goto erase_exit; 2162 goto erase_exit;
2156 } 2163 }
2157 2164
2158 /* Invalidate the page cache, if we erase the block which contains 2165 /* Invalidate the page cache, if we erase the block which contains
2159 the current cached page */ 2166 the current cached page */
2160 if (page <= this->pagebuf && this->pagebuf < (page + pages_per_block)) 2167 if (page <= this->pagebuf && this->pagebuf < (page + pages_per_block))
2161 this->pagebuf = -1; 2168 this->pagebuf = -1;
2162 2169
2163 this->erase_cmd (mtd, page & this->pagemask); 2170 this->erase_cmd (mtd, page & this->pagemask);
2164 2171
2165 status = this->waitfunc (mtd, this, FL_ERASING); 2172 status = this->waitfunc (mtd, this, FL_ERASING);
2166 2173
2167 /* See if operation failed and additional status checks are available */ 2174 /* See if operation failed and additional status checks are available */
@@ -2179,12 +2186,12 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
2179 2186
2180 /* if BBT requires refresh, set the BBT rewrite flag to the page being erased */ 2187 /* if BBT requires refresh, set the BBT rewrite flag to the page being erased */
2181 if (this->options & BBT_AUTO_REFRESH) { 2188 if (this->options & BBT_AUTO_REFRESH) {
2182 if (((page & BBT_PAGE_MASK) == bbt_masked_page) && 2189 if (((page & BBT_PAGE_MASK) == bbt_masked_page) &&
2183 (page != this->bbt_td->pages[chipnr])) { 2190 (page != this->bbt_td->pages[chipnr])) {
2184 rewrite_bbt[chipnr] = (page << this->page_shift); 2191 rewrite_bbt[chipnr] = (page << this->page_shift);
2185 } 2192 }
2186 } 2193 }
2187 2194
2188 /* Increment page address and decrement length */ 2195 /* Increment page address and decrement length */
2189 len -= (1 << this->phys_erase_shift); 2196 len -= (1 << this->phys_erase_shift);
2190 page += pages_per_block; 2197 page += pages_per_block;
@@ -2195,7 +2202,7 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
2195 this->select_chip(mtd, -1); 2202 this->select_chip(mtd, -1);
2196 this->select_chip(mtd, chipnr); 2203 this->select_chip(mtd, chipnr);
2197 2204
2198 /* if BBT requires refresh and BBT-PERCHIP, 2205 /* if BBT requires refresh and BBT-PERCHIP,
2199 * set the BBT page mask to see if this BBT should be rewritten */ 2206 * set the BBT page mask to see if this BBT should be rewritten */
2200 if ((this->options & BBT_AUTO_REFRESH) && (this->bbt_td->options & NAND_BBT_PERCHIP)) { 2207 if ((this->options & BBT_AUTO_REFRESH) && (this->bbt_td->options & NAND_BBT_PERCHIP)) {
2201 bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK; 2208 bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
@@ -2220,7 +2227,7 @@ erase_exit:
2220 for (chipnr = 0; chipnr < this->numchips; chipnr++) { 2227 for (chipnr = 0; chipnr < this->numchips; chipnr++) {
2221 if (rewrite_bbt[chipnr]) { 2228 if (rewrite_bbt[chipnr]) {
2222 /* update the BBT for chip */ 2229 /* update the BBT for chip */
2223 DEBUG (MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt (%d:0x%0x 0x%0x)\n", 2230 DEBUG (MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt (%d:0x%0x 0x%0x)\n",
2224 chipnr, rewrite_bbt[chipnr], this->bbt_td->pages[chipnr]); 2231 chipnr, rewrite_bbt[chipnr], this->bbt_td->pages[chipnr]);
2225 nand_update_bbt (mtd, rewrite_bbt[chipnr]); 2232 nand_update_bbt (mtd, rewrite_bbt[chipnr]);
2226 } 2233 }
@@ -2258,9 +2265,9 @@ static void nand_sync (struct mtd_info *mtd)
2258static int nand_block_isbad (struct mtd_info *mtd, loff_t ofs) 2265static int nand_block_isbad (struct mtd_info *mtd, loff_t ofs)
2259{ 2266{
2260 /* Check for invalid offset */ 2267 /* Check for invalid offset */
2261 if (ofs > mtd->size) 2268 if (ofs > mtd->size)
2262 return -EINVAL; 2269 return -EINVAL;
2263 2270
2264 return nand_block_checkbad (mtd, ofs, 1, 0); 2271 return nand_block_checkbad (mtd, ofs, 1, 0);
2265} 2272}
2266 2273
@@ -2285,6 +2292,34 @@ static int nand_block_markbad (struct mtd_info *mtd, loff_t ofs)
2285} 2292}
2286 2293
2287/** 2294/**
2295 * nand_suspend - [MTD Interface] Suspend the NAND flash
2296 * @mtd: MTD device structure
2297 */
2298static int nand_suspend(struct mtd_info *mtd)
2299{
2300 struct nand_chip *this = mtd->priv;
2301
2302 return nand_get_device (this, mtd, FL_PM_SUSPENDED);
2303}
2304
2305/**
2306 * nand_resume - [MTD Interface] Resume the NAND flash
2307 * @mtd: MTD device structure
2308 */
2309static void nand_resume(struct mtd_info *mtd)
2310{
2311 struct nand_chip *this = mtd->priv;
2312
2313 if (this->state == FL_PM_SUSPENDED)
2314 nand_release_device(mtd);
2315 else
2316 printk(KERN_ERR "resume() called for the chip which is not "
2317 "in suspended state\n");
2318
2319}
2320
2321
2322/**
2288 * nand_scan - [NAND Interface] Scan for the NAND device 2323 * nand_scan - [NAND Interface] Scan for the NAND device
2289 * @mtd: MTD device structure 2324 * @mtd: MTD device structure
2290 * @maxchips: Number of chips to scan for 2325 * @maxchips: Number of chips to scan for
@@ -2351,13 +2386,13 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2351 2386
2352 /* Print and store flash device information */ 2387 /* Print and store flash device information */
2353 for (i = 0; nand_flash_ids[i].name != NULL; i++) { 2388 for (i = 0; nand_flash_ids[i].name != NULL; i++) {
2354 2389
2355 if (nand_dev_id != nand_flash_ids[i].id) 2390 if (nand_dev_id != nand_flash_ids[i].id)
2356 continue; 2391 continue;
2357 2392
2358 if (!mtd->name) mtd->name = nand_flash_ids[i].name; 2393 if (!mtd->name) mtd->name = nand_flash_ids[i].name;
2359 this->chipsize = nand_flash_ids[i].chipsize << 20; 2394 this->chipsize = nand_flash_ids[i].chipsize << 20;
2360 2395
2361 /* New devices have all the information in additional id bytes */ 2396 /* New devices have all the information in additional id bytes */
2362 if (!nand_flash_ids[i].pagesize) { 2397 if (!nand_flash_ids[i].pagesize) {
2363 int extid; 2398 int extid;
@@ -2369,14 +2404,14 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2369 mtd->oobblock = 1024 << (extid & 0x3); 2404 mtd->oobblock = 1024 << (extid & 0x3);
2370 extid >>= 2; 2405 extid >>= 2;
2371 /* Calc oobsize */ 2406 /* Calc oobsize */
2372 mtd->oobsize = (8 << (extid & 0x03)) * (mtd->oobblock / 512); 2407 mtd->oobsize = (8 << (extid & 0x01)) * (mtd->oobblock >> 9);
2373 extid >>= 2; 2408 extid >>= 2;
2374 /* Calc blocksize. Blocksize is multiples of 64KiB */ 2409 /* Calc blocksize. Blocksize is multiples of 64KiB */
2375 mtd->erasesize = (64 * 1024) << (extid & 0x03); 2410 mtd->erasesize = (64 * 1024) << (extid & 0x03);
2376 extid >>= 2; 2411 extid >>= 2;
2377 /* Get buswidth information */ 2412 /* Get buswidth information */
2378 busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0; 2413 busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
2379 2414
2380 } else { 2415 } else {
2381 /* Old devices have this data hardcoded in the 2416 /* Old devices have this data hardcoded in the
2382 * device id table */ 2417 * device id table */
@@ -2396,23 +2431,23 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2396 * this correct ! */ 2431 * this correct ! */
2397 if (busw != (this->options & NAND_BUSWIDTH_16)) { 2432 if (busw != (this->options & NAND_BUSWIDTH_16)) {
2398 printk (KERN_INFO "NAND device: Manufacturer ID:" 2433 printk (KERN_INFO "NAND device: Manufacturer ID:"
2399 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, 2434 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
2400 nand_manuf_ids[maf_id].name , mtd->name); 2435 nand_manuf_ids[maf_id].name , mtd->name);
2401 printk (KERN_WARNING 2436 printk (KERN_WARNING
2402 "NAND bus width %d instead %d bit\n", 2437 "NAND bus width %d instead %d bit\n",
2403 (this->options & NAND_BUSWIDTH_16) ? 16 : 8, 2438 (this->options & NAND_BUSWIDTH_16) ? 16 : 8,
2404 busw ? 16 : 8); 2439 busw ? 16 : 8);
2405 this->select_chip(mtd, -1); 2440 this->select_chip(mtd, -1);
2406 return 1; 2441 return 1;
2407 } 2442 }
2408 2443
2409 /* Calculate the address shift from the page size */ 2444 /* Calculate the address shift from the page size */
2410 this->page_shift = ffs(mtd->oobblock) - 1; 2445 this->page_shift = ffs(mtd->oobblock) - 1;
2411 this->bbt_erase_shift = this->phys_erase_shift = ffs(mtd->erasesize) - 1; 2446 this->bbt_erase_shift = this->phys_erase_shift = ffs(mtd->erasesize) - 1;
2412 this->chip_shift = ffs(this->chipsize) - 1; 2447 this->chip_shift = ffs(this->chipsize) - 1;
2413 2448
2414 /* Set the bad block position */ 2449 /* Set the bad block position */
2415 this->badblockpos = mtd->oobblock > 512 ? 2450 this->badblockpos = mtd->oobblock > 512 ?
2416 NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS; 2451 NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS;
2417 2452
2418 /* Get chip options, preserve non chip based options */ 2453 /* Get chip options, preserve non chip based options */
@@ -2422,10 +2457,10 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2422 this->options |= NAND_NO_AUTOINCR; 2457 this->options |= NAND_NO_AUTOINCR;
2423 /* Check if this is a not a samsung device. Do not clear the options 2458 /* Check if this is a not a samsung device. Do not clear the options
2424 * for chips which are not having an extended id. 2459 * for chips which are not having an extended id.
2425 */ 2460 */
2426 if (nand_maf_id != NAND_MFR_SAMSUNG && !nand_flash_ids[i].pagesize) 2461 if (nand_maf_id != NAND_MFR_SAMSUNG && !nand_flash_ids[i].pagesize)
2427 this->options &= ~NAND_SAMSUNG_LP_OPTIONS; 2462 this->options &= ~NAND_SAMSUNG_LP_OPTIONS;
2428 2463
2429 /* Check for AND chips with 4 page planes */ 2464 /* Check for AND chips with 4 page planes */
2430 if (this->options & NAND_4PAGE_ARRAY) 2465 if (this->options & NAND_4PAGE_ARRAY)
2431 this->erase_cmd = multi_erase_cmd; 2466 this->erase_cmd = multi_erase_cmd;
@@ -2435,9 +2470,9 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2435 /* Do not replace user supplied command function ! */ 2470 /* Do not replace user supplied command function ! */
2436 if (mtd->oobblock > 512 && this->cmdfunc == nand_command) 2471 if (mtd->oobblock > 512 && this->cmdfunc == nand_command)
2437 this->cmdfunc = nand_command_lp; 2472 this->cmdfunc = nand_command_lp;
2438 2473
2439 printk (KERN_INFO "NAND device: Manufacturer ID:" 2474 printk (KERN_INFO "NAND device: Manufacturer ID:"
2440 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, 2475 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
2441 nand_manuf_ids[maf_id].name , nand_flash_ids[i].name); 2476 nand_manuf_ids[maf_id].name , nand_flash_ids[i].name);
2442 break; 2477 break;
2443 } 2478 }
@@ -2461,7 +2496,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2461 } 2496 }
2462 if (i > 1) 2497 if (i > 1)
2463 printk(KERN_INFO "%d NAND chips detected\n", i); 2498 printk(KERN_INFO "%d NAND chips detected\n", i);
2464 2499
2465 /* Allocate buffers, if neccecary */ 2500 /* Allocate buffers, if neccecary */
2466 if (!this->oob_buf) { 2501 if (!this->oob_buf) {
2467 size_t len; 2502 size_t len;
@@ -2473,7 +2508,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2473 } 2508 }
2474 this->options |= NAND_OOBBUF_ALLOC; 2509 this->options |= NAND_OOBBUF_ALLOC;
2475 } 2510 }
2476 2511
2477 if (!this->data_buf) { 2512 if (!this->data_buf) {
2478 size_t len; 2513 size_t len;
2479 len = mtd->oobblock + mtd->oobsize; 2514 len = mtd->oobblock + mtd->oobsize;
@@ -2500,7 +2535,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2500 if (!this->autooob) { 2535 if (!this->autooob) {
2501 /* Select the appropriate default oob placement scheme for 2536 /* Select the appropriate default oob placement scheme for
2502 * placement agnostic filesystems */ 2537 * placement agnostic filesystems */
2503 switch (mtd->oobsize) { 2538 switch (mtd->oobsize) {
2504 case 8: 2539 case 8:
2505 this->autooob = &nand_oob_8; 2540 this->autooob = &nand_oob_8;
2506 break; 2541 break;
@@ -2516,19 +2551,19 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2516 BUG(); 2551 BUG();
2517 } 2552 }
2518 } 2553 }
2519 2554
2520 /* The number of bytes available for the filesystem to place fs dependend 2555 /* The number of bytes available for the filesystem to place fs dependend
2521 * oob data */ 2556 * oob data */
2522 mtd->oobavail = 0; 2557 mtd->oobavail = 0;
2523 for (i = 0; this->autooob->oobfree[i][1]; i++) 2558 for (i = 0; this->autooob->oobfree[i][1]; i++)
2524 mtd->oobavail += this->autooob->oobfree[i][1]; 2559 mtd->oobavail += this->autooob->oobfree[i][1];
2525 2560
2526 /* 2561 /*
2527 * check ECC mode, default to software 2562 * check ECC mode, default to software
2528 * if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize 2563 * if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize
2529 * fallback to software ECC 2564 * fallback to software ECC
2530 */ 2565 */
2531 this->eccsize = 256; /* set default eccsize */ 2566 this->eccsize = 256; /* set default eccsize */
2532 this->eccbytes = 3; 2567 this->eccbytes = 3;
2533 2568
2534 switch (this->eccmode) { 2569 switch (this->eccmode) {
@@ -2543,56 +2578,56 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2543 this->eccsize = 2048; 2578 this->eccsize = 2048;
2544 break; 2579 break;
2545 2580
2546 case NAND_ECC_HW3_512: 2581 case NAND_ECC_HW3_512:
2547 case NAND_ECC_HW6_512: 2582 case NAND_ECC_HW6_512:
2548 case NAND_ECC_HW8_512: 2583 case NAND_ECC_HW8_512:
2549 if (mtd->oobblock == 256) { 2584 if (mtd->oobblock == 256) {
2550 printk (KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n"); 2585 printk (KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n");
2551 this->eccmode = NAND_ECC_SOFT; 2586 this->eccmode = NAND_ECC_SOFT;
2552 this->calculate_ecc = nand_calculate_ecc; 2587 this->calculate_ecc = nand_calculate_ecc;
2553 this->correct_data = nand_correct_data; 2588 this->correct_data = nand_correct_data;
2554 } else 2589 } else
2555 this->eccsize = 512; /* set eccsize to 512 */ 2590 this->eccsize = 512; /* set eccsize to 512 */
2556 break; 2591 break;
2557 2592
2558 case NAND_ECC_HW3_256: 2593 case NAND_ECC_HW3_256:
2559 break; 2594 break;
2560 2595
2561 case NAND_ECC_NONE: 2596 case NAND_ECC_NONE:
2562 printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n"); 2597 printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n");
2563 this->eccmode = NAND_ECC_NONE; 2598 this->eccmode = NAND_ECC_NONE;
2564 break; 2599 break;
2565 2600
2566 case NAND_ECC_SOFT: 2601 case NAND_ECC_SOFT:
2567 this->calculate_ecc = nand_calculate_ecc; 2602 this->calculate_ecc = nand_calculate_ecc;
2568 this->correct_data = nand_correct_data; 2603 this->correct_data = nand_correct_data;
2569 break; 2604 break;
2570 2605
2571 default: 2606 default:
2572 printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode); 2607 printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode);
2573 BUG(); 2608 BUG();
2574 } 2609 }
2575 2610
2576 /* Check hardware ecc function availability and adjust number of ecc bytes per 2611 /* Check hardware ecc function availability and adjust number of ecc bytes per
2577 * calculation step 2612 * calculation step
2578 */ 2613 */
2579 switch (this->eccmode) { 2614 switch (this->eccmode) {
2580 case NAND_ECC_HW12_2048: 2615 case NAND_ECC_HW12_2048:
2581 this->eccbytes += 4; 2616 this->eccbytes += 4;
2582 case NAND_ECC_HW8_512: 2617 case NAND_ECC_HW8_512:
2583 this->eccbytes += 2; 2618 this->eccbytes += 2;
2584 case NAND_ECC_HW6_512: 2619 case NAND_ECC_HW6_512:
2585 this->eccbytes += 3; 2620 this->eccbytes += 3;
2586 case NAND_ECC_HW3_512: 2621 case NAND_ECC_HW3_512:
2587 case NAND_ECC_HW3_256: 2622 case NAND_ECC_HW3_256:
2588 if (this->calculate_ecc && this->correct_data && this->enable_hwecc) 2623 if (this->calculate_ecc && this->correct_data && this->enable_hwecc)
2589 break; 2624 break;
2590 printk (KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n"); 2625 printk (KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n");
2591 BUG(); 2626 BUG();
2592 } 2627 }
2593 2628
2594 mtd->eccsize = this->eccsize; 2629 mtd->eccsize = this->eccsize;
2595 2630
2596 /* Set the number of read / write steps for one page to ensure ECC generation */ 2631 /* Set the number of read / write steps for one page to ensure ECC generation */
2597 switch (this->eccmode) { 2632 switch (this->eccmode) {
2598 case NAND_ECC_HW12_2048: 2633 case NAND_ECC_HW12_2048:
@@ -2604,15 +2639,15 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2604 this->eccsteps = mtd->oobblock / 512; 2639 this->eccsteps = mtd->oobblock / 512;
2605 break; 2640 break;
2606 case NAND_ECC_HW3_256: 2641 case NAND_ECC_HW3_256:
2607 case NAND_ECC_SOFT: 2642 case NAND_ECC_SOFT:
2608 this->eccsteps = mtd->oobblock / 256; 2643 this->eccsteps = mtd->oobblock / 256;
2609 break; 2644 break;
2610 2645
2611 case NAND_ECC_NONE: 2646 case NAND_ECC_NONE:
2612 this->eccsteps = 1; 2647 this->eccsteps = 1;
2613 break; 2648 break;
2614 } 2649 }
2615 2650
2616 /* Initialize state, waitqueue and spinlock */ 2651 /* Initialize state, waitqueue and spinlock */
2617 this->state = FL_READY; 2652 this->state = FL_READY;
2618 init_waitqueue_head (&this->wq); 2653 init_waitqueue_head (&this->wq);
@@ -2643,8 +2678,8 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2643 mtd->sync = nand_sync; 2678 mtd->sync = nand_sync;
2644 mtd->lock = NULL; 2679 mtd->lock = NULL;
2645 mtd->unlock = NULL; 2680 mtd->unlock = NULL;
2646 mtd->suspend = NULL; 2681 mtd->suspend = nand_suspend;
2647 mtd->resume = NULL; 2682 mtd->resume = nand_resume;
2648 mtd->block_isbad = nand_block_isbad; 2683 mtd->block_isbad = nand_block_isbad;
2649 mtd->block_markbad = nand_block_markbad; 2684 mtd->block_markbad = nand_block_markbad;
2650 2685
@@ -2652,7 +2687,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2652 memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo)); 2687 memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo));
2653 2688
2654 mtd->owner = THIS_MODULE; 2689 mtd->owner = THIS_MODULE;
2655 2690
2656 /* Check, if we should skip the bad block table scan */ 2691 /* Check, if we should skip the bad block table scan */
2657 if (this->options & NAND_SKIP_BBTSCAN) 2692 if (this->options & NAND_SKIP_BBTSCAN)
2658 return 0; 2693 return 0;
@@ -2662,7 +2697,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2662} 2697}
2663 2698
2664/** 2699/**
2665 * nand_release - [NAND Interface] Free resources held by the NAND device 2700 * nand_release - [NAND Interface] Free resources held by the NAND device
2666 * @mtd: MTD device structure 2701 * @mtd: MTD device structure
2667*/ 2702*/
2668void nand_release (struct mtd_info *mtd) 2703void nand_release (struct mtd_info *mtd)
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 7535ef53685e..ca286999fe08 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -3,10 +3,10 @@
3 * 3 *
4 * Overview: 4 * Overview:
5 * Bad block table support for the NAND driver 5 * Bad block table support for the NAND driver
6 * 6 *
7 * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de) 7 * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
8 * 8 *
9 * $Id: nand_bbt.c,v 1.35 2005/07/15 13:53:47 gleixner Exp $ 9 * $Id: nand_bbt.c,v 1.36 2005/11/07 11:14:30 gleixner Exp $
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as 12 * it under the terms of the GNU General Public License version 2 as
@@ -14,23 +14,23 @@
14 * 14 *
15 * Description: 15 * Description:
16 * 16 *
17 * When nand_scan_bbt is called, then it tries to find the bad block table 17 * When nand_scan_bbt is called, then it tries to find the bad block table
18 * depending on the options in the bbt descriptor(s). If a bbt is found 18 * depending on the options in the bbt descriptor(s). If a bbt is found
19 * then the contents are read and the memory based bbt is created. If a 19 * then the contents are read and the memory based bbt is created. If a
20 * mirrored bbt is selected then the mirror is searched too and the 20 * mirrored bbt is selected then the mirror is searched too and the
21 * versions are compared. If the mirror has a greater version number 21 * versions are compared. If the mirror has a greater version number
22 * than the mirror bbt is used to build the memory based bbt. 22 * than the mirror bbt is used to build the memory based bbt.
23 * If the tables are not versioned, then we "or" the bad block information. 23 * If the tables are not versioned, then we "or" the bad block information.
24 * If one of the bbt's is out of date or does not exist it is (re)created. 24 * If one of the bbt's is out of date or does not exist it is (re)created.
25 * If no bbt exists at all then the device is scanned for factory marked 25 * If no bbt exists at all then the device is scanned for factory marked
26 * good / bad blocks and the bad block tables are created. 26 * good / bad blocks and the bad block tables are created.
27 * 27 *
28 * For manufacturer created bbts like the one found on M-SYS DOC devices 28 * For manufacturer created bbts like the one found on M-SYS DOC devices
29 * the bbt is searched and read but never created 29 * the bbt is searched and read but never created
30 * 30 *
31 * The autogenerated bad block table is located in the last good blocks 31 * The autogenerated bad block table is located in the last good blocks
32 * of the device. The table is mirrored, so it can be updated eventually. 32 * of the device. The table is mirrored, so it can be updated eventually.
33 * The table is marked in the oob area with an ident pattern and a version 33 * The table is marked in the oob area with an ident pattern and a version
34 * number which indicates which of both tables is more up to date. 34 * number which indicates which of both tables is more up to date.
35 * 35 *
36 * The table uses 2 bits per block 36 * The table uses 2 bits per block
@@ -43,13 +43,13 @@
43 * 01b: block is marked bad due to wear 43 * 01b: block is marked bad due to wear
44 * 10b: block is reserved (to protect the bbt area) 44 * 10b: block is reserved (to protect the bbt area)
45 * 11b: block is factory marked bad 45 * 11b: block is factory marked bad
46 * 46 *
47 * Multichip devices like DOC store the bad block info per floor. 47 * Multichip devices like DOC store the bad block info per floor.
48 * 48 *
49 * Following assumptions are made: 49 * Following assumptions are made:
50 * - bbts start at a page boundary, if autolocated on a block boundary 50 * - bbts start at a page boundary, if autolocated on a block boundary
51 * - the space neccecary for a bbt in FLASH does not exceed a block boundary 51 * - the space neccecary for a bbt in FLASH does not exceed a block boundary
52 * 52 *
53 */ 53 */
54 54
55#include <linux/slab.h> 55#include <linux/slab.h>
@@ -62,7 +62,7 @@
62#include <linux/delay.h> 62#include <linux/delay.h>
63 63
64 64
65/** 65/**
66 * check_pattern - [GENERIC] check if a pattern is in the buffer 66 * check_pattern - [GENERIC] check if a pattern is in the buffer
67 * @buf: the buffer to search 67 * @buf: the buffer to search
68 * @len: the length of buffer to search 68 * @len: the length of buffer to search
@@ -86,9 +86,9 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des
86 if (p[i] != 0xff) 86 if (p[i] != 0xff)
87 return -1; 87 return -1;
88 } 88 }
89 } 89 }
90 p += end; 90 p += end;
91 91
92 /* Compare the pattern */ 92 /* Compare the pattern */
93 for (i = 0; i < td->len; i++) { 93 for (i = 0; i < td->len; i++) {
94 if (p[i] != td->pattern[i]) 94 if (p[i] != td->pattern[i])
@@ -106,13 +106,13 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des
106 return 0; 106 return 0;
107} 107}
108 108
109/** 109/**
110 * check_short_pattern - [GENERIC] check if a pattern is in the buffer 110 * check_short_pattern - [GENERIC] check if a pattern is in the buffer
111 * @buf: the buffer to search 111 * @buf: the buffer to search
112 * @td: search pattern descriptor 112 * @td: search pattern descriptor
113 * 113 *
114 * Check for a pattern at the given place. Used to search bad block 114 * Check for a pattern at the given place. Used to search bad block
115 * tables and good / bad block identifiers. Same as check_pattern, but 115 * tables and good / bad block identifiers. Same as check_pattern, but
116 * no optional empty check 116 * no optional empty check
117 * 117 *
118*/ 118*/
@@ -142,7 +142,7 @@ static int check_short_pattern (uint8_t *buf, struct nand_bbt_descr *td)
142 * Read the bad block table starting from page. 142 * Read the bad block table starting from page.
143 * 143 *
144 */ 144 */
145static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num, 145static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
146 int bits, int offs, int reserved_block_code) 146 int bits, int offs, int reserved_block_code)
147{ 147{
148 int res, i, j, act = 0; 148 int res, i, j, act = 0;
@@ -153,7 +153,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
153 153
154 totlen = (num * bits) >> 3; 154 totlen = (num * bits) >> 3;
155 from = ((loff_t)page) << this->page_shift; 155 from = ((loff_t)page) << this->page_shift;
156 156
157 while (totlen) { 157 while (totlen) {
158 len = min (totlen, (size_t) (1 << this->bbt_erase_shift)); 158 len = min (totlen, (size_t) (1 << this->bbt_erase_shift));
159 res = mtd->read_ecc (mtd, from, len, &retlen, buf, NULL, this->autooob); 159 res = mtd->read_ecc (mtd, from, len, &retlen, buf, NULL, this->autooob);
@@ -163,7 +163,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
163 return res; 163 return res;
164 } 164 }
165 printk (KERN_WARNING "nand_bbt: ECC error while reading bad block table\n"); 165 printk (KERN_WARNING "nand_bbt: ECC error while reading bad block table\n");
166 } 166 }
167 167
168 /* Analyse data */ 168 /* Analyse data */
169 for (i = 0; i < len; i++) { 169 for (i = 0; i < len; i++) {
@@ -183,12 +183,12 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
183 * message to MTD_DEBUG_LEVEL0 */ 183 * message to MTD_DEBUG_LEVEL0 */
184 printk (KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n", 184 printk (KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n",
185 ((offs << 2) + (act >> 1)) << this->bbt_erase_shift); 185 ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
186 /* Factory marked bad or worn out ? */ 186 /* Factory marked bad or worn out ? */
187 if (tmp == 0) 187 if (tmp == 0)
188 this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06); 188 this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06);
189 else 189 else
190 this->bbt[offs + (act >> 3)] |= 0x1 << (act & 0x06); 190 this->bbt[offs + (act >> 3)] |= 0x1 << (act & 0x06);
191 } 191 }
192 } 192 }
193 totlen -= len; 193 totlen -= len;
194 from += len; 194 from += len;
@@ -200,7 +200,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
200 * read_abs_bbt - [GENERIC] Read the bad block table starting at a given page 200 * read_abs_bbt - [GENERIC] Read the bad block table starting at a given page
201 * @mtd: MTD device structure 201 * @mtd: MTD device structure
202 * @buf: temporary buffer 202 * @buf: temporary buffer
203 * @td: descriptor for the bad block table 203 * @td: descriptor for the bad block table
204 * @chip: read the table for a specific chip, -1 read all chips. 204 * @chip: read the table for a specific chip, -1 read all chips.
205 * Applies only if NAND_BBT_PERCHIP option is set 205 * Applies only if NAND_BBT_PERCHIP option is set
206 * 206 *
@@ -235,7 +235,7 @@ static int read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
235 * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page 235 * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page
236 * @mtd: MTD device structure 236 * @mtd: MTD device structure
237 * @buf: temporary buffer 237 * @buf: temporary buffer
238 * @td: descriptor for the bad block table 238 * @td: descriptor for the bad block table
239 * @md: descriptor for the bad block table mirror 239 * @md: descriptor for the bad block table mirror
240 * 240 *
241 * Read the bad block table(s) for all chips starting at a given page 241 * Read the bad block table(s) for all chips starting at a given page
@@ -247,16 +247,16 @@ static int read_abs_bbts (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_de
247{ 247{
248 struct nand_chip *this = mtd->priv; 248 struct nand_chip *this = mtd->priv;
249 249
250 /* Read the primary version, if available */ 250 /* Read the primary version, if available */
251 if (td->options & NAND_BBT_VERSION) { 251 if (td->options & NAND_BBT_VERSION) {
252 nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize); 252 nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
253 td->version[0] = buf[mtd->oobblock + td->veroffs]; 253 td->version[0] = buf[mtd->oobblock + td->veroffs];
254 printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]); 254 printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]);
255 } 255 }
256 256
257 /* Read the mirror version, if available */ 257 /* Read the mirror version, if available */
258 if (md && (md->options & NAND_BBT_VERSION)) { 258 if (md && (md->options & NAND_BBT_VERSION)) {
259 nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize); 259 nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
260 md->version[0] = buf[mtd->oobblock + md->veroffs]; 260 md->version[0] = buf[mtd->oobblock + md->veroffs];
261 printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]); 261 printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]);
262 } 262 }
@@ -290,7 +290,7 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
290 else { 290 else {
291 if (bd->options & NAND_BBT_SCAN2NDPAGE) 291 if (bd->options & NAND_BBT_SCAN2NDPAGE)
292 len = 2; 292 len = 2;
293 else 293 else
294 len = 1; 294 len = 1;
295 } 295 }
296 296
@@ -322,10 +322,10 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
322 numblocks += startblock; 322 numblocks += startblock;
323 from = startblock << (this->bbt_erase_shift - 1); 323 from = startblock << (this->bbt_erase_shift - 1);
324 } 324 }
325 325
326 for (i = startblock; i < numblocks;) { 326 for (i = startblock; i < numblocks;) {
327 int ret; 327 int ret;
328 328
329 if (bd->options & NAND_BBT_SCANEMPTY) 329 if (bd->options & NAND_BBT_SCANEMPTY)
330 if ((ret = nand_read_raw (mtd, buf, from, readlen, ooblen))) 330 if ((ret = nand_read_raw (mtd, buf, from, readlen, ooblen)))
331 return ret; 331 return ret;
@@ -333,8 +333,8 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
333 for (j = 0; j < len; j++) { 333 for (j = 0; j < len; j++) {
334 if (!(bd->options & NAND_BBT_SCANEMPTY)) { 334 if (!(bd->options & NAND_BBT_SCANEMPTY)) {
335 size_t retlen; 335 size_t retlen;
336 336
337 /* Read the full oob until read_oob is fixed to 337 /* Read the full oob until read_oob is fixed to
338 * handle single byte reads for 16 bit buswidth */ 338 * handle single byte reads for 16 bit buswidth */
339 ret = mtd->read_oob(mtd, from + j * mtd->oobblock, 339 ret = mtd->read_oob(mtd, from + j * mtd->oobblock,
340 mtd->oobsize, &retlen, buf); 340 mtd->oobsize, &retlen, buf);
@@ -343,14 +343,14 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
343 343
344 if (check_short_pattern (buf, bd)) { 344 if (check_short_pattern (buf, bd)) {
345 this->bbt[i >> 3] |= 0x03 << (i & 0x6); 345 this->bbt[i >> 3] |= 0x03 << (i & 0x6);
346 printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", 346 printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
347 i >> 1, (unsigned int) from); 347 i >> 1, (unsigned int) from);
348 break; 348 break;
349 } 349 }
350 } else { 350 } else {
351 if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) { 351 if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
352 this->bbt[i >> 3] |= 0x03 << (i & 0x6); 352 this->bbt[i >> 3] |= 0x03 << (i & 0x6);
353 printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", 353 printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
354 i >> 1, (unsigned int) from); 354 i >> 1, (unsigned int) from);
355 break; 355 break;
356 } 356 }
@@ -369,15 +369,15 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
369 * @td: descriptor for the bad block table 369 * @td: descriptor for the bad block table
370 * 370 *
371 * Read the bad block table by searching for a given ident pattern. 371 * Read the bad block table by searching for a given ident pattern.
372 * Search is preformed either from the beginning up or from the end of 372 * Search is preformed either from the beginning up or from the end of
373 * the device downwards. The search starts always at the start of a 373 * the device downwards. The search starts always at the start of a
374 * block. 374 * block.
375 * If the option NAND_BBT_PERCHIP is given, each chip is searched 375 * If the option NAND_BBT_PERCHIP is given, each chip is searched
376 * for a bbt, which contains the bad block information of this chip. 376 * for a bbt, which contains the bad block information of this chip.
377 * This is neccecary to provide support for certain DOC devices. 377 * This is neccecary to provide support for certain DOC devices.
378 * 378 *
379 * The bbt ident pattern resides in the oob area of the first page 379 * The bbt ident pattern resides in the oob area of the first page
380 * in a block. 380 * in a block.
381 */ 381 */
382static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td) 382static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td)
383{ 383{
@@ -392,10 +392,10 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
392 startblock = (mtd->size >> this->bbt_erase_shift) -1; 392 startblock = (mtd->size >> this->bbt_erase_shift) -1;
393 dir = -1; 393 dir = -1;
394 } else { 394 } else {
395 startblock = 0; 395 startblock = 0;
396 dir = 1; 396 dir = 1;
397 } 397 }
398 398
399 /* Do we have a bbt per chip ? */ 399 /* Do we have a bbt per chip ? */
400 if (td->options & NAND_BBT_PERCHIP) { 400 if (td->options & NAND_BBT_PERCHIP) {
401 chips = this->numchips; 401 chips = this->numchips;
@@ -405,19 +405,19 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
405 chips = 1; 405 chips = 1;
406 bbtblocks = mtd->size >> this->bbt_erase_shift; 406 bbtblocks = mtd->size >> this->bbt_erase_shift;
407 } 407 }
408 408
409 /* Number of bits for each erase block in the bbt */ 409 /* Number of bits for each erase block in the bbt */
410 bits = td->options & NAND_BBT_NRBITS_MSK; 410 bits = td->options & NAND_BBT_NRBITS_MSK;
411 411
412 for (i = 0; i < chips; i++) { 412 for (i = 0; i < chips; i++) {
413 /* Reset version information */ 413 /* Reset version information */
414 td->version[i] = 0; 414 td->version[i] = 0;
415 td->pages[i] = -1; 415 td->pages[i] = -1;
416 /* Scan the maximum number of blocks */ 416 /* Scan the maximum number of blocks */
417 for (block = 0; block < td->maxblocks; block++) { 417 for (block = 0; block < td->maxblocks; block++) {
418 int actblock = startblock + dir * block; 418 int actblock = startblock + dir * block;
419 /* Read first page */ 419 /* Read first page */
420 nand_read_raw (mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize); 420 nand_read_raw (mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize);
421 if (!check_pattern(buf, scanlen, mtd->oobblock, td)) { 421 if (!check_pattern(buf, scanlen, mtd->oobblock, td)) {
422 td->pages[i] = actblock << (this->bbt_erase_shift - this->page_shift); 422 td->pages[i] = actblock << (this->bbt_erase_shift - this->page_shift);
423 if (td->options & NAND_BBT_VERSION) { 423 if (td->options & NAND_BBT_VERSION) {
@@ -435,46 +435,46 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
435 else 435 else
436 printk (KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i], td->version[i]); 436 printk (KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i], td->version[i]);
437 } 437 }
438 return 0; 438 return 0;
439} 439}
440 440
441/** 441/**
442 * search_read_bbts - [GENERIC] scan the device for bad block table(s) 442 * search_read_bbts - [GENERIC] scan the device for bad block table(s)
443 * @mtd: MTD device structure 443 * @mtd: MTD device structure
444 * @buf: temporary buffer 444 * @buf: temporary buffer
445 * @td: descriptor for the bad block table 445 * @td: descriptor for the bad block table
446 * @md: descriptor for the bad block table mirror 446 * @md: descriptor for the bad block table mirror
447 * 447 *
448 * Search and read the bad block table(s) 448 * Search and read the bad block table(s)
449*/ 449*/
450static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf, 450static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf,
451 struct nand_bbt_descr *td, struct nand_bbt_descr *md) 451 struct nand_bbt_descr *td, struct nand_bbt_descr *md)
452{ 452{
453 /* Search the primary table */ 453 /* Search the primary table */
454 search_bbt (mtd, buf, td); 454 search_bbt (mtd, buf, td);
455 455
456 /* Search the mirror table */ 456 /* Search the mirror table */
457 if (md) 457 if (md)
458 search_bbt (mtd, buf, md); 458 search_bbt (mtd, buf, md);
459 459
460 /* Force result check */ 460 /* Force result check */
461 return 1; 461 return 1;
462} 462}
463
464 463
465/** 464
465/**
466 * write_bbt - [GENERIC] (Re)write the bad block table 466 * write_bbt - [GENERIC] (Re)write the bad block table
467 * 467 *
468 * @mtd: MTD device structure 468 * @mtd: MTD device structure
469 * @buf: temporary buffer 469 * @buf: temporary buffer
470 * @td: descriptor for the bad block table 470 * @td: descriptor for the bad block table
471 * @md: descriptor for the bad block table mirror 471 * @md: descriptor for the bad block table mirror
472 * @chipsel: selector for a specific chip, -1 for all 472 * @chipsel: selector for a specific chip, -1 for all
473 * 473 *
474 * (Re)write the bad block table 474 * (Re)write the bad block table
475 * 475 *
476*/ 476*/
477static int write_bbt (struct mtd_info *mtd, uint8_t *buf, 477static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
478 struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel) 478 struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel)
479{ 479{
480 struct nand_chip *this = mtd->priv; 480 struct nand_chip *this = mtd->priv;
@@ -493,7 +493,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
493 /* Write bad block table per chip rather than per device ? */ 493 /* Write bad block table per chip rather than per device ? */
494 if (td->options & NAND_BBT_PERCHIP) { 494 if (td->options & NAND_BBT_PERCHIP) {
495 numblocks = (int) (this->chipsize >> this->bbt_erase_shift); 495 numblocks = (int) (this->chipsize >> this->bbt_erase_shift);
496 /* Full device write or specific chip ? */ 496 /* Full device write or specific chip ? */
497 if (chipsel == -1) { 497 if (chipsel == -1) {
498 nrchips = this->numchips; 498 nrchips = this->numchips;
499 } else { 499 } else {
@@ -503,19 +503,19 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
503 } else { 503 } else {
504 numblocks = (int) (mtd->size >> this->bbt_erase_shift); 504 numblocks = (int) (mtd->size >> this->bbt_erase_shift);
505 nrchips = 1; 505 nrchips = 1;
506 } 506 }
507 507
508 /* Loop through the chips */ 508 /* Loop through the chips */
509 for (; chip < nrchips; chip++) { 509 for (; chip < nrchips; chip++) {
510 510
511 /* There was already a version of the table, reuse the page 511 /* There was already a version of the table, reuse the page
512 * This applies for absolute placement too, as we have the 512 * This applies for absolute placement too, as we have the
513 * page nr. in td->pages. 513 * page nr. in td->pages.
514 */ 514 */
515 if (td->pages[chip] != -1) { 515 if (td->pages[chip] != -1) {
516 page = td->pages[chip]; 516 page = td->pages[chip];
517 goto write; 517 goto write;
518 } 518 }
519 519
520 /* Automatic placement of the bad block table */ 520 /* Automatic placement of the bad block table */
521 /* Search direction top -> down ? */ 521 /* Search direction top -> down ? */
@@ -525,7 +525,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
525 } else { 525 } else {
526 startblock = chip * numblocks; 526 startblock = chip * numblocks;
527 dir = 1; 527 dir = 1;
528 } 528 }
529 529
530 for (i = 0; i < td->maxblocks; i++) { 530 for (i = 0; i < td->maxblocks; i++) {
531 int block = startblock + dir * i; 531 int block = startblock + dir * i;
@@ -542,7 +542,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
542 } 542 }
543 printk (KERN_ERR "No space left to write bad block table\n"); 543 printk (KERN_ERR "No space left to write bad block table\n");
544 return -ENOSPC; 544 return -ENOSPC;
545write: 545write:
546 546
547 /* Set up shift count and masks for the flash table */ 547 /* Set up shift count and masks for the flash table */
548 bits = td->options & NAND_BBT_NRBITS_MSK; 548 bits = td->options & NAND_BBT_NRBITS_MSK;
@@ -553,14 +553,14 @@ write:
553 case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F; msk[2] = ~rcode; msk[3] = 0xff; break; 553 case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F; msk[2] = ~rcode; msk[3] = 0xff; break;
554 default: return -EINVAL; 554 default: return -EINVAL;
555 } 555 }
556 556
557 bbtoffs = chip * (numblocks >> 2); 557 bbtoffs = chip * (numblocks >> 2);
558 558
559 to = ((loff_t) page) << this->page_shift; 559 to = ((loff_t) page) << this->page_shift;
560 560
561 memcpy (&oobinfo, this->autooob, sizeof(oobinfo)); 561 memcpy (&oobinfo, this->autooob, sizeof(oobinfo));
562 oobinfo.useecc = MTD_NANDECC_PLACEONLY; 562 oobinfo.useecc = MTD_NANDECC_PLACEONLY;
563 563
564 /* Must we save the block contents ? */ 564 /* Must we save the block contents ? */
565 if (td->options & NAND_BBT_SAVECONTENT) { 565 if (td->options & NAND_BBT_SAVECONTENT) {
566 /* Make it block aligned */ 566 /* Make it block aligned */
@@ -599,7 +599,7 @@ write:
599 buf[len + td->veroffs] = td->version[chip]; 599 buf[len + td->veroffs] = td->version[chip];
600 } 600 }
601 } 601 }
602 602
603 /* walk through the memory table */ 603 /* walk through the memory table */
604 for (i = 0; i < numblocks; ) { 604 for (i = 0; i < numblocks; ) {
605 uint8_t dat; 605 uint8_t dat;
@@ -611,7 +611,7 @@ write:
611 dat >>= 2; 611 dat >>= 2;
612 } 612 }
613 } 613 }
614 614
615 memset (&einfo, 0, sizeof (einfo)); 615 memset (&einfo, 0, sizeof (einfo));
616 einfo.mtd = mtd; 616 einfo.mtd = mtd;
617 einfo.addr = (unsigned long) to; 617 einfo.addr = (unsigned long) to;
@@ -621,18 +621,18 @@ write:
621 printk (KERN_WARNING "nand_bbt: Error during block erase: %d\n", res); 621 printk (KERN_WARNING "nand_bbt: Error during block erase: %d\n", res);
622 return res; 622 return res;
623 } 623 }
624 624
625 res = mtd->write_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo); 625 res = mtd->write_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo);
626 if (res < 0) { 626 if (res < 0) {
627 printk (KERN_WARNING "nand_bbt: Error while writing bad block table %d\n", res); 627 printk (KERN_WARNING "nand_bbt: Error while writing bad block table %d\n", res);
628 return res; 628 return res;
629 } 629 }
630 printk (KERN_DEBUG "Bad block table written to 0x%08x, version 0x%02X\n", 630 printk (KERN_DEBUG "Bad block table written to 0x%08x, version 0x%02X\n",
631 (unsigned int) to, td->version[chip]); 631 (unsigned int) to, td->version[chip]);
632 632
633 /* Mark it as used */ 633 /* Mark it as used */
634 td->pages[chip] = page; 634 td->pages[chip] = page;
635 } 635 }
636 return 0; 636 return 0;
637} 637}
638 638
@@ -641,7 +641,7 @@ write:
641 * @mtd: MTD device structure 641 * @mtd: MTD device structure
642 * @bd: descriptor for the good/bad block search pattern 642 * @bd: descriptor for the good/bad block search pattern
643 * 643 *
644 * The function creates a memory based bbt by scanning the device 644 * The function creates a memory based bbt by scanning the device
645 * for manufacturer / software marked good / bad blocks 645 * for manufacturer / software marked good / bad blocks
646*/ 646*/
647static inline int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd) 647static inline int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
@@ -673,11 +673,11 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
673 struct nand_bbt_descr *rd, *rd2; 673 struct nand_bbt_descr *rd, *rd2;
674 674
675 /* Do we have a bbt per chip ? */ 675 /* Do we have a bbt per chip ? */
676 if (td->options & NAND_BBT_PERCHIP) 676 if (td->options & NAND_BBT_PERCHIP)
677 chips = this->numchips; 677 chips = this->numchips;
678 else 678 else
679 chips = 1; 679 chips = 1;
680 680
681 for (i = 0; i < chips; i++) { 681 for (i = 0; i < chips; i++) {
682 writeops = 0; 682 writeops = 0;
683 rd = NULL; 683 rd = NULL;
@@ -692,7 +692,7 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
692 } 692 }
693 693
694 if (td->pages[i] == -1) { 694 if (td->pages[i] == -1) {
695 rd = md; 695 rd = md;
696 td->version[i] = md->version[i]; 696 td->version[i] = md->version[i];
697 writeops = 1; 697 writeops = 1;
698 goto writecheck; 698 goto writecheck;
@@ -710,7 +710,7 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
710 if (!(td->options & NAND_BBT_VERSION)) 710 if (!(td->options & NAND_BBT_VERSION))
711 rd2 = md; 711 rd2 = md;
712 goto writecheck; 712 goto writecheck;
713 } 713 }
714 714
715 if (((int8_t) (td->version[i] - md->version[i])) > 0) { 715 if (((int8_t) (td->version[i] - md->version[i])) > 0) {
716 rd = td; 716 rd = td;
@@ -735,15 +735,15 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
735create: 735create:
736 /* Create the bad block table by scanning the device ? */ 736 /* Create the bad block table by scanning the device ? */
737 if (!(td->options & NAND_BBT_CREATE)) 737 if (!(td->options & NAND_BBT_CREATE))
738 continue; 738 continue;
739 739
740 /* Create the table in memory by scanning the chip(s) */ 740 /* Create the table in memory by scanning the chip(s) */
741 create_bbt (mtd, buf, bd, chipsel); 741 create_bbt (mtd, buf, bd, chipsel);
742 742
743 td->version[i] = 1; 743 td->version[i] = 1;
744 if (md) 744 if (md)
745 md->version[i] = 1; 745 md->version[i] = 1;
746writecheck: 746writecheck:
747 /* read back first ? */ 747 /* read back first ? */
748 if (rd) 748 if (rd)
749 read_abs_bbt (mtd, buf, rd, chipsel); 749 read_abs_bbt (mtd, buf, rd, chipsel);
@@ -757,7 +757,7 @@ writecheck:
757 if (res < 0) 757 if (res < 0)
758 return res; 758 return res;
759 } 759 }
760 760
761 /* Write the mirror bad block table to the device ? */ 761 /* Write the mirror bad block table to the device ? */
762 if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) { 762 if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
763 res = write_bbt (mtd, buf, md, td, chipsel); 763 res = write_bbt (mtd, buf, md, td, chipsel);
@@ -765,11 +765,11 @@ writecheck:
765 return res; 765 return res;
766 } 766 }
767 } 767 }
768 return 0; 768 return 0;
769} 769}
770 770
771/** 771/**
772 * mark_bbt_regions - [GENERIC] mark the bad block table regions 772 * mark_bbt_regions - [GENERIC] mark the bad block table regions
773 * @mtd: MTD device structure 773 * @mtd: MTD device structure
774 * @td: bad block table descriptor 774 * @td: bad block table descriptor
775 * 775 *
@@ -790,14 +790,14 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
790 } else { 790 } else {
791 chips = 1; 791 chips = 1;
792 nrblocks = (int)(mtd->size >> this->bbt_erase_shift); 792 nrblocks = (int)(mtd->size >> this->bbt_erase_shift);
793 } 793 }
794 794
795 for (i = 0; i < chips; i++) { 795 for (i = 0; i < chips; i++) {
796 if ((td->options & NAND_BBT_ABSPAGE) || 796 if ((td->options & NAND_BBT_ABSPAGE) ||
797 !(td->options & NAND_BBT_WRITE)) { 797 !(td->options & NAND_BBT_WRITE)) {
798 if (td->pages[i] == -1) continue; 798 if (td->pages[i] == -1) continue;
799 block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift); 799 block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift);
800 block <<= 1; 800 block <<= 1;
801 oldval = this->bbt[(block >> 3)]; 801 oldval = this->bbt[(block >> 3)];
802 newval = oldval | (0x2 << (block & 0x06)); 802 newval = oldval | (0x2 << (block & 0x06));
803 this->bbt[(block >> 3)] = newval; 803 this->bbt[(block >> 3)] = newval;
@@ -808,16 +808,16 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
808 update = 0; 808 update = 0;
809 if (td->options & NAND_BBT_LASTBLOCK) 809 if (td->options & NAND_BBT_LASTBLOCK)
810 block = ((i + 1) * nrblocks) - td->maxblocks; 810 block = ((i + 1) * nrblocks) - td->maxblocks;
811 else 811 else
812 block = i * nrblocks; 812 block = i * nrblocks;
813 block <<= 1; 813 block <<= 1;
814 for (j = 0; j < td->maxblocks; j++) { 814 for (j = 0; j < td->maxblocks; j++) {
815 oldval = this->bbt[(block >> 3)]; 815 oldval = this->bbt[(block >> 3)];
816 newval = oldval | (0x2 << (block & 0x06)); 816 newval = oldval | (0x2 << (block & 0x06));
817 this->bbt[(block >> 3)] = newval; 817 this->bbt[(block >> 3)] = newval;
818 if (oldval != newval) update = 1; 818 if (oldval != newval) update = 1;
819 block += 2; 819 block += 2;
820 } 820 }
821 /* If we want reserved blocks to be recorded to flash, and some 821 /* If we want reserved blocks to be recorded to flash, and some
822 new ones have been marked, then we need to update the stored 822 new ones have been marked, then we need to update the stored
823 bbts. This should only happen once. */ 823 bbts. This should only happen once. */
@@ -831,7 +831,7 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
831 * @mtd: MTD device structure 831 * @mtd: MTD device structure
832 * @bd: descriptor for the good/bad block search pattern 832 * @bd: descriptor for the good/bad block search pattern
833 * 833 *
834 * The function checks, if a bad block table(s) is/are already 834 * The function checks, if a bad block table(s) is/are already
835 * available. If not it scans the device for manufacturer 835 * available. If not it scans the device for manufacturer
836 * marked good / bad blocks and writes the bad block table(s) to 836 * marked good / bad blocks and writes the bad block table(s) to
837 * the selected place. 837 * the selected place.
@@ -880,30 +880,30 @@ int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
880 this->bbt = NULL; 880 this->bbt = NULL;
881 return -ENOMEM; 881 return -ENOMEM;
882 } 882 }
883 883
884 /* Is the bbt at a given page ? */ 884 /* Is the bbt at a given page ? */
885 if (td->options & NAND_BBT_ABSPAGE) { 885 if (td->options & NAND_BBT_ABSPAGE) {
886 res = read_abs_bbts (mtd, buf, td, md); 886 res = read_abs_bbts (mtd, buf, td, md);
887 } else { 887 } else {
888 /* Search the bad block table using a pattern in oob */ 888 /* Search the bad block table using a pattern in oob */
889 res = search_read_bbts (mtd, buf, td, md); 889 res = search_read_bbts (mtd, buf, td, md);
890 } 890 }
891 891
892 if (res) 892 if (res)
893 res = check_create (mtd, buf, bd); 893 res = check_create (mtd, buf, bd);
894 894
895 /* Prevent the bbt regions from erasing / writing */ 895 /* Prevent the bbt regions from erasing / writing */
896 mark_bbt_region (mtd, td); 896 mark_bbt_region (mtd, td);
897 if (md) 897 if (md)
898 mark_bbt_region (mtd, md); 898 mark_bbt_region (mtd, md);
899 899
900 kfree (buf); 900 kfree (buf);
901 return res; 901 return res;
902} 902}
903 903
904 904
905/** 905/**
906 * nand_update_bbt - [NAND Interface] update bad block table(s) 906 * nand_update_bbt - [NAND Interface] update bad block table(s)
907 * @mtd: MTD device structure 907 * @mtd: MTD device structure
908 * @offs: the offset of the newly marked block 908 * @offs: the offset of the newly marked block
909 * 909 *
@@ -930,7 +930,7 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
930 printk (KERN_ERR "nand_update_bbt: Out of memory\n"); 930 printk (KERN_ERR "nand_update_bbt: Out of memory\n");
931 return -ENOMEM; 931 return -ENOMEM;
932 } 932 }
933 933
934 writeops = md != NULL ? 0x03 : 0x01; 934 writeops = md != NULL ? 0x03 : 0x01;
935 935
936 /* Do we have a bbt per chip ? */ 936 /* Do we have a bbt per chip ? */
@@ -944,7 +944,7 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
944 944
945 td->version[chip]++; 945 td->version[chip]++;
946 if (md) 946 if (md)
947 md->version[chip]++; 947 md->version[chip]++;
948 948
949 /* Write the bad block table to the device ? */ 949 /* Write the bad block table to the device ? */
950 if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) { 950 if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
@@ -957,12 +957,12 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
957 res = write_bbt (mtd, buf, md, td, chipsel); 957 res = write_bbt (mtd, buf, md, td, chipsel);
958 } 958 }
959 959
960out: 960out:
961 kfree (buf); 961 kfree (buf);
962 return res; 962 return res;
963} 963}
964 964
965/* Define some generic bad / good block scan pattern which are used 965/* Define some generic bad / good block scan pattern which are used
966 * while scanning a device for factory marked good / bad blocks. */ 966 * while scanning a device for factory marked good / bad blocks. */
967static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; 967static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
968 968
@@ -1009,7 +1009,7 @@ static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
1009static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' }; 1009static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
1010 1010
1011static struct nand_bbt_descr bbt_main_descr = { 1011static struct nand_bbt_descr bbt_main_descr = {
1012 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE 1012 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
1013 | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, 1013 | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
1014 .offs = 8, 1014 .offs = 8,
1015 .len = 4, 1015 .len = 4,
@@ -1019,7 +1019,7 @@ static struct nand_bbt_descr bbt_main_descr = {
1019}; 1019};
1020 1020
1021static struct nand_bbt_descr bbt_mirror_descr = { 1021static struct nand_bbt_descr bbt_mirror_descr = {
1022 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE 1022 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
1023 | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, 1023 | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
1024 .offs = 8, 1024 .offs = 8,
1025 .len = 4, 1025 .len = 4,
@@ -1029,7 +1029,7 @@ static struct nand_bbt_descr bbt_mirror_descr = {
1029}; 1029};
1030 1030
1031/** 1031/**
1032 * nand_default_bbt - [NAND Interface] Select a default bad block table for the device 1032 * nand_default_bbt - [NAND Interface] Select a default bad block table for the device
1033 * @mtd: MTD device structure 1033 * @mtd: MTD device structure
1034 * 1034 *
1035 * This function selects the default bad block table 1035 * This function selects the default bad block table
@@ -1039,29 +1039,29 @@ static struct nand_bbt_descr bbt_mirror_descr = {
1039int nand_default_bbt (struct mtd_info *mtd) 1039int nand_default_bbt (struct mtd_info *mtd)
1040{ 1040{
1041 struct nand_chip *this = mtd->priv; 1041 struct nand_chip *this = mtd->priv;
1042 1042
1043 /* Default for AG-AND. We must use a flash based 1043 /* Default for AG-AND. We must use a flash based
1044 * bad block table as the devices have factory marked 1044 * bad block table as the devices have factory marked
1045 * _good_ blocks. Erasing those blocks leads to loss 1045 * _good_ blocks. Erasing those blocks leads to loss
1046 * of the good / bad information, so we _must_ store 1046 * of the good / bad information, so we _must_ store
1047 * this information in a good / bad table during 1047 * this information in a good / bad table during
1048 * startup 1048 * startup
1049 */ 1049 */
1050 if (this->options & NAND_IS_AND) { 1050 if (this->options & NAND_IS_AND) {
1051 /* Use the default pattern descriptors */ 1051 /* Use the default pattern descriptors */
1052 if (!this->bbt_td) { 1052 if (!this->bbt_td) {
1053 this->bbt_td = &bbt_main_descr; 1053 this->bbt_td = &bbt_main_descr;
1054 this->bbt_md = &bbt_mirror_descr; 1054 this->bbt_md = &bbt_mirror_descr;
1055 } 1055 }
1056 this->options |= NAND_USE_FLASH_BBT; 1056 this->options |= NAND_USE_FLASH_BBT;
1057 return nand_scan_bbt (mtd, &agand_flashbased); 1057 return nand_scan_bbt (mtd, &agand_flashbased);
1058 } 1058 }
1059 1059
1060 1060
1061 /* Is a flash based bad block table requested ? */ 1061 /* Is a flash based bad block table requested ? */
1062 if (this->options & NAND_USE_FLASH_BBT) { 1062 if (this->options & NAND_USE_FLASH_BBT) {
1063 /* Use the default pattern descriptors */ 1063 /* Use the default pattern descriptors */
1064 if (!this->bbt_td) { 1064 if (!this->bbt_td) {
1065 this->bbt_td = &bbt_main_descr; 1065 this->bbt_td = &bbt_main_descr;
1066 this->bbt_md = &bbt_mirror_descr; 1066 this->bbt_md = &bbt_mirror_descr;
1067 } 1067 }
@@ -1081,7 +1081,7 @@ int nand_default_bbt (struct mtd_info *mtd)
1081} 1081}
1082 1082
1083/** 1083/**
1084 * nand_isbad_bbt - [NAND Interface] Check if a block is bad 1084 * nand_isbad_bbt - [NAND Interface] Check if a block is bad
1085 * @mtd: MTD device structure 1085 * @mtd: MTD device structure
1086 * @offs: offset in the device 1086 * @offs: offset in the device
1087 * @allowbbt: allow access to bad block table region 1087 * @allowbbt: allow access to bad block table region
@@ -1092,12 +1092,12 @@ int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt)
1092 struct nand_chip *this = mtd->priv; 1092 struct nand_chip *this = mtd->priv;
1093 int block; 1093 int block;
1094 uint8_t res; 1094 uint8_t res;
1095 1095
1096 /* Get block number * 2 */ 1096 /* Get block number * 2 */
1097 block = (int) (offs >> (this->bbt_erase_shift - 1)); 1097 block = (int) (offs >> (this->bbt_erase_shift - 1));
1098 res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03; 1098 res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
1099 1099
1100 DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n", 1100 DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n",
1101 (unsigned int)offs, block >> 1, res); 1101 (unsigned int)offs, block >> 1, res);
1102 1102
1103 switch ((int)res) { 1103 switch ((int)res) {
diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c
index 2e341b75437a..40ac909150a3 100644
--- a/drivers/mtd/nand/nand_ecc.c
+++ b/drivers/mtd/nand/nand_ecc.c
@@ -7,22 +7,22 @@
7 * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com) 7 * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com)
8 * Toshiba America Electronics Components, Inc. 8 * Toshiba America Electronics Components, Inc.
9 * 9 *
10 * $Id: nand_ecc.c,v 1.14 2004/06/16 15:34:37 gleixner Exp $ 10 * $Id: nand_ecc.c,v 1.15 2005/11/07 11:14:30 gleixner Exp $
11 * 11 *
12 * This file is free software; you can redistribute it and/or modify it 12 * This file is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the 13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 or (at your option) any 14 * Free Software Foundation; either version 2 or (at your option) any
15 * later version. 15 * later version.
16 * 16 *
17 * This file is distributed in the hope that it will be useful, but WITHOUT 17 * This file is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details. 20 * for more details.
21 * 21 *
22 * You should have received a copy of the GNU General Public License along 22 * You should have received a copy of the GNU General Public License along
23 * with this file; if not, write to the Free Software Foundation, Inc., 23 * with this file; if not, write to the Free Software Foundation, Inc.,
24 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 24 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 * 25 *
26 * As a special exception, if other files instantiate templates or use 26 * As a special exception, if other files instantiate templates or use
27 * macros or inline functions from these files, or you compile these 27 * macros or inline functions from these files, or you compile these
28 * files and link them with other works to produce a work based on these 28 * files and link them with other works to produce a work based on these
@@ -30,7 +30,7 @@
30 * covered by the GNU General Public License. However the source code for 30 * covered by the GNU General Public License. However the source code for
31 * these files must still be made available in accordance with section (3) 31 * these files must still be made available in accordance with section (3)
32 * of the GNU General Public License. 32 * of the GNU General Public License.
33 * 33 *
34 * This exception does not invalidate any other reasons why a work based on 34 * This exception does not invalidate any other reasons why a work based on
35 * this file might be covered by the GNU General Public License. 35 * this file might be covered by the GNU General Public License.
36 */ 36 */
@@ -67,7 +67,7 @@ static const u_char nand_ecc_precalc_table[] = {
67 * nand_trans_result - [GENERIC] create non-inverted ECC 67 * nand_trans_result - [GENERIC] create non-inverted ECC
68 * @reg2: line parity reg 2 68 * @reg2: line parity reg 2
69 * @reg3: line parity reg 3 69 * @reg3: line parity reg 3
70 * @ecc_code: ecc 70 * @ecc_code: ecc
71 * 71 *
72 * Creates non-inverted ECC code from line parity 72 * Creates non-inverted ECC code from line parity
73 */ 73 */
@@ -75,11 +75,11 @@ static void nand_trans_result(u_char reg2, u_char reg3,
75 u_char *ecc_code) 75 u_char *ecc_code)
76{ 76{
77 u_char a, b, i, tmp1, tmp2; 77 u_char a, b, i, tmp1, tmp2;
78 78
79 /* Initialize variables */ 79 /* Initialize variables */
80 a = b = 0x80; 80 a = b = 0x80;
81 tmp1 = tmp2 = 0; 81 tmp1 = tmp2 = 0;
82 82
83 /* Calculate first ECC byte */ 83 /* Calculate first ECC byte */
84 for (i = 0; i < 4; i++) { 84 for (i = 0; i < 4; i++) {
85 if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */ 85 if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */
@@ -90,7 +90,7 @@ static void nand_trans_result(u_char reg2, u_char reg3,
90 b >>= 1; 90 b >>= 1;
91 a >>= 1; 91 a >>= 1;
92 } 92 }
93 93
94 /* Calculate second ECC byte */ 94 /* Calculate second ECC byte */
95 b = 0x80; 95 b = 0x80;
96 for (i = 0; i < 4; i++) { 96 for (i = 0; i < 4; i++) {
@@ -102,7 +102,7 @@ static void nand_trans_result(u_char reg2, u_char reg3,
102 b >>= 1; 102 b >>= 1;
103 a >>= 1; 103 a >>= 1;
104 } 104 }
105 105
106 /* Store two of the ECC bytes */ 106 /* Store two of the ECC bytes */
107 ecc_code[0] = tmp1; 107 ecc_code[0] = tmp1;
108 ecc_code[1] = tmp2; 108 ecc_code[1] = tmp2;
@@ -118,28 +118,28 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code
118{ 118{
119 u_char idx, reg1, reg2, reg3; 119 u_char idx, reg1, reg2, reg3;
120 int j; 120 int j;
121 121
122 /* Initialize variables */ 122 /* Initialize variables */
123 reg1 = reg2 = reg3 = 0; 123 reg1 = reg2 = reg3 = 0;
124 ecc_code[0] = ecc_code[1] = ecc_code[2] = 0; 124 ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
125 125
126 /* Build up column parity */ 126 /* Build up column parity */
127 for(j = 0; j < 256; j++) { 127 for(j = 0; j < 256; j++) {
128 128
129 /* Get CP0 - CP5 from table */ 129 /* Get CP0 - CP5 from table */
130 idx = nand_ecc_precalc_table[dat[j]]; 130 idx = nand_ecc_precalc_table[dat[j]];
131 reg1 ^= (idx & 0x3f); 131 reg1 ^= (idx & 0x3f);
132 132
133 /* All bit XOR = 1 ? */ 133 /* All bit XOR = 1 ? */
134 if (idx & 0x40) { 134 if (idx & 0x40) {
135 reg3 ^= (u_char) j; 135 reg3 ^= (u_char) j;
136 reg2 ^= ~((u_char) j); 136 reg2 ^= ~((u_char) j);
137 } 137 }
138 } 138 }
139 139
140 /* Create non-inverted ECC code from line parity */ 140 /* Create non-inverted ECC code from line parity */
141 nand_trans_result(reg2, reg3, ecc_code); 141 nand_trans_result(reg2, reg3, ecc_code);
142 142
143 /* Calculate final ECC code */ 143 /* Calculate final ECC code */
144 ecc_code[0] = ~ecc_code[0]; 144 ecc_code[0] = ~ecc_code[0];
145 ecc_code[1] = ~ecc_code[1]; 145 ecc_code[1] = ~ecc_code[1];
@@ -159,12 +159,12 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code
159int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) 159int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
160{ 160{
161 u_char a, b, c, d1, d2, d3, add, bit, i; 161 u_char a, b, c, d1, d2, d3, add, bit, i;
162 162
163 /* Do error detection */ 163 /* Do error detection */
164 d1 = calc_ecc[0] ^ read_ecc[0]; 164 d1 = calc_ecc[0] ^ read_ecc[0];
165 d2 = calc_ecc[1] ^ read_ecc[1]; 165 d2 = calc_ecc[1] ^ read_ecc[1];
166 d3 = calc_ecc[2] ^ read_ecc[2]; 166 d3 = calc_ecc[2] ^ read_ecc[2];
167 167
168 if ((d1 | d2 | d3) == 0) { 168 if ((d1 | d2 | d3) == 0) {
169 /* No errors */ 169 /* No errors */
170 return 0; 170 return 0;
@@ -173,7 +173,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
173 a = (d1 ^ (d1 >> 1)) & 0x55; 173 a = (d1 ^ (d1 >> 1)) & 0x55;
174 b = (d2 ^ (d2 >> 1)) & 0x55; 174 b = (d2 ^ (d2 >> 1)) & 0x55;
175 c = (d3 ^ (d3 >> 1)) & 0x54; 175 c = (d3 ^ (d3 >> 1)) & 0x54;
176 176
177 /* Found and will correct single bit error in the data */ 177 /* Found and will correct single bit error in the data */
178 if ((a == 0x55) && (b == 0x55) && (c == 0x54)) { 178 if ((a == 0x55) && (b == 0x55) && (c == 0x54)) {
179 c = 0x80; 179 c = 0x80;
@@ -237,7 +237,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
237 } 237 }
238 } 238 }
239 } 239 }
240 240
241 /* Should never happen */ 241 /* Should never happen */
242 return -1; 242 return -1;
243} 243}
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c
index efe246961b69..dbc7e55a4247 100644
--- a/drivers/mtd/nand/nand_ids.c
+++ b/drivers/mtd/nand/nand_ids.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de) 4 * Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de)
5 * 5 *
6 * $Id: nand_ids.c,v 1.14 2005/06/23 09:38:50 gleixner Exp $ 6 * $Id: nand_ids.c,v 1.16 2005/11/07 11:14:31 gleixner Exp $
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -14,14 +14,14 @@
14#include <linux/mtd/nand.h> 14#include <linux/mtd/nand.h>
15/* 15/*
16* Chip ID list 16* Chip ID list
17* 17*
18* Name. ID code, pagesize, chipsize in MegaByte, eraseblock size, 18* Name. ID code, pagesize, chipsize in MegaByte, eraseblock size,
19* options 19* options
20* 20*
21* Pagesize; 0, 256, 512 21* Pagesize; 0, 256, 512
22* 0 get this information from the extended chip ID 22* 0 get this information from the extended chip ID
23+ 256 256 Byte page size 23+ 256 256 Byte page size
24* 512 512 Byte page size 24* 512 512 Byte page size
25*/ 25*/
26struct nand_flash_dev nand_flash_ids[] = { 26struct nand_flash_dev nand_flash_ids[] = {
27 {"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0}, 27 {"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0},
@@ -34,27 +34,27 @@ struct nand_flash_dev nand_flash_ids[] = {
34 {"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, 0}, 34 {"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, 0},
35 {"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, 0}, 35 {"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, 0},
36 {"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, 0}, 36 {"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, 0},
37 37
38 {"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, 0}, 38 {"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, 0},
39 {"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, 0}, 39 {"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, 0},
40 {"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16}, 40 {"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16},
41 {"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16}, 41 {"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16},
42 42
43 {"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, 0}, 43 {"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, 0},
44 {"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, 0}, 44 {"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, 0},
45 {"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16}, 45 {"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16},
46 {"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16}, 46 {"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16},
47 47
48 {"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, 0}, 48 {"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, 0},
49 {"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, 0}, 49 {"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, 0},
50 {"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16}, 50 {"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16},
51 {"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16}, 51 {"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16},
52 52
53 {"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, 0}, 53 {"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, 0},
54 {"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, 0}, 54 {"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, 0},
55 {"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16}, 55 {"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16},
56 {"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16}, 56 {"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16},
57 57
58 {"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0}, 58 {"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0},
59 {"NAND 128MiB 1,8V 8-bit", 0x39, 512, 128, 0x4000, 0}, 59 {"NAND 128MiB 1,8V 8-bit", 0x39, 512, 128, 0x4000, 0},
60 {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0}, 60 {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0},
@@ -62,7 +62,7 @@ struct nand_flash_dev nand_flash_ids[] = {
62 {"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16}, 62 {"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16},
63 {"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16}, 63 {"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16},
64 {"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16}, 64 {"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16},
65 65
66 {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0}, 66 {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0},
67 67
68 /* These are the new chips with large page size. The pagesize 68 /* These are the new chips with large page size. The pagesize
@@ -73,7 +73,7 @@ struct nand_flash_dev nand_flash_ids[] = {
73 {"NAND 64MiB 3,3V 8-bit", 0xF2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 73 {"NAND 64MiB 3,3V 8-bit", 0xF2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
74 {"NAND 64MiB 1,8V 16-bit", 0xB2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 74 {"NAND 64MiB 1,8V 16-bit", 0xB2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
75 {"NAND 64MiB 3,3V 16-bit", 0xC2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 75 {"NAND 64MiB 3,3V 16-bit", 0xC2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
76 76
77 /* 1 Gigabit */ 77 /* 1 Gigabit */
78 {"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 78 {"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
79 {"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 79 {"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
@@ -85,13 +85,13 @@ struct nand_flash_dev nand_flash_ids[] = {
85 {"NAND 256MiB 3,3V 8-bit", 0xDA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 85 {"NAND 256MiB 3,3V 8-bit", 0xDA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
86 {"NAND 256MiB 1,8V 16-bit", 0xBA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 86 {"NAND 256MiB 1,8V 16-bit", 0xBA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
87 {"NAND 256MiB 3,3V 16-bit", 0xCA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 87 {"NAND 256MiB 3,3V 16-bit", 0xCA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
88 88
89 /* 4 Gigabit */ 89 /* 4 Gigabit */
90 {"NAND 512MiB 1,8V 8-bit", 0xAC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 90 {"NAND 512MiB 1,8V 8-bit", 0xAC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
91 {"NAND 512MiB 3,3V 8-bit", 0xDC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 91 {"NAND 512MiB 3,3V 8-bit", 0xDC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
92 {"NAND 512MiB 1,8V 16-bit", 0xBC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 92 {"NAND 512MiB 1,8V 16-bit", 0xBC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
93 {"NAND 512MiB 3,3V 16-bit", 0xCC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 93 {"NAND 512MiB 3,3V 16-bit", 0xCC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
94 94
95 /* 8 Gigabit */ 95 /* 8 Gigabit */
96 {"NAND 1GiB 1,8V 8-bit", 0xA3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 96 {"NAND 1GiB 1,8V 8-bit", 0xA3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
97 {"NAND 1GiB 3,3V 8-bit", 0xD3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 97 {"NAND 1GiB 3,3V 8-bit", 0xD3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
@@ -104,11 +104,11 @@ struct nand_flash_dev nand_flash_ids[] = {
104 {"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 104 {"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
105 {"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 105 {"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
106 106
107 /* Renesas AND 1 Gigabit. Those chips do not support extended id and have a strange page/block layout ! 107 /* Renesas AND 1 Gigabit. Those chips do not support extended id and have a strange page/block layout !
108 * The chosen minimum erasesize is 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page planes 108 * The chosen minimum erasesize is 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page planes
109 * 1 block = 2 pages, but due to plane arrangement the blocks 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7 109 * 1 block = 2 pages, but due to plane arrangement the blocks 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7
110 * Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go 110 * Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go
111 * There are more speed improvements for reads and writes possible, but not implemented now 111 * There are more speed improvements for reads and writes possible, but not implemented now
112 */ 112 */
113 {"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH}, 113 {"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH},
114 114
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index 754b6ed7ce14..de4500395300 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Author: Artem B. Bityuckiy <dedekind@oktetlabs.ru>, <dedekind@infradead.org> 4 * Author: Artem B. Bityuckiy <dedekind@oktetlabs.ru>, <dedekind@infradead.org>
5 * 5 *
6 * Copyright (C) 2004 Nokia Corporation 6 * Copyright (C) 2004 Nokia Corporation
7 * 7 *
8 * Note: NS means "NAND Simulator". 8 * Note: NS means "NAND Simulator".
9 * Note: Input means input TO flash chip, output means output FROM chip. 9 * Note: Input means input TO flash chip, output means output FROM chip.
@@ -126,7 +126,7 @@ MODULE_PARM_DESC(dbg, "Output debug information if not zero");
126 126
127/* The largest possible page size */ 127/* The largest possible page size */
128#define NS_LARGEST_PAGE_SIZE 2048 128#define NS_LARGEST_PAGE_SIZE 2048
129 129
130/* The prefix for simulator output */ 130/* The prefix for simulator output */
131#define NS_OUTPUT_PREFIX "[nandsim]" 131#define NS_OUTPUT_PREFIX "[nandsim]"
132 132
@@ -145,7 +145,7 @@ MODULE_PARM_DESC(dbg, "Output debug information if not zero");
145 do { if (do_delays) udelay(us); } while(0) 145 do { if (do_delays) udelay(us); } while(0)
146#define NS_MDELAY(us) \ 146#define NS_MDELAY(us) \
147 do { if (do_delays) mdelay(us); } while(0) 147 do { if (do_delays) mdelay(us); } while(0)
148 148
149/* Is the nandsim structure initialized ? */ 149/* Is the nandsim structure initialized ? */
150#define NS_IS_INITIALIZED(ns) ((ns)->geom.totsz != 0) 150#define NS_IS_INITIALIZED(ns) ((ns)->geom.totsz != 0)
151 151
@@ -153,12 +153,12 @@ MODULE_PARM_DESC(dbg, "Output debug information if not zero");
153#define NS_STATUS_OK(ns) (NAND_STATUS_READY | (NAND_STATUS_WP * ((ns)->lines.wp == 0))) 153#define NS_STATUS_OK(ns) (NAND_STATUS_READY | (NAND_STATUS_WP * ((ns)->lines.wp == 0)))
154 154
155/* Operation failed completion status */ 155/* Operation failed completion status */
156#define NS_STATUS_FAILED(ns) (NAND_STATUS_FAIL | NS_STATUS_OK(ns)) 156#define NS_STATUS_FAILED(ns) (NAND_STATUS_FAIL | NS_STATUS_OK(ns))
157 157
158/* Calculate the page offset in flash RAM image by (row, column) address */ 158/* Calculate the page offset in flash RAM image by (row, column) address */
159#define NS_RAW_OFFSET(ns) \ 159#define NS_RAW_OFFSET(ns) \
160 (((ns)->regs.row << (ns)->geom.pgshift) + ((ns)->regs.row * (ns)->geom.oobsz) + (ns)->regs.column) 160 (((ns)->regs.row << (ns)->geom.pgshift) + ((ns)->regs.row * (ns)->geom.oobsz) + (ns)->regs.column)
161 161
162/* Calculate the OOB offset in flash RAM image by (row, column) address */ 162/* Calculate the OOB offset in flash RAM image by (row, column) address */
163#define NS_RAW_OFFSET_OOB(ns) (NS_RAW_OFFSET(ns) + ns->geom.pgsz) 163#define NS_RAW_OFFSET_OOB(ns) (NS_RAW_OFFSET(ns) + ns->geom.pgsz)
164 164
@@ -223,15 +223,15 @@ MODULE_PARM_DESC(dbg, "Output debug information if not zero");
223 223
224/* Remove action bits ftom state */ 224/* Remove action bits ftom state */
225#define NS_STATE(x) ((x) & ~ACTION_MASK) 225#define NS_STATE(x) ((x) & ~ACTION_MASK)
226 226
227/* 227/*
228 * Maximum previous states which need to be saved. Currently saving is 228 * Maximum previous states which need to be saved. Currently saving is
229 * only needed for page programm operation with preceeded read command 229 * only needed for page programm operation with preceeded read command
230 * (which is only valid for 512-byte pages). 230 * (which is only valid for 512-byte pages).
231 */ 231 */
232#define NS_MAX_PREVSTATES 1 232#define NS_MAX_PREVSTATES 1
233 233
234/* 234/*
235 * The structure which describes all the internal simulator data. 235 * The structure which describes all the internal simulator data.
236 */ 236 */
237struct nandsim { 237struct nandsim {
@@ -242,7 +242,7 @@ struct nandsim {
242 uint32_t options; /* chip's characteristic bits */ 242 uint32_t options; /* chip's characteristic bits */
243 uint32_t state; /* current chip state */ 243 uint32_t state; /* current chip state */
244 uint32_t nxstate; /* next expected state */ 244 uint32_t nxstate; /* next expected state */
245 245
246 uint32_t *op; /* current operation, NULL operations isn't known yet */ 246 uint32_t *op; /* current operation, NULL operations isn't known yet */
247 uint32_t pstates[NS_MAX_PREVSTATES]; /* previous states */ 247 uint32_t pstates[NS_MAX_PREVSTATES]; /* previous states */
248 uint16_t npstates; /* number of previous states saved */ 248 uint16_t npstates; /* number of previous states saved */
@@ -413,7 +413,7 @@ init_nandsim(struct mtd_info *mtd)
413 ns->geom.secaddrbytes = 3; 413 ns->geom.secaddrbytes = 3;
414 } 414 }
415 } 415 }
416 416
417 /* Detect how many ID bytes the NAND chip outputs */ 417 /* Detect how many ID bytes the NAND chip outputs */
418 for (i = 0; nand_flash_ids[i].name != NULL; i++) { 418 for (i = 0; nand_flash_ids[i].name != NULL; i++) {
419 if (second_id_byte != nand_flash_ids[i].id) 419 if (second_id_byte != nand_flash_ids[i].id)
@@ -444,7 +444,7 @@ init_nandsim(struct mtd_info *mtd)
444#ifdef CONFIG_NS_ABS_POS 444#ifdef CONFIG_NS_ABS_POS
445 ns->mem.byte = ioremap(CONFIG_NS_ABS_POS, ns->geom.totszoob); 445 ns->mem.byte = ioremap(CONFIG_NS_ABS_POS, ns->geom.totszoob);
446 if (!ns->mem.byte) { 446 if (!ns->mem.byte) {
447 NS_ERR("init_nandsim: failed to map the NAND flash image at address %p\n", 447 NS_ERR("init_nandsim: failed to map the NAND flash image at address %p\n",
448 (void *)CONFIG_NS_ABS_POS); 448 (void *)CONFIG_NS_ABS_POS);
449 return -ENOMEM; 449 return -ENOMEM;
450 } 450 }
@@ -567,7 +567,7 @@ static int
567check_command(int cmd) 567check_command(int cmd)
568{ 568{
569 switch (cmd) { 569 switch (cmd) {
570 570
571 case NAND_CMD_READ0: 571 case NAND_CMD_READ0:
572 case NAND_CMD_READSTART: 572 case NAND_CMD_READSTART:
573 case NAND_CMD_PAGEPROG: 573 case NAND_CMD_PAGEPROG:
@@ -580,7 +580,7 @@ check_command(int cmd)
580 case NAND_CMD_RESET: 580 case NAND_CMD_RESET:
581 case NAND_CMD_READ1: 581 case NAND_CMD_READ1:
582 return 0; 582 return 0;
583 583
584 case NAND_CMD_STATUS_MULTI: 584 case NAND_CMD_STATUS_MULTI:
585 default: 585 default:
586 return 1; 586 return 1;
@@ -631,7 +631,7 @@ static inline void
631accept_addr_byte(struct nandsim *ns, u_char bt) 631accept_addr_byte(struct nandsim *ns, u_char bt)
632{ 632{
633 uint byte = (uint)bt; 633 uint byte = (uint)bt;
634 634
635 if (ns->regs.count < (ns->geom.pgaddrbytes - ns->geom.secaddrbytes)) 635 if (ns->regs.count < (ns->geom.pgaddrbytes - ns->geom.secaddrbytes))
636 ns->regs.column |= (byte << 8 * ns->regs.count); 636 ns->regs.column |= (byte << 8 * ns->regs.count);
637 else { 637 else {
@@ -642,11 +642,11 @@ accept_addr_byte(struct nandsim *ns, u_char bt)
642 642
643 return; 643 return;
644} 644}
645 645
646/* 646/*
647 * Switch to STATE_READY state. 647 * Switch to STATE_READY state.
648 */ 648 */
649static inline void 649static inline void
650switch_to_ready_state(struct nandsim *ns, u_char status) 650switch_to_ready_state(struct nandsim *ns, u_char status)
651{ 651{
652 NS_DBG("switch_to_ready_state: switch to %s state\n", get_state_name(STATE_READY)); 652 NS_DBG("switch_to_ready_state: switch to %s state\n", get_state_name(STATE_READY));
@@ -675,7 +675,7 @@ switch_to_ready_state(struct nandsim *ns, u_char status)
675 * (for example program from the second half and read from the 675 * (for example program from the second half and read from the
676 * second half operations both begin with the READ1 command). In this 676 * second half operations both begin with the READ1 command). In this
677 * case the ns->pstates[] array contains previous states. 677 * case the ns->pstates[] array contains previous states.
678 * 678 *
679 * Thus, the function tries to find operation containing the following 679 * Thus, the function tries to find operation containing the following
680 * states (if the 'flag' parameter is 0): 680 * states (if the 'flag' parameter is 0):
681 * ns->pstates[0], ... ns->pstates[ns->npstates], ns->state 681 * ns->pstates[0], ... ns->pstates[ns->npstates], ns->state
@@ -683,7 +683,7 @@ switch_to_ready_state(struct nandsim *ns, u_char status)
683 * If (one and only one) matching operation is found, it is accepted ( 683 * If (one and only one) matching operation is found, it is accepted (
684 * ns->ops, ns->state, ns->nxstate are initialized, ns->npstate is 684 * ns->ops, ns->state, ns->nxstate are initialized, ns->npstate is
685 * zeroed). 685 * zeroed).
686 * 686 *
687 * If there are several maches, the current state is pushed to the 687 * If there are several maches, the current state is pushed to the
688 * ns->pstates. 688 * ns->pstates.
689 * 689 *
@@ -692,7 +692,7 @@ switch_to_ready_state(struct nandsim *ns, u_char status)
692 * In such situation the function is called with 'flag' != 0, and the 692 * In such situation the function is called with 'flag' != 0, and the
693 * operation is searched using the following pattern: 693 * operation is searched using the following pattern:
694 * ns->pstates[0], ... ns->pstates[ns->npstates], <address input> 694 * ns->pstates[0], ... ns->pstates[ns->npstates], <address input>
695 * 695 *
696 * It is supposed that this pattern must either match one operation on 696 * It is supposed that this pattern must either match one operation on
697 * none. There can't be ambiguity in that case. 697 * none. There can't be ambiguity in that case.
698 * 698 *
@@ -711,15 +711,15 @@ find_operation(struct nandsim *ns, uint32_t flag)
711{ 711{
712 int opsfound = 0; 712 int opsfound = 0;
713 int i, j, idx = 0; 713 int i, j, idx = 0;
714 714
715 for (i = 0; i < NS_OPER_NUM; i++) { 715 for (i = 0; i < NS_OPER_NUM; i++) {
716 716
717 int found = 1; 717 int found = 1;
718 718
719 if (!(ns->options & ops[i].reqopts)) 719 if (!(ns->options & ops[i].reqopts))
720 /* Ignore operations we can't perform */ 720 /* Ignore operations we can't perform */
721 continue; 721 continue;
722 722
723 if (flag) { 723 if (flag) {
724 if (!(ops[i].states[ns->npstates] & STATE_ADDR_MASK)) 724 if (!(ops[i].states[ns->npstates] & STATE_ADDR_MASK))
725 continue; 725 continue;
@@ -728,7 +728,7 @@ find_operation(struct nandsim *ns, uint32_t flag)
728 continue; 728 continue;
729 } 729 }
730 730
731 for (j = 0; j < ns->npstates; j++) 731 for (j = 0; j < ns->npstates; j++)
732 if (NS_STATE(ops[i].states[j]) != NS_STATE(ns->pstates[j]) 732 if (NS_STATE(ops[i].states[j]) != NS_STATE(ns->pstates[j])
733 && (ns->options & ops[idx].reqopts)) { 733 && (ns->options & ops[idx].reqopts)) {
734 found = 0; 734 found = 0;
@@ -745,7 +745,7 @@ find_operation(struct nandsim *ns, uint32_t flag)
745 /* Exact match */ 745 /* Exact match */
746 ns->op = &ops[idx].states[0]; 746 ns->op = &ops[idx].states[0];
747 if (flag) { 747 if (flag) {
748 /* 748 /*
749 * In this case the find_operation function was 749 * In this case the find_operation function was
750 * called when address has just began input. But it isn't 750 * called when address has just began input. But it isn't
751 * yet fully input and the current state must 751 * yet fully input and the current state must
@@ -763,7 +763,7 @@ find_operation(struct nandsim *ns, uint32_t flag)
763 idx, get_state_name(ns->state), get_state_name(ns->nxstate)); 763 idx, get_state_name(ns->state), get_state_name(ns->nxstate));
764 return 0; 764 return 0;
765 } 765 }
766 766
767 if (opsfound == 0) { 767 if (opsfound == 0) {
768 /* Nothing was found. Try to ignore previous commands (if any) and search again */ 768 /* Nothing was found. Try to ignore previous commands (if any) and search again */
769 if (ns->npstates != 0) { 769 if (ns->npstates != 0) {
@@ -777,13 +777,13 @@ find_operation(struct nandsim *ns, uint32_t flag)
777 switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); 777 switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
778 return -2; 778 return -2;
779 } 779 }
780 780
781 if (flag) { 781 if (flag) {
782 /* This shouldn't happen */ 782 /* This shouldn't happen */
783 NS_DBG("find_operation: BUG, operation must be known if address is input\n"); 783 NS_DBG("find_operation: BUG, operation must be known if address is input\n");
784 return -2; 784 return -2;
785 } 785 }
786 786
787 NS_DBG("find_operation: there is still ambiguity\n"); 787 NS_DBG("find_operation: there is still ambiguity\n");
788 788
789 ns->pstates[ns->npstates++] = ns->state; 789 ns->pstates[ns->npstates++] = ns->state;
@@ -803,7 +803,7 @@ do_state_action(struct nandsim *ns, uint32_t action)
803 int busdiv = ns->busw == 8 ? 1 : 2; 803 int busdiv = ns->busw == 8 ? 1 : 2;
804 804
805 action &= ACTION_MASK; 805 action &= ACTION_MASK;
806 806
807 /* Check that page address input is correct */ 807 /* Check that page address input is correct */
808 if (action != ACTION_SECERASE && ns->regs.row >= ns->geom.pgnum) { 808 if (action != ACTION_SECERASE && ns->regs.row >= ns->geom.pgnum) {
809 NS_WARN("do_state_action: wrong page number (%#x)\n", ns->regs.row); 809 NS_WARN("do_state_action: wrong page number (%#x)\n", ns->regs.row);
@@ -827,14 +827,14 @@ do_state_action(struct nandsim *ns, uint32_t action)
827 827
828 NS_DBG("do_state_action: (ACTION_CPY:) copy %d bytes to int buf, raw offset %d\n", 828 NS_DBG("do_state_action: (ACTION_CPY:) copy %d bytes to int buf, raw offset %d\n",
829 num, NS_RAW_OFFSET(ns) + ns->regs.off); 829 num, NS_RAW_OFFSET(ns) + ns->regs.off);
830 830
831 if (ns->regs.off == 0) 831 if (ns->regs.off == 0)
832 NS_LOG("read page %d\n", ns->regs.row); 832 NS_LOG("read page %d\n", ns->regs.row);
833 else if (ns->regs.off < ns->geom.pgsz) 833 else if (ns->regs.off < ns->geom.pgsz)
834 NS_LOG("read page %d (second half)\n", ns->regs.row); 834 NS_LOG("read page %d (second half)\n", ns->regs.row);
835 else 835 else
836 NS_LOG("read OOB of page %d\n", ns->regs.row); 836 NS_LOG("read OOB of page %d\n", ns->regs.row);
837 837
838 NS_UDELAY(access_delay); 838 NS_UDELAY(access_delay);
839 NS_UDELAY(input_cycle * ns->geom.pgsz / 1000 / busdiv); 839 NS_UDELAY(input_cycle * ns->geom.pgsz / 1000 / busdiv);
840 840
@@ -844,30 +844,30 @@ do_state_action(struct nandsim *ns, uint32_t action)
844 /* 844 /*
845 * Erase sector. 845 * Erase sector.
846 */ 846 */
847 847
848 if (ns->lines.wp) { 848 if (ns->lines.wp) {
849 NS_ERR("do_state_action: device is write-protected, ignore sector erase\n"); 849 NS_ERR("do_state_action: device is write-protected, ignore sector erase\n");
850 return -1; 850 return -1;
851 } 851 }
852 852
853 if (ns->regs.row >= ns->geom.pgnum - ns->geom.pgsec 853 if (ns->regs.row >= ns->geom.pgnum - ns->geom.pgsec
854 || (ns->regs.row & ~(ns->geom.secsz - 1))) { 854 || (ns->regs.row & ~(ns->geom.secsz - 1))) {
855 NS_ERR("do_state_action: wrong sector address (%#x)\n", ns->regs.row); 855 NS_ERR("do_state_action: wrong sector address (%#x)\n", ns->regs.row);
856 return -1; 856 return -1;
857 } 857 }
858 858
859 ns->regs.row = (ns->regs.row << 859 ns->regs.row = (ns->regs.row <<
860 8 * (ns->geom.pgaddrbytes - ns->geom.secaddrbytes)) | ns->regs.column; 860 8 * (ns->geom.pgaddrbytes - ns->geom.secaddrbytes)) | ns->regs.column;
861 ns->regs.column = 0; 861 ns->regs.column = 0;
862 862
863 NS_DBG("do_state_action: erase sector at address %#x, off = %d\n", 863 NS_DBG("do_state_action: erase sector at address %#x, off = %d\n",
864 ns->regs.row, NS_RAW_OFFSET(ns)); 864 ns->regs.row, NS_RAW_OFFSET(ns));
865 NS_LOG("erase sector %d\n", ns->regs.row >> (ns->geom.secshift - ns->geom.pgshift)); 865 NS_LOG("erase sector %d\n", ns->regs.row >> (ns->geom.secshift - ns->geom.pgshift));
866 866
867 memset(ns->mem.byte + NS_RAW_OFFSET(ns), 0xFF, ns->geom.secszoob); 867 memset(ns->mem.byte + NS_RAW_OFFSET(ns), 0xFF, ns->geom.secszoob);
868 868
869 NS_MDELAY(erase_delay); 869 NS_MDELAY(erase_delay);
870 870
871 break; 871 break;
872 872
873 case ACTION_PRGPAGE: 873 case ACTION_PRGPAGE:
@@ -893,12 +893,12 @@ do_state_action(struct nandsim *ns, uint32_t action)
893 NS_DBG("do_state_action: copy %d bytes from int buf to (%#x, %#x), raw off = %d\n", 893 NS_DBG("do_state_action: copy %d bytes from int buf to (%#x, %#x), raw off = %d\n",
894 num, ns->regs.row, ns->regs.column, NS_RAW_OFFSET(ns) + ns->regs.off); 894 num, ns->regs.row, ns->regs.column, NS_RAW_OFFSET(ns) + ns->regs.off);
895 NS_LOG("programm page %d\n", ns->regs.row); 895 NS_LOG("programm page %d\n", ns->regs.row);
896 896
897 NS_UDELAY(programm_delay); 897 NS_UDELAY(programm_delay);
898 NS_UDELAY(output_cycle * ns->geom.pgsz / 1000 / busdiv); 898 NS_UDELAY(output_cycle * ns->geom.pgsz / 1000 / busdiv);
899 899
900 break; 900 break;
901 901
902 case ACTION_ZEROOFF: 902 case ACTION_ZEROOFF:
903 NS_DBG("do_state_action: set internal offset to 0\n"); 903 NS_DBG("do_state_action: set internal offset to 0\n");
904 ns->regs.off = 0; 904 ns->regs.off = 0;
@@ -918,7 +918,7 @@ do_state_action(struct nandsim *ns, uint32_t action)
918 NS_DBG("do_state_action: set internal offset to %d\n", ns->geom.pgsz); 918 NS_DBG("do_state_action: set internal offset to %d\n", ns->geom.pgsz);
919 ns->regs.off = ns->geom.pgsz; 919 ns->regs.off = ns->geom.pgsz;
920 break; 920 break;
921 921
922 default: 922 default:
923 NS_DBG("do_state_action: BUG! unknown action\n"); 923 NS_DBG("do_state_action: BUG! unknown action\n");
924 } 924 }
@@ -937,7 +937,7 @@ switch_state(struct nandsim *ns)
937 * The current operation have already been identified. 937 * The current operation have already been identified.
938 * Just follow the states chain. 938 * Just follow the states chain.
939 */ 939 */
940 940
941 ns->stateidx += 1; 941 ns->stateidx += 1;
942 ns->state = ns->nxstate; 942 ns->state = ns->nxstate;
943 ns->nxstate = ns->op[ns->stateidx + 1]; 943 ns->nxstate = ns->op[ns->stateidx + 1];
@@ -951,14 +951,14 @@ switch_state(struct nandsim *ns)
951 switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); 951 switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
952 return; 952 return;
953 } 953 }
954 954
955 } else { 955 } else {
956 /* 956 /*
957 * We don't yet know which operation we perform. 957 * We don't yet know which operation we perform.
958 * Try to identify it. 958 * Try to identify it.
959 */ 959 */
960 960
961 /* 961 /*
962 * The only event causing the switch_state function to 962 * The only event causing the switch_state function to
963 * be called with yet unknown operation is new command. 963 * be called with yet unknown operation is new command.
964 */ 964 */
@@ -987,7 +987,7 @@ switch_state(struct nandsim *ns)
987 */ 987 */
988 988
989 u_char status = NS_STATUS_OK(ns); 989 u_char status = NS_STATUS_OK(ns);
990 990
991 /* In case of data states, see if all bytes were input/output */ 991 /* In case of data states, see if all bytes were input/output */
992 if ((ns->state & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK)) 992 if ((ns->state & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK))
993 && ns->regs.count != ns->regs.num) { 993 && ns->regs.count != ns->regs.num) {
@@ -995,17 +995,17 @@ switch_state(struct nandsim *ns)
995 ns->regs.num - ns->regs.count); 995 ns->regs.num - ns->regs.count);
996 status = NS_STATUS_FAILED(ns); 996 status = NS_STATUS_FAILED(ns);
997 } 997 }
998 998
999 NS_DBG("switch_state: operation complete, switch to STATE_READY state\n"); 999 NS_DBG("switch_state: operation complete, switch to STATE_READY state\n");
1000 1000
1001 switch_to_ready_state(ns, status); 1001 switch_to_ready_state(ns, status);
1002 1002
1003 return; 1003 return;
1004 } else if (ns->nxstate & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK)) { 1004 } else if (ns->nxstate & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK)) {
1005 /* 1005 /*
1006 * If the next state is data input/output, switch to it now 1006 * If the next state is data input/output, switch to it now
1007 */ 1007 */
1008 1008
1009 ns->state = ns->nxstate; 1009 ns->state = ns->nxstate;
1010 ns->nxstate = ns->op[++ns->stateidx + 1]; 1010 ns->nxstate = ns->op[++ns->stateidx + 1];
1011 ns->regs.num = ns->regs.count = 0; 1011 ns->regs.num = ns->regs.count = 0;
@@ -1023,16 +1023,16 @@ switch_state(struct nandsim *ns)
1023 case STATE_DATAOUT: 1023 case STATE_DATAOUT:
1024 ns->regs.num = ns->geom.pgszoob - ns->regs.off - ns->regs.column; 1024 ns->regs.num = ns->geom.pgszoob - ns->regs.off - ns->regs.column;
1025 break; 1025 break;
1026 1026
1027 case STATE_DATAOUT_ID: 1027 case STATE_DATAOUT_ID:
1028 ns->regs.num = ns->geom.idbytes; 1028 ns->regs.num = ns->geom.idbytes;
1029 break; 1029 break;
1030 1030
1031 case STATE_DATAOUT_STATUS: 1031 case STATE_DATAOUT_STATUS:
1032 case STATE_DATAOUT_STATUS_M: 1032 case STATE_DATAOUT_STATUS_M:
1033 ns->regs.count = ns->regs.num = 0; 1033 ns->regs.count = ns->regs.num = 0;
1034 break; 1034 break;
1035 1035
1036 default: 1036 default:
1037 NS_ERR("switch_state: BUG! unknown data state\n"); 1037 NS_ERR("switch_state: BUG! unknown data state\n");
1038 } 1038 }
@@ -1044,16 +1044,16 @@ switch_state(struct nandsim *ns)
1044 */ 1044 */
1045 1045
1046 ns->regs.count = 0; 1046 ns->regs.count = 0;
1047 1047
1048 switch (NS_STATE(ns->nxstate)) { 1048 switch (NS_STATE(ns->nxstate)) {
1049 case STATE_ADDR_PAGE: 1049 case STATE_ADDR_PAGE:
1050 ns->regs.num = ns->geom.pgaddrbytes; 1050 ns->regs.num = ns->geom.pgaddrbytes;
1051 1051
1052 break; 1052 break;
1053 case STATE_ADDR_SEC: 1053 case STATE_ADDR_SEC:
1054 ns->regs.num = ns->geom.secaddrbytes; 1054 ns->regs.num = ns->geom.secaddrbytes;
1055 break; 1055 break;
1056 1056
1057 case STATE_ADDR_ZERO: 1057 case STATE_ADDR_ZERO:
1058 ns->regs.num = 1; 1058 ns->regs.num = 1;
1059 break; 1059 break;
@@ -1062,7 +1062,7 @@ switch_state(struct nandsim *ns)
1062 NS_ERR("switch_state: BUG! unknown address state\n"); 1062 NS_ERR("switch_state: BUG! unknown address state\n");
1063 } 1063 }
1064 } else { 1064 } else {
1065 /* 1065 /*
1066 * Just reset internal counters. 1066 * Just reset internal counters.
1067 */ 1067 */
1068 1068
@@ -1184,7 +1184,7 @@ ns_nand_read_byte(struct mtd_info *mtd)
1184 default: 1184 default:
1185 BUG(); 1185 BUG();
1186 } 1186 }
1187 1187
1188 if (ns->regs.count == ns->regs.num) { 1188 if (ns->regs.count == ns->regs.num) {
1189 NS_DBG("read_byte: all bytes were read\n"); 1189 NS_DBG("read_byte: all bytes were read\n");
1190 1190
@@ -1201,9 +1201,9 @@ ns_nand_read_byte(struct mtd_info *mtd)
1201 } 1201 }
1202 else if (NS_STATE(ns->nxstate) == STATE_READY) 1202 else if (NS_STATE(ns->nxstate) == STATE_READY)
1203 switch_state(ns); 1203 switch_state(ns);
1204 1204
1205 } 1205 }
1206 1206
1207 return outb; 1207 return outb;
1208} 1208}
1209 1209
@@ -1211,7 +1211,7 @@ static void
1211ns_nand_write_byte(struct mtd_info *mtd, u_char byte) 1211ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1212{ 1212{
1213 struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; 1213 struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
1214 1214
1215 /* Sanity and correctness checks */ 1215 /* Sanity and correctness checks */
1216 if (!ns->lines.ce) { 1216 if (!ns->lines.ce) {
1217 NS_ERR("write_byte: chip is disabled, ignore write\n"); 1217 NS_ERR("write_byte: chip is disabled, ignore write\n");
@@ -1221,7 +1221,7 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1221 NS_ERR("write_byte: ALE and CLE pins are high simultaneously, ignore write\n"); 1221 NS_ERR("write_byte: ALE and CLE pins are high simultaneously, ignore write\n");
1222 return; 1222 return;
1223 } 1223 }
1224 1224
1225 if (ns->lines.cle == 1) { 1225 if (ns->lines.cle == 1) {
1226 /* 1226 /*
1227 * The byte written is a command. 1227 * The byte written is a command.
@@ -1233,7 +1233,7 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1233 return; 1233 return;
1234 } 1234 }
1235 1235
1236 /* 1236 /*
1237 * Chip might still be in STATE_DATAOUT 1237 * Chip might still be in STATE_DATAOUT
1238 * (if OPT_AUTOINCR feature is supported), STATE_DATAOUT_STATUS or 1238 * (if OPT_AUTOINCR feature is supported), STATE_DATAOUT_STATUS or
1239 * STATE_DATAOUT_STATUS_M state. If so, switch state. 1239 * STATE_DATAOUT_STATUS_M state. If so, switch state.
@@ -1254,13 +1254,13 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1254 "ignore previous states\n", (uint)byte, get_state_name(ns->nxstate)); 1254 "ignore previous states\n", (uint)byte, get_state_name(ns->nxstate));
1255 switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); 1255 switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
1256 } 1256 }
1257 1257
1258 /* Check that the command byte is correct */ 1258 /* Check that the command byte is correct */
1259 if (check_command(byte)) { 1259 if (check_command(byte)) {
1260 NS_ERR("write_byte: unknown command %#x\n", (uint)byte); 1260 NS_ERR("write_byte: unknown command %#x\n", (uint)byte);
1261 return; 1261 return;
1262 } 1262 }
1263 1263
1264 NS_DBG("command byte corresponding to %s state accepted\n", 1264 NS_DBG("command byte corresponding to %s state accepted\n",
1265 get_state_name(get_state_by_command(byte))); 1265 get_state_name(get_state_by_command(byte)));
1266 ns->regs.command = byte; 1266 ns->regs.command = byte;
@@ -1277,12 +1277,12 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1277 1277
1278 if (find_operation(ns, 1) < 0) 1278 if (find_operation(ns, 1) < 0)
1279 return; 1279 return;
1280 1280
1281 if ((ns->state & ACTION_MASK) && do_state_action(ns, ns->state) < 0) { 1281 if ((ns->state & ACTION_MASK) && do_state_action(ns, ns->state) < 0) {
1282 switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); 1282 switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
1283 return; 1283 return;
1284 } 1284 }
1285 1285
1286 ns->regs.count = 0; 1286 ns->regs.count = 0;
1287 switch (NS_STATE(ns->nxstate)) { 1287 switch (NS_STATE(ns->nxstate)) {
1288 case STATE_ADDR_PAGE: 1288 case STATE_ADDR_PAGE:
@@ -1306,7 +1306,7 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1306 switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); 1306 switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
1307 return; 1307 return;
1308 } 1308 }
1309 1309
1310 /* Check if this is expected byte */ 1310 /* Check if this is expected byte */
1311 if (ns->regs.count == ns->regs.num) { 1311 if (ns->regs.count == ns->regs.num) {
1312 NS_ERR("write_byte: no more address bytes expected\n"); 1312 NS_ERR("write_byte: no more address bytes expected\n");
@@ -1325,12 +1325,12 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1325 NS_DBG("address (%#x, %#x) is accepted\n", ns->regs.row, ns->regs.column); 1325 NS_DBG("address (%#x, %#x) is accepted\n", ns->regs.row, ns->regs.column);
1326 switch_state(ns); 1326 switch_state(ns);
1327 } 1327 }
1328 1328
1329 } else { 1329 } else {
1330 /* 1330 /*
1331 * The byte written is an input data. 1331 * The byte written is an input data.
1332 */ 1332 */
1333 1333
1334 /* Check that chip is expecting data input */ 1334 /* Check that chip is expecting data input */
1335 if (!(ns->state & STATE_DATAIN_MASK)) { 1335 if (!(ns->state & STATE_DATAIN_MASK)) {
1336 NS_ERR("write_byte: data input (%#x) isn't expected, state is %s, " 1336 NS_ERR("write_byte: data input (%#x) isn't expected, state is %s, "
@@ -1372,7 +1372,7 @@ ns_nand_read_word(struct mtd_info *mtd)
1372 struct nand_chip *chip = (struct nand_chip *)mtd->priv; 1372 struct nand_chip *chip = (struct nand_chip *)mtd->priv;
1373 1373
1374 NS_DBG("read_word\n"); 1374 NS_DBG("read_word\n");
1375 1375
1376 return chip->read_byte(mtd) | (chip->read_byte(mtd) << 8); 1376 return chip->read_byte(mtd) | (chip->read_byte(mtd) << 8);
1377} 1377}
1378 1378
@@ -1380,14 +1380,14 @@ static void
1380ns_nand_write_word(struct mtd_info *mtd, uint16_t word) 1380ns_nand_write_word(struct mtd_info *mtd, uint16_t word)
1381{ 1381{
1382 struct nand_chip *chip = (struct nand_chip *)mtd->priv; 1382 struct nand_chip *chip = (struct nand_chip *)mtd->priv;
1383 1383
1384 NS_DBG("write_word\n"); 1384 NS_DBG("write_word\n");
1385 1385
1386 chip->write_byte(mtd, word & 0xFF); 1386 chip->write_byte(mtd, word & 0xFF);
1387 chip->write_byte(mtd, word >> 8); 1387 chip->write_byte(mtd, word >> 8);
1388} 1388}
1389 1389
1390static void 1390static void
1391ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) 1391ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
1392{ 1392{
1393 struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; 1393 struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
@@ -1409,13 +1409,13 @@ ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
1409 1409
1410 memcpy(ns->buf.byte + ns->regs.count, buf, len); 1410 memcpy(ns->buf.byte + ns->regs.count, buf, len);
1411 ns->regs.count += len; 1411 ns->regs.count += len;
1412 1412
1413 if (ns->regs.count == ns->regs.num) { 1413 if (ns->regs.count == ns->regs.num) {
1414 NS_DBG("write_buf: %d bytes were written\n", ns->regs.count); 1414 NS_DBG("write_buf: %d bytes were written\n", ns->regs.count);
1415 } 1415 }
1416} 1416}
1417 1417
1418static void 1418static void
1419ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) 1419ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
1420{ 1420{
1421 struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; 1421 struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
@@ -1453,7 +1453,7 @@ ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
1453 1453
1454 memcpy(buf, ns->buf.byte + ns->regs.count, len); 1454 memcpy(buf, ns->buf.byte + ns->regs.count, len);
1455 ns->regs.count += len; 1455 ns->regs.count += len;
1456 1456
1457 if (ns->regs.count == ns->regs.num) { 1457 if (ns->regs.count == ns->regs.num) {
1458 if ((ns->options & OPT_AUTOINCR) && NS_STATE(ns->state) == STATE_DATAOUT) { 1458 if ((ns->options & OPT_AUTOINCR) && NS_STATE(ns->state) == STATE_DATAOUT) {
1459 ns->regs.count = 0; 1459 ns->regs.count = 0;
@@ -1465,11 +1465,11 @@ ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
1465 else if (NS_STATE(ns->nxstate) == STATE_READY) 1465 else if (NS_STATE(ns->nxstate) == STATE_READY)
1466 switch_state(ns); 1466 switch_state(ns);
1467 } 1467 }
1468 1468
1469 return; 1469 return;
1470} 1470}
1471 1471
1472static int 1472static int
1473ns_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) 1473ns_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
1474{ 1474{
1475 ns_nand_read_buf(mtd, (u_char *)&ns_verify_buf[0], len); 1475 ns_nand_read_buf(mtd, (u_char *)&ns_verify_buf[0], len);
@@ -1496,7 +1496,7 @@ int __init ns_init_module(void)
1496 NS_ERR("wrong bus width (%d), use only 8 or 16\n", bus_width); 1496 NS_ERR("wrong bus width (%d), use only 8 or 16\n", bus_width);
1497 return -EINVAL; 1497 return -EINVAL;
1498 } 1498 }
1499 1499
1500 /* Allocate and initialize mtd_info, nand_chip and nandsim structures */ 1500 /* Allocate and initialize mtd_info, nand_chip and nandsim structures */
1501 nsmtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip) 1501 nsmtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip)
1502 + sizeof(struct nandsim), GFP_KERNEL); 1502 + sizeof(struct nandsim), GFP_KERNEL);
@@ -1509,7 +1509,7 @@ int __init ns_init_module(void)
1509 chip = (struct nand_chip *)(nsmtd + 1); 1509 chip = (struct nand_chip *)(nsmtd + 1);
1510 nsmtd->priv = (void *)chip; 1510 nsmtd->priv = (void *)chip;
1511 nand = (struct nandsim *)(chip + 1); 1511 nand = (struct nandsim *)(chip + 1);
1512 chip->priv = (void *)nand; 1512 chip->priv = (void *)nand;
1513 1513
1514 /* 1514 /*
1515 * Register simulator's callbacks. 1515 * Register simulator's callbacks.
@@ -1526,9 +1526,9 @@ int __init ns_init_module(void)
1526 chip->eccmode = NAND_ECC_SOFT; 1526 chip->eccmode = NAND_ECC_SOFT;
1527 chip->options |= NAND_SKIP_BBTSCAN; 1527 chip->options |= NAND_SKIP_BBTSCAN;
1528 1528
1529 /* 1529 /*
1530 * Perform minimum nandsim structure initialization to handle 1530 * Perform minimum nandsim structure initialization to handle
1531 * the initial ID read command correctly 1531 * the initial ID read command correctly
1532 */ 1532 */
1533 if (third_id_byte != 0xFF || fourth_id_byte != 0xFF) 1533 if (third_id_byte != 0xFF || fourth_id_byte != 0xFF)
1534 nand->geom.idbytes = 4; 1534 nand->geom.idbytes = 4;
@@ -1557,7 +1557,7 @@ int __init ns_init_module(void)
1557 NS_ERR("scan_bbt: can't initialize the nandsim structure\n"); 1557 NS_ERR("scan_bbt: can't initialize the nandsim structure\n");
1558 goto error; 1558 goto error;
1559 } 1559 }
1560 1560
1561 if ((retval = nand_default_bbt(nsmtd)) != 0) { 1561 if ((retval = nand_default_bbt(nsmtd)) != 0) {
1562 free_nandsim(nand); 1562 free_nandsim(nand);
1563 goto error; 1563 goto error;
diff --git a/drivers/mtd/nand/ppchameleonevb.c b/drivers/mtd/nand/ppchameleonevb.c
index e510a83d7bdb..91a95f34a6ee 100644
--- a/drivers/mtd/nand/ppchameleonevb.c
+++ b/drivers/mtd/nand/ppchameleonevb.c
@@ -6,7 +6,7 @@
6 * Derived from drivers/mtd/nand/edb7312.c 6 * Derived from drivers/mtd/nand/edb7312.c
7 * 7 *
8 * 8 *
9 * $Id: ppchameleonevb.c,v 1.6 2004/11/05 16:07:16 kalev Exp $ 9 * $Id: ppchameleonevb.c,v 1.7 2005/11/07 11:14:31 gleixner Exp $
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as 12 * it under the terms of the GNU General Public License version 2 as
@@ -338,7 +338,7 @@ nand_evb_init:
338 out_be32((volatile unsigned*)GPIO0_TSRH, in_be32((volatile unsigned*)GPIO0_TSRH) & 0xFFFFFFF0); 338 out_be32((volatile unsigned*)GPIO0_TSRH, in_be32((volatile unsigned*)GPIO0_TSRH) & 0xFFFFFFF0);
339 out_be32((volatile unsigned*)GPIO0_TSRL, in_be32((volatile unsigned*)GPIO0_TSRL) & 0x3FFFFFFF); 339 out_be32((volatile unsigned*)GPIO0_TSRL, in_be32((volatile unsigned*)GPIO0_TSRL) & 0x3FFFFFFF);
340 /* enable output driver */ 340 /* enable output driver */
341 out_be32((volatile unsigned*)GPIO0_TCR, in_be32((volatile unsigned*)GPIO0_TCR) | NAND_EVB_nCE_GPIO_PIN | 341 out_be32((volatile unsigned*)GPIO0_TCR, in_be32((volatile unsigned*)GPIO0_TCR) | NAND_EVB_nCE_GPIO_PIN |
342 NAND_EVB_CLE_GPIO_PIN | NAND_EVB_ALE_GPIO_PIN); 342 NAND_EVB_CLE_GPIO_PIN | NAND_EVB_ALE_GPIO_PIN);
343#ifdef USE_READY_BUSY_PIN 343#ifdef USE_READY_BUSY_PIN
344 /* three-state select */ 344 /* three-state select */
@@ -402,7 +402,7 @@ static void __exit ppchameleonevb_cleanup (void)
402 /* Release resources, unregister device(s) */ 402 /* Release resources, unregister device(s) */
403 nand_release (ppchameleon_mtd); 403 nand_release (ppchameleon_mtd);
404 nand_release (ppchameleonevb_mtd); 404 nand_release (ppchameleonevb_mtd);
405 405
406 /* Release iomaps */ 406 /* Release iomaps */
407 this = (struct nand_chip *) &ppchameleon_mtd[1]; 407 this = (struct nand_chip *) &ppchameleon_mtd[1];
408 iounmap((void *) this->IO_ADDR_R; 408 iounmap((void *) this->IO_ADDR_R;
diff --git a/drivers/mtd/nand/rtc_from4.c b/drivers/mtd/nand/rtc_from4.c
index 031051cbde76..3a5841c9d950 100644
--- a/drivers/mtd/nand/rtc_from4.c
+++ b/drivers/mtd/nand/rtc_from4.c
@@ -2,11 +2,11 @@
2 * drivers/mtd/nand/rtc_from4.c 2 * drivers/mtd/nand/rtc_from4.c
3 * 3 *
4 * Copyright (C) 2004 Red Hat, Inc. 4 * Copyright (C) 2004 Red Hat, Inc.
5 * 5 *
6 * Derived from drivers/mtd/nand/spia.c 6 * Derived from drivers/mtd/nand/spia.c
7 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) 7 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
8 * 8 *
9 * $Id: rtc_from4.c,v 1.9 2005/01/24 20:40:11 dmarlin Exp $ 9 * $Id: rtc_from4.c,v 1.10 2005/11/07 11:14:31 gleixner Exp $
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as 12 * it under the terms of the GNU General Public License version 2 as
@@ -14,8 +14,8 @@
14 * 14 *
15 * Overview: 15 * Overview:
16 * This is a device driver for the AG-AND flash device found on the 16 * This is a device driver for the AG-AND flash device found on the
17 * Renesas Technology Corp. Flash ROM 4-slot interface board (FROM_BOARD4), 17 * Renesas Technology Corp. Flash ROM 4-slot interface board (FROM_BOARD4),
18 * which utilizes the Renesas HN29V1G91T-30 part. 18 * which utilizes the Renesas HN29V1G91T-30 part.
19 * This chip is a 1 GBibit (128MiB x 8 bits) AG-AND flash device. 19 * This chip is a 1 GBibit (128MiB x 8 bits) AG-AND flash device.
20 */ 20 */
21 21
@@ -105,9 +105,9 @@ const static struct mtd_partition partition_info[] = {
105}; 105};
106#define NUM_PARTITIONS 1 106#define NUM_PARTITIONS 1
107 107
108/* 108/*
109 * hardware specific flash bbt decriptors 109 * hardware specific flash bbt decriptors
110 * Note: this is to allow debugging by disabling 110 * Note: this is to allow debugging by disabling
111 * NAND_BBT_CREATE and/or NAND_BBT_WRITE 111 * NAND_BBT_CREATE and/or NAND_BBT_WRITE
112 * 112 *
113 */ 113 */
@@ -141,7 +141,7 @@ static struct nand_bbt_descr rtc_from4_bbt_mirror_descr = {
141/* the Reed Solomon control structure */ 141/* the Reed Solomon control structure */
142static struct rs_control *rs_decoder; 142static struct rs_control *rs_decoder;
143 143
144/* 144/*
145 * hardware specific Out Of Band information 145 * hardware specific Out Of Band information
146 */ 146 */
147static struct nand_oobinfo rtc_from4_nand_oobinfo = { 147static struct nand_oobinfo rtc_from4_nand_oobinfo = {
@@ -200,38 +200,38 @@ static uint8_t revbits[256] = {
200 200
201 201
202 202
203/* 203/*
204 * rtc_from4_hwcontrol - hardware specific access to control-lines 204 * rtc_from4_hwcontrol - hardware specific access to control-lines
205 * @mtd: MTD device structure 205 * @mtd: MTD device structure
206 * @cmd: hardware control command 206 * @cmd: hardware control command
207 * 207 *
208 * Address lines (A5 and A4) are used to control Command and Address Latch 208 * Address lines (A5 and A4) are used to control Command and Address Latch
209 * Enable on this board, so set the read/write address appropriately. 209 * Enable on this board, so set the read/write address appropriately.
210 * 210 *
211 * Chip Enable is also controlled by the Chip Select (CS5) and 211 * Chip Enable is also controlled by the Chip Select (CS5) and
212 * Address lines (A24-A22), so no action is required here. 212 * Address lines (A24-A22), so no action is required here.
213 * 213 *
214 */ 214 */
215static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd) 215static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd)
216{ 216{
217 struct nand_chip* this = (struct nand_chip *) (mtd->priv); 217 struct nand_chip* this = (struct nand_chip *) (mtd->priv);
218 218
219 switch(cmd) { 219 switch(cmd) {
220 220
221 case NAND_CTL_SETCLE: 221 case NAND_CTL_SETCLE:
222 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_CLE); 222 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_CLE);
223 break; 223 break;
224 case NAND_CTL_CLRCLE: 224 case NAND_CTL_CLRCLE:
225 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_CLE); 225 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_CLE);
226 break; 226 break;
227 227
228 case NAND_CTL_SETALE: 228 case NAND_CTL_SETALE:
229 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_ALE); 229 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_ALE);
230 break; 230 break;
231 case NAND_CTL_CLRALE: 231 case NAND_CTL_CLRALE:
232 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_ALE); 232 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_ALE);
233 break; 233 break;
234 234
235 case NAND_CTL_SETNCE: 235 case NAND_CTL_SETNCE:
236 break; 236 break;
237 case NAND_CTL_CLRNCE: 237 case NAND_CTL_CLRNCE:
@@ -296,7 +296,7 @@ static int rtc_from4_nand_device_ready(struct mtd_info *mtd)
296 * @mtd: MTD device structure 296 * @mtd: MTD device structure
297 * @chip: Chip to select (0 == slot 3, 1 == slot 4) 297 * @chip: Chip to select (0 == slot 3, 1 == slot 4)
298 * 298 *
299 * If there was a sudden loss of power during an erase operation, a 299 * If there was a sudden loss of power during an erase operation, a
300 * "device recovery" operation must be performed when power is restored 300 * "device recovery" operation must be performed when power is restored
301 * to ensure correct operation. This routine performs the required steps 301 * to ensure correct operation. This routine performs the required steps
302 * for the requested chip. 302 * for the requested chip.
@@ -312,7 +312,7 @@ static void deplete(struct mtd_info *mtd, int chip)
312 while (!this->dev_ready(mtd)); 312 while (!this->dev_ready(mtd));
313 313
314 this->select_chip(mtd, chip); 314 this->select_chip(mtd, chip);
315 315
316 /* Send the commands for device recovery, phase 1 */ 316 /* Send the commands for device recovery, phase 1 */
317 this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0000); 317 this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0000);
318 this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1); 318 this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1);
@@ -330,7 +330,7 @@ static void deplete(struct mtd_info *mtd, int chip)
330 * @mtd: MTD device structure 330 * @mtd: MTD device structure
331 * @mode: I/O mode; read or write 331 * @mode: I/O mode; read or write
332 * 332 *
333 * enable hardware ECC for data read or write 333 * enable hardware ECC for data read or write
334 * 334 *
335 */ 335 */
336static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode) 336static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
@@ -340,7 +340,7 @@ static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
340 340
341 switch (mode) { 341 switch (mode) {
342 case NAND_ECC_READ : 342 case NAND_ECC_READ :
343 status = RTC_FROM4_RS_ECC_CTL_CLR 343 status = RTC_FROM4_RS_ECC_CTL_CLR
344 | RTC_FROM4_RS_ECC_CTL_FD_E; 344 | RTC_FROM4_RS_ECC_CTL_FD_E;
345 345
346 *rs_ecc_ctl = status; 346 *rs_ecc_ctl = status;
@@ -353,8 +353,8 @@ static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
353 break; 353 break;
354 354
355 case NAND_ECC_WRITE : 355 case NAND_ECC_WRITE :
356 status = RTC_FROM4_RS_ECC_CTL_CLR 356 status = RTC_FROM4_RS_ECC_CTL_CLR
357 | RTC_FROM4_RS_ECC_CTL_GEN 357 | RTC_FROM4_RS_ECC_CTL_GEN
358 | RTC_FROM4_RS_ECC_CTL_FD_E; 358 | RTC_FROM4_RS_ECC_CTL_FD_E;
359 359
360 *rs_ecc_ctl = status; 360 *rs_ecc_ctl = status;
@@ -411,7 +411,7 @@ static void rtc_from4_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_c
411static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_char *ecc1, u_char *ecc2) 411static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_char *ecc1, u_char *ecc2)
412{ 412{
413 int i, j, res; 413 int i, j, res;
414 unsigned short status; 414 unsigned short status;
415 uint16_t par[6], syn[6]; 415 uint16_t par[6], syn[6];
416 uint8_t ecc[8]; 416 uint8_t ecc[8];
417 volatile unsigned short *rs_ecc; 417 volatile unsigned short *rs_ecc;
@@ -430,7 +430,7 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
430 } 430 }
431 431
432 /* convert into 6 10bit syndrome fields */ 432 /* convert into 6 10bit syndrome fields */
433 par[5] = rs_decoder->index_of[(((uint16_t)ecc[0] >> 0) & 0x0ff) | 433 par[5] = rs_decoder->index_of[(((uint16_t)ecc[0] >> 0) & 0x0ff) |
434 (((uint16_t)ecc[1] << 8) & 0x300)]; 434 (((uint16_t)ecc[1] << 8) & 0x300)];
435 par[4] = rs_decoder->index_of[(((uint16_t)ecc[1] >> 2) & 0x03f) | 435 par[4] = rs_decoder->index_of[(((uint16_t)ecc[1] >> 2) & 0x03f) |
436 (((uint16_t)ecc[2] << 6) & 0x3c0)]; 436 (((uint16_t)ecc[2] << 6) & 0x3c0)];
@@ -456,7 +456,7 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
456 /* Let the library code do its magic.*/ 456 /* Let the library code do its magic.*/
457 res = decode_rs8(rs_decoder, (uint8_t *)buf, par, 512, syn, 0, NULL, 0xff, NULL); 457 res = decode_rs8(rs_decoder, (uint8_t *)buf, par, 512, syn, 0, NULL, 0xff, NULL);
458 if (res > 0) { 458 if (res > 0) {
459 DEBUG (MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: " 459 DEBUG (MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: "
460 "ECC corrected %d errors on read\n", res); 460 "ECC corrected %d errors on read\n", res);
461 } 461 }
462 return res; 462 return res;
@@ -470,9 +470,9 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
470 * @state: state or the operation 470 * @state: state or the operation
471 * @status: status code returned from read status 471 * @status: status code returned from read status
472 * @page: startpage inside the chip, must be called with (page & this->pagemask) 472 * @page: startpage inside the chip, must be called with (page & this->pagemask)
473 * 473 *
474 * Perform additional error status checks on erase and write failures 474 * Perform additional error status checks on erase and write failures
475 * to determine if errors are correctable. For this device, correctable 475 * to determine if errors are correctable. For this device, correctable
476 * 1-bit errors on erase and write are considered acceptable. 476 * 1-bit errors on erase and write are considered acceptable.
477 * 477 *
478 * note: see pages 34..37 of data sheet for details. 478 * note: see pages 34..37 of data sheet for details.
@@ -633,7 +633,7 @@ int __init rtc_from4_init (void)
633 633
634#ifdef RTC_FROM4_HWECC 634#ifdef RTC_FROM4_HWECC
635 /* We could create the decoder on demand, if memory is a concern. 635 /* We could create the decoder on demand, if memory is a concern.
636 * This way we have it handy, if an error happens 636 * This way we have it handy, if an error happens
637 * 637 *
638 * Symbolsize is 10 (bits) 638 * Symbolsize is 10 (bits)
639 * Primitve polynomial is x^10+x^3+1 639 * Primitve polynomial is x^10+x^3+1
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index 2df5e47d1f5c..97e9b7892d29 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -17,8 +17,9 @@
17 * 02-May-2005 BJD Reduced hwcontrol decode 17 * 02-May-2005 BJD Reduced hwcontrol decode
18 * 20-Jun-2005 BJD Updated s3c2440 support, fixed timing bug 18 * 20-Jun-2005 BJD Updated s3c2440 support, fixed timing bug
19 * 08-Jul-2005 BJD Fix OOPS when no platform data supplied 19 * 08-Jul-2005 BJD Fix OOPS when no platform data supplied
20 * 20-Oct-2005 BJD Fix timing calculation bug
20 * 21 *
21 * $Id: s3c2410.c,v 1.14 2005/07/06 20:05:06 bjd Exp $ 22 * $Id: s3c2410.c,v 1.20 2005/11/07 11:14:31 gleixner Exp $
22 * 23 *
23 * This program is free software; you can redistribute it and/or modify 24 * This program is free software; you can redistribute it and/or modify
24 * it under the terms of the GNU General Public License as published by 25 * it under the terms of the GNU General Public License as published by
@@ -136,13 +137,13 @@ static struct s3c2410_platform_nand *to_nand_plat(struct device *dev)
136 137
137/* timing calculations */ 138/* timing calculations */
138 139
139#define NS_IN_KHZ 10000000 140#define NS_IN_KHZ 1000000
140 141
141static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max) 142static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max)
142{ 143{
143 int result; 144 int result;
144 145
145 result = (wanted * NS_IN_KHZ) / clk; 146 result = (wanted * clk) / NS_IN_KHZ;
146 result++; 147 result++;
147 148
148 pr_debug("result %d from %ld, %d\n", result, clk, wanted); 149 pr_debug("result %d from %ld, %d\n", result, clk, wanted);
@@ -159,20 +160,22 @@ static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max)
159 return result; 160 return result;
160} 161}
161 162
162#define to_ns(ticks,clk) (((clk) * (ticks)) / NS_IN_KHZ) 163#define to_ns(ticks,clk) (((ticks) * NS_IN_KHZ) / (unsigned int)(clk))
163 164
164/* controller setup */ 165/* controller setup */
165 166
166static int s3c2410_nand_inithw(struct s3c2410_nand_info *info, 167static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
167 struct device *dev) 168 struct device *dev)
168{ 169{
169 struct s3c2410_platform_nand *plat = to_nand_plat(dev); 170 struct s3c2410_platform_nand *plat = to_nand_plat(dev);
170 unsigned int tacls, twrph0, twrph1;
171 unsigned long clkrate = clk_get_rate(info->clk); 171 unsigned long clkrate = clk_get_rate(info->clk);
172 int tacls, twrph0, twrph1;
172 unsigned long cfg; 173 unsigned long cfg;
173 174
174 /* calculate the timing information for the controller */ 175 /* calculate the timing information for the controller */
175 176
177 clkrate /= 1000; /* turn clock into kHz for ease of use */
178
176 if (plat != NULL) { 179 if (plat != NULL) {
177 tacls = s3c2410_nand_calc_rate(plat->tacls, clkrate, 4); 180 tacls = s3c2410_nand_calc_rate(plat->tacls, clkrate, 4);
178 twrph0 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8); 181 twrph0 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8);
@@ -183,16 +186,16 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
183 twrph0 = 8; 186 twrph0 = 8;
184 twrph1 = 8; 187 twrph1 = 8;
185 } 188 }
186 189
187 if (tacls < 0 || twrph0 < 0 || twrph1 < 0) { 190 if (tacls < 0 || twrph0 < 0 || twrph1 < 0) {
188 printk(KERN_ERR PFX "cannot get timings suitable for board\n"); 191 printk(KERN_ERR PFX "cannot get timings suitable for board\n");
189 return -EINVAL; 192 return -EINVAL;
190 } 193 }
191 194
192 printk(KERN_INFO PFX "timing: Tacls %ldns, Twrph0 %ldns, Twrph1 %ldns\n", 195 printk(KERN_INFO PFX "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n",
193 to_ns(tacls, clkrate), 196 tacls, to_ns(tacls, clkrate),
194 to_ns(twrph0, clkrate), 197 twrph0, to_ns(twrph0, clkrate),
195 to_ns(twrph1, clkrate)); 198 twrph1, to_ns(twrph1, clkrate));
196 199
197 if (!info->is_s3c2440) { 200 if (!info->is_s3c2440) {
198 cfg = S3C2410_NFCONF_EN; 201 cfg = S3C2410_NFCONF_EN;
@@ -216,7 +219,7 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
216static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) 219static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
217{ 220{
218 struct s3c2410_nand_info *info; 221 struct s3c2410_nand_info *info;
219 struct s3c2410_nand_mtd *nmtd; 222 struct s3c2410_nand_mtd *nmtd;
220 struct nand_chip *this = mtd->priv; 223 struct nand_chip *this = mtd->priv;
221 void __iomem *reg; 224 void __iomem *reg;
222 unsigned long cur; 225 unsigned long cur;
@@ -249,7 +252,7 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
249 writel(cur, reg); 252 writel(cur, reg);
250} 253}
251 254
252/* command and control functions 255/* command and control functions
253 * 256 *
254 * Note, these all use tglx's method of changing the IO_ADDR_W field 257 * Note, these all use tglx's method of changing the IO_ADDR_W field
255 * to make the code simpler, and use the nand layer's code to issue the 258 * to make the code simpler, and use the nand layer's code to issue the
@@ -321,7 +324,7 @@ static void s3c2440_nand_hwcontrol(struct mtd_info *mtd, int cmd)
321static int s3c2410_nand_devready(struct mtd_info *mtd) 324static int s3c2410_nand_devready(struct mtd_info *mtd)
322{ 325{
323 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 326 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
324 327
325 if (info->is_s3c2440) 328 if (info->is_s3c2440)
326 return readb(info->regs + S3C2440_NFSTAT) & S3C2440_NFSTAT_READY; 329 return readb(info->regs + S3C2440_NFSTAT) & S3C2440_NFSTAT_READY;
327 return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY; 330 return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY;
@@ -342,7 +345,7 @@ static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat,
342 345
343 if (read_ecc[0] == calc_ecc[0] && 346 if (read_ecc[0] == calc_ecc[0] &&
344 read_ecc[1] == calc_ecc[1] && 347 read_ecc[1] == calc_ecc[1] &&
345 read_ecc[2] == calc_ecc[2]) 348 read_ecc[2] == calc_ecc[2])
346 return 0; 349 return 0;
347 350
348 /* we curently have no method for correcting the error */ 351 /* we curently have no method for correcting the error */
@@ -433,14 +436,14 @@ static int s3c2410_nand_remove(struct device *dev)
433 436
434 dev_set_drvdata(dev, NULL); 437 dev_set_drvdata(dev, NULL);
435 438
436 if (info == NULL) 439 if (info == NULL)
437 return 0; 440 return 0;
438 441
439 /* first thing we need to do is release all our mtds 442 /* first thing we need to do is release all our mtds
440 * and their partitions, then go through freeing the 443 * and their partitions, then go through freeing the
441 * resources used 444 * resources used
442 */ 445 */
443 446
444 if (info->mtds != NULL) { 447 if (info->mtds != NULL) {
445 struct s3c2410_nand_mtd *ptr = info->mtds; 448 struct s3c2410_nand_mtd *ptr = info->mtds;
446 int mtdno; 449 int mtdno;
@@ -504,7 +507,7 @@ static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info,
504 507
505/* s3c2410_nand_init_chip 508/* s3c2410_nand_init_chip
506 * 509 *
507 * init a single instance of an chip 510 * init a single instance of an chip
508*/ 511*/
509 512
510static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, 513static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
@@ -576,7 +579,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
576 579
577 info = kmalloc(sizeof(*info), GFP_KERNEL); 580 info = kmalloc(sizeof(*info), GFP_KERNEL);
578 if (info == NULL) { 581 if (info == NULL) {
579 printk(KERN_ERR PFX "no memory for flash info\n"); 582 dev_err(dev, "no memory for flash info\n");
580 err = -ENOMEM; 583 err = -ENOMEM;
581 goto exit_error; 584 goto exit_error;
582 } 585 }
@@ -591,7 +594,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
591 594
592 info->clk = clk_get(dev, "nand"); 595 info->clk = clk_get(dev, "nand");
593 if (IS_ERR(info->clk)) { 596 if (IS_ERR(info->clk)) {
594 printk(KERN_ERR PFX "failed to get clock"); 597 dev_err(dev, "failed to get clock");
595 err = -ENOENT; 598 err = -ENOENT;
596 goto exit_error; 599 goto exit_error;
597 } 600 }
@@ -608,7 +611,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
608 info->area = request_mem_region(res->start, size, pdev->name); 611 info->area = request_mem_region(res->start, size, pdev->name);
609 612
610 if (info->area == NULL) { 613 if (info->area == NULL) {
611 printk(KERN_ERR PFX "cannot reserve register region\n"); 614 dev_err(dev, "cannot reserve register region\n");
612 err = -ENOENT; 615 err = -ENOENT;
613 goto exit_error; 616 goto exit_error;
614 } 617 }
@@ -619,12 +622,12 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
619 info->is_s3c2440 = is_s3c2440; 622 info->is_s3c2440 = is_s3c2440;
620 623
621 if (info->regs == NULL) { 624 if (info->regs == NULL) {
622 printk(KERN_ERR PFX "cannot reserve register region\n"); 625 dev_err(dev, "cannot reserve register region\n");
623 err = -EIO; 626 err = -EIO;
624 goto exit_error; 627 goto exit_error;
625 } 628 }
626 629
627 printk(KERN_INFO PFX "mapped registers at %p\n", info->regs); 630 dev_dbg(dev, "mapped registers at %p\n", info->regs);
628 631
629 /* initialise the hardware */ 632 /* initialise the hardware */
630 633
@@ -642,7 +645,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
642 size = nr_sets * sizeof(*info->mtds); 645 size = nr_sets * sizeof(*info->mtds);
643 info->mtds = kmalloc(size, GFP_KERNEL); 646 info->mtds = kmalloc(size, GFP_KERNEL);
644 if (info->mtds == NULL) { 647 if (info->mtds == NULL) {
645 printk(KERN_ERR PFX "failed to allocate mtd storage\n"); 648 dev_err(dev, "failed to allocate mtd storage\n");
646 err = -ENOMEM; 649 err = -ENOMEM;
647 goto exit_error; 650 goto exit_error;
648 } 651 }
@@ -656,7 +659,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
656 for (setno = 0; setno < nr_sets; setno++, nmtd++) { 659 for (setno = 0; setno < nr_sets; setno++, nmtd++) {
657 pr_debug("initialising set %d (%p, info %p)\n", 660 pr_debug("initialising set %d (%p, info %p)\n",
658 setno, nmtd, info); 661 setno, nmtd, info);
659 662
660 s3c2410_nand_init_chip(info, nmtd, sets); 663 s3c2410_nand_init_chip(info, nmtd, sets);
661 664
662 nmtd->scan_res = nand_scan(&nmtd->mtd, 665 nmtd->scan_res = nand_scan(&nmtd->mtd,
@@ -669,7 +672,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
669 if (sets != NULL) 672 if (sets != NULL)
670 sets++; 673 sets++;
671 } 674 }
672 675
673 pr_debug("initialised ok\n"); 676 pr_debug("initialised ok\n");
674 return 0; 677 return 0;
675 678
@@ -695,6 +698,7 @@ static int s3c2440_nand_probe(struct device *dev)
695 698
696static struct device_driver s3c2410_nand_driver = { 699static struct device_driver s3c2410_nand_driver = {
697 .name = "s3c2410-nand", 700 .name = "s3c2410-nand",
701 .owner = THIS_MODULE,
698 .bus = &platform_bus_type, 702 .bus = &platform_bus_type,
699 .probe = s3c2410_nand_probe, 703 .probe = s3c2410_nand_probe,
700 .remove = s3c2410_nand_remove, 704 .remove = s3c2410_nand_remove,
@@ -702,6 +706,7 @@ static struct device_driver s3c2410_nand_driver = {
702 706
703static struct device_driver s3c2440_nand_driver = { 707static struct device_driver s3c2440_nand_driver = {
704 .name = "s3c2440-nand", 708 .name = "s3c2440-nand",
709 .owner = THIS_MODULE,
705 .bus = &platform_bus_type, 710 .bus = &platform_bus_type,
706 .probe = s3c2440_nand_probe, 711 .probe = s3c2440_nand_probe,
707 .remove = s3c2410_nand_remove, 712 .remove = s3c2410_nand_remove,
diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c
index 88b5b5b40b43..1924a4f137c7 100644
--- a/drivers/mtd/nand/sharpsl.c
+++ b/drivers/mtd/nand/sharpsl.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2004 Richard Purdie 4 * Copyright (C) 2004 Richard Purdie
5 * 5 *
6 * $Id: sharpsl.c,v 1.4 2005/01/23 11:09:19 rpurdie Exp $ 6 * $Id: sharpsl.c,v 1.7 2005/11/07 11:14:31 gleixner Exp $
7 * 7 *
8 * Based on Sharp's NAND driver sharp_sl.c 8 * Based on Sharp's NAND driver sharp_sl.c
9 * 9 *
@@ -76,14 +76,14 @@ static struct mtd_partition sharpsl_nand_default_partition_info[] = {
76 }, 76 },
77}; 77};
78 78
79/* 79/*
80 * hardware specific access to control-lines 80 * hardware specific access to control-lines
81 */ 81 */
82static void 82static void
83sharpsl_nand_hwcontrol(struct mtd_info* mtd, int cmd) 83sharpsl_nand_hwcontrol(struct mtd_info* mtd, int cmd)
84{ 84{
85 switch (cmd) { 85 switch (cmd) {
86 case NAND_CTL_SETCLE: 86 case NAND_CTL_SETCLE:
87 writeb(readb(FLASHCTL) | FLCLE, FLASHCTL); 87 writeb(readb(FLASHCTL) | FLCLE, FLASHCTL);
88 break; 88 break;
89 case NAND_CTL_CLRCLE: 89 case NAND_CTL_CLRCLE:
@@ -97,10 +97,10 @@ sharpsl_nand_hwcontrol(struct mtd_info* mtd, int cmd)
97 writeb(readb(FLASHCTL) & ~FLALE, FLASHCTL); 97 writeb(readb(FLASHCTL) & ~FLALE, FLASHCTL);
98 break; 98 break;
99 99
100 case NAND_CTL_SETNCE: 100 case NAND_CTL_SETNCE:
101 writeb(readb(FLASHCTL) & ~(FLCE0|FLCE1), FLASHCTL); 101 writeb(readb(FLASHCTL) & ~(FLCE0|FLCE1), FLASHCTL);
102 break; 102 break;
103 case NAND_CTL_CLRNCE: 103 case NAND_CTL_CLRNCE:
104 writeb(readb(FLASHCTL) | (FLCE0|FLCE1), FLASHCTL); 104 writeb(readb(FLASHCTL) | (FLCE0|FLCE1), FLASHCTL);
105 break; 105 break;
106 } 106 }
@@ -115,6 +115,23 @@ static struct nand_bbt_descr sharpsl_bbt = {
115 .pattern = scan_ff_pattern 115 .pattern = scan_ff_pattern
116}; 116};
117 117
118static struct nand_bbt_descr sharpsl_akita_bbt = {
119 .options = 0,
120 .offs = 4,
121 .len = 1,
122 .pattern = scan_ff_pattern
123};
124
125static struct nand_oobinfo akita_oobinfo = {
126 .useecc = MTD_NANDECC_AUTOPLACE,
127 .eccbytes = 24,
128 .eccpos = {
129 0x5, 0x1, 0x2, 0x3, 0x6, 0x7, 0x15, 0x11,
130 0x12, 0x13, 0x16, 0x17, 0x25, 0x21, 0x22, 0x23,
131 0x26, 0x27, 0x35, 0x31, 0x32, 0x33, 0x36, 0x37},
132 .oobfree = { {0x08, 0x09} }
133};
134
118static int 135static int
119sharpsl_nand_dev_ready(struct mtd_info* mtd) 136sharpsl_nand_dev_ready(struct mtd_info* mtd)
120{ 137{
@@ -160,7 +177,7 @@ sharpsl_nand_init(void)
160 printk ("Unable to allocate SharpSL NAND MTD device structure.\n"); 177 printk ("Unable to allocate SharpSL NAND MTD device structure.\n");
161 return -ENOMEM; 178 return -ENOMEM;
162 } 179 }
163 180
164 /* map physical adress */ 181 /* map physical adress */
165 sharpsl_io_base = ioremap(sharpsl_phys_base, 0x1000); 182 sharpsl_io_base = ioremap(sharpsl_phys_base, 0x1000);
166 if(!sharpsl_io_base){ 183 if(!sharpsl_io_base){
@@ -168,7 +185,7 @@ sharpsl_nand_init(void)
168 kfree(sharpsl_mtd); 185 kfree(sharpsl_mtd);
169 return -EIO; 186 return -EIO;
170 } 187 }
171 188
172 /* Get pointer to private data */ 189 /* Get pointer to private data */
173 this = (struct nand_chip *) (&sharpsl_mtd[1]); 190 this = (struct nand_chip *) (&sharpsl_mtd[1]);
174 191
@@ -194,10 +211,14 @@ sharpsl_nand_init(void)
194 this->chip_delay = 15; 211 this->chip_delay = 15;
195 /* set eccmode using hardware ECC */ 212 /* set eccmode using hardware ECC */
196 this->eccmode = NAND_ECC_HW3_256; 213 this->eccmode = NAND_ECC_HW3_256;
214 this->badblock_pattern = &sharpsl_bbt;
215 if (machine_is_akita() || machine_is_borzoi()) {
216 this->badblock_pattern = &sharpsl_akita_bbt;
217 this->autooob = &akita_oobinfo;
218 }
197 this->enable_hwecc = sharpsl_nand_enable_hwecc; 219 this->enable_hwecc = sharpsl_nand_enable_hwecc;
198 this->calculate_ecc = sharpsl_nand_calculate_ecc; 220 this->calculate_ecc = sharpsl_nand_calculate_ecc;
199 this->correct_data = nand_correct_data; 221 this->correct_data = nand_correct_data;
200 this->badblock_pattern = &sharpsl_bbt;
201 222
202 /* Scan to find existence of the device */ 223 /* Scan to find existence of the device */
203 err=nand_scan(sharpsl_mtd,1); 224 err=nand_scan(sharpsl_mtd,1);
@@ -211,7 +232,7 @@ sharpsl_nand_init(void)
211 sharpsl_mtd->name = "sharpsl-nand"; 232 sharpsl_mtd->name = "sharpsl-nand";
212 nr_partitions = parse_mtd_partitions(sharpsl_mtd, part_probes, 233 nr_partitions = parse_mtd_partitions(sharpsl_mtd, part_probes,
213 &sharpsl_partition_info, 0); 234 &sharpsl_partition_info, 0);
214 235
215 if (nr_partitions <= 0) { 236 if (nr_partitions <= 0) {
216 nr_partitions = DEFAULT_NUM_PARTITIONS; 237 nr_partitions = DEFAULT_NUM_PARTITIONS;
217 sharpsl_partition_info = sharpsl_nand_default_partition_info; 238 sharpsl_partition_info = sharpsl_nand_default_partition_info;
@@ -230,7 +251,7 @@ sharpsl_nand_init(void)
230 } 251 }
231 } 252 }
232 253
233 if (machine_is_husky() || machine_is_borzoi()) { 254 if (machine_is_husky() || machine_is_borzoi() || machine_is_akita()) {
234 /* Need to use small eraseblock size for backward compatibility */ 255 /* Need to use small eraseblock size for backward compatibility */
235 sharpsl_mtd->flags |= MTD_NO_VIRTBLOCKS; 256 sharpsl_mtd->flags |= MTD_NO_VIRTBLOCKS;
236 } 257 }
diff --git a/drivers/mtd/nand/spia.c b/drivers/mtd/nand/spia.c
index b777c412b758..32541cbb0103 100644
--- a/drivers/mtd/nand/spia.c
+++ b/drivers/mtd/nand/spia.c
@@ -8,7 +8,7 @@
8 * to controllines (due to change in nand.c) 8 * to controllines (due to change in nand.c)
9 * page_cache added 9 * page_cache added
10 * 10 *
11 * $Id: spia.c,v 1.24 2004/11/04 12:53:10 gleixner Exp $ 11 * $Id: spia.c,v 1.25 2005/11/07 11:14:31 gleixner Exp $
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as 14 * it under the terms of the GNU General Public License version 2 as
@@ -82,7 +82,7 @@ const static struct mtd_partition partition_info[] = {
82#define NUM_PARTITIONS 2 82#define NUM_PARTITIONS 2
83 83
84 84
85/* 85/*
86 * hardware specific access to control-lines 86 * hardware specific access to control-lines
87*/ 87*/
88static void spia_hwcontrol(struct mtd_info *mtd, int cmd){ 88static void spia_hwcontrol(struct mtd_info *mtd, int cmd){
@@ -137,7 +137,7 @@ int __init spia_init (void)
137 /* Set address of hardware control function */ 137 /* Set address of hardware control function */
138 this->hwcontrol = spia_hwcontrol; 138 this->hwcontrol = spia_hwcontrol;
139 /* 15 us command delay time */ 139 /* 15 us command delay time */
140 this->chip_delay = 15; 140 this->chip_delay = 15;
141 141
142 /* Scan to find existence of the device */ 142 /* Scan to find existence of the device */
143 if (nand_scan (spia_mtd, 1)) { 143 if (nand_scan (spia_mtd, 1)) {
diff --git a/drivers/mtd/nand/toto.c b/drivers/mtd/nand/toto.c
index 52c808fb5fa9..7609c43cb3ec 100644
--- a/drivers/mtd/nand/toto.c
+++ b/drivers/mtd/nand/toto.c
@@ -15,7 +15,7 @@
15 * This is a device driver for the NAND flash device found on the 15 * This is a device driver for the NAND flash device found on the
16 * TI fido board. It supports 32MiB and 64MiB cards 16 * TI fido board. It supports 32MiB and 64MiB cards
17 * 17 *
18 * $Id: toto.c,v 1.4 2004/10/05 13:50:20 gleixner Exp $ 18 * $Id: toto.c,v 1.5 2005/11/07 11:14:31 gleixner Exp $
19 */ 19 */
20 20
21#include <linux/slab.h> 21#include <linux/slab.h>
@@ -57,7 +57,7 @@ static unsigned long toto_io_base = OMAP_FLASH_1_BASE;
57#endif 57#endif
58#define T_NAND_CTL_SETNCE(iob) gpiosetout(NAND_NCE, 0) 58#define T_NAND_CTL_SETNCE(iob) gpiosetout(NAND_NCE, 0)
59#define T_NAND_CTL_CLRNCE(iob) gpiosetout(NAND_NCE, NAND_NCE) 59#define T_NAND_CTL_CLRNCE(iob) gpiosetout(NAND_NCE, NAND_NCE)
60 60
61/* 61/*
62 * Define partitions for flash devices 62 * Define partitions for flash devices
63 */ 63 */
@@ -91,7 +91,7 @@ static struct mtd_partition partition_info32M[] = {
91 91
92#define NUM_PARTITIONS32M 3 92#define NUM_PARTITIONS32M 3
93#define NUM_PARTITIONS64M 4 93#define NUM_PARTITIONS64M 4
94/* 94/*
95 * hardware specific access to control-lines 95 * hardware specific access to control-lines
96*/ 96*/
97 97
@@ -146,7 +146,7 @@ int __init toto_init (void)
146 this->hwcontrol = toto_hwcontrol; 146 this->hwcontrol = toto_hwcontrol;
147 this->dev_ready = NULL; 147 this->dev_ready = NULL;
148 /* 25 us command delay time */ 148 /* 25 us command delay time */
149 this->chip_delay = 30; 149 this->chip_delay = 30;
150 this->eccmode = NAND_ECC_SOFT; 150 this->eccmode = NAND_ECC_SOFT;
151 151
152 /* Scan to find existance of the device */ 152 /* Scan to find existance of the device */
@@ -157,10 +157,10 @@ int __init toto_init (void)
157 157
158 /* Register the partitions */ 158 /* Register the partitions */
159 switch(toto_mtd->size){ 159 switch(toto_mtd->size){
160 case SZ_64M: add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M); break; 160 case SZ_64M: add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M); break;
161 case SZ_32M: add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M); break; 161 case SZ_32M: add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M); break;
162 default: { 162 default: {
163 printk (KERN_WARNING "Unsupported Nand device\n"); 163 printk (KERN_WARNING "Unsupported Nand device\n");
164 err = -ENXIO; 164 err = -ENXIO;
165 goto out_buf; 165 goto out_buf;
166 } 166 }
@@ -170,9 +170,9 @@ int __init toto_init (void)
170 archflashwp(0,0); /* open up flash for writing */ 170 archflashwp(0,0); /* open up flash for writing */
171 171
172 goto out; 172 goto out;
173 173
174out_buf: 174out_buf:
175 kfree (this->data_buf); 175 kfree (this->data_buf);
176out_mtd: 176out_mtd:
177 kfree (toto_mtd); 177 kfree (toto_mtd);
178out: 178out:
@@ -194,7 +194,7 @@ static void __exit toto_cleanup (void)
194 194
195 /* stop flash writes */ 195 /* stop flash writes */
196 archflashwp(0,1); 196 archflashwp(0,1);
197 197
198 /* release gpios to system */ 198 /* release gpios to system */
199 gpiorelease(NAND_MASK); 199 gpiorelease(NAND_MASK);
200} 200}
diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
index 062ff3877536..d7cd5fa16ba4 100644
--- a/drivers/mtd/nftlcore.c
+++ b/drivers/mtd/nftlcore.c
@@ -1,7 +1,7 @@
1/* Linux driver for NAND Flash Translation Layer */ 1/* Linux driver for NAND Flash Translation Layer */
2/* (c) 1999 Machine Vision Holdings, Inc. */ 2/* (c) 1999 Machine Vision Holdings, Inc. */
3/* Author: David Woodhouse <dwmw2@infradead.org> */ 3/* Author: David Woodhouse <dwmw2@infradead.org> */
4/* $Id: nftlcore.c,v 1.97 2004/11/16 18:28:59 dwmw2 Exp $ */ 4/* $Id: nftlcore.c,v 1.98 2005/11/07 11:14:21 gleixner Exp $ */
5 5
6/* 6/*
7 The contents of this file are distributed under the GNU General 7 The contents of this file are distributed under the GNU General
@@ -101,14 +101,14 @@ static void nftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
101 101
102 if (nftl->mbd.size != nftl->heads * nftl->cylinders * nftl->sectors) { 102 if (nftl->mbd.size != nftl->heads * nftl->cylinders * nftl->sectors) {
103 /* 103 /*
104 Oh no we don't have 104 Oh no we don't have
105 mbd.size == heads * cylinders * sectors 105 mbd.size == heads * cylinders * sectors
106 */ 106 */
107 printk(KERN_WARNING "NFTL: cannot calculate a geometry to " 107 printk(KERN_WARNING "NFTL: cannot calculate a geometry to "
108 "match size of 0x%lx.\n", nftl->mbd.size); 108 "match size of 0x%lx.\n", nftl->mbd.size);
109 printk(KERN_WARNING "NFTL: using C:%d H:%d S:%d " 109 printk(KERN_WARNING "NFTL: using C:%d H:%d S:%d "
110 "(== 0x%lx sects)\n", 110 "(== 0x%lx sects)\n",
111 nftl->cylinders, nftl->heads , nftl->sectors, 111 nftl->cylinders, nftl->heads , nftl->sectors,
112 (long)nftl->cylinders * (long)nftl->heads * 112 (long)nftl->cylinders * (long)nftl->heads *
113 (long)nftl->sectors ); 113 (long)nftl->sectors );
114 } 114 }
@@ -174,7 +174,7 @@ static u16 NFTL_findfreeblock(struct NFTLrecord *nftl, int desperate )
174 174
175 if (!silly--) { 175 if (!silly--) {
176 printk("Argh! No free blocks found! LastFreeEUN = %d, " 176 printk("Argh! No free blocks found! LastFreeEUN = %d, "
177 "FirstEUN = %d\n", nftl->LastFreeEUN, 177 "FirstEUN = %d\n", nftl->LastFreeEUN,
178 le16_to_cpu(nftl->MediaHdr.FirstPhysicalEUN)); 178 le16_to_cpu(nftl->MediaHdr.FirstPhysicalEUN));
179 return 0xffff; 179 return 0xffff;
180 } 180 }
@@ -206,7 +206,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
206 "Virtual Unit Chain %d!\n", thisVUC); 206 "Virtual Unit Chain %d!\n", thisVUC);
207 return BLOCK_NIL; 207 return BLOCK_NIL;
208 } 208 }
209 209
210 /* Scan to find the Erase Unit which holds the actual data for each 210 /* Scan to find the Erase Unit which holds the actual data for each
211 512-byte block within the Chain. 211 512-byte block within the Chain.
212 */ 212 */
@@ -223,7 +223,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
223 if (block == 2) { 223 if (block == 2) {
224 foldmark = oob.u.c.FoldMark | oob.u.c.FoldMark1; 224 foldmark = oob.u.c.FoldMark | oob.u.c.FoldMark1;
225 if (foldmark == FOLD_MARK_IN_PROGRESS) { 225 if (foldmark == FOLD_MARK_IN_PROGRESS) {
226 DEBUG(MTD_DEBUG_LEVEL1, 226 DEBUG(MTD_DEBUG_LEVEL1,
227 "Write Inhibited on EUN %d\n", thisEUN); 227 "Write Inhibited on EUN %d\n", thisEUN);
228 inplace = 0; 228 inplace = 0;
229 } else { 229 } else {
@@ -245,7 +245,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
245 if (!BlockFreeFound[block]) 245 if (!BlockFreeFound[block])
246 BlockMap[block] = thisEUN; 246 BlockMap[block] = thisEUN;
247 else 247 else
248 printk(KERN_WARNING 248 printk(KERN_WARNING
249 "SECTOR_USED found after SECTOR_FREE " 249 "SECTOR_USED found after SECTOR_FREE "
250 "in Virtual Unit Chain %d for block %d\n", 250 "in Virtual Unit Chain %d for block %d\n",
251 thisVUC, block); 251 thisVUC, block);
@@ -254,7 +254,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
254 if (!BlockFreeFound[block]) 254 if (!BlockFreeFound[block])
255 BlockMap[block] = BLOCK_NIL; 255 BlockMap[block] = BLOCK_NIL;
256 else 256 else
257 printk(KERN_WARNING 257 printk(KERN_WARNING
258 "SECTOR_DELETED found after SECTOR_FREE " 258 "SECTOR_DELETED found after SECTOR_FREE "
259 "in Virtual Unit Chain %d for block %d\n", 259 "in Virtual Unit Chain %d for block %d\n",
260 thisVUC, block); 260 thisVUC, block);
@@ -273,14 +273,14 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
273 thisVUC); 273 thisVUC);
274 return BLOCK_NIL; 274 return BLOCK_NIL;
275 } 275 }
276 276
277 thisEUN = nftl->ReplUnitTable[thisEUN]; 277 thisEUN = nftl->ReplUnitTable[thisEUN];
278 } 278 }
279 279
280 if (inplace) { 280 if (inplace) {
281 /* We're being asked to be a fold-in-place. Check 281 /* We're being asked to be a fold-in-place. Check
282 that all blocks which actually have data associated 282 that all blocks which actually have data associated
283 with them (i.e. BlockMap[block] != BLOCK_NIL) are 283 with them (i.e. BlockMap[block] != BLOCK_NIL) are
284 either already present or SECTOR_FREE in the target 284 either already present or SECTOR_FREE in the target
285 block. If not, we're going to have to fold out-of-place 285 block. If not, we're going to have to fold out-of-place
286 anyway. 286 anyway.
@@ -293,7 +293,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
293 "block %d was %x lastEUN, " 293 "block %d was %x lastEUN, "
294 "and is in EUN %d (%s) %d\n", 294 "and is in EUN %d (%s) %d\n",
295 thisVUC, block, BlockLastState[block], 295 thisVUC, block, BlockLastState[block],
296 BlockMap[block], 296 BlockMap[block],
297 BlockMap[block]== targetEUN ? "==" : "!=", 297 BlockMap[block]== targetEUN ? "==" : "!=",
298 targetEUN); 298 targetEUN);
299 inplace = 0; 299 inplace = 0;
@@ -310,17 +310,17 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
310 inplace = 0; 310 inplace = 0;
311 } 311 }
312 } 312 }
313 313
314 if (!inplace) { 314 if (!inplace) {
315 DEBUG(MTD_DEBUG_LEVEL1, "Cannot fold Virtual Unit Chain %d in place. " 315 DEBUG(MTD_DEBUG_LEVEL1, "Cannot fold Virtual Unit Chain %d in place. "
316 "Trying out-of-place\n", thisVUC); 316 "Trying out-of-place\n", thisVUC);
317 /* We need to find a targetEUN to fold into. */ 317 /* We need to find a targetEUN to fold into. */
318 targetEUN = NFTL_findfreeblock(nftl, 1); 318 targetEUN = NFTL_findfreeblock(nftl, 1);
319 if (targetEUN == BLOCK_NIL) { 319 if (targetEUN == BLOCK_NIL) {
320 /* Ouch. Now we're screwed. We need to do a 320 /* Ouch. Now we're screwed. We need to do a
321 fold-in-place of another chain to make room 321 fold-in-place of another chain to make room
322 for this one. We need a better way of selecting 322 for this one. We need a better way of selecting
323 which chain to fold, because makefreeblock will 323 which chain to fold, because makefreeblock will
324 only ask us to fold the same one again. 324 only ask us to fold the same one again.
325 */ 325 */
326 printk(KERN_WARNING 326 printk(KERN_WARNING
@@ -334,7 +334,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
334 chain by selecting the longer one */ 334 chain by selecting the longer one */
335 oob.u.c.FoldMark = oob.u.c.FoldMark1 = cpu_to_le16(FOLD_MARK_IN_PROGRESS); 335 oob.u.c.FoldMark = oob.u.c.FoldMark1 = cpu_to_le16(FOLD_MARK_IN_PROGRESS);
336 oob.u.c.unused = 0xffffffff; 336 oob.u.c.unused = 0xffffffff;
337 MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 2 * 512 + 8, 337 MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 2 * 512 + 8,
338 8, &retlen, (char *)&oob.u); 338 8, &retlen, (char *)&oob.u);
339 } 339 }
340 340
@@ -357,14 +357,14 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
357 happen in case of media errors or deleted blocks) */ 357 happen in case of media errors or deleted blocks) */
358 if (BlockMap[block] == BLOCK_NIL) 358 if (BlockMap[block] == BLOCK_NIL)
359 continue; 359 continue;
360 360
361 ret = MTD_READ(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block]) + (block * 512), 361 ret = MTD_READ(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block]) + (block * 512),
362 512, &retlen, movebuf); 362 512, &retlen, movebuf);
363 if (ret < 0) { 363 if (ret < 0) {
364 ret = MTD_READ(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block]) 364 ret = MTD_READ(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block])
365 + (block * 512), 512, &retlen, 365 + (block * 512), 512, &retlen,
366 movebuf); 366 movebuf);
367 if (ret != -EIO) 367 if (ret != -EIO)
368 printk("Error went away on retry.\n"); 368 printk("Error went away on retry.\n");
369 } 369 }
370 memset(&oob, 0xff, sizeof(struct nftl_oob)); 370 memset(&oob, 0xff, sizeof(struct nftl_oob));
@@ -372,18 +372,18 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
372 MTD_WRITEECC(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + (block * 512), 372 MTD_WRITEECC(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + (block * 512),
373 512, &retlen, movebuf, (char *)&oob, &nftl->oobinfo); 373 512, &retlen, movebuf, (char *)&oob, &nftl->oobinfo);
374 } 374 }
375 375
376 /* add the header so that it is now a valid chain */ 376 /* add the header so that it is now a valid chain */
377 oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum 377 oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum
378 = cpu_to_le16(thisVUC); 378 = cpu_to_le16(thisVUC);
379 oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum = 0xffff; 379 oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum = 0xffff;
380 380
381 MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 8, 381 MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 8,
382 8, &retlen, (char *)&oob.u); 382 8, &retlen, (char *)&oob.u);
383 383
384 /* OK. We've moved the whole lot into the new block. Now we have to free the original blocks. */ 384 /* OK. We've moved the whole lot into the new block. Now we have to free the original blocks. */
385 385
386 /* At this point, we have two different chains for this Virtual Unit, and no way to tell 386 /* At this point, we have two different chains for this Virtual Unit, and no way to tell
387 them apart. If we crash now, we get confused. However, both contain the same data, so we 387 them apart. If we crash now, we get confused. However, both contain the same data, so we
388 shouldn't actually lose data in this case. It's just that when we load up on a medium which 388 shouldn't actually lose data in this case. It's just that when we load up on a medium which
389 has duplicate chains, we need to free one of the chains because it's not necessary any more. 389 has duplicate chains, we need to free one of the chains because it's not necessary any more.
@@ -391,7 +391,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
391 thisEUN = nftl->EUNtable[thisVUC]; 391 thisEUN = nftl->EUNtable[thisVUC];
392 DEBUG(MTD_DEBUG_LEVEL1,"Want to erase\n"); 392 DEBUG(MTD_DEBUG_LEVEL1,"Want to erase\n");
393 393
394 /* For each block in the old chain (except the targetEUN of course), 394 /* For each block in the old chain (except the targetEUN of course),
395 free it and make it available for future use */ 395 free it and make it available for future use */
396 while (thisEUN <= nftl->lastEUN && thisEUN != targetEUN) { 396 while (thisEUN <= nftl->lastEUN && thisEUN != targetEUN) {
397 unsigned int EUNtmp; 397 unsigned int EUNtmp;
@@ -409,7 +409,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
409 } 409 }
410 thisEUN = EUNtmp; 410 thisEUN = EUNtmp;
411 } 411 }
412 412
413 /* Make this the new start of chain for thisVUC */ 413 /* Make this the new start of chain for thisVUC */
414 nftl->ReplUnitTable[targetEUN] = BLOCK_NIL; 414 nftl->ReplUnitTable[targetEUN] = BLOCK_NIL;
415 nftl->EUNtable[thisVUC] = targetEUN; 415 nftl->EUNtable[thisVUC] = targetEUN;
@@ -419,7 +419,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
419 419
420static u16 NFTL_makefreeblock( struct NFTLrecord *nftl , unsigned pendingblock) 420static u16 NFTL_makefreeblock( struct NFTLrecord *nftl , unsigned pendingblock)
421{ 421{
422 /* This is the part that needs some cleverness applied. 422 /* This is the part that needs some cleverness applied.
423 For now, I'm doing the minimum applicable to actually 423 For now, I'm doing the minimum applicable to actually
424 get the thing to work. 424 get the thing to work.
425 Wear-levelling and other clever stuff needs to be implemented 425 Wear-levelling and other clever stuff needs to be implemented
@@ -466,7 +466,7 @@ static u16 NFTL_makefreeblock( struct NFTLrecord *nftl , unsigned pendingblock)
466 return NFTL_foldchain (nftl, LongestChain, pendingblock); 466 return NFTL_foldchain (nftl, LongestChain, pendingblock);
467} 467}
468 468
469/* NFTL_findwriteunit: Return the unit number into which we can write 469/* NFTL_findwriteunit: Return the unit number into which we can write
470 for this block. Make it available if it isn't already 470 for this block. Make it available if it isn't already
471*/ 471*/
472static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block) 472static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
@@ -484,7 +484,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
484 a free space for the block in question. 484 a free space for the block in question.
485 */ 485 */
486 486
487 /* This condition catches the 0x[7f]fff cases, as well as 487 /* This condition catches the 0x[7f]fff cases, as well as
488 being a sanity check for past-end-of-media access 488 being a sanity check for past-end-of-media access
489 */ 489 */
490 lastEUN = BLOCK_NIL; 490 lastEUN = BLOCK_NIL;
@@ -499,7 +499,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
499 499
500 MTD_READOOB(nftl->mbd.mtd, (writeEUN * nftl->EraseSize) + blockofs, 500 MTD_READOOB(nftl->mbd.mtd, (writeEUN * nftl->EraseSize) + blockofs,
501 8, &retlen, (char *)&bci); 501 8, &retlen, (char *)&bci);
502 502
503 DEBUG(MTD_DEBUG_LEVEL2, "Status of block %d in EUN %d is %x\n", 503 DEBUG(MTD_DEBUG_LEVEL2, "Status of block %d in EUN %d is %x\n",
504 block , writeEUN, le16_to_cpu(bci.Status)); 504 block , writeEUN, le16_to_cpu(bci.Status));
505 505
@@ -514,10 +514,10 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
514 break; 514 break;
515 default: 515 default:
516 // Invalid block. Don't use it any more. Must implement. 516 // Invalid block. Don't use it any more. Must implement.
517 break; 517 break;
518 } 518 }
519 519
520 if (!silly--) { 520 if (!silly--) {
521 printk(KERN_WARNING 521 printk(KERN_WARNING
522 "Infinite loop in Virtual Unit Chain 0x%x\n", 522 "Infinite loop in Virtual Unit Chain 0x%x\n",
523 thisVUC); 523 thisVUC);
@@ -528,7 +528,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
528 writeEUN = nftl->ReplUnitTable[writeEUN]; 528 writeEUN = nftl->ReplUnitTable[writeEUN];
529 } 529 }
530 530
531 /* OK. We didn't find one in the existing chain, or there 531 /* OK. We didn't find one in the existing chain, or there
532 is no existing chain. */ 532 is no existing chain. */
533 533
534 /* Try to find an already-free block */ 534 /* Try to find an already-free block */
@@ -542,12 +542,12 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
542 542
543 /* First remember the start of this chain */ 543 /* First remember the start of this chain */
544 //u16 startEUN = nftl->EUNtable[thisVUC]; 544 //u16 startEUN = nftl->EUNtable[thisVUC];
545 545
546 //printk("Write to VirtualUnitChain %d, calling makefreeblock()\n", thisVUC); 546 //printk("Write to VirtualUnitChain %d, calling makefreeblock()\n", thisVUC);
547 writeEUN = NFTL_makefreeblock(nftl, 0xffff); 547 writeEUN = NFTL_makefreeblock(nftl, 0xffff);
548 548
549 if (writeEUN == BLOCK_NIL) { 549 if (writeEUN == BLOCK_NIL) {
550 /* OK, we accept that the above comment is 550 /* OK, we accept that the above comment is
551 lying - there may have been free blocks 551 lying - there may have been free blocks
552 last time we called NFTL_findfreeblock(), 552 last time we called NFTL_findfreeblock(),
553 but they are reserved for when we're 553 but they are reserved for when we're
@@ -558,21 +558,21 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
558 } 558 }
559 if (writeEUN == BLOCK_NIL) { 559 if (writeEUN == BLOCK_NIL) {
560 /* Ouch. This should never happen - we should 560 /* Ouch. This should never happen - we should
561 always be able to make some room somehow. 561 always be able to make some room somehow.
562 If we get here, we've allocated more storage 562 If we get here, we've allocated more storage
563 space than actual media, or our makefreeblock 563 space than actual media, or our makefreeblock
564 routine is missing something. 564 routine is missing something.
565 */ 565 */
566 printk(KERN_WARNING "Cannot make free space.\n"); 566 printk(KERN_WARNING "Cannot make free space.\n");
567 return BLOCK_NIL; 567 return BLOCK_NIL;
568 } 568 }
569 //printk("Restarting scan\n"); 569 //printk("Restarting scan\n");
570 lastEUN = BLOCK_NIL; 570 lastEUN = BLOCK_NIL;
571 continue; 571 continue;
572 } 572 }
573 573
574 /* We've found a free block. Insert it into the chain. */ 574 /* We've found a free block. Insert it into the chain. */
575 575
576 if (lastEUN != BLOCK_NIL) { 576 if (lastEUN != BLOCK_NIL) {
577 thisVUC |= 0x8000; /* It's a replacement block */ 577 thisVUC |= 0x8000; /* It's a replacement block */
578 } else { 578 } else {
@@ -745,7 +745,7 @@ extern char nftlmountrev[];
745 745
746static int __init init_nftl(void) 746static int __init init_nftl(void)
747{ 747{
748 printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.97 $, nftlmount.c %s\n", nftlmountrev); 748 printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.98 $, nftlmount.c %s\n", nftlmountrev);
749 749
750 return register_mtd_blktrans(&nftl_tr); 750 return register_mtd_blktrans(&nftl_tr);
751} 751}
diff --git a/drivers/mtd/nftlmount.c b/drivers/mtd/nftlmount.c
index 84afd9029f53..3b104ebb219a 100644
--- a/drivers/mtd/nftlmount.c
+++ b/drivers/mtd/nftlmount.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * NFTL mount code with extensive checks 2 * NFTL mount code with extensive checks
3 * 3 *
4 * Author: Fabrice Bellard (fabrice.bellard@netgem.com) 4 * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
5 * Copyright (C) 2000 Netgem S.A. 5 * Copyright (C) 2000 Netgem S.A.
6 * 6 *
7 * $Id: nftlmount.c,v 1.40 2004/11/22 14:38:29 kalev Exp $ 7 * $Id: nftlmount.c,v 1.41 2005/11/07 11:14:21 gleixner Exp $
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
@@ -31,7 +31,7 @@
31 31
32#define SECTORSIZE 512 32#define SECTORSIZE 512
33 33
34char nftlmountrev[]="$Revision: 1.40 $"; 34char nftlmountrev[]="$Revision: 1.41 $";
35 35
36/* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the 36/* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the
37 * various device information of the NFTL partition and Bad Unit Table. Update 37 * various device information of the NFTL partition and Bad Unit Table. Update
@@ -47,7 +47,7 @@ static int find_boot_record(struct NFTLrecord *nftl)
47 struct NFTLMediaHeader *mh = &nftl->MediaHdr; 47 struct NFTLMediaHeader *mh = &nftl->MediaHdr;
48 unsigned int i; 48 unsigned int i;
49 49
50 /* Assume logical EraseSize == physical erasesize for starting the scan. 50 /* Assume logical EraseSize == physical erasesize for starting the scan.
51 We'll sort it out later if we find a MediaHeader which says otherwise */ 51 We'll sort it out later if we find a MediaHeader which says otherwise */
52 /* Actually, we won't. The new DiskOnChip driver has already scanned 52 /* Actually, we won't. The new DiskOnChip driver has already scanned
53 the MediaHeader and adjusted the virtual erasesize it presents in 53 the MediaHeader and adjusted the virtual erasesize it presents in
@@ -83,9 +83,9 @@ static int find_boot_record(struct NFTLrecord *nftl)
83 if (retlen < 6 || memcmp(buf, "ANAND", 6)) { 83 if (retlen < 6 || memcmp(buf, "ANAND", 6)) {
84 /* ANAND\0 not found. Continue */ 84 /* ANAND\0 not found. Continue */
85#if 0 85#if 0
86 printk(KERN_DEBUG "ANAND header not found at 0x%x in mtd%d\n", 86 printk(KERN_DEBUG "ANAND header not found at 0x%x in mtd%d\n",
87 block * nftl->EraseSize, nftl->mbd.mtd->index); 87 block * nftl->EraseSize, nftl->mbd.mtd->index);
88#endif 88#endif
89 continue; 89 continue;
90 } 90 }
91 91
@@ -103,7 +103,7 @@ static int find_boot_record(struct NFTLrecord *nftl)
103 */ 103 */
104 if (le16_to_cpu(h1.EraseMark | h1.EraseMark1) != ERASE_MARK) { 104 if (le16_to_cpu(h1.EraseMark | h1.EraseMark1) != ERASE_MARK) {
105 printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but erase mark not present (0x%04x,0x%04x instead)\n", 105 printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but erase mark not present (0x%04x,0x%04x instead)\n",
106 block * nftl->EraseSize, nftl->mbd.mtd->index, 106 block * nftl->EraseSize, nftl->mbd.mtd->index,
107 le16_to_cpu(h1.EraseMark), le16_to_cpu(h1.EraseMark1)); 107 le16_to_cpu(h1.EraseMark), le16_to_cpu(h1.EraseMark1));
108 continue; 108 continue;
109 } 109 }
@@ -175,7 +175,7 @@ device is already correct.
175 nftl->nb_boot_blocks = le16_to_cpu(mh->FirstPhysicalEUN); 175 nftl->nb_boot_blocks = le16_to_cpu(mh->FirstPhysicalEUN);
176 if ((nftl->nb_boot_blocks + 2) >= nftl->nb_blocks) { 176 if ((nftl->nb_boot_blocks + 2) >= nftl->nb_blocks) {
177 printk(KERN_NOTICE "NFTL Media Header sanity check failed:\n"); 177 printk(KERN_NOTICE "NFTL Media Header sanity check failed:\n");
178 printk(KERN_NOTICE "nb_boot_blocks (%d) + 2 > nb_blocks (%d)\n", 178 printk(KERN_NOTICE "nb_boot_blocks (%d) + 2 > nb_blocks (%d)\n",
179 nftl->nb_boot_blocks, nftl->nb_blocks); 179 nftl->nb_boot_blocks, nftl->nb_blocks);
180 return -1; 180 return -1;
181 } 181 }
@@ -187,7 +187,7 @@ device is already correct.
187 nftl->numvunits, nftl->nb_blocks, nftl->nb_boot_blocks); 187 nftl->numvunits, nftl->nb_blocks, nftl->nb_boot_blocks);
188 return -1; 188 return -1;
189 } 189 }
190 190
191 nftl->mbd.size = nftl->numvunits * (nftl->EraseSize / SECTORSIZE); 191 nftl->mbd.size = nftl->numvunits * (nftl->EraseSize / SECTORSIZE);
192 192
193 /* If we're not using the last sectors in the device for some reason, 193 /* If we're not using the last sectors in the device for some reason,
@@ -210,12 +210,12 @@ device is already correct.
210 printk(KERN_NOTICE "NFTL: allocation of ReplUnitTable failed\n"); 210 printk(KERN_NOTICE "NFTL: allocation of ReplUnitTable failed\n");
211 return -ENOMEM; 211 return -ENOMEM;
212 } 212 }
213 213
214 /* mark the bios blocks (blocks before NFTL MediaHeader) as reserved */ 214 /* mark the bios blocks (blocks before NFTL MediaHeader) as reserved */
215 for (i = 0; i < nftl->nb_boot_blocks; i++) 215 for (i = 0; i < nftl->nb_boot_blocks; i++)
216 nftl->ReplUnitTable[i] = BLOCK_RESERVED; 216 nftl->ReplUnitTable[i] = BLOCK_RESERVED;
217 /* mark all remaining blocks as potentially containing data */ 217 /* mark all remaining blocks as potentially containing data */
218 for (; i < nftl->nb_blocks; i++) { 218 for (; i < nftl->nb_blocks; i++) {
219 nftl->ReplUnitTable[i] = BLOCK_NOTEXPLORED; 219 nftl->ReplUnitTable[i] = BLOCK_NOTEXPLORED;
220 } 220 }
221 221
@@ -245,12 +245,12 @@ The new DiskOnChip driver already scanned the bad block table. Just query it.
245 if (nftl->mbd.mtd->block_isbad(nftl->mbd.mtd, i * nftl->EraseSize)) 245 if (nftl->mbd.mtd->block_isbad(nftl->mbd.mtd, i * nftl->EraseSize))
246 nftl->ReplUnitTable[i] = BLOCK_RESERVED; 246 nftl->ReplUnitTable[i] = BLOCK_RESERVED;
247 } 247 }
248 248
249 nftl->MediaUnit = block; 249 nftl->MediaUnit = block;
250 boot_record_count++; 250 boot_record_count++;
251 251
252 } /* foreach (block) */ 252 } /* foreach (block) */
253 253
254 return boot_record_count?0:-1; 254 return boot_record_count?0:-1;
255} 255}
256 256
@@ -265,7 +265,7 @@ static int memcmpb(void *a, int c, int n)
265} 265}
266 266
267/* check_free_sector: check if a free sector is actually FREE, i.e. All 0xff in data and oob area */ 267/* check_free_sector: check if a free sector is actually FREE, i.e. All 0xff in data and oob area */
268static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int len, 268static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int len,
269 int check_oob) 269 int check_oob)
270{ 270{
271 int i; 271 int i;
@@ -293,7 +293,7 @@ static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int
293 * 293 *
294 * Return: 0 when succeed, -1 on error. 294 * Return: 0 when succeed, -1 on error.
295 * 295 *
296 * ToDo: 1. Is it neceressary to check_free_sector after erasing ?? 296 * ToDo: 1. Is it neceressary to check_free_sector after erasing ??
297 */ 297 */
298int NFTL_formatblock(struct NFTLrecord *nftl, int block) 298int NFTL_formatblock(struct NFTLrecord *nftl, int block)
299{ 299{
@@ -385,7 +385,7 @@ static void check_sectors_in_chain(struct NFTLrecord *nftl, unsigned int first_b
385 /* verify that the sector is really free. If not, mark 385 /* verify that the sector is really free. If not, mark
386 as ignore */ 386 as ignore */
387 if (memcmpb(&bci, 0xff, 8) != 0 || 387 if (memcmpb(&bci, 0xff, 8) != 0 ||
388 check_free_sectors(nftl, block * nftl->EraseSize + i * SECTORSIZE, 388 check_free_sectors(nftl, block * nftl->EraseSize + i * SECTORSIZE,
389 SECTORSIZE, 0) != 0) { 389 SECTORSIZE, 0) != 0) {
390 printk("Incorrect free sector %d in block %d: " 390 printk("Incorrect free sector %d in block %d: "
391 "marking it as ignored\n", 391 "marking it as ignored\n",
@@ -486,7 +486,7 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
486 size_t retlen; 486 size_t retlen;
487 487
488 /* check erase mark. */ 488 /* check erase mark. */
489 if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, 489 if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
490 &retlen, (char *)&h1) < 0) 490 &retlen, (char *)&h1) < 0)
491 return -1; 491 return -1;
492 492
@@ -501,7 +501,7 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
501 h1.EraseMark = cpu_to_le16(ERASE_MARK); 501 h1.EraseMark = cpu_to_le16(ERASE_MARK);
502 h1.EraseMark1 = cpu_to_le16(ERASE_MARK); 502 h1.EraseMark1 = cpu_to_le16(ERASE_MARK);
503 h1.WearInfo = cpu_to_le32(0); 503 h1.WearInfo = cpu_to_le32(0);
504 if (MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, 504 if (MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
505 &retlen, (char *)&h1) < 0) 505 &retlen, (char *)&h1) < 0)
506 return -1; 506 return -1;
507 } else { 507 } else {
@@ -582,9 +582,9 @@ int NFTL_mount(struct NFTLrecord *s)
582 582
583 for (;;) { 583 for (;;) {
584 /* read the block header. If error, we format the chain */ 584 /* read the block header. If error, we format the chain */
585 if (MTD_READOOB(s->mbd.mtd, block * s->EraseSize + 8, 8, 585 if (MTD_READOOB(s->mbd.mtd, block * s->EraseSize + 8, 8,
586 &retlen, (char *)&h0) < 0 || 586 &retlen, (char *)&h0) < 0 ||
587 MTD_READOOB(s->mbd.mtd, block * s->EraseSize + SECTORSIZE + 8, 8, 587 MTD_READOOB(s->mbd.mtd, block * s->EraseSize + SECTORSIZE + 8, 8,
588 &retlen, (char *)&h1) < 0) { 588 &retlen, (char *)&h1) < 0) {
589 s->ReplUnitTable[block] = BLOCK_NIL; 589 s->ReplUnitTable[block] = BLOCK_NIL;
590 do_format_chain = 1; 590 do_format_chain = 1;
@@ -639,7 +639,7 @@ int NFTL_mount(struct NFTLrecord *s)
639 first_logical_block = logical_block; 639 first_logical_block = logical_block;
640 } else { 640 } else {
641 if (logical_block != first_logical_block) { 641 if (logical_block != first_logical_block) {
642 printk("Block %d: incorrect logical block: %d expected: %d\n", 642 printk("Block %d: incorrect logical block: %d expected: %d\n",
643 block, logical_block, first_logical_block); 643 block, logical_block, first_logical_block);
644 /* the chain is incorrect : we must format it, 644 /* the chain is incorrect : we must format it,
645 but we need to read it completly */ 645 but we need to read it completly */
@@ -668,7 +668,7 @@ int NFTL_mount(struct NFTLrecord *s)
668 s->ReplUnitTable[block] = BLOCK_NIL; 668 s->ReplUnitTable[block] = BLOCK_NIL;
669 break; 669 break;
670 } else if (rep_block >= s->nb_blocks) { 670 } else if (rep_block >= s->nb_blocks) {
671 printk("Block %d: referencing invalid block %d\n", 671 printk("Block %d: referencing invalid block %d\n",
672 block, rep_block); 672 block, rep_block);
673 do_format_chain = 1; 673 do_format_chain = 1;
674 s->ReplUnitTable[block] = BLOCK_NIL; 674 s->ReplUnitTable[block] = BLOCK_NIL;
@@ -688,7 +688,7 @@ int NFTL_mount(struct NFTLrecord *s)
688 s->ReplUnitTable[block] = rep_block; 688 s->ReplUnitTable[block] = rep_block;
689 s->EUNtable[first_logical_block] = BLOCK_NIL; 689 s->EUNtable[first_logical_block] = BLOCK_NIL;
690 } else { 690 } else {
691 printk("Block %d: referencing block %d already in another chain\n", 691 printk("Block %d: referencing block %d already in another chain\n",
692 block, rep_block); 692 block, rep_block);
693 /* XXX: should handle correctly fold in progress chains */ 693 /* XXX: should handle correctly fold in progress chains */
694 do_format_chain = 1; 694 do_format_chain = 1;
@@ -710,7 +710,7 @@ int NFTL_mount(struct NFTLrecord *s)
710 } else { 710 } else {
711 unsigned int first_block1, chain_to_format, chain_length1; 711 unsigned int first_block1, chain_to_format, chain_length1;
712 int fold_mark; 712 int fold_mark;
713 713
714 /* valid chain : get foldmark */ 714 /* valid chain : get foldmark */
715 fold_mark = get_fold_mark(s, first_block); 715 fold_mark = get_fold_mark(s, first_block);
716 if (fold_mark == 0) { 716 if (fold_mark == 0) {
@@ -729,9 +729,9 @@ int NFTL_mount(struct NFTLrecord *s)
729 if (first_block1 != BLOCK_NIL) { 729 if (first_block1 != BLOCK_NIL) {
730 /* XXX: what to do if same length ? */ 730 /* XXX: what to do if same length ? */
731 chain_length1 = calc_chain_length(s, first_block1); 731 chain_length1 = calc_chain_length(s, first_block1);
732 printk("Two chains at blocks %d (len=%d) and %d (len=%d)\n", 732 printk("Two chains at blocks %d (len=%d) and %d (len=%d)\n",
733 first_block1, chain_length1, first_block, chain_length); 733 first_block1, chain_length1, first_block, chain_length);
734 734
735 if (chain_length >= chain_length1) { 735 if (chain_length >= chain_length1) {
736 chain_to_format = first_block1; 736 chain_to_format = first_block1;
737 s->EUNtable[first_logical_block] = first_block; 737 s->EUNtable[first_logical_block] = first_block;
diff --git a/drivers/mtd/onenand/Kconfig b/drivers/mtd/onenand/Kconfig
new file mode 100644
index 000000000000..126ff6bf63d5
--- /dev/null
+++ b/drivers/mtd/onenand/Kconfig
@@ -0,0 +1,38 @@
1#
2# linux/drivers/mtd/onenand/Kconfig
3#
4
5menu "OneNAND Flash Device Drivers"
6 depends on MTD != n
7
8config MTD_ONENAND
9 tristate "OneNAND Device Support"
10 depends on MTD
11 help
12 This enables support for accessing all type of OneNAND flash
13 devices. For further information see
14 <http://www.samsung.com/Products/Semiconductor/Flash/OneNAND_TM/index.htm>.
15
16config MTD_ONENAND_VERIFY_WRITE
17 bool "Verify OneNAND page writes"
18 depends on MTD_ONENAND
19 help
20 This adds an extra check when data is written to the flash. The
21 OneNAND flash device internally checks only bits transitioning
22 from 1 to 0. There is a rare possibility that even though the
23 device thinks the write was successful, a bit could have been
24 flipped accidentaly due to device wear or something else.
25
26config MTD_ONENAND_GENERIC
27 tristate "OneNAND Flash device via platform device driver"
28 depends on MTD_ONENAND && ARM
29 help
30 Support for OneNAND flash via platform device driver.
31
32config MTD_ONENAND_SYNC_READ
33 bool "OneNAND Sync. Burst Read Support"
34 depends on ARCH_OMAP
35 help
36 This enables support for Sync. Burst Read.
37
38endmenu
diff --git a/drivers/mtd/onenand/Makefile b/drivers/mtd/onenand/Makefile
new file mode 100644
index 000000000000..269cfe467345
--- /dev/null
+++ b/drivers/mtd/onenand/Makefile
@@ -0,0 +1,11 @@
1#
2# Makefile for the OneNAND MTD
3#
4
5# Core functionality.
6obj-$(CONFIG_MTD_ONENAND) += onenand.o
7
8# Board specific.
9obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o
10
11onenand-objs = onenand_base.o onenand_bbt.o
diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c
new file mode 100644
index 000000000000..48cce431f89f
--- /dev/null
+++ b/drivers/mtd/onenand/generic.c
@@ -0,0 +1,147 @@
1/*
2 * linux/drivers/mtd/onenand/generic.c
3 *
4 * Copyright (c) 2005 Samsung Electronics
5 * Kyungmin Park <kyungmin.park@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Overview:
12 * This is a device driver for the OneNAND flash for generic boards.
13 */
14
15#include <linux/device.h>
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/mtd/mtd.h>
19#include <linux/mtd/onenand.h>
20#include <linux/mtd/partitions.h>
21
22#include <asm/io.h>
23#include <asm/mach/flash.h>
24
25#define DRIVER_NAME "onenand"
26
27
28#ifdef CONFIG_MTD_PARTITIONS
29static const char *part_probes[] = { "cmdlinepart", NULL, };
30#endif
31
32struct onenand_info {
33 struct mtd_info mtd;
34 struct mtd_partition *parts;
35 struct onenand_chip onenand;
36};
37
38static int __devinit generic_onenand_probe(struct device *dev)
39{
40 struct onenand_info *info;
41 struct platform_device *pdev = to_platform_device(dev);
42 struct onenand_platform_data *pdata = pdev->dev.platform_data;
43 struct resource *res = pdev->resource;
44 unsigned long size = res->end - res->start + 1;
45 int err;
46
47 info = kmalloc(sizeof(struct onenand_info), GFP_KERNEL);
48 if (!info)
49 return -ENOMEM;
50
51 memset(info, 0, sizeof(struct onenand_info));
52
53 if (!request_mem_region(res->start, size, dev->driver->name)) {
54 err = -EBUSY;
55 goto out_free_info;
56 }
57
58 info->onenand.base = ioremap(res->start, size);
59 if (!info->onenand.base) {
60 err = -ENOMEM;
61 goto out_release_mem_region;
62 }
63
64 info->onenand.mmcontrol = pdata->mmcontrol;
65
66 info->mtd.name = pdev->dev.bus_id;
67 info->mtd.priv = &info->onenand;
68 info->mtd.owner = THIS_MODULE;
69
70 if (onenand_scan(&info->mtd, 1)) {
71 err = -ENXIO;
72 goto out_iounmap;
73 }
74
75#ifdef CONFIG_MTD_PARTITIONS
76 err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0);
77 if (err > 0)
78 add_mtd_partitions(&info->mtd, info->parts, err);
79 else if (err < 0 && pdata->parts)
80 add_mtd_partitions(&info->mtd, pdata->parts, pdata->nr_parts);
81 else
82#endif
83 err = add_mtd_device(&info->mtd);
84
85 dev_set_drvdata(&pdev->dev, info);
86
87 return 0;
88
89out_iounmap:
90 iounmap(info->onenand.base);
91out_release_mem_region:
92 release_mem_region(res->start, size);
93out_free_info:
94 kfree(info);
95
96 return err;
97}
98
99static int __devexit generic_onenand_remove(struct device *dev)
100{
101 struct platform_device *pdev = to_platform_device(dev);
102 struct onenand_info *info = dev_get_drvdata(&pdev->dev);
103 struct resource *res = pdev->resource;
104 unsigned long size = res->end - res->start + 1;
105
106 dev_set_drvdata(&pdev->dev, NULL);
107
108 if (info) {
109 if (info->parts)
110 del_mtd_partitions(&info->mtd);
111 else
112 del_mtd_device(&info->mtd);
113
114 onenand_release(&info->mtd);
115 release_mem_region(res->start, size);
116 iounmap(info->onenand.base);
117 kfree(info);
118 }
119
120 return 0;
121}
122
123static struct device_driver generic_onenand_driver = {
124 .name = DRIVER_NAME,
125 .bus = &platform_bus_type,
126 .probe = generic_onenand_probe,
127 .remove = __devexit_p(generic_onenand_remove),
128};
129
130MODULE_ALIAS(DRIVER_NAME);
131
132static int __init generic_onenand_init(void)
133{
134 return driver_register(&generic_onenand_driver);
135}
136
137static void __exit generic_onenand_exit(void)
138{
139 driver_unregister(&generic_onenand_driver);
140}
141
142module_init(generic_onenand_init);
143module_exit(generic_onenand_exit);
144
145MODULE_LICENSE("GPL");
146MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
147MODULE_DESCRIPTION("Glue layer for OneNAND flash on generic boards");
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
new file mode 100644
index 000000000000..cc38fa0d45c6
--- /dev/null
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -0,0 +1,1588 @@
1/*
2 * linux/drivers/mtd/onenand/onenand_base.c
3 *
4 * Copyright (C) 2005 Samsung Electronics
5 * Kyungmin Park <kyungmin.park@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/mtd/mtd.h>
16#include <linux/mtd/onenand.h>
17#include <linux/mtd/partitions.h>
18
19#include <asm/io.h>
20
21/**
22 * onenand_oob_64 - oob info for large (2KB) page
23 */
24static struct nand_oobinfo onenand_oob_64 = {
25 .useecc = MTD_NANDECC_AUTOPLACE,
26 .eccbytes = 20,
27 .eccpos = {
28 8, 9, 10, 11, 12,
29 24, 25, 26, 27, 28,
30 40, 41, 42, 43, 44,
31 56, 57, 58, 59, 60,
32 },
33 .oobfree = {
34 {2, 3}, {14, 2}, {18, 3}, {30, 2},
35 {24, 3}, {46, 2}, {40, 3}, {62, 2} }
36};
37
38/**
39 * onenand_oob_32 - oob info for middle (1KB) page
40 */
41static struct nand_oobinfo onenand_oob_32 = {
42 .useecc = MTD_NANDECC_AUTOPLACE,
43 .eccbytes = 10,
44 .eccpos = {
45 8, 9, 10, 11, 12,
46 24, 25, 26, 27, 28,
47 },
48 .oobfree = { {2, 3}, {14, 2}, {18, 3}, {30, 2} }
49};
50
51static const unsigned char ffchars[] = {
52 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
53 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 16 */
54 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
55 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 32 */
56 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
57 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 48 */
58 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
59 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 64 */
60};
61
62/**
63 * onenand_readw - [OneNAND Interface] Read OneNAND register
64 * @param addr address to read
65 *
66 * Read OneNAND register
67 */
68static unsigned short onenand_readw(void __iomem *addr)
69{
70 return readw(addr);
71}
72
73/**
74 * onenand_writew - [OneNAND Interface] Write OneNAND register with value
75 * @param value value to write
76 * @param addr address to write
77 *
78 * Write OneNAND register with value
79 */
80static void onenand_writew(unsigned short value, void __iomem *addr)
81{
82 writew(value, addr);
83}
84
85/**
86 * onenand_block_address - [DEFAULT] Get block address
87 * @param this onenand chip data structure
88 * @param block the block
89 * @return translated block address if DDP, otherwise same
90 *
91 * Setup Start Address 1 Register (F100h)
92 */
93static int onenand_block_address(struct onenand_chip *this, int block)
94{
95 if (this->device_id & ONENAND_DEVICE_IS_DDP) {
96 /* Device Flash Core select, NAND Flash Block Address */
97 int dfs = 0;
98
99 if (block & this->density_mask)
100 dfs = 1;
101
102 return (dfs << ONENAND_DDP_SHIFT) |
103 (block & (this->density_mask - 1));
104 }
105
106 return block;
107}
108
109/**
110 * onenand_bufferram_address - [DEFAULT] Get bufferram address
111 * @param this onenand chip data structure
112 * @param block the block
113 * @return set DBS value if DDP, otherwise 0
114 *
115 * Setup Start Address 2 Register (F101h) for DDP
116 */
117static int onenand_bufferram_address(struct onenand_chip *this, int block)
118{
119 if (this->device_id & ONENAND_DEVICE_IS_DDP) {
120 /* Device BufferRAM Select */
121 int dbs = 0;
122
123 if (block & this->density_mask)
124 dbs = 1;
125
126 return (dbs << ONENAND_DDP_SHIFT);
127 }
128
129 return 0;
130}
131
132/**
133 * onenand_page_address - [DEFAULT] Get page address
134 * @param page the page address
135 * @param sector the sector address
136 * @return combined page and sector address
137 *
138 * Setup Start Address 8 Register (F107h)
139 */
140static int onenand_page_address(int page, int sector)
141{
142 /* Flash Page Address, Flash Sector Address */
143 int fpa, fsa;
144
145 fpa = page & ONENAND_FPA_MASK;
146 fsa = sector & ONENAND_FSA_MASK;
147
148 return ((fpa << ONENAND_FPA_SHIFT) | fsa);
149}
150
151/**
152 * onenand_buffer_address - [DEFAULT] Get buffer address
153 * @param dataram1 DataRAM index
154 * @param sectors the sector address
155 * @param count the number of sectors
156 * @return the start buffer value
157 *
158 * Setup Start Buffer Register (F200h)
159 */
160static int onenand_buffer_address(int dataram1, int sectors, int count)
161{
162 int bsa, bsc;
163
164 /* BufferRAM Sector Address */
165 bsa = sectors & ONENAND_BSA_MASK;
166
167 if (dataram1)
168 bsa |= ONENAND_BSA_DATARAM1; /* DataRAM1 */
169 else
170 bsa |= ONENAND_BSA_DATARAM0; /* DataRAM0 */
171
172 /* BufferRAM Sector Count */
173 bsc = count & ONENAND_BSC_MASK;
174
175 return ((bsa << ONENAND_BSA_SHIFT) | bsc);
176}
177
178/**
179 * onenand_command - [DEFAULT] Send command to OneNAND device
180 * @param mtd MTD device structure
181 * @param cmd the command to be sent
182 * @param addr offset to read from or write to
183 * @param len number of bytes to read or write
184 *
185 * Send command to OneNAND device. This function is used for middle/large page
186 * devices (1KB/2KB Bytes per page)
187 */
188static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t len)
189{
190 struct onenand_chip *this = mtd->priv;
191 int value, readcmd = 0;
192 int block, page;
193 /* Now we use page size operation */
194 int sectors = 4, count = 4;
195
196 /* Address translation */
197 switch (cmd) {
198 case ONENAND_CMD_UNLOCK:
199 case ONENAND_CMD_LOCK:
200 case ONENAND_CMD_LOCK_TIGHT:
201 block = -1;
202 page = -1;
203 break;
204
205 case ONENAND_CMD_ERASE:
206 case ONENAND_CMD_BUFFERRAM:
207 block = (int) (addr >> this->erase_shift);
208 page = -1;
209 break;
210
211 default:
212 block = (int) (addr >> this->erase_shift);
213 page = (int) (addr >> this->page_shift);
214 page &= this->page_mask;
215 break;
216 }
217
218 /* NOTE: The setting order of the registers is very important! */
219 if (cmd == ONENAND_CMD_BUFFERRAM) {
220 /* Select DataRAM for DDP */
221 value = onenand_bufferram_address(this, block);
222 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
223
224 /* Switch to the next data buffer */
225 ONENAND_SET_NEXT_BUFFERRAM(this);
226
227 return 0;
228 }
229
230 if (block != -1) {
231 /* Write 'DFS, FBA' of Flash */
232 value = onenand_block_address(this, block);
233 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
234 }
235
236 if (page != -1) {
237 int dataram;
238
239 switch (cmd) {
240 case ONENAND_CMD_READ:
241 case ONENAND_CMD_READOOB:
242 dataram = ONENAND_SET_NEXT_BUFFERRAM(this);
243 readcmd = 1;
244 break;
245
246 default:
247 dataram = ONENAND_CURRENT_BUFFERRAM(this);
248 break;
249 }
250
251 /* Write 'FPA, FSA' of Flash */
252 value = onenand_page_address(page, sectors);
253 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS8);
254
255 /* Write 'BSA, BSC' of DataRAM */
256 value = onenand_buffer_address(dataram, sectors, count);
257 this->write_word(value, this->base + ONENAND_REG_START_BUFFER);
258
259 if (readcmd) {
260 /* Select DataRAM for DDP */
261 value = onenand_bufferram_address(this, block);
262 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
263 }
264 }
265
266 /* Interrupt clear */
267 this->write_word(ONENAND_INT_CLEAR, this->base + ONENAND_REG_INTERRUPT);
268
269 /* Write command */
270 this->write_word(cmd, this->base + ONENAND_REG_COMMAND);
271
272 return 0;
273}
274
275/**
276 * onenand_wait - [DEFAULT] wait until the command is done
277 * @param mtd MTD device structure
278 * @param state state to select the max. timeout value
279 *
280 * Wait for command done. This applies to all OneNAND command
281 * Read can take up to 30us, erase up to 2ms and program up to 350us
282 * according to general OneNAND specs
283 */
284static int onenand_wait(struct mtd_info *mtd, int state)
285{
286 struct onenand_chip * this = mtd->priv;
287 unsigned long timeout;
288 unsigned int flags = ONENAND_INT_MASTER;
289 unsigned int interrupt = 0;
290 unsigned int ctrl, ecc;
291
292 /* The 20 msec is enough */
293 timeout = jiffies + msecs_to_jiffies(20);
294 while (time_before(jiffies, timeout)) {
295 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
296
297 if (interrupt & flags)
298 break;
299
300 if (state != FL_READING)
301 cond_resched();
302 }
303 /* To get correct interrupt status in timeout case */
304 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
305
306 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
307
308 if (ctrl & ONENAND_CTRL_ERROR) {
309 /* It maybe occur at initial bad block */
310 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: controller error = 0x%04x\n", ctrl);
311 /* Clear other interrupt bits for preventing ECC error */
312 interrupt &= ONENAND_INT_MASTER;
313 }
314
315 if (ctrl & ONENAND_CTRL_LOCK) {
316 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: it's locked error = 0x%04x\n", ctrl);
317 return -EACCES;
318 }
319
320 if (interrupt & ONENAND_INT_READ) {
321 ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);
322 if (ecc & ONENAND_ECC_2BIT_ALL) {
323 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: ECC error = 0x%04x\n", ecc);
324 return -EBADMSG;
325 }
326 }
327
328 return 0;
329}
330
331/**
332 * onenand_bufferram_offset - [DEFAULT] BufferRAM offset
333 * @param mtd MTD data structure
334 * @param area BufferRAM area
335 * @return offset given area
336 *
337 * Return BufferRAM offset given area
338 */
339static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area)
340{
341 struct onenand_chip *this = mtd->priv;
342
343 if (ONENAND_CURRENT_BUFFERRAM(this)) {
344 if (area == ONENAND_DATARAM)
345 return mtd->oobblock;
346 if (area == ONENAND_SPARERAM)
347 return mtd->oobsize;
348 }
349
350 return 0;
351}
352
353/**
354 * onenand_read_bufferram - [OneNAND Interface] Read the bufferram area
355 * @param mtd MTD data structure
356 * @param area BufferRAM area
357 * @param buffer the databuffer to put/get data
358 * @param offset offset to read from or write to
359 * @param count number of bytes to read/write
360 *
361 * Read the BufferRAM area
362 */
363static int onenand_read_bufferram(struct mtd_info *mtd, int area,
364 unsigned char *buffer, int offset, size_t count)
365{
366 struct onenand_chip *this = mtd->priv;
367 void __iomem *bufferram;
368
369 bufferram = this->base + area;
370
371 bufferram += onenand_bufferram_offset(mtd, area);
372
373 memcpy(buffer, bufferram + offset, count);
374
375 return 0;
376}
377
378/**
379 * onenand_sync_read_bufferram - [OneNAND Interface] Read the bufferram area with Sync. Burst mode
380 * @param mtd MTD data structure
381 * @param area BufferRAM area
382 * @param buffer the databuffer to put/get data
383 * @param offset offset to read from or write to
384 * @param count number of bytes to read/write
385 *
386 * Read the BufferRAM area with Sync. Burst Mode
387 */
388static int onenand_sync_read_bufferram(struct mtd_info *mtd, int area,
389 unsigned char *buffer, int offset, size_t count)
390{
391 struct onenand_chip *this = mtd->priv;
392 void __iomem *bufferram;
393
394 bufferram = this->base + area;
395
396 bufferram += onenand_bufferram_offset(mtd, area);
397
398 this->mmcontrol(mtd, ONENAND_SYS_CFG1_SYNC_READ);
399
400 memcpy(buffer, bufferram + offset, count);
401
402 this->mmcontrol(mtd, 0);
403
404 return 0;
405}
406
407/**
408 * onenand_write_bufferram - [OneNAND Interface] Write the bufferram area
409 * @param mtd MTD data structure
410 * @param area BufferRAM area
411 * @param buffer the databuffer to put/get data
412 * @param offset offset to read from or write to
413 * @param count number of bytes to read/write
414 *
415 * Write the BufferRAM area
416 */
417static int onenand_write_bufferram(struct mtd_info *mtd, int area,
418 const unsigned char *buffer, int offset, size_t count)
419{
420 struct onenand_chip *this = mtd->priv;
421 void __iomem *bufferram;
422
423 bufferram = this->base + area;
424
425 bufferram += onenand_bufferram_offset(mtd, area);
426
427 memcpy(bufferram + offset, buffer, count);
428
429 return 0;
430}
431
432/**
433 * onenand_check_bufferram - [GENERIC] Check BufferRAM information
434 * @param mtd MTD data structure
435 * @param addr address to check
436 * @return 1 if there are valid data, otherwise 0
437 *
438 * Check bufferram if there is data we required
439 */
440static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
441{
442 struct onenand_chip *this = mtd->priv;
443 int block, page;
444 int i;
445
446 block = (int) (addr >> this->erase_shift);
447 page = (int) (addr >> this->page_shift);
448 page &= this->page_mask;
449
450 i = ONENAND_CURRENT_BUFFERRAM(this);
451
452 /* Is there valid data? */
453 if (this->bufferram[i].block == block &&
454 this->bufferram[i].page == page &&
455 this->bufferram[i].valid)
456 return 1;
457
458 return 0;
459}
460
461/**
462 * onenand_update_bufferram - [GENERIC] Update BufferRAM information
463 * @param mtd MTD data structure
464 * @param addr address to update
465 * @param valid valid flag
466 *
467 * Update BufferRAM information
468 */
469static int onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,
470 int valid)
471{
472 struct onenand_chip *this = mtd->priv;
473 int block, page;
474 int i;
475
476 block = (int) (addr >> this->erase_shift);
477 page = (int) (addr >> this->page_shift);
478 page &= this->page_mask;
479
480 /* Invalidate BufferRAM */
481 for (i = 0; i < MAX_BUFFERRAM; i++) {
482 if (this->bufferram[i].block == block &&
483 this->bufferram[i].page == page)
484 this->bufferram[i].valid = 0;
485 }
486
487 /* Update BufferRAM */
488 i = ONENAND_CURRENT_BUFFERRAM(this);
489 this->bufferram[i].block = block;
490 this->bufferram[i].page = page;
491 this->bufferram[i].valid = valid;
492
493 return 0;
494}
495
496/**
497 * onenand_get_device - [GENERIC] Get chip for selected access
498 * @param mtd MTD device structure
499 * @param new_state the state which is requested
500 *
501 * Get the device and lock it for exclusive access
502 */
503static int onenand_get_device(struct mtd_info *mtd, int new_state)
504{
505 struct onenand_chip *this = mtd->priv;
506 DECLARE_WAITQUEUE(wait, current);
507
508 /*
509 * Grab the lock and see if the device is available
510 */
511 while (1) {
512 spin_lock(&this->chip_lock);
513 if (this->state == FL_READY) {
514 this->state = new_state;
515 spin_unlock(&this->chip_lock);
516 break;
517 }
518 if (new_state == FL_PM_SUSPENDED) {
519 spin_unlock(&this->chip_lock);
520 return (this->state == FL_PM_SUSPENDED) ? 0 : -EAGAIN;
521 }
522 set_current_state(TASK_UNINTERRUPTIBLE);
523 add_wait_queue(&this->wq, &wait);
524 spin_unlock(&this->chip_lock);
525 schedule();
526 remove_wait_queue(&this->wq, &wait);
527 }
528
529 return 0;
530}
531
532/**
533 * onenand_release_device - [GENERIC] release chip
534 * @param mtd MTD device structure
535 *
536 * Deselect, release chip lock and wake up anyone waiting on the device
537 */
538static void onenand_release_device(struct mtd_info *mtd)
539{
540 struct onenand_chip *this = mtd->priv;
541
542 /* Release the chip */
543 spin_lock(&this->chip_lock);
544 this->state = FL_READY;
545 wake_up(&this->wq);
546 spin_unlock(&this->chip_lock);
547}
548
549/**
550 * onenand_read_ecc - [MTD Interface] Read data with ECC
551 * @param mtd MTD device structure
552 * @param from offset to read from
553 * @param len number of bytes to read
554 * @param retlen pointer to variable to store the number of read bytes
555 * @param buf the databuffer to put data
556 * @param oob_buf filesystem supplied oob data buffer
557 * @param oobsel oob selection structure
558 *
559 * OneNAND read with ECC
560 */
561static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
562 size_t *retlen, u_char *buf,
563 u_char *oob_buf, struct nand_oobinfo *oobsel)
564{
565 struct onenand_chip *this = mtd->priv;
566 int read = 0, column;
567 int thislen;
568 int ret = 0;
569
570 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
571
572 /* Do not allow reads past end of device */
573 if ((from + len) > mtd->size) {
574 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_ecc: Attempt read beyond end of device\n");
575 *retlen = 0;
576 return -EINVAL;
577 }
578
579 /* Grab the lock and see if the device is available */
580 onenand_get_device(mtd, FL_READING);
581
582 /* TODO handling oob */
583
584 while (read < len) {
585 thislen = min_t(int, mtd->oobblock, len - read);
586
587 column = from & (mtd->oobblock - 1);
588 if (column + thislen > mtd->oobblock)
589 thislen = mtd->oobblock - column;
590
591 if (!onenand_check_bufferram(mtd, from)) {
592 this->command(mtd, ONENAND_CMD_READ, from, mtd->oobblock);
593
594 ret = this->wait(mtd, FL_READING);
595 /* First copy data and check return value for ECC handling */
596 onenand_update_bufferram(mtd, from, 1);
597 }
598
599 this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);
600
601 read += thislen;
602
603 if (read == len)
604 break;
605
606 if (ret) {
607 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_ecc: read failed = %d\n", ret);
608 goto out;
609 }
610
611 from += thislen;
612 buf += thislen;
613 }
614
615out:
616 /* Deselect and wake up anyone waiting on the device */
617 onenand_release_device(mtd);
618
619 /*
620 * Return success, if no ECC failures, else -EBADMSG
621 * fs driver will take care of that, because
622 * retlen == desired len and result == -EBADMSG
623 */
624 *retlen = read;
625 return ret;
626}
627
628/**
629 * onenand_read - [MTD Interface] MTD compability function for onenand_read_ecc
630 * @param mtd MTD device structure
631 * @param from offset to read from
632 * @param len number of bytes to read
633 * @param retlen pointer to variable to store the number of read bytes
634 * @param buf the databuffer to put data
635 *
636 * This function simply calls onenand_read_ecc with oob buffer and oobsel = NULL
637*/
638static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
639 size_t *retlen, u_char *buf)
640{
641 return onenand_read_ecc(mtd, from, len, retlen, buf, NULL, NULL);
642}
643
644/**
645 * onenand_read_oob - [MTD Interface] OneNAND read out-of-band
646 * @param mtd MTD device structure
647 * @param from offset to read from
648 * @param len number of bytes to read
649 * @param retlen pointer to variable to store the number of read bytes
650 * @param buf the databuffer to put data
651 *
652 * OneNAND read out-of-band data from the spare area
653 */
654static int onenand_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
655 size_t *retlen, u_char *buf)
656{
657 struct onenand_chip *this = mtd->priv;
658 int read = 0, thislen, column;
659 int ret = 0;
660
661 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
662
663 /* Initialize return length value */
664 *retlen = 0;
665
666 /* Do not allow reads past end of device */
667 if (unlikely((from + len) > mtd->size)) {
668 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: Attempt read beyond end of device\n");
669 return -EINVAL;
670 }
671
672 /* Grab the lock and see if the device is available */
673 onenand_get_device(mtd, FL_READING);
674
675 column = from & (mtd->oobsize - 1);
676
677 while (read < len) {
678 thislen = mtd->oobsize - column;
679 thislen = min_t(int, thislen, len);
680
681 this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize);
682
683 onenand_update_bufferram(mtd, from, 0);
684
685 ret = this->wait(mtd, FL_READING);
686 /* First copy data and check return value for ECC handling */
687
688 this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
689
690 read += thislen;
691
692 if (read == len)
693 break;
694
695 if (ret) {
696 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: read failed = %d\n", ret);
697 goto out;
698 }
699
700 buf += thislen;
701
702 /* Read more? */
703 if (read < len) {
704 /* Page size */
705 from += mtd->oobblock;
706 column = 0;
707 }
708 }
709
710out:
711 /* Deselect and wake up anyone waiting on the device */
712 onenand_release_device(mtd);
713
714 *retlen = read;
715 return ret;
716}
717
718#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
719/**
720 * onenand_verify_page - [GENERIC] verify the chip contents after a write
721 * @param mtd MTD device structure
722 * @param buf the databuffer to verify
723 *
724 * Check DataRAM area directly
725 */
726static int onenand_verify_page(struct mtd_info *mtd, u_char *buf, loff_t addr)
727{
728 struct onenand_chip *this = mtd->priv;
729 void __iomem *dataram0, *dataram1;
730 int ret = 0;
731
732 this->command(mtd, ONENAND_CMD_READ, addr, mtd->oobblock);
733
734 ret = this->wait(mtd, FL_READING);
735 if (ret)
736 return ret;
737
738 onenand_update_bufferram(mtd, addr, 1);
739
740 /* Check, if the two dataram areas are same */
741 dataram0 = this->base + ONENAND_DATARAM;
742 dataram1 = dataram0 + mtd->oobblock;
743
744 if (memcmp(dataram0, dataram1, mtd->oobblock))
745 return -EBADMSG;
746
747 return 0;
748}
749#else
750#define onenand_verify_page(...) (0)
751#endif
752
753#define NOTALIGNED(x) ((x & (mtd->oobblock - 1)) != 0)
754
755/**
756 * onenand_write_ecc - [MTD Interface] OneNAND write with ECC
757 * @param mtd MTD device structure
758 * @param to offset to write to
759 * @param len number of bytes to write
760 * @param retlen pointer to variable to store the number of written bytes
761 * @param buf the data to write
762 * @param eccbuf filesystem supplied oob data buffer
763 * @param oobsel oob selection structure
764 *
765 * OneNAND write with ECC
766 */
767static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
768 size_t *retlen, const u_char *buf,
769 u_char *eccbuf, struct nand_oobinfo *oobsel)
770{
771 struct onenand_chip *this = mtd->priv;
772 int written = 0;
773 int ret = 0;
774
775 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
776
777 /* Initialize retlen, in case of early exit */
778 *retlen = 0;
779
780 /* Do not allow writes past end of device */
781 if (unlikely((to + len) > mtd->size)) {
782 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: Attempt write to past end of device\n");
783 return -EINVAL;
784 }
785
786 /* Reject writes, which are not page aligned */
787 if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) {
788 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: Attempt to write not page aligned data\n");
789 return -EINVAL;
790 }
791
792 /* Grab the lock and see if the device is available */
793 onenand_get_device(mtd, FL_WRITING);
794
795 /* Loop until all data write */
796 while (written < len) {
797 int thislen = min_t(int, mtd->oobblock, len - written);
798
799 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobblock);
800
801 this->write_bufferram(mtd, ONENAND_DATARAM, buf, 0, thislen);
802 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
803
804 this->command(mtd, ONENAND_CMD_PROG, to, mtd->oobblock);
805
806 onenand_update_bufferram(mtd, to, 1);
807
808 ret = this->wait(mtd, FL_WRITING);
809 if (ret) {
810 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: write filaed %d\n", ret);
811 goto out;
812 }
813
814 written += thislen;
815
816 /* Only check verify write turn on */
817 ret = onenand_verify_page(mtd, (u_char *) buf, to);
818 if (ret) {
819 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: verify failed %d\n", ret);
820 goto out;
821 }
822
823 if (written == len)
824 break;
825
826 to += thislen;
827 buf += thislen;
828 }
829
830out:
831 /* Deselect and wake up anyone waiting on the device */
832 onenand_release_device(mtd);
833
834 *retlen = written;
835
836 return ret;
837}
838
839/**
840 * onenand_write - [MTD Interface] compability function for onenand_write_ecc
841 * @param mtd MTD device structure
842 * @param to offset to write to
843 * @param len number of bytes to write
844 * @param retlen pointer to variable to store the number of written bytes
845 * @param buf the data to write
846 *
847 * This function simply calls onenand_write_ecc
848 * with oob buffer and oobsel = NULL
849 */
850static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
851 size_t *retlen, const u_char *buf)
852{
853 return onenand_write_ecc(mtd, to, len, retlen, buf, NULL, NULL);
854}
855
856/**
857 * onenand_write_oob - [MTD Interface] OneNAND write out-of-band
858 * @param mtd MTD device structure
859 * @param to offset to write to
860 * @param len number of bytes to write
861 * @param retlen pointer to variable to store the number of written bytes
862 * @param buf the data to write
863 *
864 * OneNAND write out-of-band
865 */
866static int onenand_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
867 size_t *retlen, const u_char *buf)
868{
869 struct onenand_chip *this = mtd->priv;
870 int column, status;
871 int written = 0;
872
873 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
874
875 /* Initialize retlen, in case of early exit */
876 *retlen = 0;
877
878 /* Do not allow writes past end of device */
879 if (unlikely((to + len) > mtd->size)) {
880 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_oob: Attempt write to past end of device\n");
881 return -EINVAL;
882 }
883
884 /* Grab the lock and see if the device is available */
885 onenand_get_device(mtd, FL_WRITING);
886
887 /* Loop until all data write */
888 while (written < len) {
889 int thislen = min_t(int, mtd->oobsize, len - written);
890
891 column = to & (mtd->oobsize - 1);
892
893 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobsize);
894
895 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
896 this->write_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
897
898 this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
899
900 onenand_update_bufferram(mtd, to, 0);
901
902 status = this->wait(mtd, FL_WRITING);
903 if (status)
904 goto out;
905
906 written += thislen;
907
908 if (written == len)
909 break;
910
911 to += thislen;
912 buf += thislen;
913 }
914
915out:
916 /* Deselect and wake up anyone waiting on the device */
917 onenand_release_device(mtd);
918
919 *retlen = written;
920
921 return 0;
922}
923
924/**
925 * onenand_writev_ecc - [MTD Interface] write with iovec with ecc
926 * @param mtd MTD device structure
927 * @param vecs the iovectors to write
928 * @param count number of vectors
929 * @param to offset to write to
930 * @param retlen pointer to variable to store the number of written bytes
931 * @param eccbuf filesystem supplied oob data buffer
932 * @param oobsel oob selection structure
933 *
934 * OneNAND write with iovec with ecc
935 */
936static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
937 unsigned long count, loff_t to, size_t *retlen,
938 u_char *eccbuf, struct nand_oobinfo *oobsel)
939{
940 struct onenand_chip *this = mtd->priv;
941 unsigned char buffer[MAX_ONENAND_PAGESIZE], *pbuf;
942 size_t total_len, len;
943 int i, written = 0;
944 int ret = 0;
945
946 /* Preset written len for early exit */
947 *retlen = 0;
948
949 /* Calculate total length of data */
950 total_len = 0;
951 for (i = 0; i < count; i++)
952 total_len += vecs[i].iov_len;
953
954 DEBUG(MTD_DEBUG_LEVEL3, "onenand_writev_ecc: to = 0x%08x, len = %i, count = %ld\n", (unsigned int) to, (unsigned int) total_len, count);
955
956 /* Do not allow write past end of the device */
957 if (unlikely((to + total_len) > mtd->size)) {
958 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: Attempted write past end of device\n");
959 return -EINVAL;
960 }
961
962 /* Reject writes, which are not page aligned */
963 if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(total_len))) {
964 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: Attempt to write not page aligned data\n");
965 return -EINVAL;
966 }
967
968 /* Grab the lock and see if the device is available */
969 onenand_get_device(mtd, FL_WRITING);
970
971 /* TODO handling oob */
972
973 /* Loop until all keve's data has been written */
974 len = 0;
975 while (count) {
976 pbuf = buffer;
977 /*
978 * If the given tuple is >= pagesize then
979 * write it out from the iov
980 */
981 if ((vecs->iov_len - len) >= mtd->oobblock) {
982 pbuf = vecs->iov_base + len;
983
984 len += mtd->oobblock;
985
986 /* Check, if we have to switch to the next tuple */
987 if (len >= (int) vecs->iov_len) {
988 vecs++;
989 len = 0;
990 count--;
991 }
992 } else {
993 int cnt = 0, thislen;
994 while (cnt < mtd->oobblock) {
995 thislen = min_t(int, mtd->oobblock - cnt, vecs->iov_len - len);
996 memcpy(buffer + cnt, vecs->iov_base + len, thislen);
997 cnt += thislen;
998 len += thislen;
999
1000 /* Check, if we have to switch to the next tuple */
1001 if (len >= (int) vecs->iov_len) {
1002 vecs++;
1003 len = 0;
1004 count--;
1005 }
1006 }
1007 }
1008
1009 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobblock);
1010
1011 this->write_bufferram(mtd, ONENAND_DATARAM, pbuf, 0, mtd->oobblock);
1012 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
1013
1014 this->command(mtd, ONENAND_CMD_PROG, to, mtd->oobblock);
1015
1016 onenand_update_bufferram(mtd, to, 1);
1017
1018 ret = this->wait(mtd, FL_WRITING);
1019 if (ret) {
1020 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: write failed %d\n", ret);
1021 goto out;
1022 }
1023
1024
1025 /* Only check verify write turn on */
1026 ret = onenand_verify_page(mtd, (u_char *) pbuf, to);
1027 if (ret) {
1028 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: verify failed %d\n", ret);
1029 goto out;
1030 }
1031
1032 written += mtd->oobblock;
1033
1034 to += mtd->oobblock;
1035 }
1036
1037out:
1038 /* Deselect and wakt up anyone waiting on the device */
1039 onenand_release_device(mtd);
1040
1041 *retlen = written;
1042
1043 return 0;
1044}
1045
1046/**
1047 * onenand_writev - [MTD Interface] compabilty function for onenand_writev_ecc
1048 * @param mtd MTD device structure
1049 * @param vecs the iovectors to write
1050 * @param count number of vectors
1051 * @param to offset to write to
1052 * @param retlen pointer to variable to store the number of written bytes
1053 *
1054 * OneNAND write with kvec. This just calls the ecc function
1055 */
1056static int onenand_writev(struct mtd_info *mtd, const struct kvec *vecs,
1057 unsigned long count, loff_t to, size_t *retlen)
1058{
1059 return onenand_writev_ecc(mtd, vecs, count, to, retlen, NULL, NULL);
1060}
1061
1062/**
1063 * onenand_block_checkbad - [GENERIC] Check if a block is marked bad
1064 * @param mtd MTD device structure
1065 * @param ofs offset from device start
1066 * @param getchip 0, if the chip is already selected
1067 * @param allowbbt 1, if its allowed to access the bbt area
1068 *
1069 * Check, if the block is bad. Either by reading the bad block table or
1070 * calling of the scan function.
1071 */
1072static int onenand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt)
1073{
1074 struct onenand_chip *this = mtd->priv;
1075 struct bbm_info *bbm = this->bbm;
1076
1077 /* Return info from the table */
1078 return bbm->isbad_bbt(mtd, ofs, allowbbt);
1079}
1080
1081/**
1082 * onenand_erase - [MTD Interface] erase block(s)
1083 * @param mtd MTD device structure
1084 * @param instr erase instruction
1085 *
1086 * Erase one ore more blocks
1087 */
1088static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
1089{
1090 struct onenand_chip *this = mtd->priv;
1091 unsigned int block_size;
1092 loff_t addr;
1093 int len;
1094 int ret = 0;
1095
1096 DEBUG(MTD_DEBUG_LEVEL3, "onenand_erase: start = 0x%08x, len = %i\n", (unsigned int) instr->addr, (unsigned int) instr->len);
1097
1098 block_size = (1 << this->erase_shift);
1099
1100 /* Start address must align on block boundary */
1101 if (unlikely(instr->addr & (block_size - 1))) {
1102 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Unaligned address\n");
1103 return -EINVAL;
1104 }
1105
1106 /* Length must align on block boundary */
1107 if (unlikely(instr->len & (block_size - 1))) {
1108 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Length not block aligned\n");
1109 return -EINVAL;
1110 }
1111
1112 /* Do not allow erase past end of device */
1113 if (unlikely((instr->len + instr->addr) > mtd->size)) {
1114 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Erase past end of device\n");
1115 return -EINVAL;
1116 }
1117
1118 instr->fail_addr = 0xffffffff;
1119
1120 /* Grab the lock and see if the device is available */
1121 onenand_get_device(mtd, FL_ERASING);
1122
1123 /* Loop throught the pages */
1124 len = instr->len;
1125 addr = instr->addr;
1126
1127 instr->state = MTD_ERASING;
1128
1129 while (len) {
1130
1131 /* Check if we have a bad block, we do not erase bad blocks */
1132 if (onenand_block_checkbad(mtd, addr, 0, 0)) {
1133 printk (KERN_WARNING "onenand_erase: attempt to erase a bad block at addr 0x%08x\n", (unsigned int) addr);
1134 instr->state = MTD_ERASE_FAILED;
1135 goto erase_exit;
1136 }
1137
1138 this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
1139
1140 ret = this->wait(mtd, FL_ERASING);
1141 /* Check, if it is write protected */
1142 if (ret) {
1143 if (ret == -EPERM)
1144 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Device is write protected!!!\n");
1145 else
1146 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift));
1147 instr->state = MTD_ERASE_FAILED;
1148 instr->fail_addr = addr;
1149 goto erase_exit;
1150 }
1151
1152 len -= block_size;
1153 addr += block_size;
1154 }
1155
1156 instr->state = MTD_ERASE_DONE;
1157
1158erase_exit:
1159
1160 ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
1161 /* Do call back function */
1162 if (!ret)
1163 mtd_erase_callback(instr);
1164
1165 /* Deselect and wake up anyone waiting on the device */
1166 onenand_release_device(mtd);
1167
1168 return ret;
1169}
1170
1171/**
1172 * onenand_sync - [MTD Interface] sync
1173 * @param mtd MTD device structure
1174 *
1175 * Sync is actually a wait for chip ready function
1176 */
1177static void onenand_sync(struct mtd_info *mtd)
1178{
1179 DEBUG(MTD_DEBUG_LEVEL3, "onenand_sync: called\n");
1180
1181 /* Grab the lock and see if the device is available */
1182 onenand_get_device(mtd, FL_SYNCING);
1183
1184 /* Release it and go back */
1185 onenand_release_device(mtd);
1186}
1187
1188
1189/**
1190 * onenand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad
1191 * @param mtd MTD device structure
1192 * @param ofs offset relative to mtd start
1193 *
1194 * Check whether the block is bad
1195 */
1196static int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
1197{
1198 /* Check for invalid offset */
1199 if (ofs > mtd->size)
1200 return -EINVAL;
1201
1202 return onenand_block_checkbad(mtd, ofs, 1, 0);
1203}
1204
1205/**
1206 * onenand_default_block_markbad - [DEFAULT] mark a block bad
1207 * @param mtd MTD device structure
1208 * @param ofs offset from device start
1209 *
1210 * This is the default implementation, which can be overridden by
1211 * a hardware specific driver.
1212 */
1213static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
1214{
1215 struct onenand_chip *this = mtd->priv;
1216 struct bbm_info *bbm = this->bbm;
1217 u_char buf[2] = {0, 0};
1218 size_t retlen;
1219 int block;
1220
1221 /* Get block number */
1222 block = ((int) ofs) >> bbm->bbt_erase_shift;
1223 if (bbm->bbt)
1224 bbm->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
1225
1226 /* We write two bytes, so we dont have to mess with 16 bit access */
1227 ofs += mtd->oobsize + (bbm->badblockpos & ~0x01);
1228 return mtd->write_oob(mtd, ofs , 2, &retlen, buf);
1229}
1230
1231/**
1232 * onenand_block_markbad - [MTD Interface] Mark the block at the given offset as bad
1233 * @param mtd MTD device structure
1234 * @param ofs offset relative to mtd start
1235 *
1236 * Mark the block as bad
1237 */
1238static int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
1239{
1240 struct onenand_chip *this = mtd->priv;
1241 int ret;
1242
1243 ret = onenand_block_isbad(mtd, ofs);
1244 if (ret) {
1245 /* If it was bad already, return success and do nothing */
1246 if (ret > 0)
1247 return 0;
1248 return ret;
1249 }
1250
1251 return this->block_markbad(mtd, ofs);
1252}
1253
1254/**
1255 * onenand_unlock - [MTD Interface] Unlock block(s)
1256 * @param mtd MTD device structure
1257 * @param ofs offset relative to mtd start
1258 * @param len number of bytes to unlock
1259 *
1260 * Unlock one or more blocks
1261 */
1262static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1263{
1264 struct onenand_chip *this = mtd->priv;
1265 int start, end, block, value, status;
1266
1267 start = ofs >> this->erase_shift;
1268 end = len >> this->erase_shift;
1269
1270 /* Continuous lock scheme */
1271 if (this->options & ONENAND_CONT_LOCK) {
1272 /* Set start block address */
1273 this->write_word(start, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
1274 /* Set end block address */
1275 this->write_word(end - 1, this->base + ONENAND_REG_END_BLOCK_ADDRESS);
1276 /* Write unlock command */
1277 this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
1278
1279 /* There's no return value */
1280 this->wait(mtd, FL_UNLOCKING);
1281
1282 /* Sanity check */
1283 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
1284 & ONENAND_CTRL_ONGO)
1285 continue;
1286
1287 /* Check lock status */
1288 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
1289 if (!(status & ONENAND_WP_US))
1290 printk(KERN_ERR "wp status = 0x%x\n", status);
1291
1292 return 0;
1293 }
1294
1295 /* Block lock scheme */
1296 for (block = start; block < end; block++) {
1297 /* Set start block address */
1298 this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
1299 /* Write unlock command */
1300 this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
1301
1302 /* There's no return value */
1303 this->wait(mtd, FL_UNLOCKING);
1304
1305 /* Sanity check */
1306 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
1307 & ONENAND_CTRL_ONGO)
1308 continue;
1309
1310 /* Set block address for read block status */
1311 value = onenand_block_address(this, block);
1312 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
1313
1314 /* Check lock status */
1315 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
1316 if (!(status & ONENAND_WP_US))
1317 printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status);
1318 }
1319
1320 return 0;
1321}
1322
1323/**
1324 * onenand_print_device_info - Print device ID
1325 * @param device device ID
1326 *
1327 * Print device ID
1328 */
1329static void onenand_print_device_info(int device)
1330{
1331 int vcc, demuxed, ddp, density;
1332
1333 vcc = device & ONENAND_DEVICE_VCC_MASK;
1334 demuxed = device & ONENAND_DEVICE_IS_DEMUX;
1335 ddp = device & ONENAND_DEVICE_IS_DDP;
1336 density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
1337 printk(KERN_INFO "%sOneNAND%s %dMB %sV 16-bit (0x%02x)\n",
1338 demuxed ? "" : "Muxed ",
1339 ddp ? "(DDP)" : "",
1340 (16 << density),
1341 vcc ? "2.65/3.3" : "1.8",
1342 device);
1343}
1344
1345static const struct onenand_manufacturers onenand_manuf_ids[] = {
1346 {ONENAND_MFR_SAMSUNG, "Samsung"},
1347 {ONENAND_MFR_UNKNOWN, "Unknown"}
1348};
1349
1350/**
1351 * onenand_check_maf - Check manufacturer ID
1352 * @param manuf manufacturer ID
1353 *
1354 * Check manufacturer ID
1355 */
1356static int onenand_check_maf(int manuf)
1357{
1358 int i;
1359
1360 for (i = 0; onenand_manuf_ids[i].id; i++) {
1361 if (manuf == onenand_manuf_ids[i].id)
1362 break;
1363 }
1364
1365 printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n",
1366 onenand_manuf_ids[i].name, manuf);
1367
1368 return (i != ONENAND_MFR_UNKNOWN);
1369}
1370
1371/**
1372 * onenand_probe - [OneNAND Interface] Probe the OneNAND device
1373 * @param mtd MTD device structure
1374 *
1375 * OneNAND detection method:
1376 * Compare the the values from command with ones from register
1377 */
1378static int onenand_probe(struct mtd_info *mtd)
1379{
1380 struct onenand_chip *this = mtd->priv;
1381 int bram_maf_id, bram_dev_id, maf_id, dev_id;
1382 int version_id;
1383 int density;
1384
1385 /* Send the command for reading device ID from BootRAM */
1386 this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
1387
1388 /* Read manufacturer and device IDs from BootRAM */
1389 bram_maf_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x0);
1390 bram_dev_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x2);
1391
1392 /* Check manufacturer ID */
1393 if (onenand_check_maf(bram_maf_id))
1394 return -ENXIO;
1395
1396 /* Reset OneNAND to read default register values */
1397 this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
1398
1399 /* Read manufacturer and device IDs from Register */
1400 maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
1401 dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
1402
1403 /* Check OneNAND device */
1404 if (maf_id != bram_maf_id || dev_id != bram_dev_id)
1405 return -ENXIO;
1406
1407 /* Flash device information */
1408 onenand_print_device_info(dev_id);
1409 this->device_id = dev_id;
1410
1411 density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
1412 this->chipsize = (16 << density) << 20;
1413 /* Set density mask. it is used for DDP */
1414 this->density_mask = (1 << (density + 6));
1415
1416 /* OneNAND page size & block size */
1417 /* The data buffer size is equal to page size */
1418 mtd->oobblock = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
1419 mtd->oobsize = mtd->oobblock >> 5;
1420 /* Pagers per block is always 64 in OneNAND */
1421 mtd->erasesize = mtd->oobblock << 6;
1422
1423 this->erase_shift = ffs(mtd->erasesize) - 1;
1424 this->page_shift = ffs(mtd->oobblock) - 1;
1425 this->ppb_shift = (this->erase_shift - this->page_shift);
1426 this->page_mask = (mtd->erasesize / mtd->oobblock) - 1;
1427
1428 /* REVIST: Multichip handling */
1429
1430 mtd->size = this->chipsize;
1431
1432 /* Version ID */
1433 version_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
1434 printk(KERN_DEBUG "OneNAND version = 0x%04x\n", version_id);
1435
1436 /* Lock scheme */
1437 if (density <= ONENAND_DEVICE_DENSITY_512Mb &&
1438 !(version_id >> ONENAND_VERSION_PROCESS_SHIFT)) {
1439 printk(KERN_INFO "Lock scheme is Continues Lock\n");
1440 this->options |= ONENAND_CONT_LOCK;
1441 }
1442
1443 return 0;
1444}
1445
1446/**
1447 * onenand_suspend - [MTD Interface] Suspend the OneNAND flash
1448 * @param mtd MTD device structure
1449 */
1450static int onenand_suspend(struct mtd_info *mtd)
1451{
1452 return onenand_get_device(mtd, FL_PM_SUSPENDED);
1453}
1454
1455/**
1456 * onenand_resume - [MTD Interface] Resume the OneNAND flash
1457 * @param mtd MTD device structure
1458 */
1459static void onenand_resume(struct mtd_info *mtd)
1460{
1461 struct onenand_chip *this = mtd->priv;
1462
1463 if (this->state == FL_PM_SUSPENDED)
1464 onenand_release_device(mtd);
1465 else
1466 printk(KERN_ERR "resume() called for the chip which is not"
1467 "in suspended state\n");
1468}
1469
1470
1471/**
1472 * onenand_scan - [OneNAND Interface] Scan for the OneNAND device
1473 * @param mtd MTD device structure
1474 * @param maxchips Number of chips to scan for
1475 *
1476 * This fills out all the not initialized function pointers
1477 * with the defaults.
1478 * The flash ID is read and the mtd/chip structures are
1479 * filled with the appropriate values.
1480 */
1481int onenand_scan(struct mtd_info *mtd, int maxchips)
1482{
1483 struct onenand_chip *this = mtd->priv;
1484
1485 if (!this->read_word)
1486 this->read_word = onenand_readw;
1487 if (!this->write_word)
1488 this->write_word = onenand_writew;
1489
1490 if (!this->command)
1491 this->command = onenand_command;
1492 if (!this->wait)
1493 this->wait = onenand_wait;
1494
1495 if (!this->read_bufferram)
1496 this->read_bufferram = onenand_read_bufferram;
1497 if (!this->write_bufferram)
1498 this->write_bufferram = onenand_write_bufferram;
1499
1500 if (!this->block_markbad)
1501 this->block_markbad = onenand_default_block_markbad;
1502 if (!this->scan_bbt)
1503 this->scan_bbt = onenand_default_bbt;
1504
1505 if (onenand_probe(mtd))
1506 return -ENXIO;
1507
1508 /* Set Sync. Burst Read after probing */
1509 if (this->mmcontrol) {
1510 printk(KERN_INFO "OneNAND Sync. Burst Read support\n");
1511 this->read_bufferram = onenand_sync_read_bufferram;
1512 }
1513
1514 this->state = FL_READY;
1515 init_waitqueue_head(&this->wq);
1516 spin_lock_init(&this->chip_lock);
1517
1518 switch (mtd->oobsize) {
1519 case 64:
1520 this->autooob = &onenand_oob_64;
1521 break;
1522
1523 case 32:
1524 this->autooob = &onenand_oob_32;
1525 break;
1526
1527 default:
1528 printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n",
1529 mtd->oobsize);
1530 /* To prevent kernel oops */
1531 this->autooob = &onenand_oob_32;
1532 break;
1533 }
1534
1535 memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo));
1536
1537 /* Fill in remaining MTD driver data */
1538 mtd->type = MTD_NANDFLASH;
1539 mtd->flags = MTD_CAP_NANDFLASH | MTD_ECC;
1540 mtd->ecctype = MTD_ECC_SW;
1541 mtd->erase = onenand_erase;
1542 mtd->point = NULL;
1543 mtd->unpoint = NULL;
1544 mtd->read = onenand_read;
1545 mtd->write = onenand_write;
1546 mtd->read_ecc = onenand_read_ecc;
1547 mtd->write_ecc = onenand_write_ecc;
1548 mtd->read_oob = onenand_read_oob;
1549 mtd->write_oob = onenand_write_oob;
1550 mtd->readv = NULL;
1551 mtd->readv_ecc = NULL;
1552 mtd->writev = onenand_writev;
1553 mtd->writev_ecc = onenand_writev_ecc;
1554 mtd->sync = onenand_sync;
1555 mtd->lock = NULL;
1556 mtd->unlock = onenand_unlock;
1557 mtd->suspend = onenand_suspend;
1558 mtd->resume = onenand_resume;
1559 mtd->block_isbad = onenand_block_isbad;
1560 mtd->block_markbad = onenand_block_markbad;
1561 mtd->owner = THIS_MODULE;
1562
1563 /* Unlock whole block */
1564 mtd->unlock(mtd, 0x0, this->chipsize);
1565
1566 return this->scan_bbt(mtd);
1567}
1568
1569/**
1570 * onenand_release - [OneNAND Interface] Free resources held by the OneNAND device
1571 * @param mtd MTD device structure
1572 */
1573void onenand_release(struct mtd_info *mtd)
1574{
1575#ifdef CONFIG_MTD_PARTITIONS
1576 /* Deregister partitions */
1577 del_mtd_partitions (mtd);
1578#endif
1579 /* Deregister the device */
1580 del_mtd_device (mtd);
1581}
1582
1583EXPORT_SYMBOL_GPL(onenand_scan);
1584EXPORT_SYMBOL_GPL(onenand_release);
1585
1586MODULE_LICENSE("GPL");
1587MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
1588MODULE_DESCRIPTION("Generic OneNAND flash driver code");
diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c
new file mode 100644
index 000000000000..f40190f499e1
--- /dev/null
+++ b/drivers/mtd/onenand/onenand_bbt.c
@@ -0,0 +1,246 @@
1/*
2 * linux/drivers/mtd/onenand/onenand_bbt.c
3 *
4 * Bad Block Table support for the OneNAND driver
5 *
6 * Copyright(c) 2005 Samsung Electronics
7 * Kyungmin Park <kyungmin.park@samsung.com>
8 *
9 * Derived from nand_bbt.c
10 *
11 * TODO:
12 * Split BBT core and chip specific BBT.
13 */
14
15#include <linux/slab.h>
16#include <linux/mtd/mtd.h>
17#include <linux/mtd/onenand.h>
18#include <linux/mtd/compatmac.h>
19
20/**
21 * check_short_pattern - [GENERIC] check if a pattern is in the buffer
22 * @param buf the buffer to search
23 * @param len the length of buffer to search
24 * @param paglen the pagelength
25 * @param td search pattern descriptor
26 *
27 * Check for a pattern at the given place. Used to search bad block
28 * tables and good / bad block identifiers. Same as check_pattern, but
29 * no optional empty check and the pattern is expected to start
30 * at offset 0.
31 *
32 */
33static int check_short_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
34{
35 int i;
36 uint8_t *p = buf;
37
38 /* Compare the pattern */
39 for (i = 0; i < td->len; i++) {
40 if (p[i] != td->pattern[i])
41 return -1;
42 }
43 return 0;
44}
45
46/**
47 * create_bbt - [GENERIC] Create a bad block table by scanning the device
48 * @param mtd MTD device structure
49 * @param buf temporary buffer
50 * @param bd descriptor for the good/bad block search pattern
51 * @param chip create the table for a specific chip, -1 read all chips.
52 * Applies only if NAND_BBT_PERCHIP option is set
53 *
54 * Create a bad block table by scanning the device
55 * for the given good/bad block identify pattern
56 */
57static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip)
58{
59 struct onenand_chip *this = mtd->priv;
60 struct bbm_info *bbm = this->bbm;
61 int i, j, numblocks, len, scanlen;
62 int startblock;
63 loff_t from;
64 size_t readlen, ooblen;
65
66 printk(KERN_INFO "Scanning device for bad blocks\n");
67
68 len = 1;
69
70 /* We need only read few bytes from the OOB area */
71 scanlen = ooblen = 0;
72 readlen = bd->len;
73
74 /* chip == -1 case only */
75 /* Note that numblocks is 2 * (real numblocks) here;
76 * see i += 2 below as it makses shifting and masking less painful
77 */
78 numblocks = mtd->size >> (bbm->bbt_erase_shift - 1);
79 startblock = 0;
80 from = 0;
81
82 for (i = startblock; i < numblocks; ) {
83 int ret;
84
85 for (j = 0; j < len; j++) {
86 size_t retlen;
87
88 /* No need to read pages fully,
89 * just read required OOB bytes */
90 ret = mtd->read_oob(mtd, from + j * mtd->oobblock + bd->offs,
91 readlen, &retlen, &buf[0]);
92
93 if (ret)
94 return ret;
95
96 if (check_short_pattern(&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
97 bbm->bbt[i >> 3] |= 0x03 << (i & 0x6);
98 printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
99 i >> 1, (unsigned int) from);
100 break;
101 }
102 }
103 i += 2;
104 from += (1 << bbm->bbt_erase_shift);
105 }
106
107 return 0;
108}
109
110
111/**
112 * onenand_memory_bbt - [GENERIC] create a memory based bad block table
113 * @param mtd MTD device structure
114 * @param bd descriptor for the good/bad block search pattern
115 *
116 * The function creates a memory based bbt by scanning the device
117 * for manufacturer / software marked good / bad blocks
118 */
119static inline int onenand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
120{
121 unsigned char data_buf[MAX_ONENAND_PAGESIZE];
122
123 bd->options &= ~NAND_BBT_SCANEMPTY;
124 return create_bbt(mtd, data_buf, bd, -1);
125}
126
127/**
128 * onenand_isbad_bbt - [OneNAND Interface] Check if a block is bad
129 * @param mtd MTD device structure
130 * @param offs offset in the device
131 * @param allowbbt allow access to bad block table region
132 */
133static int onenand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
134{
135 struct onenand_chip *this = mtd->priv;
136 struct bbm_info *bbm = this->bbm;
137 int block;
138 uint8_t res;
139
140 /* Get block number * 2 */
141 block = (int) (offs >> (bbm->bbt_erase_shift - 1));
142 res = (bbm->bbt[block >> 3] >> (block & 0x06)) & 0x03;
143
144 DEBUG(MTD_DEBUG_LEVEL2, "onenand_isbad_bbt: bbt info for offs 0x%08x: (block %d) 0x%02x\n",
145 (unsigned int) offs, block >> 1, res);
146
147 switch ((int) res) {
148 case 0x00: return 0;
149 case 0x01: return 1;
150 case 0x02: return allowbbt ? 0 : 1;
151 }
152
153 return 1;
154}
155
156/**
157 * onenand_scan_bbt - [OneNAND Interface] scan, find, read and maybe create bad block table(s)
158 * @param mtd MTD device structure
159 * @param bd descriptor for the good/bad block search pattern
160 *
161 * The function checks, if a bad block table(s) is/are already
162 * available. If not it scans the device for manufacturer
163 * marked good / bad blocks and writes the bad block table(s) to
164 * the selected place.
165 *
166 * The bad block table memory is allocated here. It must be freed
167 * by calling the onenand_free_bbt function.
168 *
169 */
170int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
171{
172 struct onenand_chip *this = mtd->priv;
173 struct bbm_info *bbm = this->bbm;
174 int len, ret = 0;
175
176 len = mtd->size >> (this->erase_shift + 2);
177 /* Allocate memory (2bit per block) */
178 bbm->bbt = kmalloc(len, GFP_KERNEL);
179 if (!bbm->bbt) {
180 printk(KERN_ERR "onenand_scan_bbt: Out of memory\n");
181 return -ENOMEM;
182 }
183 /* Clear the memory bad block table */
184 memset(bbm->bbt, 0x00, len);
185
186 /* Set the bad block position */
187 bbm->badblockpos = ONENAND_BADBLOCK_POS;
188
189 /* Set erase shift */
190 bbm->bbt_erase_shift = this->erase_shift;
191
192 if (!bbm->isbad_bbt)
193 bbm->isbad_bbt = onenand_isbad_bbt;
194
195 /* Scan the device to build a memory based bad block table */
196 if ((ret = onenand_memory_bbt(mtd, bd))) {
197 printk(KERN_ERR "onenand_scan_bbt: Can't scan flash and build the RAM-based BBT\n");
198 kfree(bbm->bbt);
199 bbm->bbt = NULL;
200 }
201
202 return ret;
203}
204
205/*
206 * Define some generic bad / good block scan pattern which are used
207 * while scanning a device for factory marked good / bad blocks.
208 */
209static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
210
211static struct nand_bbt_descr largepage_memorybased = {
212 .options = 0,
213 .offs = 0,
214 .len = 2,
215 .pattern = scan_ff_pattern,
216};
217
218/**
219 * onenand_default_bbt - [OneNAND Interface] Select a default bad block table for the device
220 * @param mtd MTD device structure
221 *
222 * This function selects the default bad block table
223 * support for the device and calls the onenand_scan_bbt function
224 */
225int onenand_default_bbt(struct mtd_info *mtd)
226{
227 struct onenand_chip *this = mtd->priv;
228 struct bbm_info *bbm;
229
230 this->bbm = kmalloc(sizeof(struct bbm_info), GFP_KERNEL);
231 if (!this->bbm)
232 return -ENOMEM;
233
234 bbm = this->bbm;
235
236 memset(bbm, 0, sizeof(struct bbm_info));
237
238 /* 1KB page has same configuration as 2KB page */
239 if (!bbm->badblock_pattern)
240 bbm->badblock_pattern = &largepage_memorybased;
241
242 return onenand_scan_bbt(mtd, bbm->badblock_pattern);
243}
244
245EXPORT_SYMBOL(onenand_scan_bbt);
246EXPORT_SYMBOL(onenand_default_bbt);
diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c
index 13f9e992bef8..7b7ca5ab5ae4 100644
--- a/drivers/mtd/redboot.c
+++ b/drivers/mtd/redboot.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: redboot.c,v 1.17 2004/11/22 11:33:56 ijc Exp $ 2 * $Id: redboot.c,v 1.18 2005/11/07 11:14:21 gleixner Exp $
3 * 3 *
4 * Parse RedBoot-style Flash Image System (FIS) tables and 4 * Parse RedBoot-style Flash Image System (FIS) tables and
5 * produce a Linux partition array to match. 5 * produce a Linux partition array to match.
@@ -39,7 +39,7 @@ static inline int redboot_checksum(struct fis_image_desc *img)
39 return 1; 39 return 1;
40} 40}
41 41
42static int parse_redboot_partitions(struct mtd_info *master, 42static int parse_redboot_partitions(struct mtd_info *master,
43 struct mtd_partition **pparts, 43 struct mtd_partition **pparts,
44 unsigned long fis_origin) 44 unsigned long fis_origin)
45{ 45{
diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c
new file mode 100644
index 000000000000..041ee59ea77d
--- /dev/null
+++ b/drivers/mtd/rfd_ftl.c
@@ -0,0 +1,855 @@
1/*
2 * rfd_ftl.c -- resident flash disk (flash translation layer)
3 *
4 * Copyright (C) 2005 Sean Young <sean@mess.org>
5 *
6 * $Id: rfd_ftl.c,v 1.5 2005/11/07 11:14:21 gleixner Exp $
7 *
8 * This type of flash translation layer (FTL) is used by the Embedded BIOS
9 * by General Software. It is known as the Resident Flash Disk (RFD), see:
10 *
11 * http://www.gensw.com/pages/prod/bios/rfd.htm
12 *
13 * based on ftl.c
14 */
15
16#include <linux/hdreg.h>
17#include <linux/init.h>
18#include <linux/mtd/blktrans.h>
19#include <linux/mtd/mtd.h>
20#include <linux/vmalloc.h>
21
22#include <asm/types.h>
23
24#define const_cpu_to_le16 __constant_cpu_to_le16
25
26static int block_size = 0;
27module_param(block_size, int, 0);
28MODULE_PARM_DESC(block_size, "Block size to use by RFD, defaults to erase unit size");
29
30#define PREFIX "rfd_ftl: "
31
32/* Major device # for FTL device */
33
34/* A request for this major has been sent to device@lanana.org */
35#ifndef RFD_FTL_MAJOR
36#define RFD_FTL_MAJOR 95
37#endif
38
39/* Maximum number of partitions in an FTL region */
40#define PART_BITS 4
41
42/* An erase unit should start with this value */
43#define RFD_MAGIC 0x9193
44
45/* the second value is 0xffff or 0xffc8; function unknown */
46
47/* the third value is always 0xffff, ignored */
48
49/* next is an array of mapping for each corresponding sector */
50#define HEADER_MAP_OFFSET 3
51#define SECTOR_DELETED 0x0000
52#define SECTOR_ZERO 0xfffe
53#define SECTOR_FREE 0xffff
54
55#define SECTOR_SIZE 512
56
57#define SECTORS_PER_TRACK 63
58
59struct block {
60 enum {
61 BLOCK_OK,
62 BLOCK_ERASING,
63 BLOCK_ERASED,
64 BLOCK_FAILED
65 } state;
66 int free_sectors;
67 int used_sectors;
68 int erases;
69 u_long offset;
70};
71
72struct partition {
73 struct mtd_blktrans_dev mbd;
74
75 u_int block_size; /* size of erase unit */
76 u_int total_blocks; /* number of erase units */
77 u_int header_sectors_per_block; /* header sectors in erase unit */
78 u_int data_sectors_per_block; /* data sectors in erase unit */
79 u_int sector_count; /* sectors in translated disk */
80 u_int header_size; /* bytes in header sector */
81 int reserved_block; /* block next up for reclaim */
82 int current_block; /* block to write to */
83 u16 *header_cache; /* cached header */
84
85 int is_reclaiming;
86 int cylinders;
87 int errors;
88 u_long *sector_map;
89 struct block *blocks;
90};
91
92static int rfd_ftl_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf);
93
94static int build_block_map(struct partition *part, int block_no)
95{
96 struct block *block = &part->blocks[block_no];
97 int i;
98
99 block->offset = part->block_size * block_no;
100
101 if (le16_to_cpu(part->header_cache[0]) != RFD_MAGIC) {
102 block->state = BLOCK_ERASED; /* assumption */
103 block->free_sectors = part->data_sectors_per_block;
104 part->reserved_block = block_no;
105 return 1;
106 }
107
108 block->state = BLOCK_OK;
109
110 for (i=0; i<part->data_sectors_per_block; i++) {
111 u16 entry;
112
113 entry = le16_to_cpu(part->header_cache[HEADER_MAP_OFFSET + i]);
114
115 if (entry == SECTOR_DELETED)
116 continue;
117
118 if (entry == SECTOR_FREE) {
119 block->free_sectors++;
120 continue;
121 }
122
123 if (entry == SECTOR_ZERO)
124 entry = 0;
125
126 if (entry >= part->sector_count) {
127 printk(KERN_NOTICE PREFIX
128 "'%s': unit #%d: entry %d corrupt, "
129 "sector %d out of range\n",
130 part->mbd.mtd->name, block_no, i, entry);
131 continue;
132 }
133
134 if (part->sector_map[entry] != -1) {
135 printk(KERN_NOTICE PREFIX
136 "'%s': more than one entry for sector %d\n",
137 part->mbd.mtd->name, entry);
138 part->errors = 1;
139 continue;
140 }
141
142 part->sector_map[entry] = block->offset +
143 (i + part->header_sectors_per_block) * SECTOR_SIZE;
144
145 block->used_sectors++;
146 }
147
148 if (block->free_sectors == part->data_sectors_per_block)
149 part->reserved_block = block_no;
150
151 return 0;
152}
153
154static int scan_header(struct partition *part)
155{
156 int sectors_per_block;
157 int i, rc = -ENOMEM;
158 int blocks_found;
159 size_t retlen;
160
161 sectors_per_block = part->block_size / SECTOR_SIZE;
162 part->total_blocks = part->mbd.mtd->size / part->block_size;
163
164 if (part->total_blocks < 2)
165 return -ENOENT;
166
167 /* each erase block has three bytes header, followed by the map */
168 part->header_sectors_per_block =
169 ((HEADER_MAP_OFFSET + sectors_per_block) *
170 sizeof(u16) + SECTOR_SIZE - 1) / SECTOR_SIZE;
171
172 part->data_sectors_per_block = sectors_per_block -
173 part->header_sectors_per_block;
174
175 part->header_size = (HEADER_MAP_OFFSET +
176 part->data_sectors_per_block) * sizeof(u16);
177
178 part->cylinders = (part->data_sectors_per_block *
179 (part->total_blocks - 1) - 1) / SECTORS_PER_TRACK;
180
181 part->sector_count = part->cylinders * SECTORS_PER_TRACK;
182
183 part->current_block = -1;
184 part->reserved_block = -1;
185 part->is_reclaiming = 0;
186
187 part->header_cache = kmalloc(part->header_size, GFP_KERNEL);
188 if (!part->header_cache)
189 goto err;
190
191 part->blocks = kcalloc(part->total_blocks, sizeof(struct block),
192 GFP_KERNEL);
193 if (!part->blocks)
194 goto err;
195
196 part->sector_map = vmalloc(part->sector_count * sizeof(u_long));
197 if (!part->sector_map) {
198 printk(KERN_ERR PREFIX "'%s': unable to allocate memory for "
199 "sector map", part->mbd.mtd->name);
200 goto err;
201 }
202
203 for (i=0; i<part->sector_count; i++)
204 part->sector_map[i] = -1;
205
206 for (i=0, blocks_found=0; i<part->total_blocks; i++) {
207 rc = part->mbd.mtd->read(part->mbd.mtd,
208 i * part->block_size, part->header_size,
209 &retlen, (u_char*)part->header_cache);
210
211 if (!rc && retlen != part->header_size)
212 rc = -EIO;
213
214 if (rc)
215 goto err;
216
217 if (!build_block_map(part, i))
218 blocks_found++;
219 }
220
221 if (blocks_found == 0) {
222 printk(KERN_NOTICE PREFIX "no RFD magic found in '%s'\n",
223 part->mbd.mtd->name);
224 rc = -ENOENT;
225 goto err;
226 }
227
228 if (part->reserved_block == -1) {
229 printk(KERN_NOTICE PREFIX "'%s': no empty erase unit found\n",
230 part->mbd.mtd->name);
231
232 part->errors = 1;
233 }
234
235 return 0;
236
237err:
238 vfree(part->sector_map);
239 kfree(part->header_cache);
240 kfree(part->blocks);
241
242 return rc;
243}
244
245static int rfd_ftl_readsect(struct mtd_blktrans_dev *dev, u_long sector, char *buf)
246{
247 struct partition *part = (struct partition*)dev;
248 u_long addr;
249 size_t retlen;
250 int rc;
251
252 if (sector >= part->sector_count)
253 return -EIO;
254
255 addr = part->sector_map[sector];
256 if (addr != -1) {
257 rc = part->mbd.mtd->read(part->mbd.mtd, addr, SECTOR_SIZE,
258 &retlen, (u_char*)buf);
259 if (!rc && retlen != SECTOR_SIZE)
260 rc = -EIO;
261
262 if (rc) {
263 printk(KERN_WARNING PREFIX "error reading '%s' at "
264 "0x%lx\n", part->mbd.mtd->name, addr);
265 return rc;
266 }
267 } else
268 memset(buf, 0, SECTOR_SIZE);
269
270 return 0;
271}
272
273static void erase_callback(struct erase_info *erase)
274{
275 struct partition *part;
276 u16 magic;
277 int i, rc;
278 size_t retlen;
279
280 part = (struct partition*)erase->priv;
281
282 i = erase->addr / part->block_size;
283 if (i >= part->total_blocks || part->blocks[i].offset != erase->addr) {
284 printk(KERN_ERR PREFIX "erase callback for unknown offset %x "
285 "on '%s'\n", erase->addr, part->mbd.mtd->name);
286 return;
287 }
288
289 if (erase->state != MTD_ERASE_DONE) {
290 printk(KERN_WARNING PREFIX "erase failed at 0x%x on '%s', "
291 "state %d\n", erase->addr,
292 part->mbd.mtd->name, erase->state);
293
294 part->blocks[i].state = BLOCK_FAILED;
295 part->blocks[i].free_sectors = 0;
296 part->blocks[i].used_sectors = 0;
297
298 kfree(erase);
299
300 return;
301 }
302
303 magic = const_cpu_to_le16(RFD_MAGIC);
304
305 part->blocks[i].state = BLOCK_ERASED;
306 part->blocks[i].free_sectors = part->data_sectors_per_block;
307 part->blocks[i].used_sectors = 0;
308 part->blocks[i].erases++;
309
310 rc = part->mbd.mtd->write(part->mbd.mtd,
311 part->blocks[i].offset, sizeof(magic), &retlen,
312 (u_char*)&magic);
313
314 if (!rc && retlen != sizeof(magic))
315 rc = -EIO;
316
317 if (rc) {
318 printk(KERN_NOTICE PREFIX "'%s': unable to write RFD "
319 "header at 0x%lx\n",
320 part->mbd.mtd->name,
321 part->blocks[i].offset);
322 part->blocks[i].state = BLOCK_FAILED;
323 }
324 else
325 part->blocks[i].state = BLOCK_OK;
326
327 kfree(erase);
328}
329
330static int erase_block(struct partition *part, int block)
331{
332 struct erase_info *erase;
333 int rc = -ENOMEM;
334
335 erase = kmalloc(sizeof(struct erase_info), GFP_KERNEL);
336 if (!erase)
337 goto err;
338
339 erase->mtd = part->mbd.mtd;
340 erase->callback = erase_callback;
341 erase->addr = part->blocks[block].offset;
342 erase->len = part->block_size;
343 erase->priv = (u_long)part;
344
345 part->blocks[block].state = BLOCK_ERASING;
346 part->blocks[block].free_sectors = 0;
347
348 rc = part->mbd.mtd->erase(part->mbd.mtd, erase);
349
350 if (rc) {
351 printk(KERN_WARNING PREFIX "erase of region %x,%x on '%s' "
352 "failed\n", erase->addr, erase->len,
353 part->mbd.mtd->name);
354 kfree(erase);
355 }
356
357err:
358 return rc;
359}
360
361static int move_block_contents(struct partition *part, int block_no, u_long *old_sector)
362{
363 void *sector_data;
364 u16 *map;
365 size_t retlen;
366 int i, rc = -ENOMEM;
367
368 part->is_reclaiming = 1;
369
370 sector_data = kmalloc(SECTOR_SIZE, GFP_KERNEL);
371 if (!sector_data)
372 goto err3;
373
374 map = kmalloc(part->header_size, GFP_KERNEL);
375 if (!map)
376 goto err2;
377
378 rc = part->mbd.mtd->read(part->mbd.mtd,
379 part->blocks[block_no].offset, part->header_size,
380 &retlen, (u_char*)map);
381
382 if (!rc && retlen != part->header_size)
383 rc = -EIO;
384
385 if (rc) {
386 printk(KERN_NOTICE PREFIX "error reading '%s' at "
387 "0x%lx\n", part->mbd.mtd->name,
388 part->blocks[block_no].offset);
389
390 goto err;
391 }
392
393 for (i=0; i<part->data_sectors_per_block; i++) {
394 u16 entry = le16_to_cpu(map[HEADER_MAP_OFFSET + i]);
395 u_long addr;
396
397
398 if (entry == SECTOR_FREE || entry == SECTOR_DELETED)
399 continue;
400
401 if (entry == SECTOR_ZERO)
402 entry = 0;
403
404 /* already warned about and ignored in build_block_map() */
405 if (entry >= part->sector_count)
406 continue;
407
408 addr = part->blocks[block_no].offset +
409 (i + part->header_sectors_per_block) * SECTOR_SIZE;
410
411 if (*old_sector == addr) {
412 *old_sector = -1;
413 if (!part->blocks[block_no].used_sectors--) {
414 rc = erase_block(part, block_no);
415 break;
416 }
417 continue;
418 }
419 rc = part->mbd.mtd->read(part->mbd.mtd, addr,
420 SECTOR_SIZE, &retlen, sector_data);
421
422 if (!rc && retlen != SECTOR_SIZE)
423 rc = -EIO;
424
425 if (rc) {
426 printk(KERN_NOTICE PREFIX "'%s': Unable to "
427 "read sector for relocation\n",
428 part->mbd.mtd->name);
429
430 goto err;
431 }
432
433 rc = rfd_ftl_writesect((struct mtd_blktrans_dev*)part,
434 entry, sector_data);
435
436 if (rc)
437 goto err;
438 }
439
440err:
441 kfree(map);
442err2:
443 kfree(sector_data);
444err3:
445 part->is_reclaiming = 0;
446
447 return rc;
448}
449
450static int reclaim_block(struct partition *part, u_long *old_sector)
451{
452 int block, best_block, score, old_sector_block;
453 int rc;
454
455 /* we have a race if sync doesn't exist */
456 if (part->mbd.mtd->sync)
457 part->mbd.mtd->sync(part->mbd.mtd);
458
459 score = 0x7fffffff; /* MAX_INT */
460 best_block = -1;
461 if (*old_sector != -1)
462 old_sector_block = *old_sector / part->block_size;
463 else
464 old_sector_block = -1;
465
466 for (block=0; block<part->total_blocks; block++) {
467 int this_score;
468
469 if (block == part->reserved_block)
470 continue;
471
472 /*
473 * Postpone reclaiming if there is a free sector as
474 * more removed sectors is more efficient (have to move
475 * less).
476 */
477 if (part->blocks[block].free_sectors)
478 return 0;
479
480 this_score = part->blocks[block].used_sectors;
481
482 if (block == old_sector_block)
483 this_score--;
484 else {
485 /* no point in moving a full block */
486 if (part->blocks[block].used_sectors ==
487 part->data_sectors_per_block)
488 continue;
489 }
490
491 this_score += part->blocks[block].erases;
492
493 if (this_score < score) {
494 best_block = block;
495 score = this_score;
496 }
497 }
498
499 if (best_block == -1)
500 return -ENOSPC;
501
502 part->current_block = -1;
503 part->reserved_block = best_block;
504
505 pr_debug("reclaim_block: reclaiming block #%d with %d used "
506 "%d free sectors\n", best_block,
507 part->blocks[best_block].used_sectors,
508 part->blocks[best_block].free_sectors);
509
510 if (part->blocks[best_block].used_sectors)
511 rc = move_block_contents(part, best_block, old_sector);
512 else
513 rc = erase_block(part, best_block);
514
515 return rc;
516}
517
518/*
519 * IMPROVE: It would be best to choose the block with the most deleted sectors,
520 * because if we fill that one up first it'll have the most chance of having
521 * the least live sectors at reclaim.
522 */
523static int find_free_block(const struct partition *part)
524{
525 int block, stop;
526
527 block = part->current_block == -1 ?
528 jiffies % part->total_blocks : part->current_block;
529 stop = block;
530
531 do {
532 if (part->blocks[block].free_sectors &&
533 block != part->reserved_block)
534 return block;
535
536 if (++block >= part->total_blocks)
537 block = 0;
538
539 } while (block != stop);
540
541 return -1;
542}
543
544static int find_writeable_block(struct partition *part, u_long *old_sector)
545{
546 int rc, block;
547 size_t retlen;
548
549 block = find_free_block(part);
550
551 if (block == -1) {
552 if (!part->is_reclaiming) {
553 rc = reclaim_block(part, old_sector);
554 if (rc)
555 goto err;
556
557 block = find_free_block(part);
558 }
559
560 if (block == -1) {
561 rc = -ENOSPC;
562 goto err;
563 }
564 }
565
566 rc = part->mbd.mtd->read(part->mbd.mtd, part->blocks[block].offset,
567 part->header_size, &retlen, (u_char*)part->header_cache);
568
569 if (!rc && retlen != part->header_size)
570 rc = -EIO;
571
572 if (rc) {
573 printk(KERN_NOTICE PREFIX "'%s': unable to read header at "
574 "0x%lx\n", part->mbd.mtd->name,
575 part->blocks[block].offset);
576 goto err;
577 }
578
579 part->current_block = block;
580
581err:
582 return rc;
583}
584
585static int mark_sector_deleted(struct partition *part, u_long old_addr)
586{
587 int block, offset, rc;
588 u_long addr;
589 size_t retlen;
590 u16 del = const_cpu_to_le16(SECTOR_DELETED);
591
592 block = old_addr / part->block_size;
593 offset = (old_addr % part->block_size) / SECTOR_SIZE -
594 part->header_sectors_per_block;
595
596 addr = part->blocks[block].offset +
597 (HEADER_MAP_OFFSET + offset) * sizeof(u16);
598 rc = part->mbd.mtd->write(part->mbd.mtd, addr,
599 sizeof(del), &retlen, (u_char*)&del);
600
601 if (!rc && retlen != sizeof(del))
602 rc = -EIO;
603
604 if (rc) {
605 printk(KERN_WARNING PREFIX "error writing '%s' at "
606 "0x%lx\n", part->mbd.mtd->name, addr);
607 if (rc)
608 goto err;
609 }
610 if (block == part->current_block)
611 part->header_cache[offset + HEADER_MAP_OFFSET] = del;
612
613 part->blocks[block].used_sectors--;
614
615 if (!part->blocks[block].used_sectors &&
616 !part->blocks[block].free_sectors)
617 rc = erase_block(part, block);
618
619err:
620 return rc;
621}
622
623static int find_free_sector(const struct partition *part, const struct block *block)
624{
625 int i, stop;
626
627 i = stop = part->data_sectors_per_block - block->free_sectors;
628
629 do {
630 if (le16_to_cpu(part->header_cache[HEADER_MAP_OFFSET + i])
631 == SECTOR_FREE)
632 return i;
633
634 if (++i == part->data_sectors_per_block)
635 i = 0;
636 }
637 while(i != stop);
638
639 return -1;
640}
641
642static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf, ulong *old_addr)
643{
644 struct partition *part = (struct partition*)dev;
645 struct block *block;
646 u_long addr;
647 int i;
648 int rc;
649 size_t retlen;
650 u16 entry;
651
652 if (part->current_block == -1 ||
653 !part->blocks[part->current_block].free_sectors) {
654
655 rc = find_writeable_block(part, old_addr);
656 if (rc)
657 goto err;
658 }
659
660 block = &part->blocks[part->current_block];
661
662 i = find_free_sector(part, block);
663
664 if (i < 0) {
665 rc = -ENOSPC;
666 goto err;
667 }
668
669 addr = (i + part->header_sectors_per_block) * SECTOR_SIZE +
670 block->offset;
671 rc = part->mbd.mtd->write(part->mbd.mtd,
672 addr, SECTOR_SIZE, &retlen, (u_char*)buf);
673
674 if (!rc && retlen != SECTOR_SIZE)
675 rc = -EIO;
676
677 if (rc) {
678 printk(KERN_WARNING PREFIX "error writing '%s' at 0x%lx\n",
679 part->mbd.mtd->name, addr);
680 if (rc)
681 goto err;
682 }
683
684 part->sector_map[sector] = addr;
685
686 entry = cpu_to_le16(sector == 0 ? SECTOR_ZERO : sector);
687
688 part->header_cache[i + HEADER_MAP_OFFSET] = entry;
689
690 addr = block->offset + (HEADER_MAP_OFFSET + i) * sizeof(u16);
691 rc = part->mbd.mtd->write(part->mbd.mtd, addr,
692 sizeof(entry), &retlen, (u_char*)&entry);
693
694 if (!rc && retlen != sizeof(entry))
695 rc = -EIO;
696
697 if (rc) {
698 printk(KERN_WARNING PREFIX "error writing '%s' at 0x%lx\n",
699 part->mbd.mtd->name, addr);
700 if (rc)
701 goto err;
702 }
703 block->used_sectors++;
704 block->free_sectors--;
705
706err:
707 return rc;
708}
709
710static int rfd_ftl_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf)
711{
712 struct partition *part = (struct partition*)dev;
713 u_long old_addr;
714 int i;
715 int rc = 0;
716
717 pr_debug("rfd_ftl_writesect(sector=0x%lx)\n", sector);
718
719 if (part->reserved_block == -1) {
720 rc = -EACCES;
721 goto err;
722 }
723
724 if (sector >= part->sector_count) {
725 rc = -EIO;
726 goto err;
727 }
728
729 old_addr = part->sector_map[sector];
730
731 for (i=0; i<SECTOR_SIZE; i++) {
732 if (!buf[i])
733 continue;
734
735 rc = do_writesect(dev, sector, buf, &old_addr);
736 if (rc)
737 goto err;
738 break;
739 }
740
741 if (i == SECTOR_SIZE)
742 part->sector_map[sector] = -1;
743
744 if (old_addr != -1)
745 rc = mark_sector_deleted(part, old_addr);
746
747err:
748 return rc;
749}
750
751static int rfd_ftl_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo)
752{
753 struct partition *part = (struct partition*)dev;
754
755 geo->heads = 1;
756 geo->sectors = SECTORS_PER_TRACK;
757 geo->cylinders = part->cylinders;
758
759 return 0;
760}
761
762static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
763{
764 struct partition *part;
765
766 if (mtd->type != MTD_NORFLASH)
767 return;
768
769 part = kcalloc(1, sizeof(struct partition), GFP_KERNEL);
770 if (!part)
771 return;
772
773 part->mbd.mtd = mtd;
774
775 if (block_size)
776 part->block_size = block_size;
777 else {
778 if (!mtd->erasesize) {
779 printk(KERN_NOTICE PREFIX "please provide block_size");
780 return;
781 }
782 else
783 part->block_size = mtd->erasesize;
784 }
785
786 if (scan_header(part) == 0) {
787 part->mbd.size = part->sector_count;
788 part->mbd.blksize = SECTOR_SIZE;
789 part->mbd.tr = tr;
790 part->mbd.devnum = -1;
791 if (!(mtd->flags & MTD_WRITEABLE))
792 part->mbd.readonly = 1;
793 else if (part->errors) {
794 printk(KERN_NOTICE PREFIX "'%s': errors found, "
795 "setting read-only", mtd->name);
796 part->mbd.readonly = 1;
797 }
798
799 printk(KERN_INFO PREFIX "name: '%s' type: %d flags %x\n",
800 mtd->name, mtd->type, mtd->flags);
801
802 if (!add_mtd_blktrans_dev((void*)part))
803 return;
804 }
805
806 kfree(part);
807}
808
809static void rfd_ftl_remove_dev(struct mtd_blktrans_dev *dev)
810{
811 struct partition *part = (struct partition*)dev;
812 int i;
813
814 for (i=0; i<part->total_blocks; i++) {
815 pr_debug("rfd_ftl_remove_dev:'%s': erase unit #%02d: %d erases\n",
816 part->mbd.mtd->name, i, part->blocks[i].erases);
817 }
818
819 del_mtd_blktrans_dev(dev);
820 vfree(part->sector_map);
821 kfree(part->header_cache);
822 kfree(part->blocks);
823 kfree(part);
824}
825
826struct mtd_blktrans_ops rfd_ftl_tr = {
827 .name = "rfd",
828 .major = RFD_FTL_MAJOR,
829 .part_bits = PART_BITS,
830 .readsect = rfd_ftl_readsect,
831 .writesect = rfd_ftl_writesect,
832 .getgeo = rfd_ftl_getgeo,
833 .add_mtd = rfd_ftl_add_mtd,
834 .remove_dev = rfd_ftl_remove_dev,
835 .owner = THIS_MODULE,
836};
837
838static int __init init_rfd_ftl(void)
839{
840 return register_mtd_blktrans(&rfd_ftl_tr);
841}
842
843static void __exit cleanup_rfd_ftl(void)
844{
845 deregister_mtd_blktrans(&rfd_ftl_tr);
846}
847
848module_init(init_rfd_ftl);
849module_exit(cleanup_rfd_ftl);
850
851MODULE_LICENSE("GPL");
852MODULE_AUTHOR("Sean Young <sean@mess.org>");
853MODULE_DESCRIPTION("Support code for RFD Flash Translation Layer, "
854 "used by General Software's Embedded BIOS");
855
diff --git a/fs/Kconfig b/fs/Kconfig
index 7cf36ca157ff..7d6ae369ce44 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -1051,6 +1051,19 @@ config JFFS2_FS_WRITEBUFFER
1051 - NOR flash with transparent ECC 1051 - NOR flash with transparent ECC
1052 - DataFlash 1052 - DataFlash
1053 1053
1054config JFFS2_SUMMARY
1055 bool "JFFS2 summary support (EXPERIMENTAL)"
1056 depends on JFFS2_FS && EXPERIMENTAL
1057 default n
1058 help
1059 This feature makes it possible to use summary information
1060 for faster filesystem mount.
1061
1062 The summary information can be inserted into a filesystem image
1063 by the utility 'sumtool'.
1064
1065 If unsure, say 'N'.
1066
1054config JFFS2_COMPRESSION_OPTIONS 1067config JFFS2_COMPRESSION_OPTIONS
1055 bool "Advanced compression options for JFFS2" 1068 bool "Advanced compression options for JFFS2"
1056 depends on JFFS2_FS 1069 depends on JFFS2_FS
@@ -1072,10 +1085,10 @@ config JFFS2_ZLIB
1072 default y 1085 default y
1073 help 1086 help
1074 Zlib is designed to be a free, general-purpose, legally unencumbered, 1087 Zlib is designed to be a free, general-purpose, legally unencumbered,
1075 lossless data-compression library for use on virtually any computer 1088 lossless data-compression library for use on virtually any computer
1076 hardware and operating system. See <http://www.gzip.org/zlib/> for 1089 hardware and operating system. See <http://www.gzip.org/zlib/> for
1077 further information. 1090 further information.
1078 1091
1079 Say 'Y' if unsure. 1092 Say 'Y' if unsure.
1080 1093
1081config JFFS2_RTIME 1094config JFFS2_RTIME
@@ -1097,7 +1110,7 @@ choice
1097 default JFFS2_CMODE_PRIORITY 1110 default JFFS2_CMODE_PRIORITY
1098 depends on JFFS2_FS 1111 depends on JFFS2_FS
1099 help 1112 help
1100 You can set here the default compression mode of JFFS2 from 1113 You can set here the default compression mode of JFFS2 from
1101 the available compression modes. Don't touch if unsure. 1114 the available compression modes. Don't touch if unsure.
1102 1115
1103config JFFS2_CMODE_NONE 1116config JFFS2_CMODE_NONE
@@ -1108,13 +1121,13 @@ config JFFS2_CMODE_NONE
1108config JFFS2_CMODE_PRIORITY 1121config JFFS2_CMODE_PRIORITY
1109 bool "priority" 1122 bool "priority"
1110 help 1123 help
1111 Tries the compressors in a predefinied order and chooses the first 1124 Tries the compressors in a predefinied order and chooses the first
1112 successful one. 1125 successful one.
1113 1126
1114config JFFS2_CMODE_SIZE 1127config JFFS2_CMODE_SIZE
1115 bool "size (EXPERIMENTAL)" 1128 bool "size (EXPERIMENTAL)"
1116 help 1129 help
1117 Tries all compressors and chooses the one which has the smallest 1130 Tries all compressors and chooses the one which has the smallest
1118 result. 1131 result.
1119 1132
1120endchoice 1133endchoice
diff --git a/fs/jffs2/Makefile b/fs/jffs2/Makefile
index f1afe681ecd6..77dc5561a04e 100644
--- a/fs/jffs2/Makefile
+++ b/fs/jffs2/Makefile
@@ -1,7 +1,7 @@
1# 1#
2# Makefile for the Linux Journalling Flash File System v2 (JFFS2) 2# Makefile for the Linux Journalling Flash File System v2 (JFFS2)
3# 3#
4# $Id: Makefile.common,v 1.9 2005/02/09 09:23:53 pavlov Exp $ 4# $Id: Makefile.common,v 1.11 2005/09/07 08:34:53 havasi Exp $
5# 5#
6 6
7obj-$(CONFIG_JFFS2_FS) += jffs2.o 7obj-$(CONFIG_JFFS2_FS) += jffs2.o
@@ -9,9 +9,10 @@ obj-$(CONFIG_JFFS2_FS) += jffs2.o
9jffs2-y := compr.o dir.o file.o ioctl.o nodelist.o malloc.o 9jffs2-y := compr.o dir.o file.o ioctl.o nodelist.o malloc.o
10jffs2-y += read.o nodemgmt.o readinode.o write.o scan.o gc.o 10jffs2-y += read.o nodemgmt.o readinode.o write.o scan.o gc.o
11jffs2-y += symlink.o build.o erase.o background.o fs.o writev.o 11jffs2-y += symlink.o build.o erase.o background.o fs.o writev.o
12jffs2-y += super.o 12jffs2-y += super.o debug.o
13 13
14jffs2-$(CONFIG_JFFS2_FS_WRITEBUFFER) += wbuf.o 14jffs2-$(CONFIG_JFFS2_FS_WRITEBUFFER) += wbuf.o
15jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rubin.o 15jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rubin.o
16jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o 16jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o
17jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o 17jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o
18jffs2-$(CONFIG_JFFS2_SUMMARY) += summary.o
diff --git a/fs/jffs2/TODO b/fs/jffs2/TODO
index 2bff82fd221f..d0e23b26fa50 100644
--- a/fs/jffs2/TODO
+++ b/fs/jffs2/TODO
@@ -1,5 +1,11 @@
1$Id: TODO,v 1.10 2002/09/09 16:31:21 dwmw2 Exp $ 1$Id: TODO,v 1.18 2005/09/22 11:24:56 dedekind Exp $
2 2
3 - support asynchronous operation -- add a per-fs 'reserved_space' count,
4 let each outstanding write reserve the _maximum_ amount of physical
5 space it could take. Let GC flush the outstanding writes because the
6 reservations will necessarily be pessimistic. With this we could even
7 do shared writable mmap, if we can have a fs hook for do_wp_page() to
8 make the reservation.
3 - disable compression in commit_write()? 9 - disable compression in commit_write()?
4 - fine-tune the allocation / GC thresholds 10 - fine-tune the allocation / GC thresholds
5 - chattr support - turning on/off and tuning compression per-inode 11 - chattr support - turning on/off and tuning compression per-inode
@@ -11,26 +17,15 @@ $Id: TODO,v 1.10 2002/09/09 16:31:21 dwmw2 Exp $
11 - test, test, test 17 - test, test, test
12 18
13 - NAND flash support: 19 - NAND flash support:
14 - flush_wbuf using GC to fill it, don't just pad. 20 - almost done :)
15 - Deal with write errors. Data don't get lost - we just have to write 21 - use bad block check instead of the hardwired byte check
16 the affected node(s) out again somewhere else.
17 - make fsync flush only if actually required
18 - make sys_sync() work.
19 - reboot notifier
20 - timed flush of old wbuf
21 - fix magical second arg of jffs2_flush_wbuf(). Split into two or more functions instead.
22
23 22
24 - Optimisations: 23 - Optimisations:
25 - Stop GC from decompressing and immediately recompressing nodes which could 24 - Split writes so they go to two separate blocks rather than just c->nextblock.
26 just be copied intact. (We now keep track of REF_PRISTINE flag. Easy now.) 25 By writing _new_ nodes to one block, and garbage-collected REF_PRISTINE
27 - Furthermore, in the case where it could be copied intact we don't even need 26 nodes to a different one, we can separate clean nodes from those which
28 to call iget() for it -- if we use (raw_node_raw->flash_offset & 2) as a flag 27 are likely to become dirty, and end up with blocks which are each far
29 to show a node can be copied intact and it's _not_ in icache, we could just do 28 closer to 100% or 0% clean, hence speeding up later GC progress dramatically.
30 it, fix up the next_in_ino list and move on. We would need a way to find out
31 _whether_ it's in icache though -- if it's in icache we also need to do the
32 fragment lists, etc. P'raps a flag or pointer in the jffs2_inode_cache could
33 help. (We have half of this now.)
34 - Stop keeping name in-core with struct jffs2_full_dirent. If we keep the hash in 29 - Stop keeping name in-core with struct jffs2_full_dirent. If we keep the hash in
35 the full dirent, we only need to go to the flash in lookup() when we think we've 30 the full dirent, we only need to go to the flash in lookup() when we think we've
36 got a match, and in readdir(). 31 got a match, and in readdir().
@@ -38,3 +33,8 @@ $Id: TODO,v 1.10 2002/09/09 16:31:21 dwmw2 Exp $
38 - Remove totlen from jffs2_raw_node_ref? Need to have totlen passed into 33 - Remove totlen from jffs2_raw_node_ref? Need to have totlen passed into
39 jffs2_mark_node_obsolete(). Can all callers work it out? 34 jffs2_mark_node_obsolete(). Can all callers work it out?
40 - Remove size from jffs2_raw_node_frag. 35 - Remove size from jffs2_raw_node_frag.
36
37dedekind:
381. __jffs2_flush_wbuf() has a strange 'pad' parameter. Eliminate.
392. get_sb()->build_fs()->scan() path... Why get_sb() removes scan()'s crap in
40 case of failure? scan() does not clean everything. Fix.
diff --git a/fs/jffs2/background.c b/fs/jffs2/background.c
index 8210ac16a368..7b77a9541125 100644
--- a/fs/jffs2/background.c
+++ b/fs/jffs2/background.c
@@ -51,7 +51,7 @@ int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c)
51 D1(printk(KERN_DEBUG "JFFS2: Garbage collect thread is pid %d\n", pid)); 51 D1(printk(KERN_DEBUG "JFFS2: Garbage collect thread is pid %d\n", pid));
52 wait_for_completion(&c->gc_thread_start); 52 wait_for_completion(&c->gc_thread_start);
53 } 53 }
54 54
55 return ret; 55 return ret;
56} 56}
57 57
@@ -101,7 +101,7 @@ static int jffs2_garbage_collect_thread(void *_c)
101 101
102 cond_resched(); 102 cond_resched();
103 103
104 /* Put_super will send a SIGKILL and then wait on the sem. 104 /* Put_super will send a SIGKILL and then wait on the sem.
105 */ 105 */
106 while (signal_pending(current)) { 106 while (signal_pending(current)) {
107 siginfo_t info; 107 siginfo_t info;
diff --git a/fs/jffs2/build.c b/fs/jffs2/build.c
index 97dc39796e2c..fff108bb118b 100644
--- a/fs/jffs2/build.c
+++ b/fs/jffs2/build.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: build.c,v 1.71 2005/07/12 16:37:08 dedekind Exp $ 10 * $Id: build.c,v 1.85 2005/11/07 11:14:38 gleixner Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -18,7 +18,8 @@
18#include <linux/mtd/mtd.h> 18#include <linux/mtd/mtd.h>
19#include "nodelist.h" 19#include "nodelist.h"
20 20
21static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *, struct jffs2_inode_cache *, struct jffs2_full_dirent **); 21static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *,
22 struct jffs2_inode_cache *, struct jffs2_full_dirent **);
22 23
23static inline struct jffs2_inode_cache * 24static inline struct jffs2_inode_cache *
24first_inode_chain(int *i, struct jffs2_sb_info *c) 25first_inode_chain(int *i, struct jffs2_sb_info *c)
@@ -46,11 +47,12 @@ next_inode(int *i, struct jffs2_inode_cache *ic, struct jffs2_sb_info *c)
46 ic = next_inode(&i, ic, (c))) 47 ic = next_inode(&i, ic, (c)))
47 48
48 49
49static inline void jffs2_build_inode_pass1(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) 50static inline void jffs2_build_inode_pass1(struct jffs2_sb_info *c,
51 struct jffs2_inode_cache *ic)
50{ 52{
51 struct jffs2_full_dirent *fd; 53 struct jffs2_full_dirent *fd;
52 54
53 D1(printk(KERN_DEBUG "jffs2_build_inode building directory inode #%u\n", ic->ino)); 55 dbg_fsbuild("building directory inode #%u\n", ic->ino);
54 56
55 /* For each child, increase nlink */ 57 /* For each child, increase nlink */
56 for(fd = ic->scan_dents; fd; fd = fd->next) { 58 for(fd = ic->scan_dents; fd; fd = fd->next) {
@@ -58,26 +60,23 @@ static inline void jffs2_build_inode_pass1(struct jffs2_sb_info *c, struct jffs2
58 if (!fd->ino) 60 if (!fd->ino)
59 continue; 61 continue;
60 62
61 /* XXX: Can get high latency here with huge directories */ 63 /* we can get high latency here with huge directories */
62 64
63 child_ic = jffs2_get_ino_cache(c, fd->ino); 65 child_ic = jffs2_get_ino_cache(c, fd->ino);
64 if (!child_ic) { 66 if (!child_ic) {
65 printk(KERN_NOTICE "Eep. Child \"%s\" (ino #%u) of dir ino #%u doesn't exist!\n", 67 dbg_fsbuild("child \"%s\" (ino #%u) of dir ino #%u doesn't exist!\n",
66 fd->name, fd->ino, ic->ino); 68 fd->name, fd->ino, ic->ino);
67 jffs2_mark_node_obsolete(c, fd->raw); 69 jffs2_mark_node_obsolete(c, fd->raw);
68 continue; 70 continue;
69 } 71 }
70 72
71 if (child_ic->nlink++ && fd->type == DT_DIR) { 73 if (child_ic->nlink++ && fd->type == DT_DIR) {
72 printk(KERN_NOTICE "Child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n", fd->name, fd->ino, ic->ino); 74 JFFS2_ERROR("child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n",
73 if (fd->ino == 1 && ic->ino == 1) { 75 fd->name, fd->ino, ic->ino);
74 printk(KERN_NOTICE "This is mostly harmless, and probably caused by creating a JFFS2 image\n"); 76 /* TODO: What do we do about it? */
75 printk(KERN_NOTICE "using a buggy version of mkfs.jffs2. Use at least v1.17.\n");
76 }
77 /* What do we do about it? */
78 } 77 }
79 D1(printk(KERN_DEBUG "Increased nlink for child \"%s\" (ino #%u)\n", fd->name, fd->ino)); 78 dbg_fsbuild("increased nlink for child \"%s\" (ino #%u)\n", fd->name, fd->ino);
80 /* Can't free them. We might need them in pass 2 */ 79 /* Can't free scan_dents so far. We might need them in pass 2 */
81 } 80 }
82} 81}
83 82
@@ -94,6 +93,8 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
94 struct jffs2_full_dirent *fd; 93 struct jffs2_full_dirent *fd;
95 struct jffs2_full_dirent *dead_fds = NULL; 94 struct jffs2_full_dirent *dead_fds = NULL;
96 95
96 dbg_fsbuild("build FS data structures\n");
97
97 /* First, scan the medium and build all the inode caches with 98 /* First, scan the medium and build all the inode caches with
98 lists of physical nodes */ 99 lists of physical nodes */
99 100
@@ -103,60 +104,54 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
103 if (ret) 104 if (ret)
104 goto exit; 105 goto exit;
105 106
106 D1(printk(KERN_DEBUG "Scanned flash completely\n")); 107 dbg_fsbuild("scanned flash completely\n");
107 D2(jffs2_dump_block_lists(c)); 108 jffs2_dbg_dump_block_lists_nolock(c);
108 109
110 dbg_fsbuild("pass 1 starting\n");
109 c->flags |= JFFS2_SB_FLAG_BUILDING; 111 c->flags |= JFFS2_SB_FLAG_BUILDING;
110 /* Now scan the directory tree, increasing nlink according to every dirent found. */ 112 /* Now scan the directory tree, increasing nlink according to every dirent found. */
111 for_each_inode(i, c, ic) { 113 for_each_inode(i, c, ic) {
112 D1(printk(KERN_DEBUG "Pass 1: ino #%u\n", ic->ino));
113
114 D1(BUG_ON(ic->ino > c->highest_ino));
115
116 if (ic->scan_dents) { 114 if (ic->scan_dents) {
117 jffs2_build_inode_pass1(c, ic); 115 jffs2_build_inode_pass1(c, ic);
118 cond_resched(); 116 cond_resched();
119 } 117 }
120 } 118 }
121 119
122 D1(printk(KERN_DEBUG "Pass 1 complete\n")); 120 dbg_fsbuild("pass 1 complete\n");
123 121
124 /* Next, scan for inodes with nlink == 0 and remove them. If 122 /* Next, scan for inodes with nlink == 0 and remove them. If
125 they were directories, then decrement the nlink of their 123 they were directories, then decrement the nlink of their
126 children too, and repeat the scan. As that's going to be 124 children too, and repeat the scan. As that's going to be
127 a fairly uncommon occurrence, it's not so evil to do it this 125 a fairly uncommon occurrence, it's not so evil to do it this
128 way. Recursion bad. */ 126 way. Recursion bad. */
129 D1(printk(KERN_DEBUG "Pass 2 starting\n")); 127 dbg_fsbuild("pass 2 starting\n");
130 128
131 for_each_inode(i, c, ic) { 129 for_each_inode(i, c, ic) {
132 D1(printk(KERN_DEBUG "Pass 2: ino #%u, nlink %d, ic %p, nodes %p\n", ic->ino, ic->nlink, ic, ic->nodes));
133 if (ic->nlink) 130 if (ic->nlink)
134 continue; 131 continue;
135 132
136 jffs2_build_remove_unlinked_inode(c, ic, &dead_fds); 133 jffs2_build_remove_unlinked_inode(c, ic, &dead_fds);
137 cond_resched(); 134 cond_resched();
138 } 135 }
139 136
140 D1(printk(KERN_DEBUG "Pass 2a starting\n")); 137 dbg_fsbuild("pass 2a starting\n");
141 138
142 while (dead_fds) { 139 while (dead_fds) {
143 fd = dead_fds; 140 fd = dead_fds;
144 dead_fds = fd->next; 141 dead_fds = fd->next;
145 142
146 ic = jffs2_get_ino_cache(c, fd->ino); 143 ic = jffs2_get_ino_cache(c, fd->ino);
147 D1(printk(KERN_DEBUG "Removing dead_fd ino #%u (\"%s\"), ic at %p\n", fd->ino, fd->name, ic));
148 144
149 if (ic) 145 if (ic)
150 jffs2_build_remove_unlinked_inode(c, ic, &dead_fds); 146 jffs2_build_remove_unlinked_inode(c, ic, &dead_fds);
151 jffs2_free_full_dirent(fd); 147 jffs2_free_full_dirent(fd);
152 } 148 }
153 149
154 D1(printk(KERN_DEBUG "Pass 2 complete\n")); 150 dbg_fsbuild("pass 2a complete\n");
155 151 dbg_fsbuild("freeing temporary data structures\n");
152
156 /* Finally, we can scan again and free the dirent structs */ 153 /* Finally, we can scan again and free the dirent structs */
157 for_each_inode(i, c, ic) { 154 for_each_inode(i, c, ic) {
158 D1(printk(KERN_DEBUG "Pass 3: ino #%u, ic %p, nodes %p\n", ic->ino, ic, ic->nodes));
159
160 while(ic->scan_dents) { 155 while(ic->scan_dents) {
161 fd = ic->scan_dents; 156 fd = ic->scan_dents;
162 ic->scan_dents = fd->next; 157 ic->scan_dents = fd->next;
@@ -166,9 +161,8 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
166 cond_resched(); 161 cond_resched();
167 } 162 }
168 c->flags &= ~JFFS2_SB_FLAG_BUILDING; 163 c->flags &= ~JFFS2_SB_FLAG_BUILDING;
169 164
170 D1(printk(KERN_DEBUG "Pass 3 complete\n")); 165 dbg_fsbuild("FS build complete\n");
171 D2(jffs2_dump_block_lists(c));
172 166
173 /* Rotate the lists by some number to ensure wear levelling */ 167 /* Rotate the lists by some number to ensure wear levelling */
174 jffs2_rotate_lists(c); 168 jffs2_rotate_lists(c);
@@ -189,24 +183,26 @@ exit:
189 return ret; 183 return ret;
190} 184}
191 185
192static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, struct jffs2_full_dirent **dead_fds) 186static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c,
187 struct jffs2_inode_cache *ic,
188 struct jffs2_full_dirent **dead_fds)
193{ 189{
194 struct jffs2_raw_node_ref *raw; 190 struct jffs2_raw_node_ref *raw;
195 struct jffs2_full_dirent *fd; 191 struct jffs2_full_dirent *fd;
196 192
197 D1(printk(KERN_DEBUG "JFFS2: Removing ino #%u with nlink == zero.\n", ic->ino)); 193 dbg_fsbuild("removing ino #%u with nlink == zero.\n", ic->ino);
198 194
199 raw = ic->nodes; 195 raw = ic->nodes;
200 while (raw != (void *)ic) { 196 while (raw != (void *)ic) {
201 struct jffs2_raw_node_ref *next = raw->next_in_ino; 197 struct jffs2_raw_node_ref *next = raw->next_in_ino;
202 D1(printk(KERN_DEBUG "obsoleting node at 0x%08x\n", ref_offset(raw))); 198 dbg_fsbuild("obsoleting node at 0x%08x\n", ref_offset(raw));
203 jffs2_mark_node_obsolete(c, raw); 199 jffs2_mark_node_obsolete(c, raw);
204 raw = next; 200 raw = next;
205 } 201 }
206 202
207 if (ic->scan_dents) { 203 if (ic->scan_dents) {
208 int whinged = 0; 204 int whinged = 0;
209 D1(printk(KERN_DEBUG "Inode #%u was a directory which may have children...\n", ic->ino)); 205 dbg_fsbuild("inode #%u was a directory which may have children...\n", ic->ino);
210 206
211 while(ic->scan_dents) { 207 while(ic->scan_dents) {
212 struct jffs2_inode_cache *child_ic; 208 struct jffs2_inode_cache *child_ic;
@@ -216,45 +212,43 @@ static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c, struct jf
216 212
217 if (!fd->ino) { 213 if (!fd->ino) {
218 /* It's a deletion dirent. Ignore it */ 214 /* It's a deletion dirent. Ignore it */
219 D1(printk(KERN_DEBUG "Child \"%s\" is a deletion dirent, skipping...\n", fd->name)); 215 dbg_fsbuild("child \"%s\" is a deletion dirent, skipping...\n", fd->name);
220 jffs2_free_full_dirent(fd); 216 jffs2_free_full_dirent(fd);
221 continue; 217 continue;
222 } 218 }
223 if (!whinged) { 219 if (!whinged)
224 whinged = 1; 220 whinged = 1;
225 printk(KERN_NOTICE "Inode #%u was a directory with children - removing those too...\n", ic->ino);
226 }
227 221
228 D1(printk(KERN_DEBUG "Removing child \"%s\", ino #%u\n", 222 dbg_fsbuild("removing child \"%s\", ino #%u\n", fd->name, fd->ino);
229 fd->name, fd->ino)); 223
230
231 child_ic = jffs2_get_ino_cache(c, fd->ino); 224 child_ic = jffs2_get_ino_cache(c, fd->ino);
232 if (!child_ic) { 225 if (!child_ic) {
233 printk(KERN_NOTICE "Cannot remove child \"%s\", ino #%u, because it doesn't exist\n", fd->name, fd->ino); 226 dbg_fsbuild("cannot remove child \"%s\", ino #%u, because it doesn't exist\n",
227 fd->name, fd->ino);
234 jffs2_free_full_dirent(fd); 228 jffs2_free_full_dirent(fd);
235 continue; 229 continue;
236 } 230 }
237 231
238 /* Reduce nlink of the child. If it's now zero, stick it on the 232 /* Reduce nlink of the child. If it's now zero, stick it on the
239 dead_fds list to be cleaned up later. Else just free the fd */ 233 dead_fds list to be cleaned up later. Else just free the fd */
240 234
241 child_ic->nlink--; 235 child_ic->nlink--;
242 236
243 if (!child_ic->nlink) { 237 if (!child_ic->nlink) {
244 D1(printk(KERN_DEBUG "Inode #%u (\"%s\") has now got zero nlink. Adding to dead_fds list.\n", 238 dbg_fsbuild("inode #%u (\"%s\") has now got zero nlink, adding to dead_fds list.\n",
245 fd->ino, fd->name)); 239 fd->ino, fd->name);
246 fd->next = *dead_fds; 240 fd->next = *dead_fds;
247 *dead_fds = fd; 241 *dead_fds = fd;
248 } else { 242 } else {
249 D1(printk(KERN_DEBUG "Inode #%u (\"%s\") has now got nlink %d. Ignoring.\n", 243 dbg_fsbuild("inode #%u (\"%s\") has now got nlink %d. Ignoring.\n",
250 fd->ino, fd->name, child_ic->nlink)); 244 fd->ino, fd->name, child_ic->nlink);
251 jffs2_free_full_dirent(fd); 245 jffs2_free_full_dirent(fd);
252 } 246 }
253 } 247 }
254 } 248 }
255 249
256 /* 250 /*
257 We don't delete the inocache from the hash list and free it yet. 251 We don't delete the inocache from the hash list and free it yet.
258 The erase code will do that, when all the nodes are completely gone. 252 The erase code will do that, when all the nodes are completely gone.
259 */ 253 */
260} 254}
@@ -268,7 +262,7 @@ static void jffs2_calc_trigger_levels(struct jffs2_sb_info *c)
268 because there's not enough free space... */ 262 because there's not enough free space... */
269 c->resv_blocks_deletion = 2; 263 c->resv_blocks_deletion = 2;
270 264
271 /* Be conservative about how much space we need before we allow writes. 265 /* Be conservative about how much space we need before we allow writes.
272 On top of that which is required for deletia, require an extra 2% 266 On top of that which is required for deletia, require an extra 2%
273 of the medium to be available, for overhead caused by nodes being 267 of the medium to be available, for overhead caused by nodes being
274 split across blocks, etc. */ 268 split across blocks, etc. */
@@ -283,7 +277,7 @@ static void jffs2_calc_trigger_levels(struct jffs2_sb_info *c)
283 277
284 c->resv_blocks_gctrigger = c->resv_blocks_write + 1; 278 c->resv_blocks_gctrigger = c->resv_blocks_write + 1;
285 279
286 /* When do we allow garbage collection to merge nodes to make 280 /* When do we allow garbage collection to merge nodes to make
287 long-term progress at the expense of short-term space exhaustion? */ 281 long-term progress at the expense of short-term space exhaustion? */
288 c->resv_blocks_gcmerge = c->resv_blocks_deletion + 1; 282 c->resv_blocks_gcmerge = c->resv_blocks_deletion + 1;
289 283
@@ -295,45 +289,45 @@ static void jffs2_calc_trigger_levels(struct jffs2_sb_info *c)
295 trying to GC to make more space. It'll be a fruitless task */ 289 trying to GC to make more space. It'll be a fruitless task */
296 c->nospc_dirty_size = c->sector_size + (c->flash_size / 100); 290 c->nospc_dirty_size = c->sector_size + (c->flash_size / 100);
297 291
298 D1(printk(KERN_DEBUG "JFFS2 trigger levels (size %d KiB, block size %d KiB, %d blocks)\n", 292 dbg_fsbuild("JFFS2 trigger levels (size %d KiB, block size %d KiB, %d blocks)\n",
299 c->flash_size / 1024, c->sector_size / 1024, c->nr_blocks)); 293 c->flash_size / 1024, c->sector_size / 1024, c->nr_blocks);
300 D1(printk(KERN_DEBUG "Blocks required to allow deletion: %d (%d KiB)\n", 294 dbg_fsbuild("Blocks required to allow deletion: %d (%d KiB)\n",
301 c->resv_blocks_deletion, c->resv_blocks_deletion*c->sector_size/1024)); 295 c->resv_blocks_deletion, c->resv_blocks_deletion*c->sector_size/1024);
302 D1(printk(KERN_DEBUG "Blocks required to allow writes: %d (%d KiB)\n", 296 dbg_fsbuild("Blocks required to allow writes: %d (%d KiB)\n",
303 c->resv_blocks_write, c->resv_blocks_write*c->sector_size/1024)); 297 c->resv_blocks_write, c->resv_blocks_write*c->sector_size/1024);
304 D1(printk(KERN_DEBUG "Blocks required to quiesce GC thread: %d (%d KiB)\n", 298 dbg_fsbuild("Blocks required to quiesce GC thread: %d (%d KiB)\n",
305 c->resv_blocks_gctrigger, c->resv_blocks_gctrigger*c->sector_size/1024)); 299 c->resv_blocks_gctrigger, c->resv_blocks_gctrigger*c->sector_size/1024);
306 D1(printk(KERN_DEBUG "Blocks required to allow GC merges: %d (%d KiB)\n", 300 dbg_fsbuild("Blocks required to allow GC merges: %d (%d KiB)\n",
307 c->resv_blocks_gcmerge, c->resv_blocks_gcmerge*c->sector_size/1024)); 301 c->resv_blocks_gcmerge, c->resv_blocks_gcmerge*c->sector_size/1024);
308 D1(printk(KERN_DEBUG "Blocks required to GC bad blocks: %d (%d KiB)\n", 302 dbg_fsbuild("Blocks required to GC bad blocks: %d (%d KiB)\n",
309 c->resv_blocks_gcbad, c->resv_blocks_gcbad*c->sector_size/1024)); 303 c->resv_blocks_gcbad, c->resv_blocks_gcbad*c->sector_size/1024);
310 D1(printk(KERN_DEBUG "Amount of dirty space required to GC: %d bytes\n", 304 dbg_fsbuild("Amount of dirty space required to GC: %d bytes\n",
311 c->nospc_dirty_size)); 305 c->nospc_dirty_size);
312} 306}
313 307
314int jffs2_do_mount_fs(struct jffs2_sb_info *c) 308int jffs2_do_mount_fs(struct jffs2_sb_info *c)
315{ 309{
310 int ret;
316 int i; 311 int i;
312 int size;
317 313
318 c->free_size = c->flash_size; 314 c->free_size = c->flash_size;
319 c->nr_blocks = c->flash_size / c->sector_size; 315 c->nr_blocks = c->flash_size / c->sector_size;
320 if (c->mtd->flags & MTD_NO_VIRTBLOCKS) 316 size = sizeof(struct jffs2_eraseblock) * c->nr_blocks;
321 c->blocks = vmalloc(sizeof(struct jffs2_eraseblock) * c->nr_blocks); 317#ifndef __ECOS
318 if (jffs2_blocks_use_vmalloc(c))
319 c->blocks = vmalloc(size);
322 else 320 else
323 c->blocks = kmalloc(sizeof(struct jffs2_eraseblock) * c->nr_blocks, GFP_KERNEL); 321#endif
322 c->blocks = kmalloc(size, GFP_KERNEL);
324 if (!c->blocks) 323 if (!c->blocks)
325 return -ENOMEM; 324 return -ENOMEM;
325
326 memset(c->blocks, 0, size);
326 for (i=0; i<c->nr_blocks; i++) { 327 for (i=0; i<c->nr_blocks; i++) {
327 INIT_LIST_HEAD(&c->blocks[i].list); 328 INIT_LIST_HEAD(&c->blocks[i].list);
328 c->blocks[i].offset = i * c->sector_size; 329 c->blocks[i].offset = i * c->sector_size;
329 c->blocks[i].free_size = c->sector_size; 330 c->blocks[i].free_size = c->sector_size;
330 c->blocks[i].dirty_size = 0;
331 c->blocks[i].wasted_size = 0;
332 c->blocks[i].unchecked_size = 0;
333 c->blocks[i].used_size = 0;
334 c->blocks[i].first_node = NULL;
335 c->blocks[i].last_node = NULL;
336 c->blocks[i].bad_count = 0;
337 } 331 }
338 332
339 INIT_LIST_HEAD(&c->clean_list); 333 INIT_LIST_HEAD(&c->clean_list);
@@ -348,16 +342,23 @@ int jffs2_do_mount_fs(struct jffs2_sb_info *c)
348 INIT_LIST_HEAD(&c->bad_list); 342 INIT_LIST_HEAD(&c->bad_list);
349 INIT_LIST_HEAD(&c->bad_used_list); 343 INIT_LIST_HEAD(&c->bad_used_list);
350 c->highest_ino = 1; 344 c->highest_ino = 1;
345 c->summary = NULL;
346
347 ret = jffs2_sum_init(c);
348 if (ret)
349 return ret;
351 350
352 if (jffs2_build_filesystem(c)) { 351 if (jffs2_build_filesystem(c)) {
353 D1(printk(KERN_DEBUG "build_fs failed\n")); 352 dbg_fsbuild("build_fs failed\n");
354 jffs2_free_ino_caches(c); 353 jffs2_free_ino_caches(c);
355 jffs2_free_raw_node_refs(c); 354 jffs2_free_raw_node_refs(c);
356 if (c->mtd->flags & MTD_NO_VIRTBLOCKS) { 355#ifndef __ECOS
356 if (jffs2_blocks_use_vmalloc(c))
357 vfree(c->blocks); 357 vfree(c->blocks);
358 } else { 358 else
359#endif
359 kfree(c->blocks); 360 kfree(c->blocks);
360 } 361
361 return -EIO; 362 return -EIO;
362 } 363 }
363 364
diff --git a/fs/jffs2/compr.c b/fs/jffs2/compr.c
index af922a9618ac..e7944e665b9f 100644
--- a/fs/jffs2/compr.c
+++ b/fs/jffs2/compr.c
@@ -9,7 +9,7 @@
9 * 9 *
10 * For licensing information, see the file 'LICENCE' in this directory. 10 * For licensing information, see the file 'LICENCE' in this directory.
11 * 11 *
12 * $Id: compr.c,v 1.42 2004/08/07 21:56:08 dwmw2 Exp $ 12 * $Id: compr.c,v 1.46 2005/11/07 11:14:38 gleixner Exp $
13 * 13 *
14 */ 14 */
15 15
@@ -36,16 +36,16 @@ static uint32_t none_stat_compr_blocks=0,none_stat_decompr_blocks=0,none_stat_co
36 * data. 36 * data.
37 * 37 *
38 * Returns: Lower byte to be stored with data indicating compression type used. 38 * Returns: Lower byte to be stored with data indicating compression type used.
39 * Zero is used to show that the data could not be compressed - the 39 * Zero is used to show that the data could not be compressed - the
40 * compressed version was actually larger than the original. 40 * compressed version was actually larger than the original.
41 * Upper byte will be used later. (soon) 41 * Upper byte will be used later. (soon)
42 * 42 *
43 * If the cdata buffer isn't large enough to hold all the uncompressed data, 43 * If the cdata buffer isn't large enough to hold all the uncompressed data,
44 * jffs2_compress should compress as much as will fit, and should set 44 * jffs2_compress should compress as much as will fit, and should set
45 * *datalen accordingly to show the amount of data which were compressed. 45 * *datalen accordingly to show the amount of data which were compressed.
46 */ 46 */
47uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 47uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
48 unsigned char *data_in, unsigned char **cpage_out, 48 unsigned char *data_in, unsigned char **cpage_out,
49 uint32_t *datalen, uint32_t *cdatalen) 49 uint32_t *datalen, uint32_t *cdatalen)
50{ 50{
51 int ret = JFFS2_COMPR_NONE; 51 int ret = JFFS2_COMPR_NONE;
@@ -164,7 +164,7 @@ uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
164} 164}
165 165
166int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 166int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
167 uint16_t comprtype, unsigned char *cdata_in, 167 uint16_t comprtype, unsigned char *cdata_in,
168 unsigned char *data_out, uint32_t cdatalen, uint32_t datalen) 168 unsigned char *data_out, uint32_t cdatalen, uint32_t datalen)
169{ 169{
170 struct jffs2_compressor *this; 170 struct jffs2_compressor *this;
@@ -298,7 +298,7 @@ char *jffs2_stats(void)
298 298
299 act_buf += sprintf(act_buf,"JFFS2 compressor statistics:\n"); 299 act_buf += sprintf(act_buf,"JFFS2 compressor statistics:\n");
300 act_buf += sprintf(act_buf,"%10s ","none"); 300 act_buf += sprintf(act_buf,"%10s ","none");
301 act_buf += sprintf(act_buf,"compr: %d blocks (%d) decompr: %d blocks\n", none_stat_compr_blocks, 301 act_buf += sprintf(act_buf,"compr: %d blocks (%d) decompr: %d blocks\n", none_stat_compr_blocks,
302 none_stat_compr_size, none_stat_decompr_blocks); 302 none_stat_compr_size, none_stat_decompr_blocks);
303 spin_lock(&jffs2_compressor_list_lock); 303 spin_lock(&jffs2_compressor_list_lock);
304 list_for_each_entry(this, &jffs2_compressor_list, list) { 304 list_for_each_entry(this, &jffs2_compressor_list, list) {
@@ -307,8 +307,8 @@ char *jffs2_stats(void)
307 act_buf += sprintf(act_buf,"- "); 307 act_buf += sprintf(act_buf,"- ");
308 else 308 else
309 act_buf += sprintf(act_buf,"+ "); 309 act_buf += sprintf(act_buf,"+ ");
310 act_buf += sprintf(act_buf,"compr: %d blocks (%d/%d) decompr: %d blocks ", this->stat_compr_blocks, 310 act_buf += sprintf(act_buf,"compr: %d blocks (%d/%d) decompr: %d blocks ", this->stat_compr_blocks,
311 this->stat_compr_new_size, this->stat_compr_orig_size, 311 this->stat_compr_new_size, this->stat_compr_orig_size,
312 this->stat_decompr_blocks); 312 this->stat_decompr_blocks);
313 act_buf += sprintf(act_buf,"\n"); 313 act_buf += sprintf(act_buf,"\n");
314 } 314 }
@@ -317,7 +317,7 @@ char *jffs2_stats(void)
317 return buf; 317 return buf;
318} 318}
319 319
320char *jffs2_get_compression_mode_name(void) 320char *jffs2_get_compression_mode_name(void)
321{ 321{
322 switch (jffs2_compression_mode) { 322 switch (jffs2_compression_mode) {
323 case JFFS2_COMPR_MODE_NONE: 323 case JFFS2_COMPR_MODE_NONE:
@@ -330,7 +330,7 @@ char *jffs2_get_compression_mode_name(void)
330 return "unkown"; 330 return "unkown";
331} 331}
332 332
333int jffs2_set_compression_mode_name(const char *name) 333int jffs2_set_compression_mode_name(const char *name)
334{ 334{
335 if (!strcmp("none",name)) { 335 if (!strcmp("none",name)) {
336 jffs2_compression_mode = JFFS2_COMPR_MODE_NONE; 336 jffs2_compression_mode = JFFS2_COMPR_MODE_NONE;
@@ -355,7 +355,7 @@ static int jffs2_compressor_Xable(const char *name, int disabled)
355 if (!strcmp(this->name, name)) { 355 if (!strcmp(this->name, name)) {
356 this->disabled = disabled; 356 this->disabled = disabled;
357 spin_unlock(&jffs2_compressor_list_lock); 357 spin_unlock(&jffs2_compressor_list_lock);
358 return 0; 358 return 0;
359 } 359 }
360 } 360 }
361 spin_unlock(&jffs2_compressor_list_lock); 361 spin_unlock(&jffs2_compressor_list_lock);
@@ -385,7 +385,7 @@ int jffs2_set_compressor_priority(const char *name, int priority)
385 } 385 }
386 } 386 }
387 spin_unlock(&jffs2_compressor_list_lock); 387 spin_unlock(&jffs2_compressor_list_lock);
388 printk(KERN_WARNING "JFFS2: compressor %s not found.\n",name); 388 printk(KERN_WARNING "JFFS2: compressor %s not found.\n",name);
389 return 1; 389 return 1;
390reinsert: 390reinsert:
391 /* list is sorted in the order of priority, so if 391 /* list is sorted in the order of priority, so if
@@ -412,7 +412,7 @@ void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig)
412 kfree(comprbuf); 412 kfree(comprbuf);
413} 413}
414 414
415int jffs2_compressors_init(void) 415int jffs2_compressors_init(void)
416{ 416{
417/* Registering compressors */ 417/* Registering compressors */
418#ifdef CONFIG_JFFS2_ZLIB 418#ifdef CONFIG_JFFS2_ZLIB
@@ -425,12 +425,6 @@ int jffs2_compressors_init(void)
425 jffs2_rubinmips_init(); 425 jffs2_rubinmips_init();
426 jffs2_dynrubin_init(); 426 jffs2_dynrubin_init();
427#endif 427#endif
428#ifdef CONFIG_JFFS2_LZARI
429 jffs2_lzari_init();
430#endif
431#ifdef CONFIG_JFFS2_LZO
432 jffs2_lzo_init();
433#endif
434/* Setting default compression mode */ 428/* Setting default compression mode */
435#ifdef CONFIG_JFFS2_CMODE_NONE 429#ifdef CONFIG_JFFS2_CMODE_NONE
436 jffs2_compression_mode = JFFS2_COMPR_MODE_NONE; 430 jffs2_compression_mode = JFFS2_COMPR_MODE_NONE;
@@ -446,15 +440,9 @@ int jffs2_compressors_init(void)
446 return 0; 440 return 0;
447} 441}
448 442
449int jffs2_compressors_exit(void) 443int jffs2_compressors_exit(void)
450{ 444{
451/* Unregistering compressors */ 445/* Unregistering compressors */
452#ifdef CONFIG_JFFS2_LZO
453 jffs2_lzo_exit();
454#endif
455#ifdef CONFIG_JFFS2_LZARI
456 jffs2_lzari_exit();
457#endif
458#ifdef CONFIG_JFFS2_RUBIN 446#ifdef CONFIG_JFFS2_RUBIN
459 jffs2_dynrubin_exit(); 447 jffs2_dynrubin_exit();
460 jffs2_rubinmips_exit(); 448 jffs2_rubinmips_exit();
diff --git a/fs/jffs2/compr.h b/fs/jffs2/compr.h
index 89ceeed201eb..a77e830d85c5 100644
--- a/fs/jffs2/compr.h
+++ b/fs/jffs2/compr.h
@@ -4,10 +4,10 @@
4 * Copyright (C) 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>, 4 * Copyright (C) 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>,
5 * University of Szeged, Hungary 5 * University of Szeged, Hungary
6 * 6 *
7 * For licensing information, see the file 'LICENCE' in the 7 * For licensing information, see the file 'LICENCE' in the
8 * jffs2 directory. 8 * jffs2 directory.
9 * 9 *
10 * $Id: compr.h,v 1.6 2004/07/16 15:17:57 dwmw2 Exp $ 10 * $Id: compr.h,v 1.9 2005/11/07 11:14:38 gleixner Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -103,13 +103,5 @@ void jffs2_rtime_exit(void);
103int jffs2_zlib_init(void); 103int jffs2_zlib_init(void);
104void jffs2_zlib_exit(void); 104void jffs2_zlib_exit(void);
105#endif 105#endif
106#ifdef CONFIG_JFFS2_LZARI
107int jffs2_lzari_init(void);
108void jffs2_lzari_exit(void);
109#endif
110#ifdef CONFIG_JFFS2_LZO
111int jffs2_lzo_init(void);
112void jffs2_lzo_exit(void);
113#endif
114 106
115#endif /* __JFFS2_COMPR_H__ */ 107#endif /* __JFFS2_COMPR_H__ */
diff --git a/fs/jffs2/compr_rtime.c b/fs/jffs2/compr_rtime.c
index 393129418666..2eb1b7428d16 100644
--- a/fs/jffs2/compr_rtime.c
+++ b/fs/jffs2/compr_rtime.c
@@ -24,8 +24,8 @@
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include <linux/types.h> 25#include <linux/types.h>
26#include <linux/errno.h> 26#include <linux/errno.h>
27#include <linux/string.h> 27#include <linux/string.h>
28#include <linux/jffs2.h> 28#include <linux/jffs2.h>
29#include "compr.h" 29#include "compr.h"
30 30
31/* _compress returns the compressed size, -1 if bigger */ 31/* _compress returns the compressed size, -1 if bigger */
@@ -38,19 +38,19 @@ static int jffs2_rtime_compress(unsigned char *data_in,
38 int outpos = 0; 38 int outpos = 0;
39 int pos=0; 39 int pos=0;
40 40
41 memset(positions,0,sizeof(positions)); 41 memset(positions,0,sizeof(positions));
42 42
43 while (pos < (*sourcelen) && outpos <= (*dstlen)-2) { 43 while (pos < (*sourcelen) && outpos <= (*dstlen)-2) {
44 int backpos, runlen=0; 44 int backpos, runlen=0;
45 unsigned char value; 45 unsigned char value;
46 46
47 value = data_in[pos]; 47 value = data_in[pos];
48 48
49 cpage_out[outpos++] = data_in[pos++]; 49 cpage_out[outpos++] = data_in[pos++];
50 50
51 backpos = positions[value]; 51 backpos = positions[value];
52 positions[value]=pos; 52 positions[value]=pos;
53 53
54 while ((backpos < pos) && (pos < (*sourcelen)) && 54 while ((backpos < pos) && (pos < (*sourcelen)) &&
55 (data_in[pos]==data_in[backpos++]) && (runlen<255)) { 55 (data_in[pos]==data_in[backpos++]) && (runlen<255)) {
56 pos++; 56 pos++;
@@ -63,12 +63,12 @@ static int jffs2_rtime_compress(unsigned char *data_in,
63 /* We failed */ 63 /* We failed */
64 return -1; 64 return -1;
65 } 65 }
66 66
67 /* Tell the caller how much we managed to compress, and how much space it took */ 67 /* Tell the caller how much we managed to compress, and how much space it took */
68 *sourcelen = pos; 68 *sourcelen = pos;
69 *dstlen = outpos; 69 *dstlen = outpos;
70 return 0; 70 return 0;
71} 71}
72 72
73 73
74static int jffs2_rtime_decompress(unsigned char *data_in, 74static int jffs2_rtime_decompress(unsigned char *data_in,
@@ -79,19 +79,19 @@ static int jffs2_rtime_decompress(unsigned char *data_in,
79 short positions[256]; 79 short positions[256];
80 int outpos = 0; 80 int outpos = 0;
81 int pos=0; 81 int pos=0;
82 82
83 memset(positions,0,sizeof(positions)); 83 memset(positions,0,sizeof(positions));
84 84
85 while (outpos<destlen) { 85 while (outpos<destlen) {
86 unsigned char value; 86 unsigned char value;
87 int backoffs; 87 int backoffs;
88 int repeat; 88 int repeat;
89 89
90 value = data_in[pos++]; 90 value = data_in[pos++];
91 cpage_out[outpos++] = value; /* first the verbatim copied byte */ 91 cpage_out[outpos++] = value; /* first the verbatim copied byte */
92 repeat = data_in[pos++]; 92 repeat = data_in[pos++];
93 backoffs = positions[value]; 93 backoffs = positions[value];
94 94
95 positions[value]=outpos; 95 positions[value]=outpos;
96 if (repeat) { 96 if (repeat) {
97 if (backoffs + repeat >= outpos) { 97 if (backoffs + repeat >= outpos) {
@@ -101,12 +101,12 @@ static int jffs2_rtime_decompress(unsigned char *data_in,
101 } 101 }
102 } else { 102 } else {
103 memcpy(&cpage_out[outpos],&cpage_out[backoffs],repeat); 103 memcpy(&cpage_out[outpos],&cpage_out[backoffs],repeat);
104 outpos+=repeat; 104 outpos+=repeat;
105 } 105 }
106 } 106 }
107 } 107 }
108 return 0; 108 return 0;
109} 109}
110 110
111static struct jffs2_compressor jffs2_rtime_comp = { 111static struct jffs2_compressor jffs2_rtime_comp = {
112 .priority = JFFS2_RTIME_PRIORITY, 112 .priority = JFFS2_RTIME_PRIORITY,
diff --git a/fs/jffs2/compr_rubin.c b/fs/jffs2/compr_rubin.c
index 09422388fb96..e792e675d624 100644
--- a/fs/jffs2/compr_rubin.c
+++ b/fs/jffs2/compr_rubin.c
@@ -11,7 +11,6 @@
11 * 11 *
12 */ 12 */
13 13
14
15#include <linux/string.h> 14#include <linux/string.h>
16#include <linux/types.h> 15#include <linux/types.h>
17#include <linux/jffs2.h> 16#include <linux/jffs2.h>
@@ -20,7 +19,7 @@
20#include "compr.h" 19#include "compr.h"
21 20
22static void init_rubin(struct rubin_state *rs, int div, int *bits) 21static void init_rubin(struct rubin_state *rs, int div, int *bits)
23{ 22{
24 int c; 23 int c;
25 24
26 rs->q = 0; 25 rs->q = 0;
@@ -40,7 +39,7 @@ static int encode(struct rubin_state *rs, long A, long B, int symbol)
40 39
41 while ((rs->q >= UPPER_BIT_RUBIN) || ((rs->p + rs->q) <= UPPER_BIT_RUBIN)) { 40 while ((rs->q >= UPPER_BIT_RUBIN) || ((rs->p + rs->q) <= UPPER_BIT_RUBIN)) {
42 rs->bit_number++; 41 rs->bit_number++;
43 42
44 ret = pushbit(&rs->pp, (rs->q & UPPER_BIT_RUBIN) ? 1 : 0, 0); 43 ret = pushbit(&rs->pp, (rs->q & UPPER_BIT_RUBIN) ? 1 : 0, 0);
45 if (ret) 44 if (ret)
46 return ret; 45 return ret;
@@ -68,7 +67,7 @@ static int encode(struct rubin_state *rs, long A, long B, int symbol)
68 67
69 68
70static void end_rubin(struct rubin_state *rs) 69static void end_rubin(struct rubin_state *rs)
71{ 70{
72 71
73 int i; 72 int i;
74 73
@@ -82,7 +81,7 @@ static void end_rubin(struct rubin_state *rs)
82 81
83static void init_decode(struct rubin_state *rs, int div, int *bits) 82static void init_decode(struct rubin_state *rs, int div, int *bits)
84{ 83{
85 init_rubin(rs, div, bits); 84 init_rubin(rs, div, bits);
86 85
87 /* behalve lower */ 86 /* behalve lower */
88 rs->rec_q = 0; 87 rs->rec_q = 0;
@@ -188,7 +187,7 @@ static int in_byte(struct rubin_state *rs)
188 187
189 188
190 189
191static int rubin_do_compress(int bit_divider, int *bits, unsigned char *data_in, 190static int rubin_do_compress(int bit_divider, int *bits, unsigned char *data_in,
192 unsigned char *cpage_out, uint32_t *sourcelen, uint32_t *dstlen) 191 unsigned char *cpage_out, uint32_t *sourcelen, uint32_t *dstlen)
193 { 192 {
194 int outpos = 0; 193 int outpos = 0;
@@ -198,31 +197,31 @@ static int rubin_do_compress(int bit_divider, int *bits, unsigned char *data_in,
198 init_pushpull(&rs.pp, cpage_out, *dstlen * 8, 0, 32); 197 init_pushpull(&rs.pp, cpage_out, *dstlen * 8, 0, 32);
199 198
200 init_rubin(&rs, bit_divider, bits); 199 init_rubin(&rs, bit_divider, bits);
201 200
202 while (pos < (*sourcelen) && !out_byte(&rs, data_in[pos])) 201 while (pos < (*sourcelen) && !out_byte(&rs, data_in[pos]))
203 pos++; 202 pos++;
204 203
205 end_rubin(&rs); 204 end_rubin(&rs);
206 205
207 if (outpos > pos) { 206 if (outpos > pos) {
208 /* We failed */ 207 /* We failed */
209 return -1; 208 return -1;
210 } 209 }
211 210
212 /* Tell the caller how much we managed to compress, 211 /* Tell the caller how much we managed to compress,
213 * and how much space it took */ 212 * and how much space it took */
214 213
215 outpos = (pushedbits(&rs.pp)+7)/8; 214 outpos = (pushedbits(&rs.pp)+7)/8;
216 215
217 if (outpos >= pos) 216 if (outpos >= pos)
218 return -1; /* We didn't actually compress */ 217 return -1; /* We didn't actually compress */
219 *sourcelen = pos; 218 *sourcelen = pos;
220 *dstlen = outpos; 219 *dstlen = outpos;
221 return 0; 220 return 0;
222} 221}
223#if 0 222#if 0
224/* _compress returns the compressed size, -1 if bigger */ 223/* _compress returns the compressed size, -1 if bigger */
225int jffs2_rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out, 224int jffs2_rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out,
226 uint32_t *sourcelen, uint32_t *dstlen, void *model) 225 uint32_t *sourcelen, uint32_t *dstlen, void *model)
227{ 226{
228 return rubin_do_compress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen); 227 return rubin_do_compress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen);
@@ -277,7 +276,7 @@ static int jffs2_dynrubin_compress(unsigned char *data_in,
277 } 276 }
278 277
279 ret = rubin_do_compress(256, bits, data_in, cpage_out+8, &mysrclen, &mydstlen); 278 ret = rubin_do_compress(256, bits, data_in, cpage_out+8, &mysrclen, &mydstlen);
280 if (ret) 279 if (ret)
281 return ret; 280 return ret;
282 281
283 /* Add back the 8 bytes we took for the probabilities */ 282 /* Add back the 8 bytes we took for the probabilities */
@@ -293,19 +292,19 @@ static int jffs2_dynrubin_compress(unsigned char *data_in,
293 return 0; 292 return 0;
294} 293}
295 294
296static void rubin_do_decompress(int bit_divider, int *bits, unsigned char *cdata_in, 295static void rubin_do_decompress(int bit_divider, int *bits, unsigned char *cdata_in,
297 unsigned char *page_out, uint32_t srclen, uint32_t destlen) 296 unsigned char *page_out, uint32_t srclen, uint32_t destlen)
298{ 297{
299 int outpos = 0; 298 int outpos = 0;
300 struct rubin_state rs; 299 struct rubin_state rs;
301 300
302 init_pushpull(&rs.pp, cdata_in, srclen, 0, 0); 301 init_pushpull(&rs.pp, cdata_in, srclen, 0, 0);
303 init_decode(&rs, bit_divider, bits); 302 init_decode(&rs, bit_divider, bits);
304 303
305 while (outpos < destlen) { 304 while (outpos < destlen) {
306 page_out[outpos++] = in_byte(&rs); 305 page_out[outpos++] = in_byte(&rs);
307 } 306 }
308} 307}
309 308
310 309
311static int jffs2_rubinmips_decompress(unsigned char *data_in, 310static int jffs2_rubinmips_decompress(unsigned char *data_in,
diff --git a/fs/jffs2/compr_rubin.h b/fs/jffs2/compr_rubin.h
index cf51e34f6574..bf1a93451621 100644
--- a/fs/jffs2/compr_rubin.h
+++ b/fs/jffs2/compr_rubin.h
@@ -1,7 +1,7 @@
1/* Rubin encoder/decoder header */ 1/* Rubin encoder/decoder header */
2/* work started at : aug 3, 1994 */ 2/* work started at : aug 3, 1994 */
3/* last modification : aug 15, 1994 */ 3/* last modification : aug 15, 1994 */
4/* $Id: compr_rubin.h,v 1.6 2002/01/25 01:49:26 dwmw2 Exp $ */ 4/* $Id: compr_rubin.h,v 1.7 2005/11/07 11:14:38 gleixner Exp $ */
5 5
6#include "pushpull.h" 6#include "pushpull.h"
7 7
@@ -11,8 +11,8 @@
11 11
12 12
13struct rubin_state { 13struct rubin_state {
14 unsigned long p; 14 unsigned long p;
15 unsigned long q; 15 unsigned long q;
16 unsigned long rec_q; 16 unsigned long rec_q;
17 long bit_number; 17 long bit_number;
18 struct pushpull pp; 18 struct pushpull pp;
diff --git a/fs/jffs2/compr_zlib.c b/fs/jffs2/compr_zlib.c
index 83f7e0788fd0..4db8be8e90cc 100644
--- a/fs/jffs2/compr_zlib.c
+++ b/fs/jffs2/compr_zlib.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: compr_zlib.c,v 1.31 2005/05/20 19:30:06 gleixner Exp $ 10 * $Id: compr_zlib.c,v 1.32 2005/11/07 11:14:38 gleixner Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -24,11 +24,11 @@
24#include "nodelist.h" 24#include "nodelist.h"
25#include "compr.h" 25#include "compr.h"
26 26
27 /* Plan: call deflate() with avail_in == *sourcelen, 27 /* Plan: call deflate() with avail_in == *sourcelen,
28 avail_out = *dstlen - 12 and flush == Z_FINISH. 28 avail_out = *dstlen - 12 and flush == Z_FINISH.
29 If it doesn't manage to finish, call it again with 29 If it doesn't manage to finish, call it again with
30 avail_in == 0 and avail_out set to the remaining 12 30 avail_in == 0 and avail_out set to the remaining 12
31 bytes for it to clean up. 31 bytes for it to clean up.
32 Q: Is 12 bytes sufficient? 32 Q: Is 12 bytes sufficient?
33 */ 33 */
34#define STREAM_END_SPACE 12 34#define STREAM_END_SPACE 12
@@ -89,7 +89,7 @@ static int jffs2_zlib_compress(unsigned char *data_in,
89 89
90 def_strm.next_in = data_in; 90 def_strm.next_in = data_in;
91 def_strm.total_in = 0; 91 def_strm.total_in = 0;
92 92
93 def_strm.next_out = cpage_out; 93 def_strm.next_out = cpage_out;
94 def_strm.total_out = 0; 94 def_strm.total_out = 0;
95 95
@@ -99,7 +99,7 @@ static int jffs2_zlib_compress(unsigned char *data_in,
99 D1(printk(KERN_DEBUG "calling deflate with avail_in %d, avail_out %d\n", 99 D1(printk(KERN_DEBUG "calling deflate with avail_in %d, avail_out %d\n",
100 def_strm.avail_in, def_strm.avail_out)); 100 def_strm.avail_in, def_strm.avail_out));
101 ret = zlib_deflate(&def_strm, Z_PARTIAL_FLUSH); 101 ret = zlib_deflate(&def_strm, Z_PARTIAL_FLUSH);
102 D1(printk(KERN_DEBUG "deflate returned with avail_in %d, avail_out %d, total_in %ld, total_out %ld\n", 102 D1(printk(KERN_DEBUG "deflate returned with avail_in %d, avail_out %d, total_in %ld, total_out %ld\n",
103 def_strm.avail_in, def_strm.avail_out, def_strm.total_in, def_strm.total_out)); 103 def_strm.avail_in, def_strm.avail_out, def_strm.total_in, def_strm.total_out));
104 if (ret != Z_OK) { 104 if (ret != Z_OK) {
105 D1(printk(KERN_DEBUG "deflate in loop returned %d\n", ret)); 105 D1(printk(KERN_DEBUG "deflate in loop returned %d\n", ret));
@@ -150,7 +150,7 @@ static int jffs2_zlib_decompress(unsigned char *data_in,
150 inf_strm.next_in = data_in; 150 inf_strm.next_in = data_in;
151 inf_strm.avail_in = srclen; 151 inf_strm.avail_in = srclen;
152 inf_strm.total_in = 0; 152 inf_strm.total_in = 0;
153 153
154 inf_strm.next_out = cpage_out; 154 inf_strm.next_out = cpage_out;
155 inf_strm.avail_out = destlen; 155 inf_strm.avail_out = destlen;
156 inf_strm.total_out = 0; 156 inf_strm.total_out = 0;
diff --git a/fs/jffs2/comprtest.c b/fs/jffs2/comprtest.c
index cf51f091d0e7..f0fb8be7740c 100644
--- a/fs/jffs2/comprtest.c
+++ b/fs/jffs2/comprtest.c
@@ -1,4 +1,4 @@
1/* $Id: comprtest.c,v 1.5 2002/01/03 15:20:44 dwmw2 Exp $ */ 1/* $Id: comprtest.c,v 1.6 2005/11/07 11:14:38 gleixner Exp $ */
2 2
3#include <linux/kernel.h> 3#include <linux/kernel.h>
4#include <linux/string.h> 4#include <linux/string.h>
@@ -265,9 +265,9 @@ static unsigned char testdata[TESTDATA_LEN] = {
265static unsigned char comprbuf[TESTDATA_LEN]; 265static unsigned char comprbuf[TESTDATA_LEN];
266static unsigned char decomprbuf[TESTDATA_LEN]; 266static unsigned char decomprbuf[TESTDATA_LEN];
267 267
268int jffs2_decompress(unsigned char comprtype, unsigned char *cdata_in, 268int jffs2_decompress(unsigned char comprtype, unsigned char *cdata_in,
269 unsigned char *data_out, uint32_t cdatalen, uint32_t datalen); 269 unsigned char *data_out, uint32_t cdatalen, uint32_t datalen);
270unsigned char jffs2_compress(unsigned char *data_in, unsigned char *cpage_out, 270unsigned char jffs2_compress(unsigned char *data_in, unsigned char *cpage_out,
271 uint32_t *datalen, uint32_t *cdatalen); 271 uint32_t *datalen, uint32_t *cdatalen);
272 272
273int init_module(void ) { 273int init_module(void ) {
@@ -276,10 +276,10 @@ int init_module(void ) {
276 int ret; 276 int ret;
277 277
278 printk("Original data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 278 printk("Original data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
279 testdata[0],testdata[1],testdata[2],testdata[3], 279 testdata[0],testdata[1],testdata[2],testdata[3],
280 testdata[4],testdata[5],testdata[6],testdata[7], 280 testdata[4],testdata[5],testdata[6],testdata[7],
281 testdata[8],testdata[9],testdata[10],testdata[11], 281 testdata[8],testdata[9],testdata[10],testdata[11],
282 testdata[12],testdata[13],testdata[14],testdata[15]); 282 testdata[12],testdata[13],testdata[14],testdata[15]);
283 d = TESTDATA_LEN; 283 d = TESTDATA_LEN;
284 c = TESTDATA_LEN; 284 c = TESTDATA_LEN;
285 comprtype = jffs2_compress(testdata, comprbuf, &d, &c); 285 comprtype = jffs2_compress(testdata, comprbuf, &d, &c);
@@ -287,18 +287,18 @@ int init_module(void ) {
287 printk("jffs2_compress used compression type %d. Compressed size %d, uncompressed size %d\n", 287 printk("jffs2_compress used compression type %d. Compressed size %d, uncompressed size %d\n",
288 comprtype, c, d); 288 comprtype, c, d);
289 printk("Compressed data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 289 printk("Compressed data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
290 comprbuf[0],comprbuf[1],comprbuf[2],comprbuf[3], 290 comprbuf[0],comprbuf[1],comprbuf[2],comprbuf[3],
291 comprbuf[4],comprbuf[5],comprbuf[6],comprbuf[7], 291 comprbuf[4],comprbuf[5],comprbuf[6],comprbuf[7],
292 comprbuf[8],comprbuf[9],comprbuf[10],comprbuf[11], 292 comprbuf[8],comprbuf[9],comprbuf[10],comprbuf[11],
293 comprbuf[12],comprbuf[13],comprbuf[14],comprbuf[15]); 293 comprbuf[12],comprbuf[13],comprbuf[14],comprbuf[15]);
294 294
295 ret = jffs2_decompress(comprtype, comprbuf, decomprbuf, c, d); 295 ret = jffs2_decompress(comprtype, comprbuf, decomprbuf, c, d);
296 printk("jffs2_decompress returned %d\n", ret); 296 printk("jffs2_decompress returned %d\n", ret);
297 printk("Decompressed data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 297 printk("Decompressed data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
298 decomprbuf[0],decomprbuf[1],decomprbuf[2],decomprbuf[3], 298 decomprbuf[0],decomprbuf[1],decomprbuf[2],decomprbuf[3],
299 decomprbuf[4],decomprbuf[5],decomprbuf[6],decomprbuf[7], 299 decomprbuf[4],decomprbuf[5],decomprbuf[6],decomprbuf[7],
300 decomprbuf[8],decomprbuf[9],decomprbuf[10],decomprbuf[11], 300 decomprbuf[8],decomprbuf[9],decomprbuf[10],decomprbuf[11],
301 decomprbuf[12],decomprbuf[13],decomprbuf[14],decomprbuf[15]); 301 decomprbuf[12],decomprbuf[13],decomprbuf[14],decomprbuf[15]);
302 if (memcmp(decomprbuf, testdata, d)) 302 if (memcmp(decomprbuf, testdata, d))
303 printk("Compression and decompression corrupted data\n"); 303 printk("Compression and decompression corrupted data\n");
304 else 304 else
diff --git a/fs/jffs2/debug.c b/fs/jffs2/debug.c
new file mode 100644
index 000000000000..1fe17de713e8
--- /dev/null
+++ b/fs/jffs2/debug.c
@@ -0,0 +1,705 @@
1/*
2 * JFFS2 -- Journalling Flash File System, Version 2.
3 *
4 * Copyright (C) 2001-2003 Red Hat, Inc.
5 *
6 * Created by David Woodhouse <dwmw2@infradead.org>
7 *
8 * For licensing information, see the file 'LICENCE' in this directory.
9 *
10 * $Id: debug.c,v 1.12 2005/11/07 11:14:39 gleixner Exp $
11 *
12 */
13#include <linux/kernel.h>
14#include <linux/types.h>
15#include <linux/pagemap.h>
16#include <linux/crc32.h>
17#include <linux/jffs2.h>
18#include <linux/mtd/mtd.h>
19#include "nodelist.h"
20#include "debug.h"
21
22#ifdef JFFS2_DBG_SANITY_CHECKS
23
24void
25__jffs2_dbg_acct_sanity_check_nolock(struct jffs2_sb_info *c,
26 struct jffs2_eraseblock *jeb)
27{
28 if (unlikely(jeb && jeb->used_size + jeb->dirty_size +
29 jeb->free_size + jeb->wasted_size +
30 jeb->unchecked_size != c->sector_size)) {
31 JFFS2_ERROR("eeep, space accounting for block at 0x%08x is screwed.\n", jeb->offset);
32 JFFS2_ERROR("free %#08x + dirty %#08x + used %#08x + wasted %#08x + unchecked %#08x != total %#08x.\n",
33 jeb->free_size, jeb->dirty_size, jeb->used_size,
34 jeb->wasted_size, jeb->unchecked_size, c->sector_size);
35 BUG();
36 }
37
38 if (unlikely(c->used_size + c->dirty_size + c->free_size + c->erasing_size + c->bad_size
39 + c->wasted_size + c->unchecked_size != c->flash_size)) {
40 JFFS2_ERROR("eeep, space accounting superblock info is screwed.\n");
41 JFFS2_ERROR("free %#08x + dirty %#08x + used %#08x + erasing %#08x + bad %#08x + wasted %#08x + unchecked %#08x != total %#08x.\n",
42 c->free_size, c->dirty_size, c->used_size, c->erasing_size, c->bad_size,
43 c->wasted_size, c->unchecked_size, c->flash_size);
44 BUG();
45 }
46}
47
48void
49__jffs2_dbg_acct_sanity_check(struct jffs2_sb_info *c,
50 struct jffs2_eraseblock *jeb)
51{
52 spin_lock(&c->erase_completion_lock);
53 jffs2_dbg_acct_sanity_check_nolock(c, jeb);
54 spin_unlock(&c->erase_completion_lock);
55}
56
57#endif /* JFFS2_DBG_SANITY_CHECKS */
58
59#ifdef JFFS2_DBG_PARANOIA_CHECKS
60/*
61 * Check the fragtree.
62 */
63void
64__jffs2_dbg_fragtree_paranoia_check(struct jffs2_inode_info *f)
65{
66 down(&f->sem);
67 __jffs2_dbg_fragtree_paranoia_check_nolock(f);
68 up(&f->sem);
69}
70
71void
72__jffs2_dbg_fragtree_paranoia_check_nolock(struct jffs2_inode_info *f)
73{
74 struct jffs2_node_frag *frag;
75 int bitched = 0;
76
77 for (frag = frag_first(&f->fragtree); frag; frag = frag_next(frag)) {
78 struct jffs2_full_dnode *fn = frag->node;
79
80 if (!fn || !fn->raw)
81 continue;
82
83 if (ref_flags(fn->raw) == REF_PRISTINE) {
84 if (fn->frags > 1) {
85 JFFS2_ERROR("REF_PRISTINE node at 0x%08x had %d frags. Tell dwmw2.\n",
86 ref_offset(fn->raw), fn->frags);
87 bitched = 1;
88 }
89
90 /* A hole node which isn't multi-page should be garbage-collected
91 and merged anyway, so we just check for the frag size here,
92 rather than mucking around with actually reading the node
93 and checking the compression type, which is the real way
94 to tell a hole node. */
95 if (frag->ofs & (PAGE_CACHE_SIZE-1) && frag_prev(frag)
96 && frag_prev(frag)->size < PAGE_CACHE_SIZE && frag_prev(frag)->node) {
97 JFFS2_ERROR("REF_PRISTINE node at 0x%08x had a previous non-hole frag in the same page. Tell dwmw2.\n",
98 ref_offset(fn->raw));
99 bitched = 1;
100 }
101
102 if ((frag->ofs+frag->size) & (PAGE_CACHE_SIZE-1) && frag_next(frag)
103 && frag_next(frag)->size < PAGE_CACHE_SIZE && frag_next(frag)->node) {
104 JFFS2_ERROR("REF_PRISTINE node at 0x%08x (%08x-%08x) had a following non-hole frag in the same page. Tell dwmw2.\n",
105 ref_offset(fn->raw), frag->ofs, frag->ofs+frag->size);
106 bitched = 1;
107 }
108 }
109 }
110
111 if (bitched) {
112 JFFS2_ERROR("fragtree is corrupted.\n");
113 __jffs2_dbg_dump_fragtree_nolock(f);
114 BUG();
115 }
116}
117
118/*
119 * Check if the flash contains all 0xFF before we start writing.
120 */
121void
122__jffs2_dbg_prewrite_paranoia_check(struct jffs2_sb_info *c,
123 uint32_t ofs, int len)
124{
125 size_t retlen;
126 int ret, i;
127 unsigned char *buf;
128
129 buf = kmalloc(len, GFP_KERNEL);
130 if (!buf)
131 return;
132
133 ret = jffs2_flash_read(c, ofs, len, &retlen, buf);
134 if (ret || (retlen != len)) {
135 JFFS2_WARNING("read %d bytes failed or short. ret %d, retlen %zd.\n",
136 len, ret, retlen);
137 kfree(buf);
138 return;
139 }
140
141 ret = 0;
142 for (i = 0; i < len; i++)
143 if (buf[i] != 0xff)
144 ret = 1;
145
146 if (ret) {
147 JFFS2_ERROR("argh, about to write node to %#08x on flash, but there are data already there. The first corrupted byte is at %#08x offset.\n",
148 ofs, ofs + i);
149 __jffs2_dbg_dump_buffer(buf, len, ofs);
150 kfree(buf);
151 BUG();
152 }
153
154 kfree(buf);
155}
156
157/*
158 * Check the space accounting and node_ref list correctness for the JFFS2 erasable block 'jeb'.
159 */
160void
161__jffs2_dbg_acct_paranoia_check(struct jffs2_sb_info *c,
162 struct jffs2_eraseblock *jeb)
163{
164 spin_lock(&c->erase_completion_lock);
165 __jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
166 spin_unlock(&c->erase_completion_lock);
167}
168
169void
170__jffs2_dbg_acct_paranoia_check_nolock(struct jffs2_sb_info *c,
171 struct jffs2_eraseblock *jeb)
172{
173 uint32_t my_used_size = 0;
174 uint32_t my_unchecked_size = 0;
175 uint32_t my_dirty_size = 0;
176 struct jffs2_raw_node_ref *ref2 = jeb->first_node;
177
178 while (ref2) {
179 uint32_t totlen = ref_totlen(c, jeb, ref2);
180
181 if (ref2->flash_offset < jeb->offset ||
182 ref2->flash_offset > jeb->offset + c->sector_size) {
183 JFFS2_ERROR("node_ref %#08x shouldn't be in block at %#08x.\n",
184 ref_offset(ref2), jeb->offset);
185 goto error;
186
187 }
188 if (ref_flags(ref2) == REF_UNCHECKED)
189 my_unchecked_size += totlen;
190 else if (!ref_obsolete(ref2))
191 my_used_size += totlen;
192 else
193 my_dirty_size += totlen;
194
195 if ((!ref2->next_phys) != (ref2 == jeb->last_node)) {
196 JFFS2_ERROR("node_ref for node at %#08x (mem %p) has next_phys at %#08x (mem %p), last_node is at %#08x (mem %p).\n",
197 ref_offset(ref2), ref2, ref_offset(ref2->next_phys), ref2->next_phys,
198 ref_offset(jeb->last_node), jeb->last_node);
199 goto error;
200 }
201 ref2 = ref2->next_phys;
202 }
203
204 if (my_used_size != jeb->used_size) {
205 JFFS2_ERROR("Calculated used size %#08x != stored used size %#08x.\n",
206 my_used_size, jeb->used_size);
207 goto error;
208 }
209
210 if (my_unchecked_size != jeb->unchecked_size) {
211 JFFS2_ERROR("Calculated unchecked size %#08x != stored unchecked size %#08x.\n",
212 my_unchecked_size, jeb->unchecked_size);
213 goto error;
214 }
215
216#if 0
217 /* This should work when we implement ref->__totlen elemination */
218 if (my_dirty_size != jeb->dirty_size + jeb->wasted_size) {
219 JFFS2_ERROR("Calculated dirty+wasted size %#08x != stored dirty + wasted size %#08x\n",
220 my_dirty_size, jeb->dirty_size + jeb->wasted_size);
221 goto error;
222 }
223
224 if (jeb->free_size == 0
225 && my_used_size + my_unchecked_size + my_dirty_size != c->sector_size) {
226 JFFS2_ERROR("The sum of all nodes in block (%#x) != size of block (%#x)\n",
227 my_used_size + my_unchecked_size + my_dirty_size,
228 c->sector_size);
229 goto error;
230 }
231#endif
232
233 return;
234
235error:
236 __jffs2_dbg_dump_node_refs_nolock(c, jeb);
237 __jffs2_dbg_dump_jeb_nolock(jeb);
238 __jffs2_dbg_dump_block_lists_nolock(c);
239 BUG();
240
241}
242#endif /* JFFS2_DBG_PARANOIA_CHECKS */
243
244#if defined(JFFS2_DBG_DUMPS) || defined(JFFS2_DBG_PARANOIA_CHECKS)
245/*
246 * Dump the node_refs of the 'jeb' JFFS2 eraseblock.
247 */
248void
249__jffs2_dbg_dump_node_refs(struct jffs2_sb_info *c,
250 struct jffs2_eraseblock *jeb)
251{
252 spin_lock(&c->erase_completion_lock);
253 __jffs2_dbg_dump_node_refs_nolock(c, jeb);
254 spin_unlock(&c->erase_completion_lock);
255}
256
257void
258__jffs2_dbg_dump_node_refs_nolock(struct jffs2_sb_info *c,
259 struct jffs2_eraseblock *jeb)
260{
261 struct jffs2_raw_node_ref *ref;
262 int i = 0;
263
264 printk(JFFS2_DBG_MSG_PREFIX " Dump node_refs of the eraseblock %#08x\n", jeb->offset);
265 if (!jeb->first_node) {
266 printk(JFFS2_DBG_MSG_PREFIX " no nodes in the eraseblock %#08x\n", jeb->offset);
267 return;
268 }
269
270 printk(JFFS2_DBG);
271 for (ref = jeb->first_node; ; ref = ref->next_phys) {
272 printk("%#08x(%#x)", ref_offset(ref), ref->__totlen);
273 if (ref->next_phys)
274 printk("->");
275 else
276 break;
277 if (++i == 4) {
278 i = 0;
279 printk("\n" JFFS2_DBG);
280 }
281 }
282 printk("\n");
283}
284
285/*
286 * Dump an eraseblock's space accounting.
287 */
288void
289__jffs2_dbg_dump_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
290{
291 spin_lock(&c->erase_completion_lock);
292 __jffs2_dbg_dump_jeb_nolock(jeb);
293 spin_unlock(&c->erase_completion_lock);
294}
295
296void
297__jffs2_dbg_dump_jeb_nolock(struct jffs2_eraseblock *jeb)
298{
299 if (!jeb)
300 return;
301
302 printk(JFFS2_DBG_MSG_PREFIX " dump space accounting for the eraseblock at %#08x:\n",
303 jeb->offset);
304
305 printk(JFFS2_DBG "used_size: %#08x\n", jeb->used_size);
306 printk(JFFS2_DBG "dirty_size: %#08x\n", jeb->dirty_size);
307 printk(JFFS2_DBG "wasted_size: %#08x\n", jeb->wasted_size);
308 printk(JFFS2_DBG "unchecked_size: %#08x\n", jeb->unchecked_size);
309 printk(JFFS2_DBG "free_size: %#08x\n", jeb->free_size);
310}
311
312void
313__jffs2_dbg_dump_block_lists(struct jffs2_sb_info *c)
314{
315 spin_lock(&c->erase_completion_lock);
316 __jffs2_dbg_dump_block_lists_nolock(c);
317 spin_unlock(&c->erase_completion_lock);
318}
319
320void
321__jffs2_dbg_dump_block_lists_nolock(struct jffs2_sb_info *c)
322{
323 printk(JFFS2_DBG_MSG_PREFIX " dump JFFS2 blocks lists:\n");
324
325 printk(JFFS2_DBG "flash_size: %#08x\n", c->flash_size);
326 printk(JFFS2_DBG "used_size: %#08x\n", c->used_size);
327 printk(JFFS2_DBG "dirty_size: %#08x\n", c->dirty_size);
328 printk(JFFS2_DBG "wasted_size: %#08x\n", c->wasted_size);
329 printk(JFFS2_DBG "unchecked_size: %#08x\n", c->unchecked_size);
330 printk(JFFS2_DBG "free_size: %#08x\n", c->free_size);
331 printk(JFFS2_DBG "erasing_size: %#08x\n", c->erasing_size);
332 printk(JFFS2_DBG "bad_size: %#08x\n", c->bad_size);
333 printk(JFFS2_DBG "sector_size: %#08x\n", c->sector_size);
334 printk(JFFS2_DBG "jffs2_reserved_blocks size: %#08x\n",
335 c->sector_size * c->resv_blocks_write);
336
337 if (c->nextblock)
338 printk(JFFS2_DBG "nextblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
339 c->nextblock->offset, c->nextblock->used_size,
340 c->nextblock->dirty_size, c->nextblock->wasted_size,
341 c->nextblock->unchecked_size, c->nextblock->free_size);
342 else
343 printk(JFFS2_DBG "nextblock: NULL\n");
344
345 if (c->gcblock)
346 printk(JFFS2_DBG "gcblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
347 c->gcblock->offset, c->gcblock->used_size, c->gcblock->dirty_size,
348 c->gcblock->wasted_size, c->gcblock->unchecked_size, c->gcblock->free_size);
349 else
350 printk(JFFS2_DBG "gcblock: NULL\n");
351
352 if (list_empty(&c->clean_list)) {
353 printk(JFFS2_DBG "clean_list: empty\n");
354 } else {
355 struct list_head *this;
356 int numblocks = 0;
357 uint32_t dirty = 0;
358
359 list_for_each(this, &c->clean_list) {
360 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
361 numblocks ++;
362 dirty += jeb->wasted_size;
363 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
364 printk(JFFS2_DBG "clean_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
365 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
366 jeb->unchecked_size, jeb->free_size);
367 }
368 }
369
370 printk (JFFS2_DBG "Contains %d blocks with total wasted size %u, average wasted size: %u\n",
371 numblocks, dirty, dirty / numblocks);
372 }
373
374 if (list_empty(&c->very_dirty_list)) {
375 printk(JFFS2_DBG "very_dirty_list: empty\n");
376 } else {
377 struct list_head *this;
378 int numblocks = 0;
379 uint32_t dirty = 0;
380
381 list_for_each(this, &c->very_dirty_list) {
382 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
383
384 numblocks ++;
385 dirty += jeb->dirty_size;
386 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
387 printk(JFFS2_DBG "very_dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
388 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
389 jeb->unchecked_size, jeb->free_size);
390 }
391 }
392
393 printk (JFFS2_DBG "Contains %d blocks with total dirty size %u, average dirty size: %u\n",
394 numblocks, dirty, dirty / numblocks);
395 }
396
397 if (list_empty(&c->dirty_list)) {
398 printk(JFFS2_DBG "dirty_list: empty\n");
399 } else {
400 struct list_head *this;
401 int numblocks = 0;
402 uint32_t dirty = 0;
403
404 list_for_each(this, &c->dirty_list) {
405 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
406
407 numblocks ++;
408 dirty += jeb->dirty_size;
409 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
410 printk(JFFS2_DBG "dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
411 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
412 jeb->unchecked_size, jeb->free_size);
413 }
414 }
415
416 printk (JFFS2_DBG "contains %d blocks with total dirty size %u, average dirty size: %u\n",
417 numblocks, dirty, dirty / numblocks);
418 }
419
420 if (list_empty(&c->erasable_list)) {
421 printk(JFFS2_DBG "erasable_list: empty\n");
422 } else {
423 struct list_head *this;
424
425 list_for_each(this, &c->erasable_list) {
426 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
427
428 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
429 printk(JFFS2_DBG "erasable_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
430 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
431 jeb->unchecked_size, jeb->free_size);
432 }
433 }
434 }
435
436 if (list_empty(&c->erasing_list)) {
437 printk(JFFS2_DBG "erasing_list: empty\n");
438 } else {
439 struct list_head *this;
440
441 list_for_each(this, &c->erasing_list) {
442 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
443
444 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
445 printk(JFFS2_DBG "erasing_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
446 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
447 jeb->unchecked_size, jeb->free_size);
448 }
449 }
450 }
451
452 if (list_empty(&c->erase_pending_list)) {
453 printk(JFFS2_DBG "erase_pending_list: empty\n");
454 } else {
455 struct list_head *this;
456
457 list_for_each(this, &c->erase_pending_list) {
458 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
459
460 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
461 printk(JFFS2_DBG "erase_pending_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
462 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
463 jeb->unchecked_size, jeb->free_size);
464 }
465 }
466 }
467
468 if (list_empty(&c->erasable_pending_wbuf_list)) {
469 printk(JFFS2_DBG "erasable_pending_wbuf_list: empty\n");
470 } else {
471 struct list_head *this;
472
473 list_for_each(this, &c->erasable_pending_wbuf_list) {
474 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
475
476 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
477 printk(JFFS2_DBG "erasable_pending_wbuf_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
478 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
479 jeb->unchecked_size, jeb->free_size);
480 }
481 }
482 }
483
484 if (list_empty(&c->free_list)) {
485 printk(JFFS2_DBG "free_list: empty\n");
486 } else {
487 struct list_head *this;
488
489 list_for_each(this, &c->free_list) {
490 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
491
492 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
493 printk(JFFS2_DBG "free_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
494 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
495 jeb->unchecked_size, jeb->free_size);
496 }
497 }
498 }
499
500 if (list_empty(&c->bad_list)) {
501 printk(JFFS2_DBG "bad_list: empty\n");
502 } else {
503 struct list_head *this;
504
505 list_for_each(this, &c->bad_list) {
506 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
507
508 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
509 printk(JFFS2_DBG "bad_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
510 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
511 jeb->unchecked_size, jeb->free_size);
512 }
513 }
514 }
515
516 if (list_empty(&c->bad_used_list)) {
517 printk(JFFS2_DBG "bad_used_list: empty\n");
518 } else {
519 struct list_head *this;
520
521 list_for_each(this, &c->bad_used_list) {
522 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
523
524 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
525 printk(JFFS2_DBG "bad_used_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
526 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
527 jeb->unchecked_size, jeb->free_size);
528 }
529 }
530 }
531}
532
533void
534__jffs2_dbg_dump_fragtree(struct jffs2_inode_info *f)
535{
536 down(&f->sem);
537 jffs2_dbg_dump_fragtree_nolock(f);
538 up(&f->sem);
539}
540
541void
542__jffs2_dbg_dump_fragtree_nolock(struct jffs2_inode_info *f)
543{
544 struct jffs2_node_frag *this = frag_first(&f->fragtree);
545 uint32_t lastofs = 0;
546 int buggy = 0;
547
548 printk(JFFS2_DBG_MSG_PREFIX " dump fragtree of ino #%u\n", f->inocache->ino);
549 while(this) {
550 if (this->node)
551 printk(JFFS2_DBG "frag %#04x-%#04x: %#08x(%d) on flash (*%p), left (%p), right (%p), parent (%p)\n",
552 this->ofs, this->ofs+this->size, ref_offset(this->node->raw),
553 ref_flags(this->node->raw), this, frag_left(this), frag_right(this),
554 frag_parent(this));
555 else
556 printk(JFFS2_DBG "frag %#04x-%#04x: hole (*%p). left (%p), right (%p), parent (%p)\n",
557 this->ofs, this->ofs+this->size, this, frag_left(this),
558 frag_right(this), frag_parent(this));
559 if (this->ofs != lastofs)
560 buggy = 1;
561 lastofs = this->ofs + this->size;
562 this = frag_next(this);
563 }
564
565 if (f->metadata)
566 printk(JFFS2_DBG "metadata at 0x%08x\n", ref_offset(f->metadata->raw));
567
568 if (buggy) {
569 JFFS2_ERROR("frag tree got a hole in it.\n");
570 BUG();
571 }
572}
573
574#define JFFS2_BUFDUMP_BYTES_PER_LINE 32
575void
576__jffs2_dbg_dump_buffer(unsigned char *buf, int len, uint32_t offs)
577{
578 int skip;
579 int i;
580
581 printk(JFFS2_DBG_MSG_PREFIX " dump from offset %#08x to offset %#08x (%x bytes).\n",
582 offs, offs + len, len);
583 i = skip = offs % JFFS2_BUFDUMP_BYTES_PER_LINE;
584 offs = offs & ~(JFFS2_BUFDUMP_BYTES_PER_LINE - 1);
585
586 if (skip != 0)
587 printk(JFFS2_DBG "%#08x: ", offs);
588
589 while (skip--)
590 printk(" ");
591
592 while (i < len) {
593 if ((i % JFFS2_BUFDUMP_BYTES_PER_LINE) == 0 && i != len -1) {
594 if (i != 0)
595 printk("\n");
596 offs += JFFS2_BUFDUMP_BYTES_PER_LINE;
597 printk(JFFS2_DBG "%0#8x: ", offs);
598 }
599
600 printk("%02x ", buf[i]);
601
602 i += 1;
603 }
604
605 printk("\n");
606}
607
608/*
609 * Dump a JFFS2 node.
610 */
611void
612__jffs2_dbg_dump_node(struct jffs2_sb_info *c, uint32_t ofs)
613{
614 union jffs2_node_union node;
615 int len = sizeof(union jffs2_node_union);
616 size_t retlen;
617 uint32_t crc;
618 int ret;
619
620 printk(JFFS2_DBG_MSG_PREFIX " dump node at offset %#08x.\n", ofs);
621
622 ret = jffs2_flash_read(c, ofs, len, &retlen, (unsigned char *)&node);
623 if (ret || (retlen != len)) {
624 JFFS2_ERROR("read %d bytes failed or short. ret %d, retlen %zd.\n",
625 len, ret, retlen);
626 return;
627 }
628
629 printk(JFFS2_DBG "magic:\t%#04x\n", je16_to_cpu(node.u.magic));
630 printk(JFFS2_DBG "nodetype:\t%#04x\n", je16_to_cpu(node.u.nodetype));
631 printk(JFFS2_DBG "totlen:\t%#08x\n", je32_to_cpu(node.u.totlen));
632 printk(JFFS2_DBG "hdr_crc:\t%#08x\n", je32_to_cpu(node.u.hdr_crc));
633
634 crc = crc32(0, &node.u, sizeof(node.u) - 4);
635 if (crc != je32_to_cpu(node.u.hdr_crc)) {
636 JFFS2_ERROR("wrong common header CRC.\n");
637 return;
638 }
639
640 if (je16_to_cpu(node.u.magic) != JFFS2_MAGIC_BITMASK &&
641 je16_to_cpu(node.u.magic) != JFFS2_OLD_MAGIC_BITMASK)
642 {
643 JFFS2_ERROR("wrong node magic: %#04x instead of %#04x.\n",
644 je16_to_cpu(node.u.magic), JFFS2_MAGIC_BITMASK);
645 return;
646 }
647
648 switch(je16_to_cpu(node.u.nodetype)) {
649
650 case JFFS2_NODETYPE_INODE:
651
652 printk(JFFS2_DBG "the node is inode node\n");
653 printk(JFFS2_DBG "ino:\t%#08x\n", je32_to_cpu(node.i.ino));
654 printk(JFFS2_DBG "version:\t%#08x\n", je32_to_cpu(node.i.version));
655 printk(JFFS2_DBG "mode:\t%#08x\n", node.i.mode.m);
656 printk(JFFS2_DBG "uid:\t%#04x\n", je16_to_cpu(node.i.uid));
657 printk(JFFS2_DBG "gid:\t%#04x\n", je16_to_cpu(node.i.gid));
658 printk(JFFS2_DBG "isize:\t%#08x\n", je32_to_cpu(node.i.isize));
659 printk(JFFS2_DBG "atime:\t%#08x\n", je32_to_cpu(node.i.atime));
660 printk(JFFS2_DBG "mtime:\t%#08x\n", je32_to_cpu(node.i.mtime));
661 printk(JFFS2_DBG "ctime:\t%#08x\n", je32_to_cpu(node.i.ctime));
662 printk(JFFS2_DBG "offset:\t%#08x\n", je32_to_cpu(node.i.offset));
663 printk(JFFS2_DBG "csize:\t%#08x\n", je32_to_cpu(node.i.csize));
664 printk(JFFS2_DBG "dsize:\t%#08x\n", je32_to_cpu(node.i.dsize));
665 printk(JFFS2_DBG "compr:\t%#02x\n", node.i.compr);
666 printk(JFFS2_DBG "usercompr:\t%#02x\n", node.i.usercompr);
667 printk(JFFS2_DBG "flags:\t%#04x\n", je16_to_cpu(node.i.flags));
668 printk(JFFS2_DBG "data_crc:\t%#08x\n", je32_to_cpu(node.i.data_crc));
669 printk(JFFS2_DBG "node_crc:\t%#08x\n", je32_to_cpu(node.i.node_crc));
670
671 crc = crc32(0, &node.i, sizeof(node.i) - 8);
672 if (crc != je32_to_cpu(node.i.node_crc)) {
673 JFFS2_ERROR("wrong node header CRC.\n");
674 return;
675 }
676 break;
677
678 case JFFS2_NODETYPE_DIRENT:
679
680 printk(JFFS2_DBG "the node is dirent node\n");
681 printk(JFFS2_DBG "pino:\t%#08x\n", je32_to_cpu(node.d.pino));
682 printk(JFFS2_DBG "version:\t%#08x\n", je32_to_cpu(node.d.version));
683 printk(JFFS2_DBG "ino:\t%#08x\n", je32_to_cpu(node.d.ino));
684 printk(JFFS2_DBG "mctime:\t%#08x\n", je32_to_cpu(node.d.mctime));
685 printk(JFFS2_DBG "nsize:\t%#02x\n", node.d.nsize);
686 printk(JFFS2_DBG "type:\t%#02x\n", node.d.type);
687 printk(JFFS2_DBG "node_crc:\t%#08x\n", je32_to_cpu(node.d.node_crc));
688 printk(JFFS2_DBG "name_crc:\t%#08x\n", je32_to_cpu(node.d.name_crc));
689
690 node.d.name[node.d.nsize] = '\0';
691 printk(JFFS2_DBG "name:\t\"%s\"\n", node.d.name);
692
693 crc = crc32(0, &node.d, sizeof(node.d) - 8);
694 if (crc != je32_to_cpu(node.d.node_crc)) {
695 JFFS2_ERROR("wrong node header CRC.\n");
696 return;
697 }
698 break;
699
700 default:
701 printk(JFFS2_DBG "node type is unknown\n");
702 break;
703 }
704}
705#endif /* JFFS2_DBG_DUMPS || JFFS2_DBG_PARANOIA_CHECKS */
diff --git a/fs/jffs2/debug.h b/fs/jffs2/debug.h
new file mode 100644
index 000000000000..f193d43a8a59
--- /dev/null
+++ b/fs/jffs2/debug.h
@@ -0,0 +1,279 @@
1/*
2 * JFFS2 -- Journalling Flash File System, Version 2.
3 *
4 * Copyright (C) 2001-2003 Red Hat, Inc.
5 *
6 * Created by David Woodhouse <dwmw2@infradead.org>
7 *
8 * For licensing information, see the file 'LICENCE' in this directory.
9 *
10 * $Id: debug.h,v 1.21 2005/11/07 11:14:39 gleixner Exp $
11 *
12 */
13#ifndef _JFFS2_DEBUG_H_
14#define _JFFS2_DEBUG_H_
15
16#include <linux/config.h>
17
18#ifndef CONFIG_JFFS2_FS_DEBUG
19#define CONFIG_JFFS2_FS_DEBUG 0
20#endif
21
22#if CONFIG_JFFS2_FS_DEBUG > 0
23/* Enable "paranoia" checks and dumps */
24#define JFFS2_DBG_PARANOIA_CHECKS
25#define JFFS2_DBG_DUMPS
26
27/*
28 * By defining/undefining the below macros one may select debugging messages
29 * fro specific JFFS2 subsystems.
30 */
31#define JFFS2_DBG_READINODE_MESSAGES
32#define JFFS2_DBG_FRAGTREE_MESSAGES
33#define JFFS2_DBG_DENTLIST_MESSAGES
34#define JFFS2_DBG_NODEREF_MESSAGES
35#define JFFS2_DBG_INOCACHE_MESSAGES
36#define JFFS2_DBG_SUMMARY_MESSAGES
37#define JFFS2_DBG_FSBUILD_MESSAGES
38#endif
39
40#if CONFIG_JFFS2_FS_DEBUG > 1
41#define JFFS2_DBG_FRAGTREE2_MESSAGES
42#define JFFS2_DBG_MEMALLOC_MESSAGES
43#endif
44
45/* Sanity checks are supposed to be light-weight and enabled by default */
46#define JFFS2_DBG_SANITY_CHECKS
47
48/*
49 * Dx() are mainly used for debugging messages, they must go away and be
50 * superseded by nicer dbg_xxx() macros...
51 */
52#if CONFIG_JFFS2_FS_DEBUG > 0
53#define D1(x) x
54#else
55#define D1(x)
56#endif
57
58#if CONFIG_JFFS2_FS_DEBUG > 1
59#define D2(x) x
60#else
61#define D2(x)
62#endif
63
64/* The prefixes of JFFS2 messages */
65#define JFFS2_DBG_PREFIX "[JFFS2 DBG]"
66#define JFFS2_ERR_PREFIX "JFFS2 error:"
67#define JFFS2_WARN_PREFIX "JFFS2 warning:"
68#define JFFS2_NOTICE_PREFIX "JFFS2 notice:"
69
70#define JFFS2_ERR KERN_ERR
71#define JFFS2_WARN KERN_WARNING
72#define JFFS2_NOT KERN_NOTICE
73#define JFFS2_DBG KERN_DEBUG
74
75#define JFFS2_DBG_MSG_PREFIX JFFS2_DBG JFFS2_DBG_PREFIX
76#define JFFS2_ERR_MSG_PREFIX JFFS2_ERR JFFS2_ERR_PREFIX
77#define JFFS2_WARN_MSG_PREFIX JFFS2_WARN JFFS2_WARN_PREFIX
78#define JFFS2_NOTICE_MSG_PREFIX JFFS2_NOT JFFS2_NOTICE_PREFIX
79
80/* JFFS2 message macros */
81#define JFFS2_ERROR(fmt, ...) \
82 do { \
83 printk(JFFS2_ERR_MSG_PREFIX \
84 " (%d) %s: " fmt, current->pid, \
85 __FUNCTION__, ##__VA_ARGS__); \
86 } while(0)
87
88#define JFFS2_WARNING(fmt, ...) \
89 do { \
90 printk(JFFS2_WARN_MSG_PREFIX \
91 " (%d) %s: " fmt, current->pid, \
92 __FUNCTION__, ##__VA_ARGS__); \
93 } while(0)
94
95#define JFFS2_NOTICE(fmt, ...) \
96 do { \
97 printk(JFFS2_NOTICE_MSG_PREFIX \
98 " (%d) %s: " fmt, current->pid, \
99 __FUNCTION__, ##__VA_ARGS__); \
100 } while(0)
101
102#define JFFS2_DEBUG(fmt, ...) \
103 do { \
104 printk(JFFS2_DBG_MSG_PREFIX \
105 " (%d) %s: " fmt, current->pid, \
106 __FUNCTION__, ##__VA_ARGS__); \
107 } while(0)
108
109/*
110 * We split our debugging messages on several parts, depending on the JFFS2
111 * subsystem the message belongs to.
112 */
113/* Read inode debugging messages */
114#ifdef JFFS2_DBG_READINODE_MESSAGES
115#define dbg_readinode(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
116#else
117#define dbg_readinode(fmt, ...)
118#endif
119
120/* Fragtree build debugging messages */
121#ifdef JFFS2_DBG_FRAGTREE_MESSAGES
122#define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
123#else
124#define dbg_fragtree(fmt, ...)
125#endif
126#ifdef JFFS2_DBG_FRAGTREE2_MESSAGES
127#define dbg_fragtree2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
128#else
129#define dbg_fragtree2(fmt, ...)
130#endif
131
132/* Directory entry list manilulation debugging messages */
133#ifdef JFFS2_DBG_DENTLIST_MESSAGES
134#define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
135#else
136#define dbg_dentlist(fmt, ...)
137#endif
138
139/* Print the messages about manipulating node_refs */
140#ifdef JFFS2_DBG_NODEREF_MESSAGES
141#define dbg_noderef(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
142#else
143#define dbg_noderef(fmt, ...)
144#endif
145
146/* Manipulations with the list of inodes (JFFS2 inocache) */
147#ifdef JFFS2_DBG_INOCACHE_MESSAGES
148#define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
149#else
150#define dbg_inocache(fmt, ...)
151#endif
152
153/* Summary debugging messages */
154#ifdef JFFS2_DBG_SUMMARY_MESSAGES
155#define dbg_summary(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
156#else
157#define dbg_summary(fmt, ...)
158#endif
159
160/* File system build messages */
161#ifdef JFFS2_DBG_FSBUILD_MESSAGES
162#define dbg_fsbuild(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
163#else
164#define dbg_fsbuild(fmt, ...)
165#endif
166
167/* Watch the object allocations */
168#ifdef JFFS2_DBG_MEMALLOC_MESSAGES
169#define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
170#else
171#define dbg_memalloc(fmt, ...)
172#endif
173
174
175/* "Sanity" checks */
176void
177__jffs2_dbg_acct_sanity_check_nolock(struct jffs2_sb_info *c,
178 struct jffs2_eraseblock *jeb);
179void
180__jffs2_dbg_acct_sanity_check(struct jffs2_sb_info *c,
181 struct jffs2_eraseblock *jeb);
182
183/* "Paranoia" checks */
184void
185__jffs2_dbg_fragtree_paranoia_check(struct jffs2_inode_info *f);
186void
187__jffs2_dbg_fragtree_paranoia_check_nolock(struct jffs2_inode_info *f);
188void
189__jffs2_dbg_acct_paranoia_check(struct jffs2_sb_info *c,
190 struct jffs2_eraseblock *jeb);
191void
192__jffs2_dbg_acct_paranoia_check_nolock(struct jffs2_sb_info *c,
193 struct jffs2_eraseblock *jeb);
194void
195__jffs2_dbg_prewrite_paranoia_check(struct jffs2_sb_info *c,
196 uint32_t ofs, int len);
197
198/* "Dump" functions */
199void
200__jffs2_dbg_dump_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
201void
202__jffs2_dbg_dump_jeb_nolock(struct jffs2_eraseblock *jeb);
203void
204__jffs2_dbg_dump_block_lists(struct jffs2_sb_info *c);
205void
206__jffs2_dbg_dump_block_lists_nolock(struct jffs2_sb_info *c);
207void
208__jffs2_dbg_dump_node_refs(struct jffs2_sb_info *c,
209 struct jffs2_eraseblock *jeb);
210void
211__jffs2_dbg_dump_node_refs_nolock(struct jffs2_sb_info *c,
212 struct jffs2_eraseblock *jeb);
213void
214__jffs2_dbg_dump_fragtree(struct jffs2_inode_info *f);
215void
216__jffs2_dbg_dump_fragtree_nolock(struct jffs2_inode_info *f);
217void
218__jffs2_dbg_dump_buffer(unsigned char *buf, int len, uint32_t offs);
219void
220__jffs2_dbg_dump_node(struct jffs2_sb_info *c, uint32_t ofs);
221
222#ifdef JFFS2_DBG_PARANOIA_CHECKS
223#define jffs2_dbg_fragtree_paranoia_check(f) \
224 __jffs2_dbg_fragtree_paranoia_check(f)
225#define jffs2_dbg_fragtree_paranoia_check_nolock(f) \
226 __jffs2_dbg_fragtree_paranoia_check_nolock(f)
227#define jffs2_dbg_acct_paranoia_check(c, jeb) \
228 __jffs2_dbg_acct_paranoia_check(c,jeb)
229#define jffs2_dbg_acct_paranoia_check_nolock(c, jeb) \
230 __jffs2_dbg_acct_paranoia_check_nolock(c,jeb)
231#define jffs2_dbg_prewrite_paranoia_check(c, ofs, len) \
232 __jffs2_dbg_prewrite_paranoia_check(c, ofs, len)
233#else
234#define jffs2_dbg_fragtree_paranoia_check(f)
235#define jffs2_dbg_fragtree_paranoia_check_nolock(f)
236#define jffs2_dbg_acct_paranoia_check(c, jeb)
237#define jffs2_dbg_acct_paranoia_check_nolock(c, jeb)
238#define jffs2_dbg_prewrite_paranoia_check(c, ofs, len)
239#endif /* !JFFS2_PARANOIA_CHECKS */
240
241#ifdef JFFS2_DBG_DUMPS
242#define jffs2_dbg_dump_jeb(c, jeb) \
243 __jffs2_dbg_dump_jeb(c, jeb);
244#define jffs2_dbg_dump_jeb_nolock(jeb) \
245 __jffs2_dbg_dump_jeb_nolock(jeb);
246#define jffs2_dbg_dump_block_lists(c) \
247 __jffs2_dbg_dump_block_lists(c)
248#define jffs2_dbg_dump_block_lists_nolock(c) \
249 __jffs2_dbg_dump_block_lists_nolock(c)
250#define jffs2_dbg_dump_fragtree(f) \
251 __jffs2_dbg_dump_fragtree(f);
252#define jffs2_dbg_dump_fragtree_nolock(f) \
253 __jffs2_dbg_dump_fragtree_nolock(f);
254#define jffs2_dbg_dump_buffer(buf, len, offs) \
255 __jffs2_dbg_dump_buffer(*buf, len, offs);
256#define jffs2_dbg_dump_node(c, ofs) \
257 __jffs2_dbg_dump_node(c, ofs);
258#else
259#define jffs2_dbg_dump_jeb(c, jeb)
260#define jffs2_dbg_dump_jeb_nolock(jeb)
261#define jffs2_dbg_dump_block_lists(c)
262#define jffs2_dbg_dump_block_lists_nolock(c)
263#define jffs2_dbg_dump_fragtree(f)
264#define jffs2_dbg_dump_fragtree_nolock(f)
265#define jffs2_dbg_dump_buffer(buf, len, offs)
266#define jffs2_dbg_dump_node(c, ofs)
267#endif /* !JFFS2_DBG_DUMPS */
268
269#ifdef JFFS2_DBG_SANITY_CHECKS
270#define jffs2_dbg_acct_sanity_check(c, jeb) \
271 __jffs2_dbg_acct_sanity_check(c, jeb)
272#define jffs2_dbg_acct_sanity_check_nolock(c, jeb) \
273 __jffs2_dbg_acct_sanity_check_nolock(c, jeb)
274#else
275#define jffs2_dbg_acct_sanity_check(c, jeb)
276#define jffs2_dbg_acct_sanity_check_nolock(c, jeb)
277#endif /* !JFFS2_DBG_SANITY_CHECKS */
278
279#endif /* _JFFS2_DEBUG_H_ */
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index 3ca0d25eef1d..a7bf9cb2567f 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: dir.c,v 1.86 2005/07/06 12:13:09 dwmw2 Exp $ 10 * $Id: dir.c,v 1.90 2005/11/07 11:14:39 gleixner Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -64,7 +64,7 @@ struct inode_operations jffs2_dir_inode_operations =
64 64
65 65
66/* We keep the dirent list sorted in increasing order of name hash, 66/* We keep the dirent list sorted in increasing order of name hash,
67 and we use the same hash function as the dentries. Makes this 67 and we use the same hash function as the dentries. Makes this
68 nice and simple 68 nice and simple
69*/ 69*/
70static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target, 70static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target,
@@ -85,7 +85,7 @@ static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target,
85 85
86 /* NB: The 2.2 backport will need to explicitly check for '.' and '..' here */ 86 /* NB: The 2.2 backport will need to explicitly check for '.' and '..' here */
87 for (fd_list = dir_f->dents; fd_list && fd_list->nhash <= target->d_name.hash; fd_list = fd_list->next) { 87 for (fd_list = dir_f->dents; fd_list && fd_list->nhash <= target->d_name.hash; fd_list = fd_list->next) {
88 if (fd_list->nhash == target->d_name.hash && 88 if (fd_list->nhash == target->d_name.hash &&
89 (!fd || fd_list->version > fd->version) && 89 (!fd || fd_list->version > fd->version) &&
90 strlen(fd_list->name) == target->d_name.len && 90 strlen(fd_list->name) == target->d_name.len &&
91 !strncmp(fd_list->name, target->d_name.name, target->d_name.len)) { 91 !strncmp(fd_list->name, target->d_name.name, target->d_name.len)) {
@@ -147,7 +147,7 @@ static int jffs2_readdir(struct file *filp, void *dirent, filldir_t filldir)
147 curofs++; 147 curofs++;
148 /* First loop: curofs = 2; offset = 2 */ 148 /* First loop: curofs = 2; offset = 2 */
149 if (curofs < offset) { 149 if (curofs < offset) {
150 D2(printk(KERN_DEBUG "Skipping dirent: \"%s\", ino #%u, type %d, because curofs %ld < offset %ld\n", 150 D2(printk(KERN_DEBUG "Skipping dirent: \"%s\", ino #%u, type %d, because curofs %ld < offset %ld\n",
151 fd->name, fd->ino, fd->type, curofs, offset)); 151 fd->name, fd->ino, fd->type, curofs, offset));
152 continue; 152 continue;
153 } 153 }
@@ -182,7 +182,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode,
182 ri = jffs2_alloc_raw_inode(); 182 ri = jffs2_alloc_raw_inode();
183 if (!ri) 183 if (!ri)
184 return -ENOMEM; 184 return -ENOMEM;
185 185
186 c = JFFS2_SB_INFO(dir_i->i_sb); 186 c = JFFS2_SB_INFO(dir_i->i_sb);
187 187
188 D1(printk(KERN_DEBUG "jffs2_create()\n")); 188 D1(printk(KERN_DEBUG "jffs2_create()\n"));
@@ -203,7 +203,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode,
203 f = JFFS2_INODE_INFO(inode); 203 f = JFFS2_INODE_INFO(inode);
204 dir_f = JFFS2_INODE_INFO(dir_i); 204 dir_f = JFFS2_INODE_INFO(dir_i);
205 205
206 ret = jffs2_do_create(c, dir_f, f, ri, 206 ret = jffs2_do_create(c, dir_f, f, ri,
207 dentry->d_name.name, dentry->d_name.len); 207 dentry->d_name.name, dentry->d_name.len);
208 208
209 if (ret) { 209 if (ret) {
@@ -232,11 +232,14 @@ static int jffs2_unlink(struct inode *dir_i, struct dentry *dentry)
232 struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i); 232 struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i);
233 struct jffs2_inode_info *dead_f = JFFS2_INODE_INFO(dentry->d_inode); 233 struct jffs2_inode_info *dead_f = JFFS2_INODE_INFO(dentry->d_inode);
234 int ret; 234 int ret;
235 uint32_t now = get_seconds();
235 236
236 ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name, 237 ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name,
237 dentry->d_name.len, dead_f); 238 dentry->d_name.len, dead_f, now);
238 if (dead_f->inocache) 239 if (dead_f->inocache)
239 dentry->d_inode->i_nlink = dead_f->inocache->nlink; 240 dentry->d_inode->i_nlink = dead_f->inocache->nlink;
241 if (!ret)
242 dir_i->i_mtime = dir_i->i_ctime = ITIME(now);
240 return ret; 243 return ret;
241} 244}
242/***********************************************************************/ 245/***********************************************************************/
@@ -249,6 +252,7 @@ static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct de
249 struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i); 252 struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i);
250 int ret; 253 int ret;
251 uint8_t type; 254 uint8_t type;
255 uint32_t now;
252 256
253 /* Don't let people make hard links to bad inodes. */ 257 /* Don't let people make hard links to bad inodes. */
254 if (!f->inocache) 258 if (!f->inocache)
@@ -261,13 +265,15 @@ static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct de
261 type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12; 265 type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12;
262 if (!type) type = DT_REG; 266 if (!type) type = DT_REG;
263 267
264 ret = jffs2_do_link(c, dir_f, f->inocache->ino, type, dentry->d_name.name, dentry->d_name.len); 268 now = get_seconds();
269 ret = jffs2_do_link(c, dir_f, f->inocache->ino, type, dentry->d_name.name, dentry->d_name.len, now);
265 270
266 if (!ret) { 271 if (!ret) {
267 down(&f->sem); 272 down(&f->sem);
268 old_dentry->d_inode->i_nlink = ++f->inocache->nlink; 273 old_dentry->d_inode->i_nlink = ++f->inocache->nlink;
269 up(&f->sem); 274 up(&f->sem);
270 d_instantiate(dentry, old_dentry->d_inode); 275 d_instantiate(dentry, old_dentry->d_inode);
276 dir_i->i_mtime = dir_i->i_ctime = ITIME(now);
271 atomic_inc(&old_dentry->d_inode->i_count); 277 atomic_inc(&old_dentry->d_inode->i_count);
272 } 278 }
273 return ret; 279 return ret;
@@ -297,14 +303,15 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
297 303
298 if (!ri) 304 if (!ri)
299 return -ENOMEM; 305 return -ENOMEM;
300 306
301 c = JFFS2_SB_INFO(dir_i->i_sb); 307 c = JFFS2_SB_INFO(dir_i->i_sb);
302 308
303 /* Try to reserve enough space for both node and dirent. 309 /* Try to reserve enough space for both node and dirent.
304 * Just the node will do for now, though 310 * Just the node will do for now, though
305 */ 311 */
306 namelen = dentry->d_name.len; 312 namelen = dentry->d_name.len;
307 ret = jffs2_reserve_space(c, sizeof(*ri) + targetlen, &phys_ofs, &alloclen, ALLOC_NORMAL); 313 ret = jffs2_reserve_space(c, sizeof(*ri) + targetlen, &phys_ofs, &alloclen,
314 ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
308 315
309 if (ret) { 316 if (ret) {
310 jffs2_free_raw_inode(ri); 317 jffs2_free_raw_inode(ri);
@@ -331,7 +338,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
331 ri->compr = JFFS2_COMPR_NONE; 338 ri->compr = JFFS2_COMPR_NONE;
332 ri->data_crc = cpu_to_je32(crc32(0, target, targetlen)); 339 ri->data_crc = cpu_to_je32(crc32(0, target, targetlen));
333 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); 340 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
334 341
335 fn = jffs2_write_dnode(c, f, ri, target, targetlen, phys_ofs, ALLOC_NORMAL); 342 fn = jffs2_write_dnode(c, f, ri, target, targetlen, phys_ofs, ALLOC_NORMAL);
336 343
337 jffs2_free_raw_inode(ri); 344 jffs2_free_raw_inode(ri);
@@ -344,9 +351,9 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
344 return PTR_ERR(fn); 351 return PTR_ERR(fn);
345 } 352 }
346 353
347 /* We use f->dents field to store the target path. */ 354 /* We use f->target field to store the target path. */
348 f->dents = kmalloc(targetlen + 1, GFP_KERNEL); 355 f->target = kmalloc(targetlen + 1, GFP_KERNEL);
349 if (!f->dents) { 356 if (!f->target) {
350 printk(KERN_WARNING "Can't allocate %d bytes of memory\n", targetlen + 1); 357 printk(KERN_WARNING "Can't allocate %d bytes of memory\n", targetlen + 1);
351 up(&f->sem); 358 up(&f->sem);
352 jffs2_complete_reservation(c); 359 jffs2_complete_reservation(c);
@@ -354,17 +361,18 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
354 return -ENOMEM; 361 return -ENOMEM;
355 } 362 }
356 363
357 memcpy(f->dents, target, targetlen + 1); 364 memcpy(f->target, target, targetlen + 1);
358 D1(printk(KERN_DEBUG "jffs2_symlink: symlink's target '%s' cached\n", (char *)f->dents)); 365 D1(printk(KERN_DEBUG "jffs2_symlink: symlink's target '%s' cached\n", (char *)f->target));
359 366
360 /* No data here. Only a metadata node, which will be 367 /* No data here. Only a metadata node, which will be
361 obsoleted by the first data write 368 obsoleted by the first data write
362 */ 369 */
363 f->metadata = fn; 370 f->metadata = fn;
364 up(&f->sem); 371 up(&f->sem);
365 372
366 jffs2_complete_reservation(c); 373 jffs2_complete_reservation(c);
367 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL); 374 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen,
375 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
368 if (ret) { 376 if (ret) {
369 /* Eep. */ 377 /* Eep. */
370 jffs2_clear_inode(inode); 378 jffs2_clear_inode(inode);
@@ -399,7 +407,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
399 fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL); 407 fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL);
400 408
401 if (IS_ERR(fd)) { 409 if (IS_ERR(fd)) {
402 /* dirent failed to write. Delete the inode normally 410 /* dirent failed to write. Delete the inode normally
403 as if it were the final unlink() */ 411 as if it were the final unlink() */
404 jffs2_complete_reservation(c); 412 jffs2_complete_reservation(c);
405 jffs2_free_raw_dirent(rd); 413 jffs2_free_raw_dirent(rd);
@@ -442,14 +450,15 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
442 ri = jffs2_alloc_raw_inode(); 450 ri = jffs2_alloc_raw_inode();
443 if (!ri) 451 if (!ri)
444 return -ENOMEM; 452 return -ENOMEM;
445 453
446 c = JFFS2_SB_INFO(dir_i->i_sb); 454 c = JFFS2_SB_INFO(dir_i->i_sb);
447 455
448 /* Try to reserve enough space for both node and dirent. 456 /* Try to reserve enough space for both node and dirent.
449 * Just the node will do for now, though 457 * Just the node will do for now, though
450 */ 458 */
451 namelen = dentry->d_name.len; 459 namelen = dentry->d_name.len;
452 ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL); 460 ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL,
461 JFFS2_SUMMARY_INODE_SIZE);
453 462
454 if (ret) { 463 if (ret) {
455 jffs2_free_raw_inode(ri); 464 jffs2_free_raw_inode(ri);
@@ -473,7 +482,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
473 482
474 ri->data_crc = cpu_to_je32(0); 483 ri->data_crc = cpu_to_je32(0);
475 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); 484 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
476 485
477 fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL); 486 fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL);
478 487
479 jffs2_free_raw_inode(ri); 488 jffs2_free_raw_inode(ri);
@@ -485,20 +494,21 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
485 jffs2_clear_inode(inode); 494 jffs2_clear_inode(inode);
486 return PTR_ERR(fn); 495 return PTR_ERR(fn);
487 } 496 }
488 /* No data here. Only a metadata node, which will be 497 /* No data here. Only a metadata node, which will be
489 obsoleted by the first data write 498 obsoleted by the first data write
490 */ 499 */
491 f->metadata = fn; 500 f->metadata = fn;
492 up(&f->sem); 501 up(&f->sem);
493 502
494 jffs2_complete_reservation(c); 503 jffs2_complete_reservation(c);
495 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL); 504 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen,
505 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
496 if (ret) { 506 if (ret) {
497 /* Eep. */ 507 /* Eep. */
498 jffs2_clear_inode(inode); 508 jffs2_clear_inode(inode);
499 return ret; 509 return ret;
500 } 510 }
501 511
502 rd = jffs2_alloc_raw_dirent(); 512 rd = jffs2_alloc_raw_dirent();
503 if (!rd) { 513 if (!rd) {
504 /* Argh. Now we treat it like a normal delete */ 514 /* Argh. Now we treat it like a normal delete */
@@ -525,9 +535,9 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
525 rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen)); 535 rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen));
526 536
527 fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL); 537 fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL);
528 538
529 if (IS_ERR(fd)) { 539 if (IS_ERR(fd)) {
530 /* dirent failed to write. Delete the inode normally 540 /* dirent failed to write. Delete the inode normally
531 as if it were the final unlink() */ 541 as if it were the final unlink() */
532 jffs2_complete_reservation(c); 542 jffs2_complete_reservation(c);
533 jffs2_free_raw_dirent(rd); 543 jffs2_free_raw_dirent(rd);
@@ -589,19 +599,20 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
589 ri = jffs2_alloc_raw_inode(); 599 ri = jffs2_alloc_raw_inode();
590 if (!ri) 600 if (!ri)
591 return -ENOMEM; 601 return -ENOMEM;
592 602
593 c = JFFS2_SB_INFO(dir_i->i_sb); 603 c = JFFS2_SB_INFO(dir_i->i_sb);
594 604
595 if (S_ISBLK(mode) || S_ISCHR(mode)) { 605 if (S_ISBLK(mode) || S_ISCHR(mode)) {
596 dev = cpu_to_je16(old_encode_dev(rdev)); 606 dev = cpu_to_je16(old_encode_dev(rdev));
597 devlen = sizeof(dev); 607 devlen = sizeof(dev);
598 } 608 }
599 609
600 /* Try to reserve enough space for both node and dirent. 610 /* Try to reserve enough space for both node and dirent.
601 * Just the node will do for now, though 611 * Just the node will do for now, though
602 */ 612 */
603 namelen = dentry->d_name.len; 613 namelen = dentry->d_name.len;
604 ret = jffs2_reserve_space(c, sizeof(*ri) + devlen, &phys_ofs, &alloclen, ALLOC_NORMAL); 614 ret = jffs2_reserve_space(c, sizeof(*ri) + devlen, &phys_ofs, &alloclen,
615 ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
605 616
606 if (ret) { 617 if (ret) {
607 jffs2_free_raw_inode(ri); 618 jffs2_free_raw_inode(ri);
@@ -627,7 +638,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
627 ri->compr = JFFS2_COMPR_NONE; 638 ri->compr = JFFS2_COMPR_NONE;
628 ri->data_crc = cpu_to_je32(crc32(0, &dev, devlen)); 639 ri->data_crc = cpu_to_je32(crc32(0, &dev, devlen));
629 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); 640 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
630 641
631 fn = jffs2_write_dnode(c, f, ri, (char *)&dev, devlen, phys_ofs, ALLOC_NORMAL); 642 fn = jffs2_write_dnode(c, f, ri, (char *)&dev, devlen, phys_ofs, ALLOC_NORMAL);
632 643
633 jffs2_free_raw_inode(ri); 644 jffs2_free_raw_inode(ri);
@@ -639,14 +650,15 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
639 jffs2_clear_inode(inode); 650 jffs2_clear_inode(inode);
640 return PTR_ERR(fn); 651 return PTR_ERR(fn);
641 } 652 }
642 /* No data here. Only a metadata node, which will be 653 /* No data here. Only a metadata node, which will be
643 obsoleted by the first data write 654 obsoleted by the first data write
644 */ 655 */
645 f->metadata = fn; 656 f->metadata = fn;
646 up(&f->sem); 657 up(&f->sem);
647 658
648 jffs2_complete_reservation(c); 659 jffs2_complete_reservation(c);
649 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL); 660 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen,
661 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
650 if (ret) { 662 if (ret) {
651 /* Eep. */ 663 /* Eep. */
652 jffs2_clear_inode(inode); 664 jffs2_clear_inode(inode);
@@ -682,9 +694,9 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
682 rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen)); 694 rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen));
683 695
684 fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL); 696 fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL);
685 697
686 if (IS_ERR(fd)) { 698 if (IS_ERR(fd)) {
687 /* dirent failed to write. Delete the inode normally 699 /* dirent failed to write. Delete the inode normally
688 as if it were the final unlink() */ 700 as if it were the final unlink() */
689 jffs2_complete_reservation(c); 701 jffs2_complete_reservation(c);
690 jffs2_free_raw_dirent(rd); 702 jffs2_free_raw_dirent(rd);
@@ -716,8 +728,9 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
716 struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb); 728 struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb);
717 struct jffs2_inode_info *victim_f = NULL; 729 struct jffs2_inode_info *victim_f = NULL;
718 uint8_t type; 730 uint8_t type;
731 uint32_t now;
719 732
720 /* The VFS will check for us and prevent trying to rename a 733 /* The VFS will check for us and prevent trying to rename a
721 * file over a directory and vice versa, but if it's a directory, 734 * file over a directory and vice versa, but if it's a directory,
722 * the VFS can't check whether the victim is empty. The filesystem 735 * the VFS can't check whether the victim is empty. The filesystem
723 * needs to do that for itself. 736 * needs to do that for itself.
@@ -739,19 +752,20 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
739 } 752 }
740 753
741 /* XXX: We probably ought to alloc enough space for 754 /* XXX: We probably ought to alloc enough space for
742 both nodes at the same time. Writing the new link, 755 both nodes at the same time. Writing the new link,
743 then getting -ENOSPC, is quite bad :) 756 then getting -ENOSPC, is quite bad :)
744 */ 757 */
745 758
746 /* Make a hard link */ 759 /* Make a hard link */
747 760
748 /* XXX: This is ugly */ 761 /* XXX: This is ugly */
749 type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12; 762 type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12;
750 if (!type) type = DT_REG; 763 if (!type) type = DT_REG;
751 764
752 ret = jffs2_do_link(c, JFFS2_INODE_INFO(new_dir_i), 765 now = get_seconds();
766 ret = jffs2_do_link(c, JFFS2_INODE_INFO(new_dir_i),
753 old_dentry->d_inode->i_ino, type, 767 old_dentry->d_inode->i_ino, type,
754 new_dentry->d_name.name, new_dentry->d_name.len); 768 new_dentry->d_name.name, new_dentry->d_name.len, now);
755 769
756 if (ret) 770 if (ret)
757 return ret; 771 return ret;
@@ -768,14 +782,14 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
768 } 782 }
769 } 783 }
770 784
771 /* If it was a directory we moved, and there was no victim, 785 /* If it was a directory we moved, and there was no victim,
772 increase i_nlink on its new parent */ 786 increase i_nlink on its new parent */
773 if (S_ISDIR(old_dentry->d_inode->i_mode) && !victim_f) 787 if (S_ISDIR(old_dentry->d_inode->i_mode) && !victim_f)
774 new_dir_i->i_nlink++; 788 new_dir_i->i_nlink++;
775 789
776 /* Unlink the original */ 790 /* Unlink the original */
777 ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), 791 ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
778 old_dentry->d_name.name, old_dentry->d_name.len, NULL); 792 old_dentry->d_name.name, old_dentry->d_name.len, NULL, now);
779 793
780 /* We don't touch inode->i_nlink */ 794 /* We don't touch inode->i_nlink */
781 795
@@ -792,12 +806,15 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
792 /* Might as well let the VFS know */ 806 /* Might as well let the VFS know */
793 d_instantiate(new_dentry, old_dentry->d_inode); 807 d_instantiate(new_dentry, old_dentry->d_inode);
794 atomic_inc(&old_dentry->d_inode->i_count); 808 atomic_inc(&old_dentry->d_inode->i_count);
809 new_dir_i->i_mtime = new_dir_i->i_ctime = ITIME(now);
795 return ret; 810 return ret;
796 } 811 }
797 812
798 if (S_ISDIR(old_dentry->d_inode->i_mode)) 813 if (S_ISDIR(old_dentry->d_inode->i_mode))
799 old_dir_i->i_nlink--; 814 old_dir_i->i_nlink--;
800 815
816 new_dir_i->i_mtime = new_dir_i->i_ctime = old_dir_i->i_mtime = old_dir_i->i_ctime = ITIME(now);
817
801 return 0; 818 return 0;
802} 819}
803 820
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
index 787d84ac2bcd..dad68fdffe9e 100644
--- a/fs/jffs2/erase.c
+++ b/fs/jffs2/erase.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: erase.c,v 1.80 2005/07/14 19:46:24 joern Exp $ 10 * $Id: erase.c,v 1.85 2005/09/20 14:53:15 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -24,7 +24,7 @@ struct erase_priv_struct {
24 struct jffs2_eraseblock *jeb; 24 struct jffs2_eraseblock *jeb;
25 struct jffs2_sb_info *c; 25 struct jffs2_sb_info *c;
26}; 26};
27 27
28#ifndef __ECOS 28#ifndef __ECOS
29static void jffs2_erase_callback(struct erase_info *); 29static void jffs2_erase_callback(struct erase_info *);
30#endif 30#endif
@@ -48,7 +48,8 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,
48#else /* Linux */ 48#else /* Linux */
49 struct erase_info *instr; 49 struct erase_info *instr;
50 50
51 D1(printk(KERN_DEBUG "jffs2_erase_block(): erase block %#x (range %#x-%#x)\n", jeb->offset, jeb->offset, jeb->offset + c->sector_size)); 51 D1(printk(KERN_DEBUG "jffs2_erase_block(): erase block %#08x (range %#08x-%#08x)\n",
52 jeb->offset, jeb->offset, jeb->offset + c->sector_size));
52 instr = kmalloc(sizeof(struct erase_info) + sizeof(struct erase_priv_struct), GFP_KERNEL); 53 instr = kmalloc(sizeof(struct erase_info) + sizeof(struct erase_priv_struct), GFP_KERNEL);
53 if (!instr) { 54 if (!instr) {
54 printk(KERN_WARNING "kmalloc for struct erase_info in jffs2_erase_block failed. Refiling block for later\n"); 55 printk(KERN_WARNING "kmalloc for struct erase_info in jffs2_erase_block failed. Refiling block for later\n");
@@ -70,7 +71,7 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,
70 instr->callback = jffs2_erase_callback; 71 instr->callback = jffs2_erase_callback;
71 instr->priv = (unsigned long)(&instr[1]); 72 instr->priv = (unsigned long)(&instr[1]);
72 instr->fail_addr = 0xffffffff; 73 instr->fail_addr = 0xffffffff;
73 74
74 ((struct erase_priv_struct *)instr->priv)->jeb = jeb; 75 ((struct erase_priv_struct *)instr->priv)->jeb = jeb;
75 ((struct erase_priv_struct *)instr->priv)->c = c; 76 ((struct erase_priv_struct *)instr->priv)->c = c;
76 77
@@ -95,7 +96,7 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,
95 return; 96 return;
96 } 97 }
97 98
98 if (ret == -EROFS) 99 if (ret == -EROFS)
99 printk(KERN_WARNING "Erase at 0x%08x failed immediately: -EROFS. Is the sector locked?\n", jeb->offset); 100 printk(KERN_WARNING "Erase at 0x%08x failed immediately: -EROFS. Is the sector locked?\n", jeb->offset);
100 else 101 else
101 printk(KERN_WARNING "Erase at 0x%08x failed immediately: errno %d\n", jeb->offset, ret); 102 printk(KERN_WARNING "Erase at 0x%08x failed immediately: errno %d\n", jeb->offset, ret);
@@ -196,7 +197,7 @@ static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock
196 c->nr_erasing_blocks--; 197 c->nr_erasing_blocks--;
197 spin_unlock(&c->erase_completion_lock); 198 spin_unlock(&c->erase_completion_lock);
198 wake_up(&c->erase_wait); 199 wake_up(&c->erase_wait);
199} 200}
200 201
201#ifndef __ECOS 202#ifndef __ECOS
202static void jffs2_erase_callback(struct erase_info *instr) 203static void jffs2_erase_callback(struct erase_info *instr)
@@ -208,7 +209,7 @@ static void jffs2_erase_callback(struct erase_info *instr)
208 jffs2_erase_failed(priv->c, priv->jeb, instr->fail_addr); 209 jffs2_erase_failed(priv->c, priv->jeb, instr->fail_addr);
209 } else { 210 } else {
210 jffs2_erase_succeeded(priv->c, priv->jeb); 211 jffs2_erase_succeeded(priv->c, priv->jeb);
211 } 212 }
212 kfree(instr); 213 kfree(instr);
213} 214}
214#endif /* !__ECOS */ 215#endif /* !__ECOS */
@@ -226,13 +227,13 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c,
226 /* Walk the inode's list once, removing any nodes from this eraseblock */ 227 /* Walk the inode's list once, removing any nodes from this eraseblock */
227 while (1) { 228 while (1) {
228 if (!(*prev)->next_in_ino) { 229 if (!(*prev)->next_in_ino) {
229 /* We're looking at the jffs2_inode_cache, which is 230 /* We're looking at the jffs2_inode_cache, which is
230 at the end of the linked list. Stash it and continue 231 at the end of the linked list. Stash it and continue
231 from the beginning of the list */ 232 from the beginning of the list */
232 ic = (struct jffs2_inode_cache *)(*prev); 233 ic = (struct jffs2_inode_cache *)(*prev);
233 prev = &ic->nodes; 234 prev = &ic->nodes;
234 continue; 235 continue;
235 } 236 }
236 237
237 if (SECTOR_ADDR((*prev)->flash_offset) == jeb->offset) { 238 if (SECTOR_ADDR((*prev)->flash_offset) == jeb->offset) {
238 /* It's in the block we're erasing */ 239 /* It's in the block we're erasing */
@@ -266,7 +267,7 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c,
266 printk(KERN_DEBUG "After remove_node_refs_from_ino_list: \n" KERN_DEBUG); 267 printk(KERN_DEBUG "After remove_node_refs_from_ino_list: \n" KERN_DEBUG);
267 268
268 this = ic->nodes; 269 this = ic->nodes;
269 270
270 while(this) { 271 while(this) {
271 printk( "0x%08x(%d)->", ref_offset(this), ref_flags(this)); 272 printk( "0x%08x(%d)->", ref_offset(this), ref_flags(this));
272 if (++i == 5) { 273 if (++i == 5) {
@@ -289,7 +290,7 @@ static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_erase
289 while(jeb->first_node) { 290 while(jeb->first_node) {
290 ref = jeb->first_node; 291 ref = jeb->first_node;
291 jeb->first_node = ref->next_phys; 292 jeb->first_node = ref->next_phys;
292 293
293 /* Remove from the inode-list */ 294 /* Remove from the inode-list */
294 if (ref->next_in_ino) 295 if (ref->next_in_ino)
295 jffs2_remove_node_refs_from_ino_list(c, ref, jeb); 296 jffs2_remove_node_refs_from_ino_list(c, ref, jeb);
@@ -306,7 +307,7 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl
306 uint32_t ofs; 307 uint32_t ofs;
307 size_t retlen; 308 size_t retlen;
308 int ret = -EIO; 309 int ret = -EIO;
309 310
310 ebuf = kmalloc(PAGE_SIZE, GFP_KERNEL); 311 ebuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
311 if (!ebuf) { 312 if (!ebuf) {
312 printk(KERN_WARNING "Failed to allocate page buffer for verifying erase at 0x%08x. Refiling\n", jeb->offset); 313 printk(KERN_WARNING "Failed to allocate page buffer for verifying erase at 0x%08x. Refiling\n", jeb->offset);
@@ -360,7 +361,7 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
360 case -EIO: goto filebad; 361 case -EIO: goto filebad;
361 } 362 }
362 363
363 /* Write the erase complete marker */ 364 /* Write the erase complete marker */
364 D1(printk(KERN_DEBUG "Writing erased marker to block at 0x%08x\n", jeb->offset)); 365 D1(printk(KERN_DEBUG "Writing erased marker to block at 0x%08x\n", jeb->offset));
365 bad_offset = jeb->offset; 366 bad_offset = jeb->offset;
366 367
@@ -398,7 +399,7 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
398 vecs[0].iov_base = (unsigned char *) &marker; 399 vecs[0].iov_base = (unsigned char *) &marker;
399 vecs[0].iov_len = sizeof(marker); 400 vecs[0].iov_len = sizeof(marker);
400 ret = jffs2_flash_direct_writev(c, vecs, 1, jeb->offset, &retlen); 401 ret = jffs2_flash_direct_writev(c, vecs, 1, jeb->offset, &retlen);
401 402
402 if (ret || retlen != sizeof(marker)) { 403 if (ret || retlen != sizeof(marker)) {
403 if (ret) 404 if (ret)
404 printk(KERN_WARNING "Write clean marker to block at 0x%08x failed: %d\n", 405 printk(KERN_WARNING "Write clean marker to block at 0x%08x failed: %d\n",
@@ -415,9 +416,9 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
415 marker_ref->next_phys = NULL; 416 marker_ref->next_phys = NULL;
416 marker_ref->flash_offset = jeb->offset | REF_NORMAL; 417 marker_ref->flash_offset = jeb->offset | REF_NORMAL;
417 marker_ref->__totlen = c->cleanmarker_size; 418 marker_ref->__totlen = c->cleanmarker_size;
418 419
419 jeb->first_node = jeb->last_node = marker_ref; 420 jeb->first_node = jeb->last_node = marker_ref;
420 421
421 jeb->free_size = c->sector_size - c->cleanmarker_size; 422 jeb->free_size = c->sector_size - c->cleanmarker_size;
422 jeb->used_size = c->cleanmarker_size; 423 jeb->used_size = c->cleanmarker_size;
423 jeb->dirty_size = 0; 424 jeb->dirty_size = 0;
@@ -429,8 +430,8 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
429 c->free_size += jeb->free_size; 430 c->free_size += jeb->free_size;
430 c->used_size += jeb->used_size; 431 c->used_size += jeb->used_size;
431 432
432 ACCT_SANITY_CHECK(c,jeb); 433 jffs2_dbg_acct_sanity_check_nolock(c,jeb);
433 D1(ACCT_PARANOIA_CHECK(jeb)); 434 jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
434 435
435 list_add_tail(&jeb->list, &c->free_list); 436 list_add_tail(&jeb->list, &c->free_list);
436 c->nr_erasing_blocks--; 437 c->nr_erasing_blocks--;
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index 8279bf0133ff..935f273dc57b 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: file.c,v 1.102 2005/07/06 12:13:09 dwmw2 Exp $ 10 * $Id: file.c,v 1.104 2005/10/18 23:29:35 tpoynor Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -34,8 +34,8 @@ int jffs2_fsync(struct file *filp, struct dentry *dentry, int datasync)
34 34
35 /* Trigger GC to flush any pending writes for this inode */ 35 /* Trigger GC to flush any pending writes for this inode */
36 jffs2_flush_wbuf_gc(c, inode->i_ino); 36 jffs2_flush_wbuf_gc(c, inode->i_ino);
37 37
38 return 0; 38 return 0;
39} 39}
40 40
41struct file_operations jffs2_file_operations = 41struct file_operations jffs2_file_operations =
@@ -107,7 +107,7 @@ static int jffs2_readpage (struct file *filp, struct page *pg)
107{ 107{
108 struct jffs2_inode_info *f = JFFS2_INODE_INFO(pg->mapping->host); 108 struct jffs2_inode_info *f = JFFS2_INODE_INFO(pg->mapping->host);
109 int ret; 109 int ret;
110 110
111 down(&f->sem); 111 down(&f->sem);
112 ret = jffs2_do_readpage_unlock(pg->mapping->host, pg); 112 ret = jffs2_do_readpage_unlock(pg->mapping->host, pg);
113 up(&f->sem); 113 up(&f->sem);
@@ -130,11 +130,12 @@ static int jffs2_prepare_write (struct file *filp, struct page *pg,
130 struct jffs2_raw_inode ri; 130 struct jffs2_raw_inode ri;
131 struct jffs2_full_dnode *fn; 131 struct jffs2_full_dnode *fn;
132 uint32_t phys_ofs, alloc_len; 132 uint32_t phys_ofs, alloc_len;
133 133
134 D1(printk(KERN_DEBUG "Writing new hole frag 0x%x-0x%x between current EOF and new page\n", 134 D1(printk(KERN_DEBUG "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
135 (unsigned int)inode->i_size, pageofs)); 135 (unsigned int)inode->i_size, pageofs));
136 136
137 ret = jffs2_reserve_space(c, sizeof(ri), &phys_ofs, &alloc_len, ALLOC_NORMAL); 137 ret = jffs2_reserve_space(c, sizeof(ri), &phys_ofs, &alloc_len,
138 ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
138 if (ret) 139 if (ret)
139 return ret; 140 return ret;
140 141
@@ -159,7 +160,7 @@ static int jffs2_prepare_write (struct file *filp, struct page *pg,
159 ri.compr = JFFS2_COMPR_ZERO; 160 ri.compr = JFFS2_COMPR_ZERO;
160 ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8)); 161 ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
161 ri.data_crc = cpu_to_je32(0); 162 ri.data_crc = cpu_to_je32(0);
162 163
163 fn = jffs2_write_dnode(c, f, &ri, NULL, 0, phys_ofs, ALLOC_NORMAL); 164 fn = jffs2_write_dnode(c, f, &ri, NULL, 0, phys_ofs, ALLOC_NORMAL);
164 165
165 if (IS_ERR(fn)) { 166 if (IS_ERR(fn)) {
@@ -186,7 +187,7 @@ static int jffs2_prepare_write (struct file *filp, struct page *pg,
186 inode->i_size = pageofs; 187 inode->i_size = pageofs;
187 up(&f->sem); 188 up(&f->sem);
188 } 189 }
189 190
190 /* Read in the page if it wasn't already present, unless it's a whole page */ 191 /* Read in the page if it wasn't already present, unless it's a whole page */
191 if (!PageUptodate(pg) && (start || end < PAGE_CACHE_SIZE)) { 192 if (!PageUptodate(pg) && (start || end < PAGE_CACHE_SIZE)) {
192 down(&f->sem); 193 down(&f->sem);
@@ -217,7 +218,7 @@ static int jffs2_commit_write (struct file *filp, struct page *pg,
217 if (!start && end == PAGE_CACHE_SIZE) { 218 if (!start && end == PAGE_CACHE_SIZE) {
218 /* We need to avoid deadlock with page_cache_read() in 219 /* We need to avoid deadlock with page_cache_read() in
219 jffs2_garbage_collect_pass(). So we have to mark the 220 jffs2_garbage_collect_pass(). So we have to mark the
220 page up to date, to prevent page_cache_read() from 221 page up to date, to prevent page_cache_read() from
221 trying to re-lock it. */ 222 trying to re-lock it. */
222 SetPageUptodate(pg); 223 SetPageUptodate(pg);
223 } 224 }
@@ -251,7 +252,7 @@ static int jffs2_commit_write (struct file *filp, struct page *pg,
251 /* There was an error writing. */ 252 /* There was an error writing. */
252 SetPageError(pg); 253 SetPageError(pg);
253 } 254 }
254 255
255 /* Adjust writtenlen for the padding we did, so we don't confuse our caller */ 256 /* Adjust writtenlen for the padding we did, so we don't confuse our caller */
256 if (writtenlen < (start&3)) 257 if (writtenlen < (start&3))
257 writtenlen = 0; 258 writtenlen = 0;
@@ -262,7 +263,7 @@ static int jffs2_commit_write (struct file *filp, struct page *pg,
262 if (inode->i_size < (pg->index << PAGE_CACHE_SHIFT) + start + writtenlen) { 263 if (inode->i_size < (pg->index << PAGE_CACHE_SHIFT) + start + writtenlen) {
263 inode->i_size = (pg->index << PAGE_CACHE_SHIFT) + start + writtenlen; 264 inode->i_size = (pg->index << PAGE_CACHE_SHIFT) + start + writtenlen;
264 inode->i_blocks = (inode->i_size + 511) >> 9; 265 inode->i_blocks = (inode->i_size + 511) >> 9;
265 266
266 inode->i_ctime = inode->i_mtime = ITIME(je32_to_cpu(ri->ctime)); 267 inode->i_ctime = inode->i_mtime = ITIME(je32_to_cpu(ri->ctime));
267 } 268 }
268 } 269 }
@@ -271,13 +272,13 @@ static int jffs2_commit_write (struct file *filp, struct page *pg,
271 272
272 if (start+writtenlen < end) { 273 if (start+writtenlen < end) {
273 /* generic_file_write has written more to the page cache than we've 274 /* generic_file_write has written more to the page cache than we've
274 actually written to the medium. Mark the page !Uptodate so that 275 actually written to the medium. Mark the page !Uptodate so that
275 it gets reread */ 276 it gets reread */
276 D1(printk(KERN_DEBUG "jffs2_commit_write(): Not all bytes written. Marking page !uptodate\n")); 277 D1(printk(KERN_DEBUG "jffs2_commit_write(): Not all bytes written. Marking page !uptodate\n"));
277 SetPageError(pg); 278 SetPageError(pg);
278 ClearPageUptodate(pg); 279 ClearPageUptodate(pg);
279 } 280 }
280 281
281 D1(printk(KERN_DEBUG "jffs2_commit_write() returning %d\n",writtenlen?writtenlen:ret)); 282 D1(printk(KERN_DEBUG "jffs2_commit_write() returning %d\n",start+writtenlen==end?0:ret));
282 return writtenlen?writtenlen:ret; 283 return start+writtenlen==end?0:ret;
283} 284}
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 5687c3f42002..543420665c5b 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: fs.c,v 1.56 2005/07/06 12:13:09 dwmw2 Exp $ 10 * $Id: fs.c,v 1.66 2005/09/27 13:17:29 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -40,7 +40,7 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
40 int ret; 40 int ret;
41 D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino)); 41 D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino));
42 ret = inode_change_ok(inode, iattr); 42 ret = inode_change_ok(inode, iattr);
43 if (ret) 43 if (ret)
44 return ret; 44 return ret;
45 45
46 /* Special cases - we don't want more than one data node 46 /* Special cases - we don't want more than one data node
@@ -73,8 +73,9 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
73 kfree(mdata); 73 kfree(mdata);
74 return -ENOMEM; 74 return -ENOMEM;
75 } 75 }
76 76
77 ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &phys_ofs, &alloclen, ALLOC_NORMAL); 77 ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &phys_ofs, &alloclen,
78 ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
78 if (ret) { 79 if (ret) {
79 jffs2_free_raw_inode(ri); 80 jffs2_free_raw_inode(ri);
80 if (S_ISLNK(inode->i_mode & S_IFMT)) 81 if (S_ISLNK(inode->i_mode & S_IFMT))
@@ -83,7 +84,7 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
83 } 84 }
84 down(&f->sem); 85 down(&f->sem);
85 ivalid = iattr->ia_valid; 86 ivalid = iattr->ia_valid;
86 87
87 ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); 88 ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
88 ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); 89 ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
89 ri->totlen = cpu_to_je32(sizeof(*ri) + mdatalen); 90 ri->totlen = cpu_to_je32(sizeof(*ri) + mdatalen);
@@ -99,7 +100,7 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
99 if (iattr->ia_mode & S_ISGID && 100 if (iattr->ia_mode & S_ISGID &&
100 !in_group_p(je16_to_cpu(ri->gid)) && !capable(CAP_FSETID)) 101 !in_group_p(je16_to_cpu(ri->gid)) && !capable(CAP_FSETID))
101 ri->mode = cpu_to_jemode(iattr->ia_mode & ~S_ISGID); 102 ri->mode = cpu_to_jemode(iattr->ia_mode & ~S_ISGID);
102 else 103 else
103 ri->mode = cpu_to_jemode(iattr->ia_mode); 104 ri->mode = cpu_to_jemode(iattr->ia_mode);
104 else 105 else
105 ri->mode = cpu_to_jemode(inode->i_mode); 106 ri->mode = cpu_to_jemode(inode->i_mode);
@@ -128,7 +129,7 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
128 new_metadata = jffs2_write_dnode(c, f, ri, mdata, mdatalen, phys_ofs, ALLOC_NORMAL); 129 new_metadata = jffs2_write_dnode(c, f, ri, mdata, mdatalen, phys_ofs, ALLOC_NORMAL);
129 if (S_ISLNK(inode->i_mode)) 130 if (S_ISLNK(inode->i_mode))
130 kfree(mdata); 131 kfree(mdata);
131 132
132 if (IS_ERR(new_metadata)) { 133 if (IS_ERR(new_metadata)) {
133 jffs2_complete_reservation(c); 134 jffs2_complete_reservation(c);
134 jffs2_free_raw_inode(ri); 135 jffs2_free_raw_inode(ri);
@@ -147,7 +148,7 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
147 old_metadata = f->metadata; 148 old_metadata = f->metadata;
148 149
149 if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size) 150 if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size)
150 jffs2_truncate_fraglist (c, &f->fragtree, iattr->ia_size); 151 jffs2_truncate_fragtree (c, &f->fragtree, iattr->ia_size);
151 152
152 if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) { 153 if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) {
153 jffs2_add_full_dnode_to_inode(c, f, new_metadata); 154 jffs2_add_full_dnode_to_inode(c, f, new_metadata);
@@ -166,7 +167,7 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
166 jffs2_complete_reservation(c); 167 jffs2_complete_reservation(c);
167 168
168 /* We have to do the vmtruncate() without f->sem held, since 169 /* We have to do the vmtruncate() without f->sem held, since
169 some pages may be locked and waiting for it in readpage(). 170 some pages may be locked and waiting for it in readpage().
170 We are protected from a simultaneous write() extending i_size 171 We are protected from a simultaneous write() extending i_size
171 back past iattr->ia_size, because do_truncate() holds the 172 back past iattr->ia_size, because do_truncate() holds the
172 generic inode semaphore. */ 173 generic inode semaphore. */
@@ -194,31 +195,27 @@ int jffs2_statfs(struct super_block *sb, struct kstatfs *buf)
194 buf->f_namelen = JFFS2_MAX_NAME_LEN; 195 buf->f_namelen = JFFS2_MAX_NAME_LEN;
195 196
196 spin_lock(&c->erase_completion_lock); 197 spin_lock(&c->erase_completion_lock);
197
198 avail = c->dirty_size + c->free_size; 198 avail = c->dirty_size + c->free_size;
199 if (avail > c->sector_size * c->resv_blocks_write) 199 if (avail > c->sector_size * c->resv_blocks_write)
200 avail -= c->sector_size * c->resv_blocks_write; 200 avail -= c->sector_size * c->resv_blocks_write;
201 else 201 else
202 avail = 0; 202 avail = 0;
203 spin_unlock(&c->erase_completion_lock);
203 204
204 buf->f_bavail = buf->f_bfree = avail >> PAGE_SHIFT; 205 buf->f_bavail = buf->f_bfree = avail >> PAGE_SHIFT;
205 206
206 D2(jffs2_dump_block_lists(c));
207
208 spin_unlock(&c->erase_completion_lock);
209
210 return 0; 207 return 0;
211} 208}
212 209
213 210
214void jffs2_clear_inode (struct inode *inode) 211void jffs2_clear_inode (struct inode *inode)
215{ 212{
216 /* We can forget about this inode for now - drop all 213 /* We can forget about this inode for now - drop all
217 * the nodelists associated with it, etc. 214 * the nodelists associated with it, etc.
218 */ 215 */
219 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); 216 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
220 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); 217 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
221 218
222 D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode)); 219 D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode));
223 220
224 jffs2_do_clear_inode(c, f); 221 jffs2_do_clear_inode(c, f);
@@ -237,7 +234,7 @@ void jffs2_read_inode (struct inode *inode)
237 c = JFFS2_SB_INFO(inode->i_sb); 234 c = JFFS2_SB_INFO(inode->i_sb);
238 235
239 jffs2_init_inode_info(f); 236 jffs2_init_inode_info(f);
240 237
241 ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node); 238 ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node);
242 239
243 if (ret) { 240 if (ret) {
@@ -257,14 +254,14 @@ void jffs2_read_inode (struct inode *inode)
257 254
258 inode->i_blksize = PAGE_SIZE; 255 inode->i_blksize = PAGE_SIZE;
259 inode->i_blocks = (inode->i_size + 511) >> 9; 256 inode->i_blocks = (inode->i_size + 511) >> 9;
260 257
261 switch (inode->i_mode & S_IFMT) { 258 switch (inode->i_mode & S_IFMT) {
262 jint16_t rdev; 259 jint16_t rdev;
263 260
264 case S_IFLNK: 261 case S_IFLNK:
265 inode->i_op = &jffs2_symlink_inode_operations; 262 inode->i_op = &jffs2_symlink_inode_operations;
266 break; 263 break;
267 264
268 case S_IFDIR: 265 case S_IFDIR:
269 { 266 {
270 struct jffs2_full_dirent *fd; 267 struct jffs2_full_dirent *fd;
@@ -301,7 +298,7 @@ void jffs2_read_inode (struct inode *inode)
301 jffs2_do_clear_inode(c, f); 298 jffs2_do_clear_inode(c, f);
302 make_bad_inode(inode); 299 make_bad_inode(inode);
303 return; 300 return;
304 } 301 }
305 302
306 case S_IFSOCK: 303 case S_IFSOCK:
307 case S_IFIFO: 304 case S_IFIFO:
@@ -357,11 +354,11 @@ int jffs2_remount_fs (struct super_block *sb, int *flags, char *data)
357 down(&c->alloc_sem); 354 down(&c->alloc_sem);
358 jffs2_flush_wbuf_pad(c); 355 jffs2_flush_wbuf_pad(c);
359 up(&c->alloc_sem); 356 up(&c->alloc_sem);
360 } 357 }
361 358
362 if (!(*flags & MS_RDONLY)) 359 if (!(*flags & MS_RDONLY))
363 jffs2_start_garbage_collect_thread(c); 360 jffs2_start_garbage_collect_thread(c);
364 361
365 *flags |= MS_NOATIME; 362 *flags |= MS_NOATIME;
366 363
367 return 0; 364 return 0;
@@ -395,9 +392,9 @@ struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_i
395 D1(printk(KERN_DEBUG "jffs2_new_inode(): dir_i %ld, mode 0x%x\n", dir_i->i_ino, mode)); 392 D1(printk(KERN_DEBUG "jffs2_new_inode(): dir_i %ld, mode 0x%x\n", dir_i->i_ino, mode));
396 393
397 c = JFFS2_SB_INFO(sb); 394 c = JFFS2_SB_INFO(sb);
398 395
399 inode = new_inode(sb); 396 inode = new_inode(sb);
400 397
401 if (!inode) 398 if (!inode)
402 return ERR_PTR(-ENOMEM); 399 return ERR_PTR(-ENOMEM);
403 400
@@ -461,40 +458,24 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
461#endif 458#endif
462 459
463 c->flash_size = c->mtd->size; 460 c->flash_size = c->mtd->size;
464 461 c->sector_size = c->mtd->erasesize;
465 /*
466 * Check, if we have to concatenate physical blocks to larger virtual blocks
467 * to reduce the memorysize for c->blocks. (kmalloc allows max. 128K allocation)
468 */
469 c->sector_size = c->mtd->erasesize;
470 blocks = c->flash_size / c->sector_size; 462 blocks = c->flash_size / c->sector_size;
471 if (!(c->mtd->flags & MTD_NO_VIRTBLOCKS)) {
472 while ((blocks * sizeof (struct jffs2_eraseblock)) > (128 * 1024)) {
473 blocks >>= 1;
474 c->sector_size <<= 1;
475 }
476 }
477 463
478 /* 464 /*
479 * Size alignment check 465 * Size alignment check
480 */ 466 */
481 if ((c->sector_size * blocks) != c->flash_size) { 467 if ((c->sector_size * blocks) != c->flash_size) {
482 c->flash_size = c->sector_size * blocks; 468 c->flash_size = c->sector_size * blocks;
483 printk(KERN_INFO "jffs2: Flash size not aligned to erasesize, reducing to %dKiB\n", 469 printk(KERN_INFO "jffs2: Flash size not aligned to erasesize, reducing to %dKiB\n",
484 c->flash_size / 1024); 470 c->flash_size / 1024);
485 } 471 }
486 472
487 if (c->sector_size != c->mtd->erasesize)
488 printk(KERN_INFO "jffs2: Erase block size too small (%dKiB). Using virtual blocks size (%dKiB) instead\n",
489 c->mtd->erasesize / 1024, c->sector_size / 1024);
490
491 if (c->flash_size < 5*c->sector_size) { 473 if (c->flash_size < 5*c->sector_size) {
492 printk(KERN_ERR "jffs2: Too few erase blocks (%d)\n", c->flash_size / c->sector_size); 474 printk(KERN_ERR "jffs2: Too few erase blocks (%d)\n", c->flash_size / c->sector_size);
493 return -EINVAL; 475 return -EINVAL;
494 } 476 }
495 477
496 c->cleanmarker_size = sizeof(struct jffs2_unknown_node); 478 c->cleanmarker_size = sizeof(struct jffs2_unknown_node);
497 /* Joern -- stick alignment for weird 8-byte-page flash here */
498 479
499 /* NAND (or other bizarre) flash... do setup accordingly */ 480 /* NAND (or other bizarre) flash... do setup accordingly */
500 ret = jffs2_flash_setup(c); 481 ret = jffs2_flash_setup(c);
@@ -517,7 +498,7 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
517 root_i = iget(sb, 1); 498 root_i = iget(sb, 1);
518 if (is_bad_inode(root_i)) { 499 if (is_bad_inode(root_i)) {
519 D1(printk(KERN_WARNING "get root inode failed\n")); 500 D1(printk(KERN_WARNING "get root inode failed\n"));
520 goto out_nodes; 501 goto out_root_i;
521 } 502 }
522 503
523 D1(printk(KERN_DEBUG "jffs2_do_fill_super(): d_alloc_root()\n")); 504 D1(printk(KERN_DEBUG "jffs2_do_fill_super(): d_alloc_root()\n"));
@@ -535,10 +516,9 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
535 516
536 out_root_i: 517 out_root_i:
537 iput(root_i); 518 iput(root_i);
538 out_nodes:
539 jffs2_free_ino_caches(c); 519 jffs2_free_ino_caches(c);
540 jffs2_free_raw_node_refs(c); 520 jffs2_free_raw_node_refs(c);
541 if (c->mtd->flags & MTD_NO_VIRTBLOCKS) 521 if (jffs2_blocks_use_vmalloc(c))
542 vfree(c->blocks); 522 vfree(c->blocks);
543 else 523 else
544 kfree(c->blocks); 524 kfree(c->blocks);
@@ -563,16 +543,16 @@ struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
563 struct jffs2_inode_cache *ic; 543 struct jffs2_inode_cache *ic;
564 if (!nlink) { 544 if (!nlink) {
565 /* The inode has zero nlink but its nodes weren't yet marked 545 /* The inode has zero nlink but its nodes weren't yet marked
566 obsolete. This has to be because we're still waiting for 546 obsolete. This has to be because we're still waiting for
567 the final (close() and) iput() to happen. 547 the final (close() and) iput() to happen.
568 548
569 There's a possibility that the final iput() could have 549 There's a possibility that the final iput() could have
570 happened while we were contemplating. In order to ensure 550 happened while we were contemplating. In order to ensure
571 that we don't cause a new read_inode() (which would fail) 551 that we don't cause a new read_inode() (which would fail)
572 for the inode in question, we use ilookup() in this case 552 for the inode in question, we use ilookup() in this case
573 instead of iget(). 553 instead of iget().
574 554
575 The nlink can't _become_ zero at this point because we're 555 The nlink can't _become_ zero at this point because we're
576 holding the alloc_sem, and jffs2_do_unlink() would also 556 holding the alloc_sem, and jffs2_do_unlink() would also
577 need that while decrementing nlink on any inode. 557 need that while decrementing nlink on any inode.
578 */ 558 */
@@ -619,19 +599,19 @@ struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
619 return JFFS2_INODE_INFO(inode); 599 return JFFS2_INODE_INFO(inode);
620} 600}
621 601
622unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c, 602unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c,
623 struct jffs2_inode_info *f, 603 struct jffs2_inode_info *f,
624 unsigned long offset, 604 unsigned long offset,
625 unsigned long *priv) 605 unsigned long *priv)
626{ 606{
627 struct inode *inode = OFNI_EDONI_2SFFJ(f); 607 struct inode *inode = OFNI_EDONI_2SFFJ(f);
628 struct page *pg; 608 struct page *pg;
629 609
630 pg = read_cache_page(inode->i_mapping, offset >> PAGE_CACHE_SHIFT, 610 pg = read_cache_page(inode->i_mapping, offset >> PAGE_CACHE_SHIFT,
631 (void *)jffs2_do_readpage_unlock, inode); 611 (void *)jffs2_do_readpage_unlock, inode);
632 if (IS_ERR(pg)) 612 if (IS_ERR(pg))
633 return (void *)pg; 613 return (void *)pg;
634 614
635 *priv = (unsigned long)pg; 615 *priv = (unsigned long)pg;
636 return kmap(pg); 616 return kmap(pg);
637} 617}
@@ -648,7 +628,7 @@ void jffs2_gc_release_page(struct jffs2_sb_info *c,
648 628
649static int jffs2_flash_setup(struct jffs2_sb_info *c) { 629static int jffs2_flash_setup(struct jffs2_sb_info *c) {
650 int ret = 0; 630 int ret = 0;
651 631
652 if (jffs2_cleanmarker_oob(c)) { 632 if (jffs2_cleanmarker_oob(c)) {
653 /* NAND flash... do setup accordingly */ 633 /* NAND flash... do setup accordingly */
654 ret = jffs2_nand_flash_setup(c); 634 ret = jffs2_nand_flash_setup(c);
@@ -662,14 +642,21 @@ static int jffs2_flash_setup(struct jffs2_sb_info *c) {
662 if (ret) 642 if (ret)
663 return ret; 643 return ret;
664 } 644 }
665 645
666 /* and Dataflash */ 646 /* and Dataflash */
667 if (jffs2_dataflash(c)) { 647 if (jffs2_dataflash(c)) {
668 ret = jffs2_dataflash_setup(c); 648 ret = jffs2_dataflash_setup(c);
669 if (ret) 649 if (ret)
670 return ret; 650 return ret;
671 } 651 }
672 652
653 /* and Intel "Sibley" flash */
654 if (jffs2_nor_wbuf_flash(c)) {
655 ret = jffs2_nor_wbuf_flash_setup(c);
656 if (ret)
657 return ret;
658 }
659
673 return ret; 660 return ret;
674} 661}
675 662
@@ -683,9 +670,14 @@ void jffs2_flash_cleanup(struct jffs2_sb_info *c) {
683 if (jffs2_nor_ecc(c)) { 670 if (jffs2_nor_ecc(c)) {
684 jffs2_nor_ecc_flash_cleanup(c); 671 jffs2_nor_ecc_flash_cleanup(c);
685 } 672 }
686 673
687 /* and DataFlash */ 674 /* and DataFlash */
688 if (jffs2_dataflash(c)) { 675 if (jffs2_dataflash(c)) {
689 jffs2_dataflash_cleanup(c); 676 jffs2_dataflash_cleanup(c);
690 } 677 }
678
679 /* and Intel "Sibley" flash */
680 if (jffs2_nor_wbuf_flash(c)) {
681 jffs2_nor_wbuf_flash_cleanup(c);
682 }
691} 683}
diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c
index 7086cd634503..f9ffece453a3 100644
--- a/fs/jffs2/gc.c
+++ b/fs/jffs2/gc.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: gc.c,v 1.148 2005/04/09 10:47:00 dedekind Exp $ 10 * $Id: gc.c,v 1.155 2005/11/07 11:14:39 gleixner Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -21,14 +21,14 @@
21#include "nodelist.h" 21#include "nodelist.h"
22#include "compr.h" 22#include "compr.h"
23 23
24static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, 24static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
25 struct jffs2_inode_cache *ic, 25 struct jffs2_inode_cache *ic,
26 struct jffs2_raw_node_ref *raw); 26 struct jffs2_raw_node_ref *raw);
27static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 27static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
28 struct jffs2_inode_info *f, struct jffs2_full_dnode *fd); 28 struct jffs2_inode_info *f, struct jffs2_full_dnode *fd);
29static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 29static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
30 struct jffs2_inode_info *f, struct jffs2_full_dirent *fd); 30 struct jffs2_inode_info *f, struct jffs2_full_dirent *fd);
31static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 31static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
32 struct jffs2_inode_info *f, struct jffs2_full_dirent *fd); 32 struct jffs2_inode_info *f, struct jffs2_full_dirent *fd);
33static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 33static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
34 struct jffs2_inode_info *f, struct jffs2_full_dnode *fn, 34 struct jffs2_inode_info *f, struct jffs2_full_dnode *fn,
@@ -55,7 +55,7 @@ again:
55 D1(printk(KERN_DEBUG "Picking block from bad_used_list to GC next\n")); 55 D1(printk(KERN_DEBUG "Picking block from bad_used_list to GC next\n"));
56 nextlist = &c->bad_used_list; 56 nextlist = &c->bad_used_list;
57 } else if (n < 50 && !list_empty(&c->erasable_list)) { 57 } else if (n < 50 && !list_empty(&c->erasable_list)) {
58 /* Note that most of them will have gone directly to be erased. 58 /* Note that most of them will have gone directly to be erased.
59 So don't favour the erasable_list _too_ much. */ 59 So don't favour the erasable_list _too_ much. */
60 D1(printk(KERN_DEBUG "Picking block from erasable_list to GC next\n")); 60 D1(printk(KERN_DEBUG "Picking block from erasable_list to GC next\n"));
61 nextlist = &c->erasable_list; 61 nextlist = &c->erasable_list;
@@ -101,7 +101,7 @@ again:
101 printk(KERN_WARNING "Eep. ret->gc_node for block at 0x%08x is NULL\n", ret->offset); 101 printk(KERN_WARNING "Eep. ret->gc_node for block at 0x%08x is NULL\n", ret->offset);
102 BUG(); 102 BUG();
103 } 103 }
104 104
105 /* Have we accidentally picked a clean block with wasted space ? */ 105 /* Have we accidentally picked a clean block with wasted space ? */
106 if (ret->wasted_size) { 106 if (ret->wasted_size) {
107 D1(printk(KERN_DEBUG "Converting wasted_size %08x to dirty_size\n", ret->wasted_size)); 107 D1(printk(KERN_DEBUG "Converting wasted_size %08x to dirty_size\n", ret->wasted_size));
@@ -111,7 +111,6 @@ again:
111 ret->wasted_size = 0; 111 ret->wasted_size = 0;
112 } 112 }
113 113
114 D2(jffs2_dump_block_lists(c));
115 return ret; 114 return ret;
116} 115}
117 116
@@ -137,12 +136,12 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
137 136
138 /* We can't start doing GC yet. We haven't finished checking 137 /* We can't start doing GC yet. We haven't finished checking
139 the node CRCs etc. Do it now. */ 138 the node CRCs etc. Do it now. */
140 139
141 /* checked_ino is protected by the alloc_sem */ 140 /* checked_ino is protected by the alloc_sem */
142 if (c->checked_ino > c->highest_ino) { 141 if (c->checked_ino > c->highest_ino) {
143 printk(KERN_CRIT "Checked all inodes but still 0x%x bytes of unchecked space?\n", 142 printk(KERN_CRIT "Checked all inodes but still 0x%x bytes of unchecked space?\n",
144 c->unchecked_size); 143 c->unchecked_size);
145 D2(jffs2_dump_block_lists(c)); 144 jffs2_dbg_dump_block_lists_nolock(c);
146 spin_unlock(&c->erase_completion_lock); 145 spin_unlock(&c->erase_completion_lock);
147 BUG(); 146 BUG();
148 } 147 }
@@ -179,7 +178,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
179 178
180 case INO_STATE_READING: 179 case INO_STATE_READING:
181 /* We need to wait for it to finish, lest we move on 180 /* We need to wait for it to finish, lest we move on
182 and trigger the BUG() above while we haven't yet 181 and trigger the BUG() above while we haven't yet
183 finished checking all its nodes */ 182 finished checking all its nodes */
184 D1(printk(KERN_DEBUG "Waiting for ino #%u to finish reading\n", ic->ino)); 183 D1(printk(KERN_DEBUG "Waiting for ino #%u to finish reading\n", ic->ino));
185 up(&c->alloc_sem); 184 up(&c->alloc_sem);
@@ -229,13 +228,13 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
229 } 228 }
230 229
231 raw = jeb->gc_node; 230 raw = jeb->gc_node;
232 231
233 while(ref_obsolete(raw)) { 232 while(ref_obsolete(raw)) {
234 D1(printk(KERN_DEBUG "Node at 0x%08x is obsolete... skipping\n", ref_offset(raw))); 233 D1(printk(KERN_DEBUG "Node at 0x%08x is obsolete... skipping\n", ref_offset(raw)));
235 raw = raw->next_phys; 234 raw = raw->next_phys;
236 if (unlikely(!raw)) { 235 if (unlikely(!raw)) {
237 printk(KERN_WARNING "eep. End of raw list while still supposedly nodes to GC\n"); 236 printk(KERN_WARNING "eep. End of raw list while still supposedly nodes to GC\n");
238 printk(KERN_WARNING "erase block at 0x%08x. free_size 0x%08x, dirty_size 0x%08x, used_size 0x%08x\n", 237 printk(KERN_WARNING "erase block at 0x%08x. free_size 0x%08x, dirty_size 0x%08x, used_size 0x%08x\n",
239 jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size); 238 jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size);
240 jeb->gc_node = raw; 239 jeb->gc_node = raw;
241 spin_unlock(&c->erase_completion_lock); 240 spin_unlock(&c->erase_completion_lock);
@@ -260,7 +259,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
260 ic = jffs2_raw_ref_to_ic(raw); 259 ic = jffs2_raw_ref_to_ic(raw);
261 260
262 /* We need to hold the inocache. Either the erase_completion_lock or 261 /* We need to hold the inocache. Either the erase_completion_lock or
263 the inocache_lock are sufficient; we trade down since the inocache_lock 262 the inocache_lock are sufficient; we trade down since the inocache_lock
264 causes less contention. */ 263 causes less contention. */
265 spin_lock(&c->inocache_lock); 264 spin_lock(&c->inocache_lock);
266 265
@@ -279,14 +278,14 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
279 278
280 switch(ic->state) { 279 switch(ic->state) {
281 case INO_STATE_CHECKEDABSENT: 280 case INO_STATE_CHECKEDABSENT:
282 /* It's been checked, but it's not currently in-core. 281 /* It's been checked, but it's not currently in-core.
283 We can just copy any pristine nodes, but have 282 We can just copy any pristine nodes, but have
284 to prevent anyone else from doing read_inode() while 283 to prevent anyone else from doing read_inode() while
285 we're at it, so we set the state accordingly */ 284 we're at it, so we set the state accordingly */
286 if (ref_flags(raw) == REF_PRISTINE) 285 if (ref_flags(raw) == REF_PRISTINE)
287 ic->state = INO_STATE_GC; 286 ic->state = INO_STATE_GC;
288 else { 287 else {
289 D1(printk(KERN_DEBUG "Ino #%u is absent but node not REF_PRISTINE. Reading.\n", 288 D1(printk(KERN_DEBUG "Ino #%u is absent but node not REF_PRISTINE. Reading.\n",
290 ic->ino)); 289 ic->ino));
291 } 290 }
292 break; 291 break;
@@ -299,8 +298,8 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
299 case INO_STATE_CHECKING: 298 case INO_STATE_CHECKING:
300 case INO_STATE_GC: 299 case INO_STATE_GC:
301 /* Should never happen. We should have finished checking 300 /* Should never happen. We should have finished checking
302 by the time we actually start doing any GC, and since 301 by the time we actually start doing any GC, and since
303 we're holding the alloc_sem, no other garbage collection 302 we're holding the alloc_sem, no other garbage collection
304 can happen. 303 can happen.
305 */ 304 */
306 printk(KERN_CRIT "Inode #%u already in state %d in jffs2_garbage_collect_pass()!\n", 305 printk(KERN_CRIT "Inode #%u already in state %d in jffs2_garbage_collect_pass()!\n",
@@ -320,21 +319,21 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
320 D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass() waiting for ino #%u in state %d\n", 319 D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass() waiting for ino #%u in state %d\n",
321 ic->ino, ic->state)); 320 ic->ino, ic->state));
322 sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock); 321 sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
323 /* And because we dropped the alloc_sem we must start again from the 322 /* And because we dropped the alloc_sem we must start again from the
324 beginning. Ponder chance of livelock here -- we're returning success 323 beginning. Ponder chance of livelock here -- we're returning success
325 without actually making any progress. 324 without actually making any progress.
326 325
327 Q: What are the chances that the inode is back in INO_STATE_READING 326 Q: What are the chances that the inode is back in INO_STATE_READING
328 again by the time we next enter this function? And that this happens 327 again by the time we next enter this function? And that this happens
329 enough times to cause a real delay? 328 enough times to cause a real delay?
330 329
331 A: Small enough that I don't care :) 330 A: Small enough that I don't care :)
332 */ 331 */
333 return 0; 332 return 0;
334 } 333 }
335 334
336 /* OK. Now if the inode is in state INO_STATE_GC, we are going to copy the 335 /* OK. Now if the inode is in state INO_STATE_GC, we are going to copy the
337 node intact, and we don't have to muck about with the fragtree etc. 336 node intact, and we don't have to muck about with the fragtree etc.
338 because we know it's not in-core. If it _was_ in-core, we go through 337 because we know it's not in-core. If it _was_ in-core, we go through
339 all the iget() crap anyway */ 338 all the iget() crap anyway */
340 339
@@ -454,7 +453,7 @@ static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_era
454 if (!ret) { 453 if (!ret) {
455 /* Urgh. Return it sensibly. */ 454 /* Urgh. Return it sensibly. */
456 frag->node->raw = f->inocache->nodes; 455 frag->node->raw = f->inocache->nodes;
457 } 456 }
458 if (ret != -EBADFD) 457 if (ret != -EBADFD)
459 goto upnout; 458 goto upnout;
460 } 459 }
@@ -468,7 +467,7 @@ static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_era
468 } 467 }
469 goto upnout; 468 goto upnout;
470 } 469 }
471 470
472 /* Wasn't a dnode. Try dirent */ 471 /* Wasn't a dnode. Try dirent */
473 for (fd = f->dents; fd; fd=fd->next) { 472 for (fd = f->dents; fd; fd=fd->next) {
474 if (fd->raw == raw) 473 if (fd->raw == raw)
@@ -485,7 +484,8 @@ static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_era
485 if (ref_obsolete(raw)) { 484 if (ref_obsolete(raw)) {
486 printk(KERN_WARNING "But it's obsolete so we don't mind too much\n"); 485 printk(KERN_WARNING "But it's obsolete so we don't mind too much\n");
487 } else { 486 } else {
488 ret = -EIO; 487 jffs2_dbg_dump_node(c, ref_offset(raw));
488 BUG();
489 } 489 }
490 } 490 }
491 upnout: 491 upnout:
@@ -494,7 +494,7 @@ static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_era
494 return ret; 494 return ret;
495} 495}
496 496
497static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, 497static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
498 struct jffs2_inode_cache *ic, 498 struct jffs2_inode_cache *ic,
499 struct jffs2_raw_node_ref *raw) 499 struct jffs2_raw_node_ref *raw)
500{ 500{
@@ -513,8 +513,11 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
513 /* Ask for a small amount of space (or the totlen if smaller) because we 513 /* Ask for a small amount of space (or the totlen if smaller) because we
514 don't want to force wastage of the end of a block if splitting would 514 don't want to force wastage of the end of a block if splitting would
515 work. */ 515 work. */
516 ret = jffs2_reserve_space_gc(c, min_t(uint32_t, sizeof(struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN, 516 ret = jffs2_reserve_space_gc(c, min_t(uint32_t, sizeof(struct jffs2_raw_inode) +
517 rawlen), &phys_ofs, &alloclen); 517 JFFS2_MIN_DATA_LEN, rawlen), &phys_ofs, &alloclen, rawlen);
518 /* this is not the exact summary size of it,
519 it is only an upper estimation */
520
518 if (ret) 521 if (ret)
519 return ret; 522 return ret;
520 523
@@ -577,7 +580,7 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
577 } 580 }
578 break; 581 break;
579 default: 582 default:
580 printk(KERN_WARNING "Unknown node type for REF_PRISTINE node at 0x%08x: 0x%04x\n", 583 printk(KERN_WARNING "Unknown node type for REF_PRISTINE node at 0x%08x: 0x%04x\n",
581 ref_offset(raw), je16_to_cpu(node->u.nodetype)); 584 ref_offset(raw), je16_to_cpu(node->u.nodetype));
582 goto bail; 585 goto bail;
583 } 586 }
@@ -618,17 +621,19 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
618 retried = 1; 621 retried = 1;
619 622
620 D1(printk(KERN_DEBUG "Retrying failed write of REF_PRISTINE node.\n")); 623 D1(printk(KERN_DEBUG "Retrying failed write of REF_PRISTINE node.\n"));
621
622 ACCT_SANITY_CHECK(c,jeb);
623 D1(ACCT_PARANOIA_CHECK(jeb));
624 624
625 ret = jffs2_reserve_space_gc(c, rawlen, &phys_ofs, &dummy); 625 jffs2_dbg_acct_sanity_check(c,jeb);
626 jffs2_dbg_acct_paranoia_check(c, jeb);
627
628 ret = jffs2_reserve_space_gc(c, rawlen, &phys_ofs, &dummy, rawlen);
629 /* this is not the exact summary size of it,
630 it is only an upper estimation */
626 631
627 if (!ret) { 632 if (!ret) {
628 D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", phys_ofs)); 633 D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", phys_ofs));
629 634
630 ACCT_SANITY_CHECK(c,jeb); 635 jffs2_dbg_acct_sanity_check(c,jeb);
631 D1(ACCT_PARANOIA_CHECK(jeb)); 636 jffs2_dbg_acct_paranoia_check(c, jeb);
632 637
633 goto retry; 638 goto retry;
634 } 639 }
@@ -664,7 +669,7 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
664 goto out_node; 669 goto out_node;
665} 670}
666 671
667static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 672static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
668 struct jffs2_inode_info *f, struct jffs2_full_dnode *fn) 673 struct jffs2_inode_info *f, struct jffs2_full_dnode *fn)
669{ 674{
670 struct jffs2_full_dnode *new_fn; 675 struct jffs2_full_dnode *new_fn;
@@ -679,7 +684,7 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
679 S_ISCHR(JFFS2_F_I_MODE(f)) ) { 684 S_ISCHR(JFFS2_F_I_MODE(f)) ) {
680 /* For these, we don't actually need to read the old node */ 685 /* For these, we don't actually need to read the old node */
681 /* FIXME: for minor or major > 255. */ 686 /* FIXME: for minor or major > 255. */
682 dev = cpu_to_je16(((JFFS2_F_I_RDEV_MAJ(f) << 8) | 687 dev = cpu_to_je16(((JFFS2_F_I_RDEV_MAJ(f) << 8) |
683 JFFS2_F_I_RDEV_MIN(f))); 688 JFFS2_F_I_RDEV_MIN(f)));
684 mdata = (char *)&dev; 689 mdata = (char *)&dev;
685 mdatalen = sizeof(dev); 690 mdatalen = sizeof(dev);
@@ -700,14 +705,15 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
700 D1(printk(KERN_DEBUG "jffs2_garbage_collect_metadata(): Writing %d bites of symlink target\n", mdatalen)); 705 D1(printk(KERN_DEBUG "jffs2_garbage_collect_metadata(): Writing %d bites of symlink target\n", mdatalen));
701 706
702 } 707 }
703 708
704 ret = jffs2_reserve_space_gc(c, sizeof(ri) + mdatalen, &phys_ofs, &alloclen); 709 ret = jffs2_reserve_space_gc(c, sizeof(ri) + mdatalen, &phys_ofs, &alloclen,
710 JFFS2_SUMMARY_INODE_SIZE);
705 if (ret) { 711 if (ret) {
706 printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_metadata failed: %d\n", 712 printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_metadata failed: %d\n",
707 sizeof(ri)+ mdatalen, ret); 713 sizeof(ri)+ mdatalen, ret);
708 goto out; 714 goto out;
709 } 715 }
710 716
711 last_frag = frag_last(&f->fragtree); 717 last_frag = frag_last(&f->fragtree);
712 if (last_frag) 718 if (last_frag)
713 /* Fetch the inode length from the fragtree rather then 719 /* Fetch the inode length from the fragtree rather then
@@ -715,7 +721,7 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
715 ilen = last_frag->ofs + last_frag->size; 721 ilen = last_frag->ofs + last_frag->size;
716 else 722 else
717 ilen = JFFS2_F_I_SIZE(f); 723 ilen = JFFS2_F_I_SIZE(f);
718 724
719 memset(&ri, 0, sizeof(ri)); 725 memset(&ri, 0, sizeof(ri));
720 ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); 726 ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
721 ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); 727 ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
@@ -754,7 +760,7 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
754 return ret; 760 return ret;
755} 761}
756 762
757static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 763static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
758 struct jffs2_inode_info *f, struct jffs2_full_dirent *fd) 764 struct jffs2_inode_info *f, struct jffs2_full_dirent *fd)
759{ 765{
760 struct jffs2_full_dirent *new_fd; 766 struct jffs2_full_dirent *new_fd;
@@ -771,12 +777,18 @@ static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_er
771 rd.pino = cpu_to_je32(f->inocache->ino); 777 rd.pino = cpu_to_je32(f->inocache->ino);
772 rd.version = cpu_to_je32(++f->highest_version); 778 rd.version = cpu_to_je32(++f->highest_version);
773 rd.ino = cpu_to_je32(fd->ino); 779 rd.ino = cpu_to_je32(fd->ino);
774 rd.mctime = cpu_to_je32(max(JFFS2_F_I_MTIME(f), JFFS2_F_I_CTIME(f))); 780 /* If the times on this inode were set by explicit utime() they can be different,
781 so refrain from splatting them. */
782 if (JFFS2_F_I_MTIME(f) == JFFS2_F_I_CTIME(f))
783 rd.mctime = cpu_to_je32(JFFS2_F_I_MTIME(f));
784 else
785 rd.mctime = cpu_to_je32(0);
775 rd.type = fd->type; 786 rd.type = fd->type;
776 rd.node_crc = cpu_to_je32(crc32(0, &rd, sizeof(rd)-8)); 787 rd.node_crc = cpu_to_je32(crc32(0, &rd, sizeof(rd)-8));
777 rd.name_crc = cpu_to_je32(crc32(0, fd->name, rd.nsize)); 788 rd.name_crc = cpu_to_je32(crc32(0, fd->name, rd.nsize));
778 789
779 ret = jffs2_reserve_space_gc(c, sizeof(rd)+rd.nsize, &phys_ofs, &alloclen); 790 ret = jffs2_reserve_space_gc(c, sizeof(rd)+rd.nsize, &phys_ofs, &alloclen,
791 JFFS2_SUMMARY_DIRENT_SIZE(rd.nsize));
780 if (ret) { 792 if (ret) {
781 printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_dirent failed: %d\n", 793 printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_dirent failed: %d\n",
782 sizeof(rd)+rd.nsize, ret); 794 sizeof(rd)+rd.nsize, ret);
@@ -792,7 +804,7 @@ static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_er
792 return 0; 804 return 0;
793} 805}
794 806
795static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 807static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
796 struct jffs2_inode_info *f, struct jffs2_full_dirent *fd) 808 struct jffs2_inode_info *f, struct jffs2_full_dirent *fd)
797{ 809{
798 struct jffs2_full_dirent **fdp = &f->dents; 810 struct jffs2_full_dirent **fdp = &f->dents;
@@ -831,7 +843,7 @@ static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct
831 if (ref_totlen(c, NULL, raw) != rawlen) 843 if (ref_totlen(c, NULL, raw) != rawlen)
832 continue; 844 continue;
833 845
834 /* Doesn't matter if there's one in the same erase block. We're going to 846 /* Doesn't matter if there's one in the same erase block. We're going to
835 delete it too at the same time. */ 847 delete it too at the same time. */
836 if (SECTOR_ADDR(raw->flash_offset) == SECTOR_ADDR(fd->raw->flash_offset)) 848 if (SECTOR_ADDR(raw->flash_offset) == SECTOR_ADDR(fd->raw->flash_offset))
837 continue; 849 continue;
@@ -883,6 +895,9 @@ static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct
883 kfree(rd); 895 kfree(rd);
884 } 896 }
885 897
898 /* FIXME: If we're deleting a dirent which contains the current mtime and ctime,
899 we should update the metadata node with those times accordingly */
900
886 /* No need for it any more. Just mark it obsolete and remove it from the list */ 901 /* No need for it any more. Just mark it obsolete and remove it from the list */
887 while (*fdp) { 902 while (*fdp) {
888 if ((*fdp) == fd) { 903 if ((*fdp) == fd) {
@@ -912,13 +927,13 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
912 927
913 D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%u from offset 0x%x to 0x%x\n", 928 D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%u from offset 0x%x to 0x%x\n",
914 f->inocache->ino, start, end)); 929 f->inocache->ino, start, end));
915 930
916 memset(&ri, 0, sizeof(ri)); 931 memset(&ri, 0, sizeof(ri));
917 932
918 if(fn->frags > 1) { 933 if(fn->frags > 1) {
919 size_t readlen; 934 size_t readlen;
920 uint32_t crc; 935 uint32_t crc;
921 /* It's partially obsoleted by a later write. So we have to 936 /* It's partially obsoleted by a later write. So we have to
922 write it out again with the _same_ version as before */ 937 write it out again with the _same_ version as before */
923 ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(ri), &readlen, (char *)&ri); 938 ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(ri), &readlen, (char *)&ri);
924 if (readlen != sizeof(ri) || ret) { 939 if (readlen != sizeof(ri) || ret) {
@@ -940,16 +955,16 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
940 crc = crc32(0, &ri, sizeof(ri)-8); 955 crc = crc32(0, &ri, sizeof(ri)-8);
941 if (crc != je32_to_cpu(ri.node_crc)) { 956 if (crc != je32_to_cpu(ri.node_crc)) {
942 printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had CRC 0x%08x which doesn't match calculated CRC 0x%08x\n", 957 printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had CRC 0x%08x which doesn't match calculated CRC 0x%08x\n",
943 ref_offset(fn->raw), 958 ref_offset(fn->raw),
944 je32_to_cpu(ri.node_crc), crc); 959 je32_to_cpu(ri.node_crc), crc);
945 /* FIXME: We could possibly deal with this by writing new holes for each frag */ 960 /* FIXME: We could possibly deal with this by writing new holes for each frag */
946 printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n", 961 printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n",
947 start, end, f->inocache->ino); 962 start, end, f->inocache->ino);
948 goto fill; 963 goto fill;
949 } 964 }
950 if (ri.compr != JFFS2_COMPR_ZERO) { 965 if (ri.compr != JFFS2_COMPR_ZERO) {
951 printk(KERN_WARNING "jffs2_garbage_collect_hole: Node 0x%08x wasn't a hole node!\n", ref_offset(fn->raw)); 966 printk(KERN_WARNING "jffs2_garbage_collect_hole: Node 0x%08x wasn't a hole node!\n", ref_offset(fn->raw));
952 printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n", 967 printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n",
953 start, end, f->inocache->ino); 968 start, end, f->inocache->ino);
954 goto fill; 969 goto fill;
955 } 970 }
@@ -967,7 +982,7 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
967 ri.csize = cpu_to_je32(0); 982 ri.csize = cpu_to_je32(0);
968 ri.compr = JFFS2_COMPR_ZERO; 983 ri.compr = JFFS2_COMPR_ZERO;
969 } 984 }
970 985
971 frag = frag_last(&f->fragtree); 986 frag = frag_last(&f->fragtree);
972 if (frag) 987 if (frag)
973 /* Fetch the inode length from the fragtree rather then 988 /* Fetch the inode length from the fragtree rather then
@@ -986,7 +1001,8 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
986 ri.data_crc = cpu_to_je32(0); 1001 ri.data_crc = cpu_to_je32(0);
987 ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8)); 1002 ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
988 1003
989 ret = jffs2_reserve_space_gc(c, sizeof(ri), &phys_ofs, &alloclen); 1004 ret = jffs2_reserve_space_gc(c, sizeof(ri), &phys_ofs, &alloclen,
1005 JFFS2_SUMMARY_INODE_SIZE);
990 if (ret) { 1006 if (ret) {
991 printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_hole failed: %d\n", 1007 printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_hole failed: %d\n",
992 sizeof(ri), ret); 1008 sizeof(ri), ret);
@@ -1008,10 +1024,10 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
1008 return 0; 1024 return 0;
1009 } 1025 }
1010 1026
1011 /* 1027 /*
1012 * We should only get here in the case where the node we are 1028 * We should only get here in the case where the node we are
1013 * replacing had more than one frag, so we kept the same version 1029 * replacing had more than one frag, so we kept the same version
1014 * number as before. (Except in case of error -- see 'goto fill;' 1030 * number as before. (Except in case of error -- see 'goto fill;'
1015 * above.) 1031 * above.)
1016 */ 1032 */
1017 D1(if(unlikely(fn->frags <= 1)) { 1033 D1(if(unlikely(fn->frags <= 1)) {
@@ -1023,7 +1039,7 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
1023 /* This is a partially-overlapped hole node. Mark it REF_NORMAL not REF_PRISTINE */ 1039 /* This is a partially-overlapped hole node. Mark it REF_NORMAL not REF_PRISTINE */
1024 mark_ref_normal(new_fn->raw); 1040 mark_ref_normal(new_fn->raw);
1025 1041
1026 for (frag = jffs2_lookup_node_frag(&f->fragtree, fn->ofs); 1042 for (frag = jffs2_lookup_node_frag(&f->fragtree, fn->ofs);
1027 frag; frag = frag_next(frag)) { 1043 frag; frag = frag_next(frag)) {
1028 if (frag->ofs > fn->size + fn->ofs) 1044 if (frag->ofs > fn->size + fn->ofs)
1029 break; 1045 break;
@@ -1041,10 +1057,10 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
1041 printk(KERN_WARNING "jffs2_garbage_collect_hole: New node has no frags!\n"); 1057 printk(KERN_WARNING "jffs2_garbage_collect_hole: New node has no frags!\n");
1042 BUG(); 1058 BUG();
1043 } 1059 }
1044 1060
1045 jffs2_mark_node_obsolete(c, fn->raw); 1061 jffs2_mark_node_obsolete(c, fn->raw);
1046 jffs2_free_full_dnode(fn); 1062 jffs2_free_full_dnode(fn);
1047 1063
1048 return 0; 1064 return 0;
1049} 1065}
1050 1066
@@ -1054,12 +1070,12 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
1054{ 1070{
1055 struct jffs2_full_dnode *new_fn; 1071 struct jffs2_full_dnode *new_fn;
1056 struct jffs2_raw_inode ri; 1072 struct jffs2_raw_inode ri;
1057 uint32_t alloclen, phys_ofs, offset, orig_end, orig_start; 1073 uint32_t alloclen, phys_ofs, offset, orig_end, orig_start;
1058 int ret = 0; 1074 int ret = 0;
1059 unsigned char *comprbuf = NULL, *writebuf; 1075 unsigned char *comprbuf = NULL, *writebuf;
1060 unsigned long pg; 1076 unsigned long pg;
1061 unsigned char *pg_ptr; 1077 unsigned char *pg_ptr;
1062 1078
1063 memset(&ri, 0, sizeof(ri)); 1079 memset(&ri, 0, sizeof(ri));
1064 1080
1065 D1(printk(KERN_DEBUG "Writing replacement dnode for ino #%u from offset 0x%x to 0x%x\n", 1081 D1(printk(KERN_DEBUG "Writing replacement dnode for ino #%u from offset 0x%x to 0x%x\n",
@@ -1071,8 +1087,8 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
1071 if (c->nr_free_blocks + c->nr_erasing_blocks > c->resv_blocks_gcmerge) { 1087 if (c->nr_free_blocks + c->nr_erasing_blocks > c->resv_blocks_gcmerge) {
1072 /* Attempt to do some merging. But only expand to cover logically 1088 /* Attempt to do some merging. But only expand to cover logically
1073 adjacent frags if the block containing them is already considered 1089 adjacent frags if the block containing them is already considered
1074 to be dirty. Otherwise we end up with GC just going round in 1090 to be dirty. Otherwise we end up with GC just going round in
1075 circles dirtying the nodes it already wrote out, especially 1091 circles dirtying the nodes it already wrote out, especially
1076 on NAND where we have small eraseblocks and hence a much higher 1092 on NAND where we have small eraseblocks and hence a much higher
1077 chance of nodes having to be split to cross boundaries. */ 1093 chance of nodes having to be split to cross boundaries. */
1078 1094
@@ -1106,7 +1122,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
1106 break; 1122 break;
1107 } else { 1123 } else {
1108 1124
1109 /* OK, it's a frag which extends to the beginning of the page. Does it live 1125 /* OK, it's a frag which extends to the beginning of the page. Does it live
1110 in a block which is still considered clean? If so, don't obsolete it. 1126 in a block which is still considered clean? If so, don't obsolete it.
1111 If not, cover it anyway. */ 1127 If not, cover it anyway. */
1112 1128
@@ -1156,7 +1172,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
1156 break; 1172 break;
1157 } else { 1173 } else {
1158 1174
1159 /* OK, it's a frag which extends to the beginning of the page. Does it live 1175 /* OK, it's a frag which extends to the beginning of the page. Does it live
1160 in a block which is still considered clean? If so, don't obsolete it. 1176 in a block which is still considered clean? If so, don't obsolete it.
1161 If not, cover it anyway. */ 1177 If not, cover it anyway. */
1162 1178
@@ -1183,14 +1199,14 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
1183 break; 1199 break;
1184 } 1200 }
1185 } 1201 }
1186 D1(printk(KERN_DEBUG "Expanded dnode to write from (0x%x-0x%x) to (0x%x-0x%x)\n", 1202 D1(printk(KERN_DEBUG "Expanded dnode to write from (0x%x-0x%x) to (0x%x-0x%x)\n",
1187 orig_start, orig_end, start, end)); 1203 orig_start, orig_end, start, end));
1188 1204
1189 D1(BUG_ON(end > frag_last(&f->fragtree)->ofs + frag_last(&f->fragtree)->size)); 1205 D1(BUG_ON(end > frag_last(&f->fragtree)->ofs + frag_last(&f->fragtree)->size));
1190 BUG_ON(end < orig_end); 1206 BUG_ON(end < orig_end);
1191 BUG_ON(start > orig_start); 1207 BUG_ON(start > orig_start);
1192 } 1208 }
1193 1209
1194 /* First, use readpage() to read the appropriate page into the page cache */ 1210 /* First, use readpage() to read the appropriate page into the page cache */
1195 /* Q: What happens if we actually try to GC the _same_ page for which commit_write() 1211 /* Q: What happens if we actually try to GC the _same_ page for which commit_write()
1196 * triggered garbage collection in the first place? 1212 * triggered garbage collection in the first place?
@@ -1211,7 +1227,8 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
1211 uint32_t cdatalen; 1227 uint32_t cdatalen;
1212 uint16_t comprtype = JFFS2_COMPR_NONE; 1228 uint16_t comprtype = JFFS2_COMPR_NONE;
1213 1229
1214 ret = jffs2_reserve_space_gc(c, sizeof(ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, &alloclen); 1230 ret = jffs2_reserve_space_gc(c, sizeof(ri) + JFFS2_MIN_DATA_LEN, &phys_ofs,
1231 &alloclen, JFFS2_SUMMARY_INODE_SIZE);
1215 1232
1216 if (ret) { 1233 if (ret) {
1217 printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_dnode failed: %d\n", 1234 printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_dnode failed: %d\n",
@@ -1246,7 +1263,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
1246 ri.usercompr = (comprtype >> 8) & 0xff; 1263 ri.usercompr = (comprtype >> 8) & 0xff;
1247 ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8)); 1264 ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
1248 ri.data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen)); 1265 ri.data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen));
1249 1266
1250 new_fn = jffs2_write_dnode(c, f, &ri, comprbuf, cdatalen, phys_ofs, ALLOC_GC); 1267 new_fn = jffs2_write_dnode(c, f, &ri, comprbuf, cdatalen, phys_ofs, ALLOC_GC);
1251 1268
1252 jffs2_free_comprbuf(comprbuf, writebuf); 1269 jffs2_free_comprbuf(comprbuf, writebuf);
@@ -1268,4 +1285,3 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
1268 jffs2_gc_release_page(c, pg_ptr, &pg); 1285 jffs2_gc_release_page(c, pg_ptr, &pg);
1269 return ret; 1286 return ret;
1270} 1287}
1271
diff --git a/fs/jffs2/histo.h b/fs/jffs2/histo.h
index 84f184f0836f..22a93a08210c 100644
--- a/fs/jffs2/histo.h
+++ b/fs/jffs2/histo.h
@@ -1,3 +1,3 @@
1/* This file provides the bit-probabilities for the input file */ 1/* This file provides the bit-probabilities for the input file */
2#define BIT_DIVIDER 629 2#define BIT_DIVIDER 629
3static int bits[9] = { 179,167,183,165,159,198,178,119,}; /* ia32 .so files */ 3static int bits[9] = { 179,167,183,165,159,198,178,119,}; /* ia32 .so files */
diff --git a/fs/jffs2/histo_mips.h b/fs/jffs2/histo_mips.h
index 9a443268d885..fa3dac19a109 100644
--- a/fs/jffs2/histo_mips.h
+++ b/fs/jffs2/histo_mips.h
@@ -1,2 +1,2 @@
1#define BIT_DIVIDER_MIPS 1043 1#define BIT_DIVIDER_MIPS 1043
2static int bits_mips[8] = { 277,249,290,267,229,341,212,241}; /* mips32 */ 2static int bits_mips[8] = { 277,249,290,267,229,341,212,241}; /* mips32 */
diff --git a/fs/jffs2/ioctl.c b/fs/jffs2/ioctl.c
index 238c7992064c..69099835de1c 100644
--- a/fs/jffs2/ioctl.c
+++ b/fs/jffs2/ioctl.c
@@ -7,17 +7,17 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: ioctl.c,v 1.9 2004/11/16 20:36:11 dwmw2 Exp $ 10 * $Id: ioctl.c,v 1.10 2005/11/07 11:14:40 gleixner Exp $
11 * 11 *
12 */ 12 */
13 13
14#include <linux/fs.h> 14#include <linux/fs.h>
15 15
16int jffs2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, 16int jffs2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
17 unsigned long arg) 17 unsigned long arg)
18{ 18{
19 /* Later, this will provide for lsattr.jffs2 and chattr.jffs2, which 19 /* Later, this will provide for lsattr.jffs2 and chattr.jffs2, which
20 will include compression support etc. */ 20 will include compression support etc. */
21 return -ENOTTY; 21 return -ENOTTY;
22} 22}
23 23
diff --git a/fs/jffs2/malloc.c b/fs/jffs2/malloc.c
index 5abb431c2a00..036cbd11c004 100644
--- a/fs/jffs2/malloc.c
+++ b/fs/jffs2/malloc.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: malloc.c,v 1.28 2004/11/16 20:36:11 dwmw2 Exp $ 10 * $Id: malloc.c,v 1.31 2005/11/07 11:14:40 gleixner Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -17,15 +17,6 @@
17#include <linux/jffs2.h> 17#include <linux/jffs2.h>
18#include "nodelist.h" 18#include "nodelist.h"
19 19
20#if 0
21#define JFFS2_SLAB_POISON SLAB_POISON
22#else
23#define JFFS2_SLAB_POISON 0
24#endif
25
26// replace this by #define D3 (x) x for cache debugging
27#define D3(x)
28
29/* These are initialised to NULL in the kernel startup code. 20/* These are initialised to NULL in the kernel startup code.
30 If you're porting to other operating systems, beware */ 21 If you're porting to other operating systems, beware */
31static kmem_cache_t *full_dnode_slab; 22static kmem_cache_t *full_dnode_slab;
@@ -38,45 +29,45 @@ static kmem_cache_t *inode_cache_slab;
38 29
39int __init jffs2_create_slab_caches(void) 30int __init jffs2_create_slab_caches(void)
40{ 31{
41 full_dnode_slab = kmem_cache_create("jffs2_full_dnode", 32 full_dnode_slab = kmem_cache_create("jffs2_full_dnode",
42 sizeof(struct jffs2_full_dnode), 33 sizeof(struct jffs2_full_dnode),
43 0, JFFS2_SLAB_POISON, NULL, NULL); 34 0, 0, NULL, NULL);
44 if (!full_dnode_slab) 35 if (!full_dnode_slab)
45 goto err; 36 goto err;
46 37
47 raw_dirent_slab = kmem_cache_create("jffs2_raw_dirent", 38 raw_dirent_slab = kmem_cache_create("jffs2_raw_dirent",
48 sizeof(struct jffs2_raw_dirent), 39 sizeof(struct jffs2_raw_dirent),
49 0, JFFS2_SLAB_POISON, NULL, NULL); 40 0, 0, NULL, NULL);
50 if (!raw_dirent_slab) 41 if (!raw_dirent_slab)
51 goto err; 42 goto err;
52 43
53 raw_inode_slab = kmem_cache_create("jffs2_raw_inode", 44 raw_inode_slab = kmem_cache_create("jffs2_raw_inode",
54 sizeof(struct jffs2_raw_inode), 45 sizeof(struct jffs2_raw_inode),
55 0, JFFS2_SLAB_POISON, NULL, NULL); 46 0, 0, NULL, NULL);
56 if (!raw_inode_slab) 47 if (!raw_inode_slab)
57 goto err; 48 goto err;
58 49
59 tmp_dnode_info_slab = kmem_cache_create("jffs2_tmp_dnode", 50 tmp_dnode_info_slab = kmem_cache_create("jffs2_tmp_dnode",
60 sizeof(struct jffs2_tmp_dnode_info), 51 sizeof(struct jffs2_tmp_dnode_info),
61 0, JFFS2_SLAB_POISON, NULL, NULL); 52 0, 0, NULL, NULL);
62 if (!tmp_dnode_info_slab) 53 if (!tmp_dnode_info_slab)
63 goto err; 54 goto err;
64 55
65 raw_node_ref_slab = kmem_cache_create("jffs2_raw_node_ref", 56 raw_node_ref_slab = kmem_cache_create("jffs2_raw_node_ref",
66 sizeof(struct jffs2_raw_node_ref), 57 sizeof(struct jffs2_raw_node_ref),
67 0, JFFS2_SLAB_POISON, NULL, NULL); 58 0, 0, NULL, NULL);
68 if (!raw_node_ref_slab) 59 if (!raw_node_ref_slab)
69 goto err; 60 goto err;
70 61
71 node_frag_slab = kmem_cache_create("jffs2_node_frag", 62 node_frag_slab = kmem_cache_create("jffs2_node_frag",
72 sizeof(struct jffs2_node_frag), 63 sizeof(struct jffs2_node_frag),
73 0, JFFS2_SLAB_POISON, NULL, NULL); 64 0, 0, NULL, NULL);
74 if (!node_frag_slab) 65 if (!node_frag_slab)
75 goto err; 66 goto err;
76 67
77 inode_cache_slab = kmem_cache_create("jffs2_inode_cache", 68 inode_cache_slab = kmem_cache_create("jffs2_inode_cache",
78 sizeof(struct jffs2_inode_cache), 69 sizeof(struct jffs2_inode_cache),
79 0, JFFS2_SLAB_POISON, NULL, NULL); 70 0, 0, NULL, NULL);
80 if (inode_cache_slab) 71 if (inode_cache_slab)
81 return 0; 72 return 0;
82 err: 73 err:
@@ -104,102 +95,113 @@ void jffs2_destroy_slab_caches(void)
104 95
105struct jffs2_full_dirent *jffs2_alloc_full_dirent(int namesize) 96struct jffs2_full_dirent *jffs2_alloc_full_dirent(int namesize)
106{ 97{
107 return kmalloc(sizeof(struct jffs2_full_dirent) + namesize, GFP_KERNEL); 98 struct jffs2_full_dirent *ret;
99 ret = kmalloc(sizeof(struct jffs2_full_dirent) + namesize, GFP_KERNEL);
100 dbg_memalloc("%p\n", ret);
101 return ret;
108} 102}
109 103
110void jffs2_free_full_dirent(struct jffs2_full_dirent *x) 104void jffs2_free_full_dirent(struct jffs2_full_dirent *x)
111{ 105{
106 dbg_memalloc("%p\n", x);
112 kfree(x); 107 kfree(x);
113} 108}
114 109
115struct jffs2_full_dnode *jffs2_alloc_full_dnode(void) 110struct jffs2_full_dnode *jffs2_alloc_full_dnode(void)
116{ 111{
117 struct jffs2_full_dnode *ret = kmem_cache_alloc(full_dnode_slab, GFP_KERNEL); 112 struct jffs2_full_dnode *ret;
118 D3 (printk (KERN_DEBUG "alloc_full_dnode at %p\n", ret)); 113 ret = kmem_cache_alloc(full_dnode_slab, GFP_KERNEL);
114 dbg_memalloc("%p\n", ret);
119 return ret; 115 return ret;
120} 116}
121 117
122void jffs2_free_full_dnode(struct jffs2_full_dnode *x) 118void jffs2_free_full_dnode(struct jffs2_full_dnode *x)
123{ 119{
124 D3 (printk (KERN_DEBUG "free full_dnode at %p\n", x)); 120 dbg_memalloc("%p\n", x);
125 kmem_cache_free(full_dnode_slab, x); 121 kmem_cache_free(full_dnode_slab, x);
126} 122}
127 123
128struct jffs2_raw_dirent *jffs2_alloc_raw_dirent(void) 124struct jffs2_raw_dirent *jffs2_alloc_raw_dirent(void)
129{ 125{
130 struct jffs2_raw_dirent *ret = kmem_cache_alloc(raw_dirent_slab, GFP_KERNEL); 126 struct jffs2_raw_dirent *ret;
131 D3 (printk (KERN_DEBUG "alloc_raw_dirent\n", ret)); 127 ret = kmem_cache_alloc(raw_dirent_slab, GFP_KERNEL);
128 dbg_memalloc("%p\n", ret);
132 return ret; 129 return ret;
133} 130}
134 131
135void jffs2_free_raw_dirent(struct jffs2_raw_dirent *x) 132void jffs2_free_raw_dirent(struct jffs2_raw_dirent *x)
136{ 133{
137 D3 (printk (KERN_DEBUG "free_raw_dirent at %p\n", x)); 134 dbg_memalloc("%p\n", x);
138 kmem_cache_free(raw_dirent_slab, x); 135 kmem_cache_free(raw_dirent_slab, x);
139} 136}
140 137
141struct jffs2_raw_inode *jffs2_alloc_raw_inode(void) 138struct jffs2_raw_inode *jffs2_alloc_raw_inode(void)
142{ 139{
143 struct jffs2_raw_inode *ret = kmem_cache_alloc(raw_inode_slab, GFP_KERNEL); 140 struct jffs2_raw_inode *ret;
144 D3 (printk (KERN_DEBUG "alloc_raw_inode at %p\n", ret)); 141 ret = kmem_cache_alloc(raw_inode_slab, GFP_KERNEL);
142 dbg_memalloc("%p\n", ret);
145 return ret; 143 return ret;
146} 144}
147 145
148void jffs2_free_raw_inode(struct jffs2_raw_inode *x) 146void jffs2_free_raw_inode(struct jffs2_raw_inode *x)
149{ 147{
150 D3 (printk (KERN_DEBUG "free_raw_inode at %p\n", x)); 148 dbg_memalloc("%p\n", x);
151 kmem_cache_free(raw_inode_slab, x); 149 kmem_cache_free(raw_inode_slab, x);
152} 150}
153 151
154struct jffs2_tmp_dnode_info *jffs2_alloc_tmp_dnode_info(void) 152struct jffs2_tmp_dnode_info *jffs2_alloc_tmp_dnode_info(void)
155{ 153{
156 struct jffs2_tmp_dnode_info *ret = kmem_cache_alloc(tmp_dnode_info_slab, GFP_KERNEL); 154 struct jffs2_tmp_dnode_info *ret;
157 D3 (printk (KERN_DEBUG "alloc_tmp_dnode_info at %p\n", ret)); 155 ret = kmem_cache_alloc(tmp_dnode_info_slab, GFP_KERNEL);
156 dbg_memalloc("%p\n",
157 ret);
158 return ret; 158 return ret;
159} 159}
160 160
161void jffs2_free_tmp_dnode_info(struct jffs2_tmp_dnode_info *x) 161void jffs2_free_tmp_dnode_info(struct jffs2_tmp_dnode_info *x)
162{ 162{
163 D3 (printk (KERN_DEBUG "free_tmp_dnode_info at %p\n", x)); 163 dbg_memalloc("%p\n", x);
164 kmem_cache_free(tmp_dnode_info_slab, x); 164 kmem_cache_free(tmp_dnode_info_slab, x);
165} 165}
166 166
167struct jffs2_raw_node_ref *jffs2_alloc_raw_node_ref(void) 167struct jffs2_raw_node_ref *jffs2_alloc_raw_node_ref(void)
168{ 168{
169 struct jffs2_raw_node_ref *ret = kmem_cache_alloc(raw_node_ref_slab, GFP_KERNEL); 169 struct jffs2_raw_node_ref *ret;
170 D3 (printk (KERN_DEBUG "alloc_raw_node_ref at %p\n", ret)); 170 ret = kmem_cache_alloc(raw_node_ref_slab, GFP_KERNEL);
171 dbg_memalloc("%p\n", ret);
171 return ret; 172 return ret;
172} 173}
173 174
174void jffs2_free_raw_node_ref(struct jffs2_raw_node_ref *x) 175void jffs2_free_raw_node_ref(struct jffs2_raw_node_ref *x)
175{ 176{
176 D3 (printk (KERN_DEBUG "free_raw_node_ref at %p\n", x)); 177 dbg_memalloc("%p\n", x);
177 kmem_cache_free(raw_node_ref_slab, x); 178 kmem_cache_free(raw_node_ref_slab, x);
178} 179}
179 180
180struct jffs2_node_frag *jffs2_alloc_node_frag(void) 181struct jffs2_node_frag *jffs2_alloc_node_frag(void)
181{ 182{
182 struct jffs2_node_frag *ret = kmem_cache_alloc(node_frag_slab, GFP_KERNEL); 183 struct jffs2_node_frag *ret;
183 D3 (printk (KERN_DEBUG "alloc_node_frag at %p\n", ret)); 184 ret = kmem_cache_alloc(node_frag_slab, GFP_KERNEL);
185 dbg_memalloc("%p\n", ret);
184 return ret; 186 return ret;
185} 187}
186 188
187void jffs2_free_node_frag(struct jffs2_node_frag *x) 189void jffs2_free_node_frag(struct jffs2_node_frag *x)
188{ 190{
189 D3 (printk (KERN_DEBUG "free_node_frag at %p\n", x)); 191 dbg_memalloc("%p\n", x);
190 kmem_cache_free(node_frag_slab, x); 192 kmem_cache_free(node_frag_slab, x);
191} 193}
192 194
193struct jffs2_inode_cache *jffs2_alloc_inode_cache(void) 195struct jffs2_inode_cache *jffs2_alloc_inode_cache(void)
194{ 196{
195 struct jffs2_inode_cache *ret = kmem_cache_alloc(inode_cache_slab, GFP_KERNEL); 197 struct jffs2_inode_cache *ret;
196 D3 (printk(KERN_DEBUG "Allocated inocache at %p\n", ret)); 198 ret = kmem_cache_alloc(inode_cache_slab, GFP_KERNEL);
199 dbg_memalloc("%p\n", ret);
197 return ret; 200 return ret;
198} 201}
199 202
200void jffs2_free_inode_cache(struct jffs2_inode_cache *x) 203void jffs2_free_inode_cache(struct jffs2_inode_cache *x)
201{ 204{
202 D3 (printk(KERN_DEBUG "Freeing inocache at %p\n", x)); 205 dbg_memalloc("%p\n", x);
203 kmem_cache_free(inode_cache_slab, x); 206 kmem_cache_free(inode_cache_slab, x);
204} 207}
205
diff --git a/fs/jffs2/nodelist.c b/fs/jffs2/nodelist.c
index 4991c348f6ec..c79eebb8ab32 100644
--- a/fs/jffs2/nodelist.c
+++ b/fs/jffs2/nodelist.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: nodelist.c,v 1.98 2005/07/10 15:15:32 dedekind Exp $ 10 * $Id: nodelist.c,v 1.115 2005/11/07 11:14:40 gleixner Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -24,469 +24,832 @@
24void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list) 24void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list)
25{ 25{
26 struct jffs2_full_dirent **prev = list; 26 struct jffs2_full_dirent **prev = list;
27 D1(printk(KERN_DEBUG "jffs2_add_fd_to_list( %p, %p (->%p))\n", new, list, *list)); 27
28 dbg_dentlist("add dirent \"%s\", ino #%u\n", new->name, new->ino);
28 29
29 while ((*prev) && (*prev)->nhash <= new->nhash) { 30 while ((*prev) && (*prev)->nhash <= new->nhash) {
30 if ((*prev)->nhash == new->nhash && !strcmp((*prev)->name, new->name)) { 31 if ((*prev)->nhash == new->nhash && !strcmp((*prev)->name, new->name)) {
31 /* Duplicate. Free one */ 32 /* Duplicate. Free one */
32 if (new->version < (*prev)->version) { 33 if (new->version < (*prev)->version) {
33 D1(printk(KERN_DEBUG "Eep! Marking new dirent node obsolete\n")); 34 dbg_dentlist("Eep! Marking new dirent node is obsolete, old is \"%s\", ino #%u\n",
34 D1(printk(KERN_DEBUG "New dirent is \"%s\"->ino #%u. Old is \"%s\"->ino #%u\n", new->name, new->ino, (*prev)->name, (*prev)->ino)); 35 (*prev)->name, (*prev)->ino);
35 jffs2_mark_node_obsolete(c, new->raw); 36 jffs2_mark_node_obsolete(c, new->raw);
36 jffs2_free_full_dirent(new); 37 jffs2_free_full_dirent(new);
37 } else { 38 } else {
38 D1(printk(KERN_DEBUG "Marking old dirent node (ino #%u) obsolete\n", (*prev)->ino)); 39 dbg_dentlist("marking old dirent \"%s\", ino #%u bsolete\n",
40 (*prev)->name, (*prev)->ino);
39 new->next = (*prev)->next; 41 new->next = (*prev)->next;
40 jffs2_mark_node_obsolete(c, ((*prev)->raw)); 42 jffs2_mark_node_obsolete(c, ((*prev)->raw));
41 jffs2_free_full_dirent(*prev); 43 jffs2_free_full_dirent(*prev);
42 *prev = new; 44 *prev = new;
43 } 45 }
44 goto out; 46 return;
45 } 47 }
46 prev = &((*prev)->next); 48 prev = &((*prev)->next);
47 } 49 }
48 new->next = *prev; 50 new->next = *prev;
49 *prev = new; 51 *prev = new;
52}
53
54void jffs2_truncate_fragtree(struct jffs2_sb_info *c, struct rb_root *list, uint32_t size)
55{
56 struct jffs2_node_frag *frag = jffs2_lookup_node_frag(list, size);
57
58 dbg_fragtree("truncating fragtree to 0x%08x bytes\n", size);
59
60 /* We know frag->ofs <= size. That's what lookup does for us */
61 if (frag && frag->ofs != size) {
62 if (frag->ofs+frag->size > size) {
63 frag->size = size - frag->ofs;
64 }
65 frag = frag_next(frag);
66 }
67 while (frag && frag->ofs >= size) {
68 struct jffs2_node_frag *next = frag_next(frag);
69
70 frag_erase(frag, list);
71 jffs2_obsolete_node_frag(c, frag);
72 frag = next;
73 }
50 74
51 out: 75 if (size == 0)
52 D2(while(*list) { 76 return;
53 printk(KERN_DEBUG "Dirent \"%s\" (hash 0x%08x, ino #%u\n", (*list)->name, (*list)->nhash, (*list)->ino); 77
54 list = &(*list)->next; 78 /*
55 }); 79 * If the last fragment starts at the RAM page boundary, it is
80 * REF_PRISTINE irrespective of its size.
81 */
82 frag = frag_last(list);
83 if (frag->node && (frag->ofs & (PAGE_CACHE_SIZE - 1)) == 0) {
84 dbg_fragtree2("marking the last fragment 0x%08x-0x%08x REF_PRISTINE.\n",
85 frag->ofs, frag->ofs + frag->size);
86 frag->node->raw->flash_offset = ref_offset(frag->node->raw) | REF_PRISTINE;
87 }
56} 88}
57 89
58/* 90void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *this)
59 * Put a new tmp_dnode_info into the temporaty RB-tree, keeping the list in
60 * order of increasing version.
61 */
62static void jffs2_add_tn_to_tree(struct jffs2_tmp_dnode_info *tn, struct rb_root *list)
63{ 91{
64 struct rb_node **p = &list->rb_node; 92 if (this->node) {
65 struct rb_node * parent = NULL; 93 this->node->frags--;
66 struct jffs2_tmp_dnode_info *this; 94 if (!this->node->frags) {
67 95 /* The node has no valid frags left. It's totally obsoleted */
68 while (*p) { 96 dbg_fragtree2("marking old node @0x%08x (0x%04x-0x%04x) obsolete\n",
69 parent = *p; 97 ref_offset(this->node->raw), this->node->ofs, this->node->ofs+this->node->size);
70 this = rb_entry(parent, struct jffs2_tmp_dnode_info, rb); 98 jffs2_mark_node_obsolete(c, this->node->raw);
71 99 jffs2_free_full_dnode(this->node);
72 /* There may actually be a collision here, but it doesn't 100 } else {
73 actually matter. As long as the two nodes with the same 101 dbg_fragtree2("marking old node @0x%08x (0x%04x-0x%04x) REF_NORMAL. frags is %d\n",
74 version are together, it's all fine. */ 102 ref_offset(this->node->raw), this->node->ofs, this->node->ofs+this->node->size, this->node->frags);
75 if (tn->version < this->version) 103 mark_ref_normal(this->node->raw);
76 p = &(*p)->rb_left; 104 }
77 else
78 p = &(*p)->rb_right;
79 }
80 105
81 rb_link_node(&tn->rb, parent, p); 106 }
82 rb_insert_color(&tn->rb, list); 107 jffs2_free_node_frag(this);
83} 108}
84 109
85static void jffs2_free_tmp_dnode_info_list(struct rb_root *list) 110static void jffs2_fragtree_insert(struct jffs2_node_frag *newfrag, struct jffs2_node_frag *base)
86{ 111{
87 struct rb_node *this; 112 struct rb_node *parent = &base->rb;
88 struct jffs2_tmp_dnode_info *tn; 113 struct rb_node **link = &parent;
89 114
90 this = list->rb_node; 115 dbg_fragtree2("insert frag (0x%04x-0x%04x)\n", newfrag->ofs, newfrag->ofs + newfrag->size);
91 116
92 /* Now at bottom of tree */ 117 while (*link) {
93 while (this) { 118 parent = *link;
94 if (this->rb_left) 119 base = rb_entry(parent, struct jffs2_node_frag, rb);
95 this = this->rb_left; 120
96 else if (this->rb_right) 121 if (newfrag->ofs > base->ofs)
97 this = this->rb_right; 122 link = &base->rb.rb_right;
123 else if (newfrag->ofs < base->ofs)
124 link = &base->rb.rb_left;
98 else { 125 else {
99 tn = rb_entry(this, struct jffs2_tmp_dnode_info, rb); 126 JFFS2_ERROR("duplicate frag at %08x (%p,%p)\n", newfrag->ofs, newfrag, base);
100 jffs2_free_full_dnode(tn->fn); 127 BUG();
101 jffs2_free_tmp_dnode_info(tn);
102
103 this = this->rb_parent;
104 if (!this)
105 break;
106
107 if (this->rb_left == &tn->rb)
108 this->rb_left = NULL;
109 else if (this->rb_right == &tn->rb)
110 this->rb_right = NULL;
111 else BUG();
112 } 128 }
113 } 129 }
114 list->rb_node = NULL; 130
131 rb_link_node(&newfrag->rb, &base->rb, link);
115} 132}
116 133
117static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd) 134/*
135 * Allocate and initializes a new fragment.
136 */
137static inline struct jffs2_node_frag * new_fragment(struct jffs2_full_dnode *fn, uint32_t ofs, uint32_t size)
118{ 138{
119 struct jffs2_full_dirent *next; 139 struct jffs2_node_frag *newfrag;
120 140
121 while (fd) { 141 newfrag = jffs2_alloc_node_frag();
122 next = fd->next; 142 if (likely(newfrag)) {
123 jffs2_free_full_dirent(fd); 143 newfrag->ofs = ofs;
124 fd = next; 144 newfrag->size = size;
145 newfrag->node = fn;
146 } else {
147 JFFS2_ERROR("cannot allocate a jffs2_node_frag object\n");
125 } 148 }
149
150 return newfrag;
126} 151}
127 152
128/* Returns first valid node after 'ref'. May return 'ref' */ 153/*
129static struct jffs2_raw_node_ref *jffs2_first_valid_node(struct jffs2_raw_node_ref *ref) 154 * Called when there is no overlapping fragment exist. Inserts a hole before the new
155 * fragment and inserts the new fragment to the fragtree.
156 */
157static int no_overlapping_node(struct jffs2_sb_info *c, struct rb_root *root,
158 struct jffs2_node_frag *newfrag,
159 struct jffs2_node_frag *this, uint32_t lastend)
130{ 160{
131 while (ref && ref->next_in_ino) { 161 if (lastend < newfrag->node->ofs) {
132 if (!ref_obsolete(ref)) 162 /* put a hole in before the new fragment */
133 return ref; 163 struct jffs2_node_frag *holefrag;
134 D1(printk(KERN_DEBUG "node at 0x%08x is obsoleted. Ignoring.\n", ref_offset(ref))); 164
135 ref = ref->next_in_ino; 165 holefrag= new_fragment(NULL, lastend, newfrag->node->ofs - lastend);
166 if (unlikely(!holefrag)) {
167 jffs2_free_node_frag(newfrag);
168 return -ENOMEM;
169 }
170
171 if (this) {
172 /* By definition, the 'this' node has no right-hand child,
173 because there are no frags with offset greater than it.
174 So that's where we want to put the hole */
175 dbg_fragtree2("add hole frag %#04x-%#04x on the right of the new frag.\n",
176 holefrag->ofs, holefrag->ofs + holefrag->size);
177 rb_link_node(&holefrag->rb, &this->rb, &this->rb.rb_right);
178 } else {
179 dbg_fragtree2("Add hole frag %#04x-%#04x to the root of the tree.\n",
180 holefrag->ofs, holefrag->ofs + holefrag->size);
181 rb_link_node(&holefrag->rb, NULL, &root->rb_node);
182 }
183 rb_insert_color(&holefrag->rb, root);
184 this = holefrag;
185 }
186
187 if (this) {
188 /* By definition, the 'this' node has no right-hand child,
189 because there are no frags with offset greater than it.
190 So that's where we want to put new fragment */
191 dbg_fragtree2("add the new node at the right\n");
192 rb_link_node(&newfrag->rb, &this->rb, &this->rb.rb_right);
193 } else {
194 dbg_fragtree2("insert the new node at the root of the tree\n");
195 rb_link_node(&newfrag->rb, NULL, &root->rb_node);
136 } 196 }
137 return NULL; 197 rb_insert_color(&newfrag->rb, root);
198
199 return 0;
138} 200}
139 201
140/* Get tmp_dnode_info and full_dirent for all non-obsolete nodes associated 202/* Doesn't set inode->i_size */
141 with this ino, returning the former in order of version */ 203static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *root, struct jffs2_node_frag *newfrag)
204{
205 struct jffs2_node_frag *this;
206 uint32_t lastend;
207
208 /* Skip all the nodes which are completed before this one starts */
209 this = jffs2_lookup_node_frag(root, newfrag->node->ofs);
210
211 if (this) {
212 dbg_fragtree2("lookup gave frag 0x%04x-0x%04x; phys 0x%08x (*%p)\n",
213 this->ofs, this->ofs+this->size, this->node?(ref_offset(this->node->raw)):0xffffffff, this);
214 lastend = this->ofs + this->size;
215 } else {
216 dbg_fragtree2("lookup gave no frag\n");
217 lastend = 0;
218 }
219
220 /* See if we ran off the end of the fragtree */
221 if (lastend <= newfrag->ofs) {
222 /* We did */
223
224 /* Check if 'this' node was on the same page as the new node.
225 If so, both 'this' and the new node get marked REF_NORMAL so
226 the GC can take a look.
227 */
228 if (lastend && (lastend-1) >> PAGE_CACHE_SHIFT == newfrag->ofs >> PAGE_CACHE_SHIFT) {
229 if (this->node)
230 mark_ref_normal(this->node->raw);
231 mark_ref_normal(newfrag->node->raw);
232 }
233
234 return no_overlapping_node(c, root, newfrag, this, lastend);
235 }
142 236
143int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 237 if (this->node)
144 struct rb_root *tnp, struct jffs2_full_dirent **fdp, 238 dbg_fragtree2("dealing with frag %u-%u, phys %#08x(%d).\n",
145 uint32_t *highest_version, uint32_t *latest_mctime, 239 this->ofs, this->ofs + this->size,
146 uint32_t *mctime_ver) 240 ref_offset(this->node->raw), ref_flags(this->node->raw));
241 else
242 dbg_fragtree2("dealing with hole frag %u-%u.\n",
243 this->ofs, this->ofs + this->size);
244
245 /* OK. 'this' is pointing at the first frag that newfrag->ofs at least partially obsoletes,
246 * - i.e. newfrag->ofs < this->ofs+this->size && newfrag->ofs >= this->ofs
247 */
248 if (newfrag->ofs > this->ofs) {
249 /* This node isn't completely obsoleted. The start of it remains valid */
250
251 /* Mark the new node and the partially covered node REF_NORMAL -- let
252 the GC take a look at them */
253 mark_ref_normal(newfrag->node->raw);
254 if (this->node)
255 mark_ref_normal(this->node->raw);
256
257 if (this->ofs + this->size > newfrag->ofs + newfrag->size) {
258 /* The new node splits 'this' frag into two */
259 struct jffs2_node_frag *newfrag2;
260
261 if (this->node)
262 dbg_fragtree2("split old frag 0x%04x-0x%04x, phys 0x%08x\n",
263 this->ofs, this->ofs+this->size, ref_offset(this->node->raw));
264 else
265 dbg_fragtree2("split old hole frag 0x%04x-0x%04x\n",
266 this->ofs, this->ofs+this->size);
267
268 /* New second frag pointing to this's node */
269 newfrag2 = new_fragment(this->node, newfrag->ofs + newfrag->size,
270 this->ofs + this->size - newfrag->ofs - newfrag->size);
271 if (unlikely(!newfrag2))
272 return -ENOMEM;
273 if (this->node)
274 this->node->frags++;
275
276 /* Adjust size of original 'this' */
277 this->size = newfrag->ofs - this->ofs;
278
279 /* Now, we know there's no node with offset
280 greater than this->ofs but smaller than
281 newfrag2->ofs or newfrag->ofs, for obvious
282 reasons. So we can do a tree insert from
283 'this' to insert newfrag, and a tree insert
284 from newfrag to insert newfrag2. */
285 jffs2_fragtree_insert(newfrag, this);
286 rb_insert_color(&newfrag->rb, root);
287
288 jffs2_fragtree_insert(newfrag2, newfrag);
289 rb_insert_color(&newfrag2->rb, root);
290
291 return 0;
292 }
293 /* New node just reduces 'this' frag in size, doesn't split it */
294 this->size = newfrag->ofs - this->ofs;
295
296 /* Again, we know it lives down here in the tree */
297 jffs2_fragtree_insert(newfrag, this);
298 rb_insert_color(&newfrag->rb, root);
299 } else {
300 /* New frag starts at the same point as 'this' used to. Replace
301 it in the tree without doing a delete and insertion */
302 dbg_fragtree2("inserting newfrag (*%p),%d-%d in before 'this' (*%p),%d-%d\n",
303 newfrag, newfrag->ofs, newfrag->ofs+newfrag->size, this, this->ofs, this->ofs+this->size);
304
305 rb_replace_node(&this->rb, &newfrag->rb, root);
306
307 if (newfrag->ofs + newfrag->size >= this->ofs+this->size) {
308 dbg_fragtree2("obsoleting node frag %p (%x-%x)\n", this, this->ofs, this->ofs+this->size);
309 jffs2_obsolete_node_frag(c, this);
310 } else {
311 this->ofs += newfrag->size;
312 this->size -= newfrag->size;
313
314 jffs2_fragtree_insert(this, newfrag);
315 rb_insert_color(&this->rb, root);
316 return 0;
317 }
318 }
319 /* OK, now we have newfrag added in the correct place in the tree, but
320 frag_next(newfrag) may be a fragment which is overlapped by it
321 */
322 while ((this = frag_next(newfrag)) && newfrag->ofs + newfrag->size >= this->ofs + this->size) {
323 /* 'this' frag is obsoleted completely. */
324 dbg_fragtree2("obsoleting node frag %p (%x-%x) and removing from tree\n",
325 this, this->ofs, this->ofs+this->size);
326 rb_erase(&this->rb, root);
327 jffs2_obsolete_node_frag(c, this);
328 }
329 /* Now we're pointing at the first frag which isn't totally obsoleted by
330 the new frag */
331
332 if (!this || newfrag->ofs + newfrag->size == this->ofs)
333 return 0;
334
335 /* Still some overlap but we don't need to move it in the tree */
336 this->size = (this->ofs + this->size) - (newfrag->ofs + newfrag->size);
337 this->ofs = newfrag->ofs + newfrag->size;
338
339 /* And mark them REF_NORMAL so the GC takes a look at them */
340 if (this->node)
341 mark_ref_normal(this->node->raw);
342 mark_ref_normal(newfrag->node->raw);
343
344 return 0;
345}
346
347/*
348 * Given an inode, probably with existing tree of fragments, add the new node
349 * to the fragment tree.
350 */
351int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn)
147{ 352{
148 struct jffs2_raw_node_ref *ref, *valid_ref; 353 int ret;
149 struct jffs2_tmp_dnode_info *tn; 354 struct jffs2_node_frag *newfrag;
150 struct rb_root ret_tn = RB_ROOT;
151 struct jffs2_full_dirent *fd, *ret_fd = NULL;
152 union jffs2_node_union node;
153 size_t retlen;
154 int err;
155
156 *mctime_ver = 0;
157
158 D1(printk(KERN_DEBUG "jffs2_get_inode_nodes(): ino #%u\n", f->inocache->ino));
159 355
160 spin_lock(&c->erase_completion_lock); 356 if (unlikely(!fn->size))
357 return 0;
161 358
162 valid_ref = jffs2_first_valid_node(f->inocache->nodes); 359 newfrag = new_fragment(fn, fn->ofs, fn->size);
360 if (unlikely(!newfrag))
361 return -ENOMEM;
362 newfrag->node->frags = 1;
163 363
164 if (!valid_ref && (f->inocache->ino != 1)) 364 dbg_fragtree("adding node %#04x-%#04x @0x%08x on flash, newfrag *%p\n",
165 printk(KERN_WARNING "Eep. No valid nodes for ino #%u\n", f->inocache->ino); 365 fn->ofs, fn->ofs+fn->size, ref_offset(fn->raw), newfrag);
166 366
167 while (valid_ref) { 367 ret = jffs2_add_frag_to_fragtree(c, &f->fragtree, newfrag);
168 /* We can hold a pointer to a non-obsolete node without the spinlock, 368 if (unlikely(ret))
169 but _obsolete_ nodes may disappear at any time, if the block 369 return ret;
170 they're in gets erased. So if we mark 'ref' obsolete while we're
171 not holding the lock, it can go away immediately. For that reason,
172 we find the next valid node first, before processing 'ref'.
173 */
174 ref = valid_ref;
175 valid_ref = jffs2_first_valid_node(ref->next_in_ino);
176 spin_unlock(&c->erase_completion_lock);
177 370
178 cond_resched(); 371 /* If we now share a page with other nodes, mark either previous
372 or next node REF_NORMAL, as appropriate. */
373 if (newfrag->ofs & (PAGE_CACHE_SIZE-1)) {
374 struct jffs2_node_frag *prev = frag_prev(newfrag);
375
376 mark_ref_normal(fn->raw);
377 /* If we don't start at zero there's _always_ a previous */
378 if (prev->node)
379 mark_ref_normal(prev->node->raw);
380 }
381
382 if ((newfrag->ofs+newfrag->size) & (PAGE_CACHE_SIZE-1)) {
383 struct jffs2_node_frag *next = frag_next(newfrag);
384
385 if (next) {
386 mark_ref_normal(fn->raw);
387 if (next->node)
388 mark_ref_normal(next->node->raw);
389 }
390 }
391 jffs2_dbg_fragtree_paranoia_check_nolock(f);
392
393 return 0;
394}
395
396/*
397 * Check the data CRC of the node.
398 *
399 * Returns: 0 if the data CRC is correct;
400 * 1 - if incorrect;
401 * error code if an error occured.
402 */
403static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info *tn)
404{
405 struct jffs2_raw_node_ref *ref = tn->fn->raw;
406 int err = 0, pointed = 0;
407 struct jffs2_eraseblock *jeb;
408 unsigned char *buffer;
409 uint32_t crc, ofs, retlen, len;
410
411 BUG_ON(tn->csize == 0);
412
413 if (!jffs2_is_writebuffered(c))
414 goto adj_acc;
415
416 /* Calculate how many bytes were already checked */
417 ofs = ref_offset(ref) + sizeof(struct jffs2_raw_inode);
418 len = ofs % c->wbuf_pagesize;
419 if (likely(len))
420 len = c->wbuf_pagesize - len;
421
422 if (len >= tn->csize) {
423 dbg_readinode("no need to check node at %#08x, data length %u, data starts at %#08x - it has already been checked.\n",
424 ref_offset(ref), tn->csize, ofs);
425 goto adj_acc;
426 }
427
428 ofs += len;
429 len = tn->csize - len;
430
431 dbg_readinode("check node at %#08x, data length %u, partial CRC %#08x, correct CRC %#08x, data starts at %#08x, start checking from %#08x - %u bytes.\n",
432 ref_offset(ref), tn->csize, tn->partial_crc, tn->data_crc, ofs - len, ofs, len);
433
434#ifndef __ECOS
435 /* TODO: instead, incapsulate point() stuff to jffs2_flash_read(),
436 * adding and jffs2_flash_read_end() interface. */
437 if (c->mtd->point) {
438 err = c->mtd->point(c->mtd, ofs, len, &retlen, &buffer);
439 if (!err && retlen < tn->csize) {
440 JFFS2_WARNING("MTD point returned len too short: %u instead of %u.\n", retlen, tn->csize);
441 c->mtd->unpoint(c->mtd, buffer, ofs, len);
442 } else if (err)
443 JFFS2_WARNING("MTD point failed: error code %d.\n", err);
444 else
445 pointed = 1; /* succefully pointed to device */
446 }
447#endif
448
449 if (!pointed) {
450 buffer = kmalloc(len, GFP_KERNEL);
451 if (unlikely(!buffer))
452 return -ENOMEM;
179 453
180 /* FIXME: point() */ 454 /* TODO: this is very frequent pattern, make it a separate
181 err = jffs2_flash_read(c, (ref_offset(ref)), 455 * routine */
182 min_t(uint32_t, ref_totlen(c, NULL, ref), sizeof(node)), 456 err = jffs2_flash_read(c, ofs, len, &retlen, buffer);
183 &retlen, (void *)&node);
184 if (err) { 457 if (err) {
185 printk(KERN_WARNING "error %d reading node at 0x%08x in get_inode_nodes()\n", err, ref_offset(ref)); 458 JFFS2_ERROR("can not read %d bytes from 0x%08x, error code: %d.\n", len, ofs, err);
186 goto free_out; 459 goto free_out;
187 } 460 }
188
189 461
190 /* Check we've managed to read at least the common node header */ 462 if (retlen != len) {
191 if (retlen < min_t(uint32_t, ref_totlen(c, NULL, ref), sizeof(node.u))) { 463 JFFS2_ERROR("short read at %#08x: %d instead of %d.\n", ofs, retlen, len);
192 printk(KERN_WARNING "short read in get_inode_nodes()\n");
193 err = -EIO; 464 err = -EIO;
194 goto free_out; 465 goto free_out;
195 } 466 }
196 467 }
197 switch (je16_to_cpu(node.u.nodetype)) {
198 case JFFS2_NODETYPE_DIRENT:
199 D1(printk(KERN_DEBUG "Node at %08x (%d) is a dirent node\n", ref_offset(ref), ref_flags(ref)));
200 if (ref_flags(ref) == REF_UNCHECKED) {
201 printk(KERN_WARNING "BUG: Dirent node at 0x%08x never got checked? How?\n", ref_offset(ref));
202 BUG();
203 }
204 if (retlen < sizeof(node.d)) {
205 printk(KERN_WARNING "short read in get_inode_nodes()\n");
206 err = -EIO;
207 goto free_out;
208 }
209 /* sanity check */
210 if (PAD((node.d.nsize + sizeof (node.d))) != PAD(je32_to_cpu (node.d.totlen))) {
211 printk(KERN_NOTICE "jffs2_get_inode_nodes(): Illegal nsize in node at 0x%08x: nsize 0x%02x, totlen %04x\n",
212 ref_offset(ref), node.d.nsize, je32_to_cpu(node.d.totlen));
213 jffs2_mark_node_obsolete(c, ref);
214 spin_lock(&c->erase_completion_lock);
215 continue;
216 }
217 if (je32_to_cpu(node.d.version) > *highest_version)
218 *highest_version = je32_to_cpu(node.d.version);
219 if (ref_obsolete(ref)) {
220 /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
221 printk(KERN_ERR "Dirent node at 0x%08x became obsolete while we weren't looking\n",
222 ref_offset(ref));
223 BUG();
224 }
225
226 fd = jffs2_alloc_full_dirent(node.d.nsize+1);
227 if (!fd) {
228 err = -ENOMEM;
229 goto free_out;
230 }
231 fd->raw = ref;
232 fd->version = je32_to_cpu(node.d.version);
233 fd->ino = je32_to_cpu(node.d.ino);
234 fd->type = node.d.type;
235
236 /* Pick out the mctime of the latest dirent */
237 if(fd->version > *mctime_ver) {
238 *mctime_ver = fd->version;
239 *latest_mctime = je32_to_cpu(node.d.mctime);
240 }
241 468
242 /* memcpy as much of the name as possible from the raw 469 /* Continue calculating CRC */
243 dirent we've already read from the flash 470 crc = crc32(tn->partial_crc, buffer, len);
244 */ 471 if(!pointed)
245 if (retlen > sizeof(struct jffs2_raw_dirent)) 472 kfree(buffer);
246 memcpy(&fd->name[0], &node.d.name[0], min_t(uint32_t, node.d.nsize, (retlen-sizeof(struct jffs2_raw_dirent)))); 473#ifndef __ECOS
247 474 else
248 /* Do we need to copy any more of the name directly 475 c->mtd->unpoint(c->mtd, buffer, ofs, len);
249 from the flash? 476#endif
250 */
251 if (node.d.nsize + sizeof(struct jffs2_raw_dirent) > retlen) {
252 /* FIXME: point() */
253 int already = retlen - sizeof(struct jffs2_raw_dirent);
254
255 err = jffs2_flash_read(c, (ref_offset(ref)) + retlen,
256 node.d.nsize - already, &retlen, &fd->name[already]);
257 if (!err && retlen != node.d.nsize - already)
258 err = -EIO;
259
260 if (err) {
261 printk(KERN_WARNING "Read remainder of name in jffs2_get_inode_nodes(): error %d\n", err);
262 jffs2_free_full_dirent(fd);
263 goto free_out;
264 }
265 }
266 fd->nhash = full_name_hash(fd->name, node.d.nsize);
267 fd->next = NULL;
268 fd->name[node.d.nsize] = '\0';
269 /* Wheee. We now have a complete jffs2_full_dirent structure, with
270 the name in it and everything. Link it into the list
271 */
272 D1(printk(KERN_DEBUG "Adding fd \"%s\", ino #%u\n", fd->name, fd->ino));
273 jffs2_add_fd_to_list(c, fd, &ret_fd);
274 break;
275
276 case JFFS2_NODETYPE_INODE:
277 D1(printk(KERN_DEBUG "Node at %08x (%d) is a data node\n", ref_offset(ref), ref_flags(ref)));
278 if (retlen < sizeof(node.i)) {
279 printk(KERN_WARNING "read too short for dnode\n");
280 err = -EIO;
281 goto free_out;
282 }
283 if (je32_to_cpu(node.i.version) > *highest_version)
284 *highest_version = je32_to_cpu(node.i.version);
285 D1(printk(KERN_DEBUG "version %d, highest_version now %d\n", je32_to_cpu(node.i.version), *highest_version));
286
287 if (ref_obsolete(ref)) {
288 /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
289 printk(KERN_ERR "Inode node at 0x%08x became obsolete while we weren't looking\n",
290 ref_offset(ref));
291 BUG();
292 }
293 477
294 /* If we've never checked the CRCs on this node, check them now. */ 478 if (crc != tn->data_crc) {
295 if (ref_flags(ref) == REF_UNCHECKED) { 479 JFFS2_NOTICE("wrong data CRC in data node at 0x%08x: read %#08x, calculated %#08x.\n",
296 uint32_t crc, len; 480 ofs, tn->data_crc, crc);
297 struct jffs2_eraseblock *jeb; 481 return 1;
298 482 }
299 crc = crc32(0, &node, sizeof(node.i)-8);
300 if (crc != je32_to_cpu(node.i.node_crc)) {
301 printk(KERN_NOTICE "jffs2_get_inode_nodes(): CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
302 ref_offset(ref), je32_to_cpu(node.i.node_crc), crc);
303 jffs2_mark_node_obsolete(c, ref);
304 spin_lock(&c->erase_completion_lock);
305 continue;
306 }
307
308 /* sanity checks */
309 if ( je32_to_cpu(node.i.offset) > je32_to_cpu(node.i.isize) ||
310 PAD(je32_to_cpu(node.i.csize) + sizeof (node.i)) != PAD(je32_to_cpu(node.i.totlen))) {
311 printk(KERN_NOTICE "jffs2_get_inode_nodes(): Inode corrupted at 0x%08x, totlen %d, #ino %d, version %d, isize %d, csize %d, dsize %d \n",
312 ref_offset(ref), je32_to_cpu(node.i.totlen), je32_to_cpu(node.i.ino),
313 je32_to_cpu(node.i.version), je32_to_cpu(node.i.isize),
314 je32_to_cpu(node.i.csize), je32_to_cpu(node.i.dsize));
315 jffs2_mark_node_obsolete(c, ref);
316 spin_lock(&c->erase_completion_lock);
317 continue;
318 }
319 483
320 if (node.i.compr != JFFS2_COMPR_ZERO && je32_to_cpu(node.i.csize)) { 484adj_acc:
321 unsigned char *buf=NULL; 485 jeb = &c->blocks[ref->flash_offset / c->sector_size];
322 uint32_t pointed = 0; 486 len = ref_totlen(c, jeb, ref);
323#ifndef __ECOS 487
324 if (c->mtd->point) { 488 /*
325 err = c->mtd->point (c->mtd, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize), 489 * Mark the node as having been checked and fix the
326 &retlen, &buf); 490 * accounting accordingly.
327 if (!err && retlen < je32_to_cpu(node.i.csize)) { 491 */
328 D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", retlen)); 492 spin_lock(&c->erase_completion_lock);
329 c->mtd->unpoint(c->mtd, buf, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize)); 493 jeb->used_size += len;
330 } else if (err){ 494 jeb->unchecked_size -= len;
331 D1(printk(KERN_DEBUG "MTD point failed %d\n", err)); 495 c->used_size += len;
332 } else 496 c->unchecked_size -= len;
333 pointed = 1; /* succefully pointed to device */ 497 spin_unlock(&c->erase_completion_lock);
334 } 498
335#endif 499 return 0;
336 if(!pointed){ 500
337 buf = kmalloc(je32_to_cpu(node.i.csize), GFP_KERNEL); 501free_out:
338 if (!buf) 502 if(!pointed)
339 return -ENOMEM; 503 kfree(buffer);
340
341 err = jffs2_flash_read(c, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize),
342 &retlen, buf);
343 if (!err && retlen != je32_to_cpu(node.i.csize))
344 err = -EIO;
345 if (err) {
346 kfree(buf);
347 return err;
348 }
349 }
350 crc = crc32(0, buf, je32_to_cpu(node.i.csize));
351 if(!pointed)
352 kfree(buf);
353#ifndef __ECOS 504#ifndef __ECOS
354 else 505 else
355 c->mtd->unpoint(c->mtd, buf, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize)); 506 c->mtd->unpoint(c->mtd, buffer, ofs, len);
356#endif 507#endif
508 return err;
509}
357 510
358 if (crc != je32_to_cpu(node.i.data_crc)) { 511/*
359 printk(KERN_NOTICE "jffs2_get_inode_nodes(): Data CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", 512 * Helper function for jffs2_add_older_frag_to_fragtree().
360 ref_offset(ref), je32_to_cpu(node.i.data_crc), crc); 513 *
361 jffs2_mark_node_obsolete(c, ref); 514 * Checks the node if we are in the checking stage.
362 spin_lock(&c->erase_completion_lock); 515 */
363 continue; 516static inline int check_node(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_tmp_dnode_info *tn)
364 } 517{
365 518 int ret;
366 }
367 519
368 /* Mark the node as having been checked and fix the accounting accordingly */ 520 BUG_ON(ref_obsolete(tn->fn->raw));
369 spin_lock(&c->erase_completion_lock); 521
370 jeb = &c->blocks[ref->flash_offset / c->sector_size]; 522 /* We only check the data CRC of unchecked nodes */
371 len = ref_totlen(c, jeb, ref); 523 if (ref_flags(tn->fn->raw) != REF_UNCHECKED)
372 524 return 0;
373 jeb->used_size += len; 525
374 jeb->unchecked_size -= len; 526 dbg_fragtree2("check node %#04x-%#04x, phys offs %#08x.\n",
375 c->used_size += len; 527 tn->fn->ofs, tn->fn->ofs + tn->fn->size, ref_offset(tn->fn->raw));
376 c->unchecked_size -= len; 528
377 529 ret = check_node_data(c, tn);
378 /* If node covers at least a whole page, or if it starts at the 530 if (unlikely(ret < 0)) {
379 beginning of a page and runs to the end of the file, or if 531 JFFS2_ERROR("check_node_data() returned error: %d.\n",
380 it's a hole node, mark it REF_PRISTINE, else REF_NORMAL. 532 ret);
381 533 } else if (unlikely(ret > 0)) {
382 If it's actually overlapped, it'll get made NORMAL (or OBSOLETE) 534 dbg_fragtree2("CRC error, mark it obsolete.\n");
383 when the overlapping node(s) get added to the tree anyway. 535 jffs2_mark_node_obsolete(c, tn->fn->raw);
384 */ 536 }
385 if ((je32_to_cpu(node.i.dsize) >= PAGE_CACHE_SIZE) || 537
386 ( ((je32_to_cpu(node.i.offset)&(PAGE_CACHE_SIZE-1))==0) && 538 return ret;
387 (je32_to_cpu(node.i.dsize)+je32_to_cpu(node.i.offset) == je32_to_cpu(node.i.isize)))) { 539}
388 D1(printk(KERN_DEBUG "Marking node at 0x%08x REF_PRISTINE\n", ref_offset(ref))); 540
389 ref->flash_offset = ref_offset(ref) | REF_PRISTINE; 541/*
390 } else { 542 * Helper function for jffs2_add_older_frag_to_fragtree().
391 D1(printk(KERN_DEBUG "Marking node at 0x%08x REF_NORMAL\n", ref_offset(ref))); 543 *
392 ref->flash_offset = ref_offset(ref) | REF_NORMAL; 544 * Called when the new fragment that is being inserted
393 } 545 * splits a hole fragment.
394 spin_unlock(&c->erase_completion_lock); 546 */
547static int split_hole(struct jffs2_sb_info *c, struct rb_root *root,
548 struct jffs2_node_frag *newfrag, struct jffs2_node_frag *hole)
549{
550 dbg_fragtree2("fragment %#04x-%#04x splits the hole %#04x-%#04x\n",
551 newfrag->ofs, newfrag->ofs + newfrag->size, hole->ofs, hole->ofs + hole->size);
552
553 if (hole->ofs == newfrag->ofs) {
554 /*
555 * Well, the new fragment actually starts at the same offset as
556 * the hole.
557 */
558 if (hole->ofs + hole->size > newfrag->ofs + newfrag->size) {
559 /*
560 * We replace the overlapped left part of the hole by
561 * the new node.
562 */
563
564 dbg_fragtree2("insert fragment %#04x-%#04x and cut the left part of the hole\n",
565 newfrag->ofs, newfrag->ofs + newfrag->size);
566 rb_replace_node(&hole->rb, &newfrag->rb, root);
567
568 hole->ofs += newfrag->size;
569 hole->size -= newfrag->size;
570
571 /*
572 * We know that 'hole' should be the right hand
573 * fragment.
574 */
575 jffs2_fragtree_insert(hole, newfrag);
576 rb_insert_color(&hole->rb, root);
577 } else {
578 /*
579 * Ah, the new fragment is of the same size as the hole.
580 * Relace the hole by it.
581 */
582 dbg_fragtree2("insert fragment %#04x-%#04x and overwrite hole\n",
583 newfrag->ofs, newfrag->ofs + newfrag->size);
584 rb_replace_node(&hole->rb, &newfrag->rb, root);
585 jffs2_free_node_frag(hole);
586 }
587 } else {
588 /* The new fragment lefts some hole space at the left */
589
590 struct jffs2_node_frag * newfrag2 = NULL;
591
592 if (hole->ofs + hole->size > newfrag->ofs + newfrag->size) {
593 /* The new frag also lefts some space at the right */
594 newfrag2 = new_fragment(NULL, newfrag->ofs +
595 newfrag->size, hole->ofs + hole->size
596 - newfrag->ofs - newfrag->size);
597 if (unlikely(!newfrag2)) {
598 jffs2_free_node_frag(newfrag);
599 return -ENOMEM;
395 } 600 }
601 }
602
603 hole->size = newfrag->ofs - hole->ofs;
604 dbg_fragtree2("left the hole %#04x-%#04x at the left and inserd fragment %#04x-%#04x\n",
605 hole->ofs, hole->ofs + hole->size, newfrag->ofs, newfrag->ofs + newfrag->size);
606
607 jffs2_fragtree_insert(newfrag, hole);
608 rb_insert_color(&newfrag->rb, root);
609
610 if (newfrag2) {
611 dbg_fragtree2("left the hole %#04x-%#04x at the right\n",
612 newfrag2->ofs, newfrag2->ofs + newfrag2->size);
613 jffs2_fragtree_insert(newfrag2, newfrag);
614 rb_insert_color(&newfrag2->rb, root);
615 }
616 }
617
618 return 0;
619}
620
621/*
622 * This function is used when we build inode. It expects the nodes are passed
623 * in the decreasing version order. The whole point of this is to improve the
624 * inodes checking on NAND: we check the nodes' data CRC only when they are not
625 * obsoleted. Previously, add_frag_to_fragtree() function was used and
626 * nodes were passed to it in the increasing version ordes and CRCs of all
627 * nodes were checked.
628 *
629 * Note: tn->fn->size shouldn't be zero.
630 *
631 * Returns 0 if the node was inserted
632 * 1 if it wasn't inserted (since it is obsolete)
633 * < 0 an if error occured
634 */
635int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
636 struct jffs2_tmp_dnode_info *tn)
637{
638 struct jffs2_node_frag *this, *newfrag;
639 uint32_t lastend;
640 struct jffs2_full_dnode *fn = tn->fn;
641 struct rb_root *root = &f->fragtree;
642 uint32_t fn_size = fn->size, fn_ofs = fn->ofs;
643 int err, checked = 0;
644 int ref_flag;
645
646 dbg_fragtree("insert fragment %#04x-%#04x, ver %u\n", fn_ofs, fn_ofs + fn_size, tn->version);
647
648 /* Skip all the nodes which are completed before this one starts */
649 this = jffs2_lookup_node_frag(root, fn_ofs);
650 if (this)
651 dbg_fragtree2("'this' found %#04x-%#04x (%s)\n", this->ofs, this->ofs + this->size, this->node ? "data" : "hole");
652
653 if (this)
654 lastend = this->ofs + this->size;
655 else
656 lastend = 0;
657
658 /* Detect the preliminary type of node */
659 if (fn->size >= PAGE_CACHE_SIZE)
660 ref_flag = REF_PRISTINE;
661 else
662 ref_flag = REF_NORMAL;
663
664 /* See if we ran off the end of the root */
665 if (lastend <= fn_ofs) {
666 /* We did */
667
668 /*
669 * We are going to insert the new node into the
670 * fragment tree, so check it.
671 */
672 err = check_node(c, f, tn);
673 if (err != 0)
674 return err;
675
676 fn->frags = 1;
677
678 newfrag = new_fragment(fn, fn_ofs, fn_size);
679 if (unlikely(!newfrag))
680 return -ENOMEM;
681
682 err = no_overlapping_node(c, root, newfrag, this, lastend);
683 if (unlikely(err != 0)) {
684 jffs2_free_node_frag(newfrag);
685 return err;
686 }
687
688 goto out_ok;
689 }
396 690
397 tn = jffs2_alloc_tmp_dnode_info(); 691 fn->frags = 0;
398 if (!tn) { 692
399 D1(printk(KERN_DEBUG "alloc tn failed\n")); 693 while (1) {
400 err = -ENOMEM; 694 /*
401 goto free_out; 695 * Here we have:
696 * fn_ofs < this->ofs + this->size && fn_ofs >= this->ofs.
697 *
698 * Remember, 'this' has higher version, any non-hole node
699 * which is already in the fragtree is newer then the newly
700 * inserted.
701 */
702 if (!this->node) {
703 /*
704 * 'this' is the hole fragment, so at least the
705 * beginning of the new fragment is valid.
706 */
707
708 /*
709 * We are going to insert the new node into the
710 * fragment tree, so check it.
711 */
712 if (!checked) {
713 err = check_node(c, f, tn);
714 if (unlikely(err != 0))
715 return err;
716 checked = 1;
402 } 717 }
403 718
404 tn->fn = jffs2_alloc_full_dnode(); 719 if (this->ofs + this->size >= fn_ofs + fn_size) {
405 if (!tn->fn) { 720 /* We split the hole on two parts */
406 D1(printk(KERN_DEBUG "alloc fn failed\n")); 721
407 err = -ENOMEM; 722 fn->frags += 1;
408 jffs2_free_tmp_dnode_info(tn); 723 newfrag = new_fragment(fn, fn_ofs, fn_size);
409 goto free_out; 724 if (unlikely(!newfrag))
725 return -ENOMEM;
726
727 err = split_hole(c, root, newfrag, this);
728 if (unlikely(err))
729 return err;
730 goto out_ok;
410 } 731 }
411 tn->version = je32_to_cpu(node.i.version); 732
412 tn->fn->ofs = je32_to_cpu(node.i.offset); 733 /*
413 /* There was a bug where we wrote hole nodes out with 734 * The beginning of the new fragment is valid since it
414 csize/dsize swapped. Deal with it */ 735 * overlaps the hole node.
415 if (node.i.compr == JFFS2_COMPR_ZERO && !je32_to_cpu(node.i.dsize) && je32_to_cpu(node.i.csize)) 736 */
416 tn->fn->size = je32_to_cpu(node.i.csize); 737
417 else // normal case... 738 ref_flag = REF_NORMAL;
418 tn->fn->size = je32_to_cpu(node.i.dsize); 739
419 tn->fn->raw = ref; 740 fn->frags += 1;
420 D1(printk(KERN_DEBUG "dnode @%08x: ver %u, offset %04x, dsize %04x\n", 741 newfrag = new_fragment(fn, fn_ofs,
421 ref_offset(ref), je32_to_cpu(node.i.version), 742 this->ofs + this->size - fn_ofs);
422 je32_to_cpu(node.i.offset), je32_to_cpu(node.i.dsize))); 743 if (unlikely(!newfrag))
423 jffs2_add_tn_to_tree(tn, &ret_tn); 744 return -ENOMEM;
424 break; 745
425 746 if (fn_ofs == this->ofs) {
426 default: 747 /*
427 if (ref_flags(ref) == REF_UNCHECKED) { 748 * The new node starts at the same offset as
428 struct jffs2_eraseblock *jeb; 749 * the hole and supersieds the hole.
429 uint32_t len; 750 */
430 751 dbg_fragtree2("add the new fragment instead of hole %#04x-%#04x, refcnt %d\n",
431 printk(KERN_ERR "Eep. Unknown node type %04x at %08x was marked REF_UNCHECKED\n", 752 fn_ofs, fn_ofs + this->ofs + this->size - fn_ofs, fn->frags);
432 je16_to_cpu(node.u.nodetype), ref_offset(ref)); 753
433 754 rb_replace_node(&this->rb, &newfrag->rb, root);
434 /* Mark the node as having been checked and fix the accounting accordingly */ 755 jffs2_free_node_frag(this);
435 spin_lock(&c->erase_completion_lock); 756 } else {
436 jeb = &c->blocks[ref->flash_offset / c->sector_size]; 757 /*
437 len = ref_totlen(c, jeb, ref); 758 * The hole becomes shorter as its right part
438 759 * is supersieded by the new fragment.
439 jeb->used_size += len; 760 */
440 jeb->unchecked_size -= len; 761 dbg_fragtree2("reduce size of hole %#04x-%#04x to %#04x-%#04x\n",
441 c->used_size += len; 762 this->ofs, this->ofs + this->size, this->ofs, this->ofs + this->size - newfrag->size);
442 c->unchecked_size -= len; 763
443 764 dbg_fragtree2("add new fragment %#04x-%#04x, refcnt %d\n", fn_ofs,
444 mark_ref_normal(ref); 765 fn_ofs + this->ofs + this->size - fn_ofs, fn->frags);
445 spin_unlock(&c->erase_completion_lock); 766
767 this->size -= newfrag->size;
768 jffs2_fragtree_insert(newfrag, this);
769 rb_insert_color(&newfrag->rb, root);
446 } 770 }
447 node.u.nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(node.u.nodetype)); 771
448 if (crc32(0, &node, sizeof(struct jffs2_unknown_node)-4) != je32_to_cpu(node.u.hdr_crc)) { 772 fn_ofs += newfrag->size;
449 /* Hmmm. This should have been caught at scan time. */ 773 fn_size -= newfrag->size;
450 printk(KERN_ERR "Node header CRC failed at %08x. But it must have been OK earlier.\n", 774 this = rb_entry(rb_next(&newfrag->rb),
451 ref_offset(ref)); 775 struct jffs2_node_frag, rb);
452 printk(KERN_ERR "Node was: { %04x, %04x, %08x, %08x }\n", 776
453 je16_to_cpu(node.u.magic), je16_to_cpu(node.u.nodetype), je32_to_cpu(node.u.totlen), 777 dbg_fragtree2("switch to the next 'this' fragment: %#04x-%#04x %s\n",
454 je32_to_cpu(node.u.hdr_crc)); 778 this->ofs, this->ofs + this->size, this->node ? "(data)" : "(hole)");
455 jffs2_mark_node_obsolete(c, ref); 779 }
456 } else switch(je16_to_cpu(node.u.nodetype) & JFFS2_COMPAT_MASK) { 780
457 case JFFS2_FEATURE_INCOMPAT: 781 /*
458 printk(KERN_NOTICE "Unknown INCOMPAT nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref)); 782 * 'This' node is not the hole so it obsoletes the new fragment
459 /* EEP */ 783 * either fully or partially.
460 BUG(); 784 */
461 break; 785 if (this->ofs + this->size >= fn_ofs + fn_size) {
462 case JFFS2_FEATURE_ROCOMPAT: 786 /* The new node is obsolete, drop it */
463 printk(KERN_NOTICE "Unknown ROCOMPAT nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref)); 787 if (fn->frags == 0) {
464 if (!(c->flags & JFFS2_SB_FLAG_RO)) 788 dbg_fragtree2("%#04x-%#04x is obsolete, mark it obsolete\n", fn_ofs, fn_ofs + fn_size);
465 BUG(); 789 ref_flag = REF_OBSOLETE;
466 break;
467 case JFFS2_FEATURE_RWCOMPAT_COPY:
468 printk(KERN_NOTICE "Unknown RWCOMPAT_COPY nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref));
469 break;
470 case JFFS2_FEATURE_RWCOMPAT_DELETE:
471 printk(KERN_NOTICE "Unknown RWCOMPAT_DELETE nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref));
472 jffs2_mark_node_obsolete(c, ref);
473 break;
474 } 790 }
791 goto out_ok;
792 } else {
793 struct jffs2_node_frag *new_this;
794
795 /* 'This' node obsoletes the beginning of the new node */
796 dbg_fragtree2("the beginning %#04x-%#04x is obsolete\n", fn_ofs, this->ofs + this->size);
797
798 ref_flag = REF_NORMAL;
799
800 fn_size -= this->ofs + this->size - fn_ofs;
801 fn_ofs = this->ofs + this->size;
802 dbg_fragtree2("now considering %#04x-%#04x\n", fn_ofs, fn_ofs + fn_size);
803
804 new_this = rb_entry(rb_next(&this->rb), struct jffs2_node_frag, rb);
805 if (!new_this) {
806 /*
807 * There is no next fragment. Add the rest of
808 * the new node as the right-hand child.
809 */
810 if (!checked) {
811 err = check_node(c, f, tn);
812 if (unlikely(err != 0))
813 return err;
814 checked = 1;
815 }
475 816
817 fn->frags += 1;
818 newfrag = new_fragment(fn, fn_ofs, fn_size);
819 if (unlikely(!newfrag))
820 return -ENOMEM;
821
822 dbg_fragtree2("there are no more fragments, insert %#04x-%#04x\n",
823 newfrag->ofs, newfrag->ofs + newfrag->size);
824 rb_link_node(&newfrag->rb, &this->rb, &this->rb.rb_right);
825 rb_insert_color(&newfrag->rb, root);
826 goto out_ok;
827 } else {
828 this = new_this;
829 dbg_fragtree2("switch to the next 'this' fragment: %#04x-%#04x %s\n",
830 this->ofs, this->ofs + this->size, this->node ? "(data)" : "(hole)");
831 }
476 } 832 }
477 spin_lock(&c->erase_completion_lock); 833 }
834
835out_ok:
836 BUG_ON(fn->size < PAGE_CACHE_SIZE && ref_flag == REF_PRISTINE);
478 837
838 if (ref_flag == REF_OBSOLETE) {
839 dbg_fragtree2("the node is obsolete now\n");
840 /* jffs2_mark_node_obsolete() will adjust space accounting */
841 jffs2_mark_node_obsolete(c, fn->raw);
842 return 1;
479 } 843 }
844
845 dbg_fragtree2("the node is \"%s\" now\n", ref_flag == REF_NORMAL ? "REF_NORMAL" : "REF_PRISTINE");
846
847 /* Space accounting was adjusted at check_node_data() */
848 spin_lock(&c->erase_completion_lock);
849 fn->raw->flash_offset = ref_offset(fn->raw) | ref_flag;
480 spin_unlock(&c->erase_completion_lock); 850 spin_unlock(&c->erase_completion_lock);
481 *tnp = ret_tn;
482 *fdp = ret_fd;
483 851
484 return 0; 852 return 0;
485
486 free_out:
487 jffs2_free_tmp_dnode_info_list(&ret_tn);
488 jffs2_free_full_dirent_list(ret_fd);
489 return err;
490} 853}
491 854
492void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, int state) 855void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, int state)
@@ -499,24 +862,21 @@ void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache
499 862
500/* During mount, this needs no locking. During normal operation, its 863/* During mount, this needs no locking. During normal operation, its
501 callers want to do other stuff while still holding the inocache_lock. 864 callers want to do other stuff while still holding the inocache_lock.
502 Rather than introducing special case get_ino_cache functions or 865 Rather than introducing special case get_ino_cache functions or
503 callbacks, we just let the caller do the locking itself. */ 866 callbacks, we just let the caller do the locking itself. */
504 867
505struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, uint32_t ino) 868struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, uint32_t ino)
506{ 869{
507 struct jffs2_inode_cache *ret; 870 struct jffs2_inode_cache *ret;
508 871
509 D2(printk(KERN_DEBUG "jffs2_get_ino_cache(): ino %u\n", ino));
510
511 ret = c->inocache_list[ino % INOCACHE_HASHSIZE]; 872 ret = c->inocache_list[ino % INOCACHE_HASHSIZE];
512 while (ret && ret->ino < ino) { 873 while (ret && ret->ino < ino) {
513 ret = ret->next; 874 ret = ret->next;
514 } 875 }
515 876
516 if (ret && ret->ino != ino) 877 if (ret && ret->ino != ino)
517 ret = NULL; 878 ret = NULL;
518 879
519 D2(printk(KERN_DEBUG "jffs2_get_ino_cache found %p for ino %u\n", ret, ino));
520 return ret; 880 return ret;
521} 881}
522 882
@@ -528,7 +888,7 @@ void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new
528 if (!new->ino) 888 if (!new->ino)
529 new->ino = ++c->highest_ino; 889 new->ino = ++c->highest_ino;
530 890
531 D2(printk(KERN_DEBUG "jffs2_add_ino_cache: Add %p (ino #%u)\n", new, new->ino)); 891 dbg_inocache("add %p (ino #%u)\n", new, new->ino);
532 892
533 prev = &c->inocache_list[new->ino % INOCACHE_HASHSIZE]; 893 prev = &c->inocache_list[new->ino % INOCACHE_HASHSIZE];
534 894
@@ -544,11 +904,12 @@ void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new
544void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old) 904void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old)
545{ 905{
546 struct jffs2_inode_cache **prev; 906 struct jffs2_inode_cache **prev;
547 D1(printk(KERN_DEBUG "jffs2_del_ino_cache: Del %p (ino #%u)\n", old, old->ino)); 907
908 dbg_inocache("del %p (ino #%u)\n", old, old->ino);
548 spin_lock(&c->inocache_lock); 909 spin_lock(&c->inocache_lock);
549 910
550 prev = &c->inocache_list[old->ino % INOCACHE_HASHSIZE]; 911 prev = &c->inocache_list[old->ino % INOCACHE_HASHSIZE];
551 912
552 while ((*prev) && (*prev)->ino < old->ino) { 913 while ((*prev) && (*prev)->ino < old->ino) {
553 prev = &(*prev)->next; 914 prev = &(*prev)->next;
554 } 915 }
@@ -558,7 +919,7 @@ void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old)
558 919
559 /* Free it now unless it's in READING or CLEARING state, which 920 /* Free it now unless it's in READING or CLEARING state, which
560 are the transitions upon read_inode() and clear_inode(). The 921 are the transitions upon read_inode() and clear_inode(). The
561 rest of the time we know nobody else is looking at it, and 922 rest of the time we know nobody else is looking at it, and
562 if it's held by read_inode() or clear_inode() they'll free it 923 if it's held by read_inode() or clear_inode() they'll free it
563 for themselves. */ 924 for themselves. */
564 if (old->state != INO_STATE_READING && old->state != INO_STATE_CLEARING) 925 if (old->state != INO_STATE_READING && old->state != INO_STATE_CLEARING)
@@ -571,7 +932,7 @@ void jffs2_free_ino_caches(struct jffs2_sb_info *c)
571{ 932{
572 int i; 933 int i;
573 struct jffs2_inode_cache *this, *next; 934 struct jffs2_inode_cache *this, *next;
574 935
575 for (i=0; i<INOCACHE_HASHSIZE; i++) { 936 for (i=0; i<INOCACHE_HASHSIZE; i++) {
576 this = c->inocache_list[i]; 937 this = c->inocache_list[i];
577 while (this) { 938 while (this) {
@@ -598,38 +959,30 @@ void jffs2_free_raw_node_refs(struct jffs2_sb_info *c)
598 c->blocks[i].first_node = c->blocks[i].last_node = NULL; 959 c->blocks[i].first_node = c->blocks[i].last_node = NULL;
599 } 960 }
600} 961}
601 962
602struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_t offset) 963struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_t offset)
603{ 964{
604 /* The common case in lookup is that there will be a node 965 /* The common case in lookup is that there will be a node
605 which precisely matches. So we go looking for that first */ 966 which precisely matches. So we go looking for that first */
606 struct rb_node *next; 967 struct rb_node *next;
607 struct jffs2_node_frag *prev = NULL; 968 struct jffs2_node_frag *prev = NULL;
608 struct jffs2_node_frag *frag = NULL; 969 struct jffs2_node_frag *frag = NULL;
609 970
610 D2(printk(KERN_DEBUG "jffs2_lookup_node_frag(%p, %d)\n", fragtree, offset)); 971 dbg_fragtree2("root %p, offset %d\n", fragtree, offset);
611 972
612 next = fragtree->rb_node; 973 next = fragtree->rb_node;
613 974
614 while(next) { 975 while(next) {
615 frag = rb_entry(next, struct jffs2_node_frag, rb); 976 frag = rb_entry(next, struct jffs2_node_frag, rb);
616 977
617 D2(printk(KERN_DEBUG "Considering frag %d-%d (%p). left %p, right %p\n",
618 frag->ofs, frag->ofs+frag->size, frag, frag->rb.rb_left, frag->rb.rb_right));
619 if (frag->ofs + frag->size <= offset) { 978 if (frag->ofs + frag->size <= offset) {
620 D2(printk(KERN_DEBUG "Going right from frag %d-%d, before the region we care about\n",
621 frag->ofs, frag->ofs+frag->size));
622 /* Remember the closest smaller match on the way down */ 979 /* Remember the closest smaller match on the way down */
623 if (!prev || frag->ofs > prev->ofs) 980 if (!prev || frag->ofs > prev->ofs)
624 prev = frag; 981 prev = frag;
625 next = frag->rb.rb_right; 982 next = frag->rb.rb_right;
626 } else if (frag->ofs > offset) { 983 } else if (frag->ofs > offset) {
627 D2(printk(KERN_DEBUG "Going left from frag %d-%d, after the region we care about\n",
628 frag->ofs, frag->ofs+frag->size));
629 next = frag->rb.rb_left; 984 next = frag->rb.rb_left;
630 } else { 985 } else {
631 D2(printk(KERN_DEBUG "Returning frag %d,%d, matched\n",
632 frag->ofs, frag->ofs+frag->size));
633 return frag; 986 return frag;
634 } 987 }
635 } 988 }
@@ -638,11 +991,11 @@ struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_
638 and return the closest smaller one */ 991 and return the closest smaller one */
639 992
640 if (prev) 993 if (prev)
641 D2(printk(KERN_DEBUG "No match. Returning frag %d,%d, closest previous\n", 994 dbg_fragtree2("no match. Returning frag %#04x-%#04x, closest previous\n",
642 prev->ofs, prev->ofs+prev->size)); 995 prev->ofs, prev->ofs+prev->size);
643 else 996 else
644 D2(printk(KERN_DEBUG "Returning NULL, empty fragtree\n")); 997 dbg_fragtree2("returning NULL, empty fragtree\n");
645 998
646 return prev; 999 return prev;
647} 1000}
648 1001
@@ -656,39 +1009,32 @@ void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c)
656 if (!root->rb_node) 1009 if (!root->rb_node)
657 return; 1010 return;
658 1011
659 frag = (rb_entry(root->rb_node, struct jffs2_node_frag, rb)); 1012 dbg_fragtree("killing\n");
660 1013
1014 frag = (rb_entry(root->rb_node, struct jffs2_node_frag, rb));
661 while(frag) { 1015 while(frag) {
662 if (frag->rb.rb_left) { 1016 if (frag->rb.rb_left) {
663 D2(printk(KERN_DEBUG "Going left from frag (%p) %d-%d\n",
664 frag, frag->ofs, frag->ofs+frag->size));
665 frag = frag_left(frag); 1017 frag = frag_left(frag);
666 continue; 1018 continue;
667 } 1019 }
668 if (frag->rb.rb_right) { 1020 if (frag->rb.rb_right) {
669 D2(printk(KERN_DEBUG "Going right from frag (%p) %d-%d\n",
670 frag, frag->ofs, frag->ofs+frag->size));
671 frag = frag_right(frag); 1021 frag = frag_right(frag);
672 continue; 1022 continue;
673 } 1023 }
674 1024
675 D2(printk(KERN_DEBUG "jffs2_kill_fragtree: frag at 0x%x-0x%x: node %p, frags %d--\n",
676 frag->ofs, frag->ofs+frag->size, frag->node,
677 frag->node?frag->node->frags:0));
678
679 if (frag->node && !(--frag->node->frags)) { 1025 if (frag->node && !(--frag->node->frags)) {
680 /* Not a hole, and it's the final remaining frag 1026 /* Not a hole, and it's the final remaining frag
681 of this node. Free the node */ 1027 of this node. Free the node */
682 if (c) 1028 if (c)
683 jffs2_mark_node_obsolete(c, frag->node->raw); 1029 jffs2_mark_node_obsolete(c, frag->node->raw);
684 1030
685 jffs2_free_full_dnode(frag->node); 1031 jffs2_free_full_dnode(frag->node);
686 } 1032 }
687 parent = frag_parent(frag); 1033 parent = frag_parent(frag);
688 if (parent) { 1034 if (parent) {
689 if (frag_left(parent) == frag) 1035 if (frag_left(parent) == frag)
690 parent->rb.rb_left = NULL; 1036 parent->rb.rb_left = NULL;
691 else 1037 else
692 parent->rb.rb_right = NULL; 1038 parent->rb.rb_right = NULL;
693 } 1039 }
694 1040
@@ -698,29 +1044,3 @@ void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c)
698 cond_resched(); 1044 cond_resched();
699 } 1045 }
700} 1046}
701
702void jffs2_fragtree_insert(struct jffs2_node_frag *newfrag, struct jffs2_node_frag *base)
703{
704 struct rb_node *parent = &base->rb;
705 struct rb_node **link = &parent;
706
707 D2(printk(KERN_DEBUG "jffs2_fragtree_insert(%p; %d-%d, %p)\n", newfrag,
708 newfrag->ofs, newfrag->ofs+newfrag->size, base));
709
710 while (*link) {
711 parent = *link;
712 base = rb_entry(parent, struct jffs2_node_frag, rb);
713
714 D2(printk(KERN_DEBUG "fragtree_insert considering frag at 0x%x\n", base->ofs));
715 if (newfrag->ofs > base->ofs)
716 link = &base->rb.rb_right;
717 else if (newfrag->ofs < base->ofs)
718 link = &base->rb.rb_left;
719 else {
720 printk(KERN_CRIT "Duplicate frag at %08x (%p,%p)\n", newfrag->ofs, newfrag, base);
721 BUG();
722 }
723 }
724
725 rb_link_node(&newfrag->rb, &base->rb, link);
726}
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h
index b34c397909ef..23a67bb3052f 100644
--- a/fs/jffs2/nodelist.h
+++ b/fs/jffs2/nodelist.h
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: nodelist.h,v 1.131 2005/07/05 21:03:07 dwmw2 Exp $ 10 * $Id: nodelist.h,v 1.140 2005/09/07 08:34:54 havasi Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -20,30 +20,15 @@
20#include <linux/jffs2.h> 20#include <linux/jffs2.h>
21#include <linux/jffs2_fs_sb.h> 21#include <linux/jffs2_fs_sb.h>
22#include <linux/jffs2_fs_i.h> 22#include <linux/jffs2_fs_i.h>
23#include "summary.h"
23 24
24#ifdef __ECOS 25#ifdef __ECOS
25#include "os-ecos.h" 26#include "os-ecos.h"
26#else 27#else
27#include <linux/mtd/compatmac.h> /* For min/max in older kernels */ 28#include <linux/mtd/compatmac.h> /* For compatibility with older kernels */
28#include "os-linux.h" 29#include "os-linux.h"
29#endif 30#endif
30 31
31#ifndef CONFIG_JFFS2_FS_DEBUG
32#define CONFIG_JFFS2_FS_DEBUG 1
33#endif
34
35#if CONFIG_JFFS2_FS_DEBUG > 0
36#define D1(x) x
37#else
38#define D1(x)
39#endif
40
41#if CONFIG_JFFS2_FS_DEBUG > 1
42#define D2(x) x
43#else
44#define D2(x)
45#endif
46
47#define JFFS2_NATIVE_ENDIAN 32#define JFFS2_NATIVE_ENDIAN
48 33
49/* Note we handle mode bits conversion from JFFS2 (i.e. Linux) to/from 34/* Note we handle mode bits conversion from JFFS2 (i.e. Linux) to/from
@@ -73,14 +58,17 @@
73#define je16_to_cpu(x) (le16_to_cpu(x.v16)) 58#define je16_to_cpu(x) (le16_to_cpu(x.v16))
74#define je32_to_cpu(x) (le32_to_cpu(x.v32)) 59#define je32_to_cpu(x) (le32_to_cpu(x.v32))
75#define jemode_to_cpu(x) (le32_to_cpu(jffs2_to_os_mode((x).m))) 60#define jemode_to_cpu(x) (le32_to_cpu(jffs2_to_os_mode((x).m)))
76#else 61#else
77#error wibble 62#error wibble
78#endif 63#endif
79 64
65/* The minimal node header size */
66#define JFFS2_MIN_NODE_HEADER sizeof(struct jffs2_raw_dirent)
67
80/* 68/*
81 This is all we need to keep in-core for each raw node during normal 69 This is all we need to keep in-core for each raw node during normal
82 operation. As and when we do read_inode on a particular inode, we can 70 operation. As and when we do read_inode on a particular inode, we can
83 scan the nodes which are listed for it and build up a proper map of 71 scan the nodes which are listed for it and build up a proper map of
84 which nodes are currently valid. JFFSv1 always used to keep that whole 72 which nodes are currently valid. JFFSv1 always used to keep that whole
85 map in core for each inode. 73 map in core for each inode.
86*/ 74*/
@@ -97,7 +85,7 @@ struct jffs2_raw_node_ref
97 85
98 /* flash_offset & 3 always has to be zero, because nodes are 86 /* flash_offset & 3 always has to be zero, because nodes are
99 always aligned at 4 bytes. So we have a couple of extra bits 87 always aligned at 4 bytes. So we have a couple of extra bits
100 to play with, which indicate the node's status; see below: */ 88 to play with, which indicate the node's status; see below: */
101#define REF_UNCHECKED 0 /* We haven't yet checked the CRC or built its inode */ 89#define REF_UNCHECKED 0 /* We haven't yet checked the CRC or built its inode */
102#define REF_OBSOLETE 1 /* Obsolete, can be completely ignored */ 90#define REF_OBSOLETE 1 /* Obsolete, can be completely ignored */
103#define REF_PRISTINE 2 /* Completely clean. GC without looking */ 91#define REF_PRISTINE 2 /* Completely clean. GC without looking */
@@ -110,7 +98,7 @@ struct jffs2_raw_node_ref
110/* For each inode in the filesystem, we need to keep a record of 98/* For each inode in the filesystem, we need to keep a record of
111 nlink, because it would be a PITA to scan the whole directory tree 99 nlink, because it would be a PITA to scan the whole directory tree
112 at read_inode() time to calculate it, and to keep sufficient information 100 at read_inode() time to calculate it, and to keep sufficient information
113 in the raw_node_ref (basically both parent and child inode number for 101 in the raw_node_ref (basically both parent and child inode number for
114 dirent nodes) would take more space than this does. We also keep 102 dirent nodes) would take more space than this does. We also keep
115 a pointer to the first physical node which is part of this inode, too. 103 a pointer to the first physical node which is part of this inode, too.
116*/ 104*/
@@ -140,7 +128,7 @@ struct jffs2_inode_cache {
140#define INOCACHE_HASHSIZE 128 128#define INOCACHE_HASHSIZE 128
141 129
142/* 130/*
143 Larger representation of a raw node, kept in-core only when the 131 Larger representation of a raw node, kept in-core only when the
144 struct inode for this particular ino is instantiated. 132 struct inode for this particular ino is instantiated.
145*/ 133*/
146 134
@@ -150,11 +138,11 @@ struct jffs2_full_dnode
150 uint32_t ofs; /* The offset to which the data of this node belongs */ 138 uint32_t ofs; /* The offset to which the data of this node belongs */
151 uint32_t size; 139 uint32_t size;
152 uint32_t frags; /* Number of fragments which currently refer 140 uint32_t frags; /* Number of fragments which currently refer
153 to this node. When this reaches zero, 141 to this node. When this reaches zero,
154 the node is obsolete. */ 142 the node is obsolete. */
155}; 143};
156 144
157/* 145/*
158 Even larger representation of a raw node, kept in-core only while 146 Even larger representation of a raw node, kept in-core only while
159 we're actually building up the original map of which nodes go where, 147 we're actually building up the original map of which nodes go where,
160 in read_inode() 148 in read_inode()
@@ -164,7 +152,10 @@ struct jffs2_tmp_dnode_info
164 struct rb_node rb; 152 struct rb_node rb;
165 struct jffs2_full_dnode *fn; 153 struct jffs2_full_dnode *fn;
166 uint32_t version; 154 uint32_t version;
167}; 155 uint32_t data_crc;
156 uint32_t partial_crc;
157 uint32_t csize;
158};
168 159
169struct jffs2_full_dirent 160struct jffs2_full_dirent
170{ 161{
@@ -178,7 +169,7 @@ struct jffs2_full_dirent
178}; 169};
179 170
180/* 171/*
181 Fragments - used to build a map of which raw node to obtain 172 Fragments - used to build a map of which raw node to obtain
182 data from for each part of the ino 173 data from for each part of the ino
183*/ 174*/
184struct jffs2_node_frag 175struct jffs2_node_frag
@@ -207,86 +198,18 @@ struct jffs2_eraseblock
207 struct jffs2_raw_node_ref *gc_node; /* Next node to be garbage collected */ 198 struct jffs2_raw_node_ref *gc_node; /* Next node to be garbage collected */
208}; 199};
209 200
210#define ACCT_SANITY_CHECK(c, jeb) do { \ 201static inline int jffs2_blocks_use_vmalloc(struct jffs2_sb_info *c)
211 struct jffs2_eraseblock *___j = jeb; \
212 if ((___j) && ___j->used_size + ___j->dirty_size + ___j->free_size + ___j->wasted_size + ___j->unchecked_size != c->sector_size) { \
213 printk(KERN_NOTICE "Eeep. Space accounting for block at 0x%08x is screwed\n", ___j->offset); \
214 printk(KERN_NOTICE "free 0x%08x + dirty 0x%08x + used %08x + wasted %08x + unchecked %08x != total %08x\n", \
215 ___j->free_size, ___j->dirty_size, ___j->used_size, ___j->wasted_size, ___j->unchecked_size, c->sector_size); \
216 BUG(); \
217 } \
218 if (c->used_size + c->dirty_size + c->free_size + c->erasing_size + c->bad_size + c->wasted_size + c->unchecked_size != c->flash_size) { \
219 printk(KERN_NOTICE "Eeep. Space accounting superblock info is screwed\n"); \
220 printk(KERN_NOTICE "free 0x%08x + dirty 0x%08x + used %08x + erasing %08x + bad %08x + wasted %08x + unchecked %08x != total %08x\n", \
221 c->free_size, c->dirty_size, c->used_size, c->erasing_size, c->bad_size, c->wasted_size, c->unchecked_size, c->flash_size); \
222 BUG(); \
223 } \
224} while(0)
225
226static inline void paranoia_failed_dump(struct jffs2_eraseblock *jeb)
227{ 202{
228 struct jffs2_raw_node_ref *ref; 203 return ((c->flash_size / c->sector_size) * sizeof (struct jffs2_eraseblock)) > (128 * 1024);
229 int i=0;
230
231 printk(KERN_NOTICE);
232 for (ref = jeb->first_node; ref; ref = ref->next_phys) {
233 printk("%08x->", ref_offset(ref));
234 if (++i == 8) {
235 i = 0;
236 printk("\n" KERN_NOTICE);
237 }
238 }
239 printk("\n");
240} 204}
241 205
242
243#define ACCT_PARANOIA_CHECK(jeb) do { \
244 uint32_t my_used_size = 0; \
245 uint32_t my_unchecked_size = 0; \
246 struct jffs2_raw_node_ref *ref2 = jeb->first_node; \
247 while (ref2) { \
248 if (unlikely(ref2->flash_offset < jeb->offset || \
249 ref2->flash_offset > jeb->offset + c->sector_size)) { \
250 printk(KERN_NOTICE "Node %08x shouldn't be in block at %08x!\n", \
251 ref_offset(ref2), jeb->offset); \
252 paranoia_failed_dump(jeb); \
253 BUG(); \
254 } \
255 if (ref_flags(ref2) == REF_UNCHECKED) \
256 my_unchecked_size += ref_totlen(c, jeb, ref2); \
257 else if (!ref_obsolete(ref2)) \
258 my_used_size += ref_totlen(c, jeb, ref2); \
259 if (unlikely((!ref2->next_phys) != (ref2 == jeb->last_node))) { \
260 if (!ref2->next_phys) \
261 printk("ref for node at %p (phys %08x) has next_phys->%p (----), last_node->%p (phys %08x)\n", \
262 ref2, ref_offset(ref2), ref2->next_phys, \
263 jeb->last_node, ref_offset(jeb->last_node)); \
264 else \
265 printk("ref for node at %p (phys %08x) has next_phys->%p (%08x), last_node->%p (phys %08x)\n", \
266 ref2, ref_offset(ref2), ref2->next_phys, ref_offset(ref2->next_phys), \
267 jeb->last_node, ref_offset(jeb->last_node)); \
268 paranoia_failed_dump(jeb); \
269 BUG(); \
270 } \
271 ref2 = ref2->next_phys; \
272 } \
273 if (my_used_size != jeb->used_size) { \
274 printk(KERN_NOTICE "Calculated used size %08x != stored used size %08x\n", my_used_size, jeb->used_size); \
275 BUG(); \
276 } \
277 if (my_unchecked_size != jeb->unchecked_size) { \
278 printk(KERN_NOTICE "Calculated unchecked size %08x != stored unchecked size %08x\n", my_unchecked_size, jeb->unchecked_size); \
279 BUG(); \
280 } \
281 } while(0)
282
283/* Calculate totlen from surrounding nodes or eraseblock */ 206/* Calculate totlen from surrounding nodes or eraseblock */
284static inline uint32_t __ref_totlen(struct jffs2_sb_info *c, 207static inline uint32_t __ref_totlen(struct jffs2_sb_info *c,
285 struct jffs2_eraseblock *jeb, 208 struct jffs2_eraseblock *jeb,
286 struct jffs2_raw_node_ref *ref) 209 struct jffs2_raw_node_ref *ref)
287{ 210{
288 uint32_t ref_end; 211 uint32_t ref_end;
289 212
290 if (ref->next_phys) 213 if (ref->next_phys)
291 ref_end = ref_offset(ref->next_phys); 214 ref_end = ref_offset(ref->next_phys);
292 else { 215 else {
@@ -306,11 +229,13 @@ static inline uint32_t ref_totlen(struct jffs2_sb_info *c,
306{ 229{
307 uint32_t ret; 230 uint32_t ret;
308 231
309 D1(if (jeb && jeb != &c->blocks[ref->flash_offset / c->sector_size]) { 232#if CONFIG_JFFS2_FS_DEBUG > 0
233 if (jeb && jeb != &c->blocks[ref->flash_offset / c->sector_size]) {
310 printk(KERN_CRIT "ref_totlen called with wrong block -- at 0x%08x instead of 0x%08x; ref 0x%08x\n", 234 printk(KERN_CRIT "ref_totlen called with wrong block -- at 0x%08x instead of 0x%08x; ref 0x%08x\n",
311 jeb->offset, c->blocks[ref->flash_offset / c->sector_size].offset, ref_offset(ref)); 235 jeb->offset, c->blocks[ref->flash_offset / c->sector_size].offset, ref_offset(ref));
312 BUG(); 236 BUG();
313 }) 237 }
238#endif
314 239
315#if 1 240#if 1
316 ret = ref->__totlen; 241 ret = ref->__totlen;
@@ -323,14 +248,13 @@ static inline uint32_t ref_totlen(struct jffs2_sb_info *c,
323 ret, ref->__totlen); 248 ret, ref->__totlen);
324 if (!jeb) 249 if (!jeb)
325 jeb = &c->blocks[ref->flash_offset / c->sector_size]; 250 jeb = &c->blocks[ref->flash_offset / c->sector_size];
326 paranoia_failed_dump(jeb); 251 jffs2_dbg_dump_node_refs_nolock(c, jeb);
327 BUG(); 252 BUG();
328 } 253 }
329#endif 254#endif
330 return ret; 255 return ret;
331} 256}
332 257
333
334#define ALLOC_NORMAL 0 /* Normal allocation */ 258#define ALLOC_NORMAL 0 /* Normal allocation */
335#define ALLOC_DELETION 1 /* Deletion node. Best to allow it */ 259#define ALLOC_DELETION 1 /* Deletion node. Best to allow it */
336#define ALLOC_GC 2 /* Space requested for GC. Give it or die */ 260#define ALLOC_GC 2 /* Space requested for GC. Give it or die */
@@ -340,7 +264,7 @@ static inline uint32_t ref_totlen(struct jffs2_sb_info *c,
340#define VERYDIRTY(c, size) ((size) >= ((c)->sector_size / 2)) 264#define VERYDIRTY(c, size) ((size) >= ((c)->sector_size / 2))
341 265
342/* check if dirty space is more than 255 Byte */ 266/* check if dirty space is more than 255 Byte */
343#define ISDIRTY(size) ((size) > sizeof (struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN) 267#define ISDIRTY(size) ((size) > sizeof (struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN)
344 268
345#define PAD(x) (((x)+3)&~3) 269#define PAD(x) (((x)+3)&~3)
346 270
@@ -384,12 +308,7 @@ static inline struct jffs2_node_frag *frag_last(struct rb_root *root)
384#define frag_erase(frag, list) rb_erase(&frag->rb, list); 308#define frag_erase(frag, list) rb_erase(&frag->rb, list);
385 309
386/* nodelist.c */ 310/* nodelist.c */
387D2(void jffs2_print_frag_list(struct jffs2_inode_info *f));
388void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list); 311void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list);
389int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
390 struct rb_root *tnp, struct jffs2_full_dirent **fdp,
391 uint32_t *highest_version, uint32_t *latest_mctime,
392 uint32_t *mctime_ver);
393void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, int state); 312void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, int state);
394struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, uint32_t ino); 313struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, uint32_t ino);
395void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new); 314void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new);
@@ -398,19 +317,23 @@ void jffs2_free_ino_caches(struct jffs2_sb_info *c);
398void jffs2_free_raw_node_refs(struct jffs2_sb_info *c); 317void jffs2_free_raw_node_refs(struct jffs2_sb_info *c);
399struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_t offset); 318struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_t offset);
400void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c_delete); 319void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c_delete);
401void jffs2_fragtree_insert(struct jffs2_node_frag *newfrag, struct jffs2_node_frag *base);
402struct rb_node *rb_next(struct rb_node *); 320struct rb_node *rb_next(struct rb_node *);
403struct rb_node *rb_prev(struct rb_node *); 321struct rb_node *rb_prev(struct rb_node *);
404void rb_replace_node(struct rb_node *victim, struct rb_node *new, struct rb_root *root); 322void rb_replace_node(struct rb_node *victim, struct rb_node *new, struct rb_root *root);
323void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *this);
324int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn);
325void jffs2_truncate_fragtree (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size);
326int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_tmp_dnode_info *tn);
405 327
406/* nodemgmt.c */ 328/* nodemgmt.c */
407int jffs2_thread_should_wake(struct jffs2_sb_info *c); 329int jffs2_thread_should_wake(struct jffs2_sb_info *c);
408int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, int prio); 330int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs,
409int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len); 331 uint32_t *len, int prio, uint32_t sumsize);
332int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs,
333 uint32_t *len, uint32_t sumsize);
410int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new); 334int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new);
411void jffs2_complete_reservation(struct jffs2_sb_info *c); 335void jffs2_complete_reservation(struct jffs2_sb_info *c);
412void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *raw); 336void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *raw);
413void jffs2_dump_block_lists(struct jffs2_sb_info *c);
414 337
415/* write.c */ 338/* write.c */
416int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint32_t mode, struct jffs2_raw_inode *ri); 339int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint32_t mode, struct jffs2_raw_inode *ri);
@@ -418,17 +341,15 @@ int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint
418struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const unsigned char *data, uint32_t datalen, uint32_t flash_ofs, int alloc_mode); 341struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const unsigned char *data, uint32_t datalen, uint32_t flash_ofs, int alloc_mode);
419struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_dirent *rd, const unsigned char *name, uint32_t namelen, uint32_t flash_ofs, int alloc_mode); 342struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_dirent *rd, const unsigned char *name, uint32_t namelen, uint32_t flash_ofs, int alloc_mode);
420int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 343int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
421 struct jffs2_raw_inode *ri, unsigned char *buf, 344 struct jffs2_raw_inode *ri, unsigned char *buf,
422 uint32_t offset, uint32_t writelen, uint32_t *retlen); 345 uint32_t offset, uint32_t writelen, uint32_t *retlen);
423int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const char *name, int namelen); 346int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const char *name, int namelen);
424int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, const char *name, int namelen, struct jffs2_inode_info *dead_f); 347int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, const char *name, int namelen, struct jffs2_inode_info *dead_f, uint32_t time);
425int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, uint8_t type, const char *name, int namelen); 348int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, uint8_t type, const char *name, int namelen, uint32_t time);
426 349
427 350
428/* readinode.c */ 351/* readinode.c */
429void jffs2_truncate_fraglist (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size); 352int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
430int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn);
431int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
432 uint32_t ino, struct jffs2_raw_inode *latest_node); 353 uint32_t ino, struct jffs2_raw_inode *latest_node);
433int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic); 354int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic);
434void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f); 355void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f);
@@ -468,6 +389,10 @@ char *jffs2_getlink(struct jffs2_sb_info *c, struct jffs2_inode_info *f);
468/* scan.c */ 389/* scan.c */
469int jffs2_scan_medium(struct jffs2_sb_info *c); 390int jffs2_scan_medium(struct jffs2_sb_info *c);
470void jffs2_rotate_lists(struct jffs2_sb_info *c); 391void jffs2_rotate_lists(struct jffs2_sb_info *c);
392int jffs2_fill_scan_buf(struct jffs2_sb_info *c, void *buf,
393 uint32_t ofs, uint32_t len);
394struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino);
395int jffs2_scan_classify_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
471 396
472/* build.c */ 397/* build.c */
473int jffs2_do_mount_fs(struct jffs2_sb_info *c); 398int jffs2_do_mount_fs(struct jffs2_sb_info *c);
@@ -483,4 +408,6 @@ int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_erasebloc
483int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); 408int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
484#endif 409#endif
485 410
411#include "debug.h"
412
486#endif /* __JFFS2_NODELIST_H__ */ 413#endif /* __JFFS2_NODELIST_H__ */
diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c
index c1d8b5ed9ab9..49127a1f0458 100644
--- a/fs/jffs2/nodemgmt.c
+++ b/fs/jffs2/nodemgmt.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: nodemgmt.c,v 1.122 2005/05/06 09:30:27 dedekind Exp $ 10 * $Id: nodemgmt.c,v 1.127 2005/09/20 15:49:12 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -17,6 +17,7 @@
17#include <linux/compiler.h> 17#include <linux/compiler.h>
18#include <linux/sched.h> /* For cond_resched() */ 18#include <linux/sched.h> /* For cond_resched() */
19#include "nodelist.h" 19#include "nodelist.h"
20#include "debug.h"
20 21
21/** 22/**
22 * jffs2_reserve_space - request physical space to write nodes to flash 23 * jffs2_reserve_space - request physical space to write nodes to flash
@@ -38,9 +39,11 @@
38 * for the requested allocation. 39 * for the requested allocation.
39 */ 40 */
40 41
41static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len); 42static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize,
43 uint32_t *ofs, uint32_t *len, uint32_t sumsize);
42 44
43int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, int prio) 45int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs,
46 uint32_t *len, int prio, uint32_t sumsize)
44{ 47{
45 int ret = -EAGAIN; 48 int ret = -EAGAIN;
46 int blocksneeded = c->resv_blocks_write; 49 int blocksneeded = c->resv_blocks_write;
@@ -85,12 +88,12 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs
85 up(&c->alloc_sem); 88 up(&c->alloc_sem);
86 return -ENOSPC; 89 return -ENOSPC;
87 } 90 }
88 91
89 /* Calc possibly available space. Possibly available means that we 92 /* Calc possibly available space. Possibly available means that we
90 * don't know, if unchecked size contains obsoleted nodes, which could give us some 93 * don't know, if unchecked size contains obsoleted nodes, which could give us some
91 * more usable space. This will affect the sum only once, as gc first finishes checking 94 * more usable space. This will affect the sum only once, as gc first finishes checking
92 * of nodes. 95 * of nodes.
93 + Return -ENOSPC, if the maximum possibly available space is less or equal than 96 + Return -ENOSPC, if the maximum possibly available space is less or equal than
94 * blocksneeded * sector_size. 97 * blocksneeded * sector_size.
95 * This blocks endless gc looping on a filesystem, which is nearly full, even if 98 * This blocks endless gc looping on a filesystem, which is nearly full, even if
96 * the check above passes. 99 * the check above passes.
@@ -115,7 +118,7 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs
115 c->nr_free_blocks, c->nr_erasing_blocks, c->free_size, c->dirty_size, c->wasted_size, c->used_size, c->erasing_size, c->bad_size, 118 c->nr_free_blocks, c->nr_erasing_blocks, c->free_size, c->dirty_size, c->wasted_size, c->used_size, c->erasing_size, c->bad_size,
116 c->free_size + c->dirty_size + c->wasted_size + c->used_size + c->erasing_size + c->bad_size, c->flash_size)); 119 c->free_size + c->dirty_size + c->wasted_size + c->used_size + c->erasing_size + c->bad_size, c->flash_size));
117 spin_unlock(&c->erase_completion_lock); 120 spin_unlock(&c->erase_completion_lock);
118 121
119 ret = jffs2_garbage_collect_pass(c); 122 ret = jffs2_garbage_collect_pass(c);
120 if (ret) 123 if (ret)
121 return ret; 124 return ret;
@@ -129,7 +132,7 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs
129 spin_lock(&c->erase_completion_lock); 132 spin_lock(&c->erase_completion_lock);
130 } 133 }
131 134
132 ret = jffs2_do_reserve_space(c, minsize, ofs, len); 135 ret = jffs2_do_reserve_space(c, minsize, ofs, len, sumsize);
133 if (ret) { 136 if (ret) {
134 D1(printk(KERN_DEBUG "jffs2_reserve_space: ret is %d\n", ret)); 137 D1(printk(KERN_DEBUG "jffs2_reserve_space: ret is %d\n", ret));
135 } 138 }
@@ -140,7 +143,8 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs
140 return ret; 143 return ret;
141} 144}
142 145
143int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len) 146int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs,
147 uint32_t *len, uint32_t sumsize)
144{ 148{
145 int ret = -EAGAIN; 149 int ret = -EAGAIN;
146 minsize = PAD(minsize); 150 minsize = PAD(minsize);
@@ -149,7 +153,7 @@ int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *
149 153
150 spin_lock(&c->erase_completion_lock); 154 spin_lock(&c->erase_completion_lock);
151 while(ret == -EAGAIN) { 155 while(ret == -EAGAIN) {
152 ret = jffs2_do_reserve_space(c, minsize, ofs, len); 156 ret = jffs2_do_reserve_space(c, minsize, ofs, len, sumsize);
153 if (ret) { 157 if (ret) {
154 D1(printk(KERN_DEBUG "jffs2_reserve_space_gc: looping, ret is %d\n", ret)); 158 D1(printk(KERN_DEBUG "jffs2_reserve_space_gc: looping, ret is %d\n", ret));
155 } 159 }
@@ -158,105 +162,185 @@ int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *
158 return ret; 162 return ret;
159} 163}
160 164
161/* Called with alloc sem _and_ erase_completion_lock */ 165
162static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len) 166/* Classify nextblock (clean, dirty of verydirty) and force to select an other one */
167
168static void jffs2_close_nextblock(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
163{ 169{
164 struct jffs2_eraseblock *jeb = c->nextblock; 170
165 171 /* Check, if we have a dirty block now, or if it was dirty already */
166 restart: 172 if (ISDIRTY (jeb->wasted_size + jeb->dirty_size)) {
167 if (jeb && minsize > jeb->free_size) { 173 c->dirty_size += jeb->wasted_size;
168 /* Skip the end of this block and file it as having some dirty space */ 174 c->wasted_size -= jeb->wasted_size;
169 /* If there's a pending write to it, flush now */ 175 jeb->dirty_size += jeb->wasted_size;
170 if (jffs2_wbuf_dirty(c)) { 176 jeb->wasted_size = 0;
177 if (VERYDIRTY(c, jeb->dirty_size)) {
178 D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to very_dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
179 jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
180 list_add_tail(&jeb->list, &c->very_dirty_list);
181 } else {
182 D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
183 jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
184 list_add_tail(&jeb->list, &c->dirty_list);
185 }
186 } else {
187 D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
188 jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
189 list_add_tail(&jeb->list, &c->clean_list);
190 }
191 c->nextblock = NULL;
192
193}
194
195/* Select a new jeb for nextblock */
196
197static int jffs2_find_nextblock(struct jffs2_sb_info *c)
198{
199 struct list_head *next;
200
201 /* Take the next block off the 'free' list */
202
203 if (list_empty(&c->free_list)) {
204
205 if (!c->nr_erasing_blocks &&
206 !list_empty(&c->erasable_list)) {
207 struct jffs2_eraseblock *ejeb;
208
209 ejeb = list_entry(c->erasable_list.next, struct jffs2_eraseblock, list);
210 list_del(&ejeb->list);
211 list_add_tail(&ejeb->list, &c->erase_pending_list);
212 c->nr_erasing_blocks++;
213 jffs2_erase_pending_trigger(c);
214 D1(printk(KERN_DEBUG "jffs2_find_nextblock: Triggering erase of erasable block at 0x%08x\n",
215 ejeb->offset));
216 }
217
218 if (!c->nr_erasing_blocks &&
219 !list_empty(&c->erasable_pending_wbuf_list)) {
220 D1(printk(KERN_DEBUG "jffs2_find_nextblock: Flushing write buffer\n"));
221 /* c->nextblock is NULL, no update to c->nextblock allowed */
171 spin_unlock(&c->erase_completion_lock); 222 spin_unlock(&c->erase_completion_lock);
172 D1(printk(KERN_DEBUG "jffs2_do_reserve_space: Flushing write buffer\n"));
173 jffs2_flush_wbuf_pad(c); 223 jffs2_flush_wbuf_pad(c);
174 spin_lock(&c->erase_completion_lock); 224 spin_lock(&c->erase_completion_lock);
175 jeb = c->nextblock; 225 /* Have another go. It'll be on the erasable_list now */
176 goto restart; 226 return -EAGAIN;
177 } 227 }
178 c->wasted_size += jeb->free_size; 228
179 c->free_size -= jeb->free_size; 229 if (!c->nr_erasing_blocks) {
180 jeb->wasted_size += jeb->free_size; 230 /* Ouch. We're in GC, or we wouldn't have got here.
181 jeb->free_size = 0; 231 And there's no space left. At all. */
182 232 printk(KERN_CRIT "Argh. No free space left for GC. nr_erasing_blocks is %d. nr_free_blocks is %d. (erasableempty: %s, erasingempty: %s, erasependingempty: %s)\n",
183 /* Check, if we have a dirty block now, or if it was dirty already */ 233 c->nr_erasing_blocks, c->nr_free_blocks, list_empty(&c->erasable_list)?"yes":"no",
184 if (ISDIRTY (jeb->wasted_size + jeb->dirty_size)) { 234 list_empty(&c->erasing_list)?"yes":"no", list_empty(&c->erase_pending_list)?"yes":"no");
185 c->dirty_size += jeb->wasted_size; 235 return -ENOSPC;
186 c->wasted_size -= jeb->wasted_size;
187 jeb->dirty_size += jeb->wasted_size;
188 jeb->wasted_size = 0;
189 if (VERYDIRTY(c, jeb->dirty_size)) {
190 D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to very_dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
191 jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
192 list_add_tail(&jeb->list, &c->very_dirty_list);
193 } else {
194 D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
195 jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
196 list_add_tail(&jeb->list, &c->dirty_list);
197 }
198 } else {
199 D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
200 jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
201 list_add_tail(&jeb->list, &c->clean_list);
202 } 236 }
203 c->nextblock = jeb = NULL; 237
238 spin_unlock(&c->erase_completion_lock);
239 /* Don't wait for it; just erase one right now */
240 jffs2_erase_pending_blocks(c, 1);
241 spin_lock(&c->erase_completion_lock);
242
243 /* An erase may have failed, decreasing the
244 amount of free space available. So we must
245 restart from the beginning */
246 return -EAGAIN;
204 } 247 }
205
206 if (!jeb) {
207 struct list_head *next;
208 /* Take the next block off the 'free' list */
209 248
210 if (list_empty(&c->free_list)) { 249 next = c->free_list.next;
250 list_del(next);
251 c->nextblock = list_entry(next, struct jffs2_eraseblock, list);
252 c->nr_free_blocks--;
211 253
212 if (!c->nr_erasing_blocks && 254 jffs2_sum_reset_collected(c->summary); /* reset collected summary */
213 !list_empty(&c->erasable_list)) {
214 struct jffs2_eraseblock *ejeb;
215 255
216 ejeb = list_entry(c->erasable_list.next, struct jffs2_eraseblock, list); 256 D1(printk(KERN_DEBUG "jffs2_find_nextblock(): new nextblock = 0x%08x\n", c->nextblock->offset));
217 list_del(&ejeb->list); 257
218 list_add_tail(&ejeb->list, &c->erase_pending_list); 258 return 0;
219 c->nr_erasing_blocks++; 259}
220 jffs2_erase_pending_trigger(c); 260
221 D1(printk(KERN_DEBUG "jffs2_do_reserve_space: Triggering erase of erasable block at 0x%08x\n", 261/* Called with alloc sem _and_ erase_completion_lock */
222 ejeb->offset)); 262static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, uint32_t sumsize)
263{
264 struct jffs2_eraseblock *jeb = c->nextblock;
265 uint32_t reserved_size; /* for summary information at the end of the jeb */
266 int ret;
267
268 restart:
269 reserved_size = 0;
270
271 if (jffs2_sum_active() && (sumsize != JFFS2_SUMMARY_NOSUM_SIZE)) {
272 /* NOSUM_SIZE means not to generate summary */
273
274 if (jeb) {
275 reserved_size = PAD(sumsize + c->summary->sum_size + JFFS2_SUMMARY_FRAME_SIZE);
276 dbg_summary("minsize=%d , jeb->free=%d ,"
277 "summary->size=%d , sumsize=%d\n",
278 minsize, jeb->free_size,
279 c->summary->sum_size, sumsize);
280 }
281
282 /* Is there enough space for writing out the current node, or we have to
283 write out summary information now, close this jeb and select new nextblock? */
284 if (jeb && (PAD(minsize) + PAD(c->summary->sum_size + sumsize +
285 JFFS2_SUMMARY_FRAME_SIZE) > jeb->free_size)) {
286
287 /* Has summary been disabled for this jeb? */
288 if (jffs2_sum_is_disabled(c->summary)) {
289 sumsize = JFFS2_SUMMARY_NOSUM_SIZE;
290 goto restart;
223 } 291 }
224 292
225 if (!c->nr_erasing_blocks && 293 /* Writing out the collected summary information */
226 !list_empty(&c->erasable_pending_wbuf_list)) { 294 dbg_summary("generating summary for 0x%08x.\n", jeb->offset);
227 D1(printk(KERN_DEBUG "jffs2_do_reserve_space: Flushing write buffer\n")); 295 ret = jffs2_sum_write_sumnode(c);
228 /* c->nextblock is NULL, no update to c->nextblock allowed */ 296
297 if (ret)
298 return ret;
299
300 if (jffs2_sum_is_disabled(c->summary)) {
301 /* jffs2_write_sumnode() couldn't write out the summary information
302 diabling summary for this jeb and free the collected information
303 */
304 sumsize = JFFS2_SUMMARY_NOSUM_SIZE;
305 goto restart;
306 }
307
308 jffs2_close_nextblock(c, jeb);
309 jeb = NULL;
310 /* keep always valid value in reserved_size */
311 reserved_size = PAD(sumsize + c->summary->sum_size + JFFS2_SUMMARY_FRAME_SIZE);
312 }
313 } else {
314 if (jeb && minsize > jeb->free_size) {
315 /* Skip the end of this block and file it as having some dirty space */
316 /* If there's a pending write to it, flush now */
317
318 if (jffs2_wbuf_dirty(c)) {
229 spin_unlock(&c->erase_completion_lock); 319 spin_unlock(&c->erase_completion_lock);
320 D1(printk(KERN_DEBUG "jffs2_do_reserve_space: Flushing write buffer\n"));
230 jffs2_flush_wbuf_pad(c); 321 jffs2_flush_wbuf_pad(c);
231 spin_lock(&c->erase_completion_lock); 322 spin_lock(&c->erase_completion_lock);
232 /* Have another go. It'll be on the erasable_list now */ 323 jeb = c->nextblock;
233 return -EAGAIN; 324 goto restart;
234 } 325 }
235 326
236 if (!c->nr_erasing_blocks) { 327 c->wasted_size += jeb->free_size;
237 /* Ouch. We're in GC, or we wouldn't have got here. 328 c->free_size -= jeb->free_size;
238 And there's no space left. At all. */ 329 jeb->wasted_size += jeb->free_size;
239 printk(KERN_CRIT "Argh. No free space left for GC. nr_erasing_blocks is %d. nr_free_blocks is %d. (erasableempty: %s, erasingempty: %s, erasependingempty: %s)\n", 330 jeb->free_size = 0;
240 c->nr_erasing_blocks, c->nr_free_blocks, list_empty(&c->erasable_list)?"yes":"no",
241 list_empty(&c->erasing_list)?"yes":"no", list_empty(&c->erase_pending_list)?"yes":"no");
242 return -ENOSPC;
243 }
244
245 spin_unlock(&c->erase_completion_lock);
246 /* Don't wait for it; just erase one right now */
247 jffs2_erase_pending_blocks(c, 1);
248 spin_lock(&c->erase_completion_lock);
249 331
250 /* An erase may have failed, decreasing the 332 jffs2_close_nextblock(c, jeb);
251 amount of free space available. So we must 333 jeb = NULL;
252 restart from the beginning */
253 return -EAGAIN;
254 } 334 }
335 }
336
337 if (!jeb) {
255 338
256 next = c->free_list.next; 339 ret = jffs2_find_nextblock(c);
257 list_del(next); 340 if (ret)
258 c->nextblock = jeb = list_entry(next, struct jffs2_eraseblock, list); 341 return ret;
259 c->nr_free_blocks--; 342
343 jeb = c->nextblock;
260 344
261 if (jeb->free_size != c->sector_size - c->cleanmarker_size) { 345 if (jeb->free_size != c->sector_size - c->cleanmarker_size) {
262 printk(KERN_WARNING "Eep. Block 0x%08x taken from free_list had free_size of 0x%08x!!\n", jeb->offset, jeb->free_size); 346 printk(KERN_WARNING "Eep. Block 0x%08x taken from free_list had free_size of 0x%08x!!\n", jeb->offset, jeb->free_size);
@@ -266,13 +350,13 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, ui
266 /* OK, jeb (==c->nextblock) is now pointing at a block which definitely has 350 /* OK, jeb (==c->nextblock) is now pointing at a block which definitely has
267 enough space */ 351 enough space */
268 *ofs = jeb->offset + (c->sector_size - jeb->free_size); 352 *ofs = jeb->offset + (c->sector_size - jeb->free_size);
269 *len = jeb->free_size; 353 *len = jeb->free_size - reserved_size;
270 354
271 if (c->cleanmarker_size && jeb->used_size == c->cleanmarker_size && 355 if (c->cleanmarker_size && jeb->used_size == c->cleanmarker_size &&
272 !jeb->first_node->next_in_ino) { 356 !jeb->first_node->next_in_ino) {
273 /* Only node in it beforehand was a CLEANMARKER node (we think). 357 /* Only node in it beforehand was a CLEANMARKER node (we think).
274 So mark it obsolete now that there's going to be another node 358 So mark it obsolete now that there's going to be another node
275 in the block. This will reduce used_size to zero but We've 359 in the block. This will reduce used_size to zero but We've
276 already set c->nextblock so that jffs2_mark_node_obsolete() 360 already set c->nextblock so that jffs2_mark_node_obsolete()
277 won't try to refile it to the dirty_list. 361 won't try to refile it to the dirty_list.
278 */ 362 */
@@ -292,12 +376,12 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, ui
292 * @len: length of this physical node 376 * @len: length of this physical node
293 * @dirty: dirty flag for new node 377 * @dirty: dirty flag for new node
294 * 378 *
295 * Should only be used to report nodes for which space has been allocated 379 * Should only be used to report nodes for which space has been allocated
296 * by jffs2_reserve_space. 380 * by jffs2_reserve_space.
297 * 381 *
298 * Must be called with the alloc_sem held. 382 * Must be called with the alloc_sem held.
299 */ 383 */
300 384
301int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new) 385int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new)
302{ 386{
303 struct jffs2_eraseblock *jeb; 387 struct jffs2_eraseblock *jeb;
@@ -349,8 +433,8 @@ int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_r
349 list_add_tail(&jeb->list, &c->clean_list); 433 list_add_tail(&jeb->list, &c->clean_list);
350 c->nextblock = NULL; 434 c->nextblock = NULL;
351 } 435 }
352 ACCT_SANITY_CHECK(c,jeb); 436 jffs2_dbg_acct_sanity_check_nolock(c,jeb);
353 D1(ACCT_PARANOIA_CHECK(jeb)); 437 jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
354 438
355 spin_unlock(&c->erase_completion_lock); 439 spin_unlock(&c->erase_completion_lock);
356 440
@@ -404,8 +488,8 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
404 488
405 if (jffs2_can_mark_obsolete(c) && !jffs2_is_readonly(c) && 489 if (jffs2_can_mark_obsolete(c) && !jffs2_is_readonly(c) &&
406 !(c->flags & (JFFS2_SB_FLAG_SCANNING | JFFS2_SB_FLAG_BUILDING))) { 490 !(c->flags & (JFFS2_SB_FLAG_SCANNING | JFFS2_SB_FLAG_BUILDING))) {
407 /* Hm. This may confuse static lock analysis. If any of the above 491 /* Hm. This may confuse static lock analysis. If any of the above
408 three conditions is false, we're going to return from this 492 three conditions is false, we're going to return from this
409 function without actually obliterating any nodes or freeing 493 function without actually obliterating any nodes or freeing
410 any jffs2_raw_node_refs. So we don't need to stop erases from 494 any jffs2_raw_node_refs. So we don't need to stop erases from
411 happening, or protect against people holding an obsolete 495 happening, or protect against people holding an obsolete
@@ -430,7 +514,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
430 ref_totlen(c, jeb, ref), blocknr, ref->flash_offset, jeb->used_size); 514 ref_totlen(c, jeb, ref), blocknr, ref->flash_offset, jeb->used_size);
431 BUG(); 515 BUG();
432 }) 516 })
433 D1(printk(KERN_DEBUG "Obsoleting node at 0x%08x of len %x: ", ref_offset(ref), ref_totlen(c, jeb, ref))); 517 D1(printk(KERN_DEBUG "Obsoleting node at 0x%08x of len %#x: ", ref_offset(ref), ref_totlen(c, jeb, ref)));
434 jeb->used_size -= ref_totlen(c, jeb, ref); 518 jeb->used_size -= ref_totlen(c, jeb, ref);
435 c->used_size -= ref_totlen(c, jeb, ref); 519 c->used_size -= ref_totlen(c, jeb, ref);
436 } 520 }
@@ -462,18 +546,17 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
462 D1(printk(KERN_DEBUG "Wasting\n")); 546 D1(printk(KERN_DEBUG "Wasting\n"));
463 addedsize = 0; 547 addedsize = 0;
464 jeb->wasted_size += ref_totlen(c, jeb, ref); 548 jeb->wasted_size += ref_totlen(c, jeb, ref);
465 c->wasted_size += ref_totlen(c, jeb, ref); 549 c->wasted_size += ref_totlen(c, jeb, ref);
466 } 550 }
467 ref->flash_offset = ref_offset(ref) | REF_OBSOLETE; 551 ref->flash_offset = ref_offset(ref) | REF_OBSOLETE;
468
469 ACCT_SANITY_CHECK(c, jeb);
470 552
471 D1(ACCT_PARANOIA_CHECK(jeb)); 553 jffs2_dbg_acct_sanity_check_nolock(c, jeb);
554 jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
472 555
473 if (c->flags & JFFS2_SB_FLAG_SCANNING) { 556 if (c->flags & JFFS2_SB_FLAG_SCANNING) {
474 /* Flash scanning is in progress. Don't muck about with the block 557 /* Flash scanning is in progress. Don't muck about with the block
475 lists because they're not ready yet, and don't actually 558 lists because they're not ready yet, and don't actually
476 obliterate nodes that look obsolete. If they weren't 559 obliterate nodes that look obsolete. If they weren't
477 marked obsolete on the flash at the time they _became_ 560 marked obsolete on the flash at the time they _became_
478 obsolete, there was probably a reason for that. */ 561 obsolete, there was probably a reason for that. */
479 spin_unlock(&c->erase_completion_lock); 562 spin_unlock(&c->erase_completion_lock);
@@ -507,7 +590,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
507 immediately reused, and we spread the load a bit. */ 590 immediately reused, and we spread the load a bit. */
508 D1(printk(KERN_DEBUG "...and adding to erasable_list\n")); 591 D1(printk(KERN_DEBUG "...and adding to erasable_list\n"));
509 list_add_tail(&jeb->list, &c->erasable_list); 592 list_add_tail(&jeb->list, &c->erasable_list);
510 } 593 }
511 } 594 }
512 D1(printk(KERN_DEBUG "Done OK\n")); 595 D1(printk(KERN_DEBUG "Done OK\n"));
513 } else if (jeb == c->gcblock) { 596 } else if (jeb == c->gcblock) {
@@ -525,8 +608,8 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
525 list_add_tail(&jeb->list, &c->very_dirty_list); 608 list_add_tail(&jeb->list, &c->very_dirty_list);
526 } else { 609 } else {
527 D1(printk(KERN_DEBUG "Eraseblock at 0x%08x not moved anywhere. (free 0x%08x, dirty 0x%08x, used 0x%08x)\n", 610 D1(printk(KERN_DEBUG "Eraseblock at 0x%08x not moved anywhere. (free 0x%08x, dirty 0x%08x, used 0x%08x)\n",
528 jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size)); 611 jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
529 } 612 }
530 613
531 spin_unlock(&c->erase_completion_lock); 614 spin_unlock(&c->erase_completion_lock);
532 615
@@ -573,11 +656,11 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
573 656
574 /* Nodes which have been marked obsolete no longer need to be 657 /* Nodes which have been marked obsolete no longer need to be
575 associated with any inode. Remove them from the per-inode list. 658 associated with any inode. Remove them from the per-inode list.
576 659
577 Note we can't do this for NAND at the moment because we need 660 Note we can't do this for NAND at the moment because we need
578 obsolete dirent nodes to stay on the lists, because of the 661 obsolete dirent nodes to stay on the lists, because of the
579 horridness in jffs2_garbage_collect_deletion_dirent(). Also 662 horridness in jffs2_garbage_collect_deletion_dirent(). Also
580 because we delete the inocache, and on NAND we need that to 663 because we delete the inocache, and on NAND we need that to
581 stay around until all the nodes are actually erased, in order 664 stay around until all the nodes are actually erased, in order
582 to stop us from giving the same inode number to another newly 665 to stop us from giving the same inode number to another newly
583 created inode. */ 666 created inode. */
@@ -606,7 +689,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
606 if (ref->next_phys && ref_obsolete(ref->next_phys) && 689 if (ref->next_phys && ref_obsolete(ref->next_phys) &&
607 !ref->next_phys->next_in_ino) { 690 !ref->next_phys->next_in_ino) {
608 struct jffs2_raw_node_ref *n = ref->next_phys; 691 struct jffs2_raw_node_ref *n = ref->next_phys;
609 692
610 spin_lock(&c->erase_completion_lock); 693 spin_lock(&c->erase_completion_lock);
611 694
612 ref->__totlen += n->__totlen; 695 ref->__totlen += n->__totlen;
@@ -620,7 +703,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
620 703
621 jffs2_free_raw_node_ref(n); 704 jffs2_free_raw_node_ref(n);
622 } 705 }
623 706
624 /* Also merge with the previous node in the list, if there is one 707 /* Also merge with the previous node in the list, if there is one
625 and that one is obsolete */ 708 and that one is obsolete */
626 if (ref != jeb->first_node ) { 709 if (ref != jeb->first_node ) {
@@ -630,7 +713,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
630 713
631 while (p->next_phys != ref) 714 while (p->next_phys != ref)
632 p = p->next_phys; 715 p = p->next_phys;
633 716
634 if (ref_obsolete(p) && !ref->next_in_ino) { 717 if (ref_obsolete(p) && !ref->next_in_ino) {
635 p->__totlen += ref->__totlen; 718 p->__totlen += ref->__totlen;
636 if (jeb->last_node == ref) { 719 if (jeb->last_node == ref) {
@@ -649,164 +732,6 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
649 up(&c->erase_free_sem); 732 up(&c->erase_free_sem);
650} 733}
651 734
652#if CONFIG_JFFS2_FS_DEBUG >= 2
653void jffs2_dump_block_lists(struct jffs2_sb_info *c)
654{
655
656
657 printk(KERN_DEBUG "jffs2_dump_block_lists:\n");
658 printk(KERN_DEBUG "flash_size: %08x\n", c->flash_size);
659 printk(KERN_DEBUG "used_size: %08x\n", c->used_size);
660 printk(KERN_DEBUG "dirty_size: %08x\n", c->dirty_size);
661 printk(KERN_DEBUG "wasted_size: %08x\n", c->wasted_size);
662 printk(KERN_DEBUG "unchecked_size: %08x\n", c->unchecked_size);
663 printk(KERN_DEBUG "free_size: %08x\n", c->free_size);
664 printk(KERN_DEBUG "erasing_size: %08x\n", c->erasing_size);
665 printk(KERN_DEBUG "bad_size: %08x\n", c->bad_size);
666 printk(KERN_DEBUG "sector_size: %08x\n", c->sector_size);
667 printk(KERN_DEBUG "jffs2_reserved_blocks size: %08x\n",c->sector_size * c->resv_blocks_write);
668
669 if (c->nextblock) {
670 printk(KERN_DEBUG "nextblock: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
671 c->nextblock->offset, c->nextblock->used_size, c->nextblock->dirty_size, c->nextblock->wasted_size, c->nextblock->unchecked_size, c->nextblock->free_size);
672 } else {
673 printk(KERN_DEBUG "nextblock: NULL\n");
674 }
675 if (c->gcblock) {
676 printk(KERN_DEBUG "gcblock: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
677 c->gcblock->offset, c->gcblock->used_size, c->gcblock->dirty_size, c->gcblock->wasted_size, c->gcblock->unchecked_size, c->gcblock->free_size);
678 } else {
679 printk(KERN_DEBUG "gcblock: NULL\n");
680 }
681 if (list_empty(&c->clean_list)) {
682 printk(KERN_DEBUG "clean_list: empty\n");
683 } else {
684 struct list_head *this;
685 int numblocks = 0;
686 uint32_t dirty = 0;
687
688 list_for_each(this, &c->clean_list) {
689 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
690 numblocks ++;
691 dirty += jeb->wasted_size;
692 printk(KERN_DEBUG "clean_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n", jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
693 }
694 printk (KERN_DEBUG "Contains %d blocks with total wasted size %u, average wasted size: %u\n", numblocks, dirty, dirty / numblocks);
695 }
696 if (list_empty(&c->very_dirty_list)) {
697 printk(KERN_DEBUG "very_dirty_list: empty\n");
698 } else {
699 struct list_head *this;
700 int numblocks = 0;
701 uint32_t dirty = 0;
702
703 list_for_each(this, &c->very_dirty_list) {
704 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
705 numblocks ++;
706 dirty += jeb->dirty_size;
707 printk(KERN_DEBUG "very_dirty_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
708 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
709 }
710 printk (KERN_DEBUG "Contains %d blocks with total dirty size %u, average dirty size: %u\n",
711 numblocks, dirty, dirty / numblocks);
712 }
713 if (list_empty(&c->dirty_list)) {
714 printk(KERN_DEBUG "dirty_list: empty\n");
715 } else {
716 struct list_head *this;
717 int numblocks = 0;
718 uint32_t dirty = 0;
719
720 list_for_each(this, &c->dirty_list) {
721 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
722 numblocks ++;
723 dirty += jeb->dirty_size;
724 printk(KERN_DEBUG "dirty_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
725 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
726 }
727 printk (KERN_DEBUG "Contains %d blocks with total dirty size %u, average dirty size: %u\n",
728 numblocks, dirty, dirty / numblocks);
729 }
730 if (list_empty(&c->erasable_list)) {
731 printk(KERN_DEBUG "erasable_list: empty\n");
732 } else {
733 struct list_head *this;
734
735 list_for_each(this, &c->erasable_list) {
736 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
737 printk(KERN_DEBUG "erasable_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
738 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
739 }
740 }
741 if (list_empty(&c->erasing_list)) {
742 printk(KERN_DEBUG "erasing_list: empty\n");
743 } else {
744 struct list_head *this;
745
746 list_for_each(this, &c->erasing_list) {
747 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
748 printk(KERN_DEBUG "erasing_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
749 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
750 }
751 }
752 if (list_empty(&c->erase_pending_list)) {
753 printk(KERN_DEBUG "erase_pending_list: empty\n");
754 } else {
755 struct list_head *this;
756
757 list_for_each(this, &c->erase_pending_list) {
758 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
759 printk(KERN_DEBUG "erase_pending_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
760 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
761 }
762 }
763 if (list_empty(&c->erasable_pending_wbuf_list)) {
764 printk(KERN_DEBUG "erasable_pending_wbuf_list: empty\n");
765 } else {
766 struct list_head *this;
767
768 list_for_each(this, &c->erasable_pending_wbuf_list) {
769 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
770 printk(KERN_DEBUG "erasable_pending_wbuf_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
771 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
772 }
773 }
774 if (list_empty(&c->free_list)) {
775 printk(KERN_DEBUG "free_list: empty\n");
776 } else {
777 struct list_head *this;
778
779 list_for_each(this, &c->free_list) {
780 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
781 printk(KERN_DEBUG "free_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
782 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
783 }
784 }
785 if (list_empty(&c->bad_list)) {
786 printk(KERN_DEBUG "bad_list: empty\n");
787 } else {
788 struct list_head *this;
789
790 list_for_each(this, &c->bad_list) {
791 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
792 printk(KERN_DEBUG "bad_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
793 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
794 }
795 }
796 if (list_empty(&c->bad_used_list)) {
797 printk(KERN_DEBUG "bad_used_list: empty\n");
798 } else {
799 struct list_head *this;
800
801 list_for_each(this, &c->bad_used_list) {
802 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
803 printk(KERN_DEBUG "bad_used_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
804 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
805 }
806 }
807}
808#endif /* CONFIG_JFFS2_FS_DEBUG */
809
810int jffs2_thread_should_wake(struct jffs2_sb_info *c) 735int jffs2_thread_should_wake(struct jffs2_sb_info *c)
811{ 736{
812 int ret = 0; 737 int ret = 0;
@@ -828,11 +753,11 @@ int jffs2_thread_should_wake(struct jffs2_sb_info *c)
828 */ 753 */
829 dirty = c->dirty_size + c->erasing_size - c->nr_erasing_blocks * c->sector_size; 754 dirty = c->dirty_size + c->erasing_size - c->nr_erasing_blocks * c->sector_size;
830 755
831 if (c->nr_free_blocks + c->nr_erasing_blocks < c->resv_blocks_gctrigger && 756 if (c->nr_free_blocks + c->nr_erasing_blocks < c->resv_blocks_gctrigger &&
832 (dirty > c->nospc_dirty_size)) 757 (dirty > c->nospc_dirty_size))
833 ret = 1; 758 ret = 1;
834 759
835 D1(printk(KERN_DEBUG "jffs2_thread_should_wake(): nr_free_blocks %d, nr_erasing_blocks %d, dirty_size 0x%x: %s\n", 760 D1(printk(KERN_DEBUG "jffs2_thread_should_wake(): nr_free_blocks %d, nr_erasing_blocks %d, dirty_size 0x%x: %s\n",
836 c->nr_free_blocks, c->nr_erasing_blocks, c->dirty_size, ret?"yes":"no")); 761 c->nr_free_blocks, c->nr_erasing_blocks, c->dirty_size, ret?"yes":"no"));
837 762
838 return ret; 763 return ret;
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
index d900c8929b09..59e7a393200c 100644
--- a/fs/jffs2/os-linux.h
+++ b/fs/jffs2/os-linux.h
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: os-linux.h,v 1.58 2005/07/12 02:34:35 tpoynor Exp $ 10 * $Id: os-linux.h,v 1.64 2005/09/30 13:59:13 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -57,6 +57,7 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
57 f->fragtree = RB_ROOT; 57 f->fragtree = RB_ROOT;
58 f->metadata = NULL; 58 f->metadata = NULL;
59 f->dents = NULL; 59 f->dents = NULL;
60 f->target = NULL;
60 f->flags = 0; 61 f->flags = 0;
61 f->usercompr = 0; 62 f->usercompr = 0;
62} 63}
@@ -64,17 +65,24 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
64 65
65#define jffs2_is_readonly(c) (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY) 66#define jffs2_is_readonly(c) (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY)
66 67
68#define SECTOR_ADDR(x) ( (((unsigned long)(x) / c->sector_size) * c->sector_size) )
67#ifndef CONFIG_JFFS2_FS_WRITEBUFFER 69#ifndef CONFIG_JFFS2_FS_WRITEBUFFER
68#define SECTOR_ADDR(x) ( ((unsigned long)(x) & ~(c->sector_size-1)) ) 70
71
72#ifdef CONFIG_JFFS2_SUMMARY
73#define jffs2_can_mark_obsolete(c) (0)
74#else
69#define jffs2_can_mark_obsolete(c) (1) 75#define jffs2_can_mark_obsolete(c) (1)
76#endif
77
70#define jffs2_is_writebuffered(c) (0) 78#define jffs2_is_writebuffered(c) (0)
71#define jffs2_cleanmarker_oob(c) (0) 79#define jffs2_cleanmarker_oob(c) (0)
72#define jffs2_write_nand_cleanmarker(c,jeb) (-EIO) 80#define jffs2_write_nand_cleanmarker(c,jeb) (-EIO)
73 81
74#define jffs2_flash_write(c, ofs, len, retlen, buf) ((c)->mtd->write((c)->mtd, ofs, len, retlen, buf)) 82#define jffs2_flash_write(c, ofs, len, retlen, buf) jffs2_flash_direct_write(c, ofs, len, retlen, buf)
75#define jffs2_flash_read(c, ofs, len, retlen, buf) ((c)->mtd->read((c)->mtd, ofs, len, retlen, buf)) 83#define jffs2_flash_read(c, ofs, len, retlen, buf) ((c)->mtd->read((c)->mtd, ofs, len, retlen, buf))
76#define jffs2_flush_wbuf_pad(c) ({ (void)(c), 0; }) 84#define jffs2_flush_wbuf_pad(c) ({ do{} while(0); (void)(c), 0; })
77#define jffs2_flush_wbuf_gc(c, i) ({ (void)(c), (void) i, 0; }) 85#define jffs2_flush_wbuf_gc(c, i) ({ do{} while(0); (void)(c), (void) i, 0; })
78#define jffs2_write_nand_badblock(c,jeb,bad_offset) (1) 86#define jffs2_write_nand_badblock(c,jeb,bad_offset) (1)
79#define jffs2_nand_flash_setup(c) (0) 87#define jffs2_nand_flash_setup(c) (0)
80#define jffs2_nand_flash_cleanup(c) do {} while(0) 88#define jffs2_nand_flash_cleanup(c) do {} while(0)
@@ -84,16 +92,26 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
84#define jffs2_wbuf_process NULL 92#define jffs2_wbuf_process NULL
85#define jffs2_nor_ecc(c) (0) 93#define jffs2_nor_ecc(c) (0)
86#define jffs2_dataflash(c) (0) 94#define jffs2_dataflash(c) (0)
95#define jffs2_nor_wbuf_flash(c) (0)
87#define jffs2_nor_ecc_flash_setup(c) (0) 96#define jffs2_nor_ecc_flash_setup(c) (0)
88#define jffs2_nor_ecc_flash_cleanup(c) do {} while (0) 97#define jffs2_nor_ecc_flash_cleanup(c) do {} while (0)
89#define jffs2_dataflash_setup(c) (0) 98#define jffs2_dataflash_setup(c) (0)
90#define jffs2_dataflash_cleanup(c) do {} while (0) 99#define jffs2_dataflash_cleanup(c) do {} while (0)
100#define jffs2_nor_wbuf_flash_setup(c) (0)
101#define jffs2_nor_wbuf_flash_cleanup(c) do {} while (0)
91 102
92#else /* NAND and/or ECC'd NOR support present */ 103#else /* NAND and/or ECC'd NOR support present */
93 104
94#define jffs2_is_writebuffered(c) (c->wbuf != NULL) 105#define jffs2_is_writebuffered(c) (c->wbuf != NULL)
95#define SECTOR_ADDR(x) ( ((unsigned long)(x) / (unsigned long)(c->sector_size)) * c->sector_size ) 106
96#define jffs2_can_mark_obsolete(c) ((c->mtd->type == MTD_NORFLASH && !(c->mtd->flags & MTD_ECC)) || c->mtd->type == MTD_RAM) 107#ifdef CONFIG_JFFS2_SUMMARY
108#define jffs2_can_mark_obsolete(c) (0)
109#else
110#define jffs2_can_mark_obsolete(c) \
111 ((c->mtd->type == MTD_NORFLASH && !(c->mtd->flags & (MTD_ECC|MTD_PROGRAM_REGIONS))) || \
112 c->mtd->type == MTD_RAM)
113#endif
114
97#define jffs2_cleanmarker_oob(c) (c->mtd->type == MTD_NANDFLASH) 115#define jffs2_cleanmarker_oob(c) (c->mtd->type == MTD_NANDFLASH)
98 116
99#define jffs2_flash_write_oob(c, ofs, len, retlen, buf) ((c)->mtd->write_oob((c)->mtd, ofs, len, retlen, buf)) 117#define jffs2_flash_write_oob(c, ofs, len, retlen, buf) ((c)->mtd->write_oob((c)->mtd, ofs, len, retlen, buf))
@@ -123,6 +141,10 @@ void jffs2_nor_ecc_flash_cleanup(struct jffs2_sb_info *c);
123int jffs2_dataflash_setup(struct jffs2_sb_info *c); 141int jffs2_dataflash_setup(struct jffs2_sb_info *c);
124void jffs2_dataflash_cleanup(struct jffs2_sb_info *c); 142void jffs2_dataflash_cleanup(struct jffs2_sb_info *c);
125 143
144#define jffs2_nor_wbuf_flash(c) (c->mtd->type == MTD_NORFLASH && (c->mtd->flags & MTD_PROGRAM_REGIONS))
145int jffs2_nor_wbuf_flash_setup(struct jffs2_sb_info *c);
146void jffs2_nor_wbuf_flash_cleanup(struct jffs2_sb_info *c);
147
126#endif /* WRITEBUFFER */ 148#endif /* WRITEBUFFER */
127 149
128/* erase.c */ 150/* erase.c */
@@ -169,20 +191,21 @@ void jffs2_gc_release_inode(struct jffs2_sb_info *c,
169struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c, 191struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
170 int inum, int nlink); 192 int inum, int nlink);
171 193
172unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c, 194unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c,
173 struct jffs2_inode_info *f, 195 struct jffs2_inode_info *f,
174 unsigned long offset, 196 unsigned long offset,
175 unsigned long *priv); 197 unsigned long *priv);
176void jffs2_gc_release_page(struct jffs2_sb_info *c, 198void jffs2_gc_release_page(struct jffs2_sb_info *c,
177 unsigned char *pg, 199 unsigned char *pg,
178 unsigned long *priv); 200 unsigned long *priv);
179void jffs2_flash_cleanup(struct jffs2_sb_info *c); 201void jffs2_flash_cleanup(struct jffs2_sb_info *c);
180 202
181 203
182/* writev.c */ 204/* writev.c */
183int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct kvec *vecs, 205int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct kvec *vecs,
184 unsigned long count, loff_t to, size_t *retlen); 206 unsigned long count, loff_t to, size_t *retlen);
185 207int jffs2_flash_direct_write(struct jffs2_sb_info *c, loff_t ofs, size_t len,
208 size_t *retlen, const u_char *buf);
186 209
187#endif /* __JFFS2_OS_LINUX_H__ */ 210#endif /* __JFFS2_OS_LINUX_H__ */
188 211
diff --git a/fs/jffs2/read.c b/fs/jffs2/read.c
index c7f9068907cf..f3b86da833ba 100644
--- a/fs/jffs2/read.c
+++ b/fs/jffs2/read.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: read.c,v 1.39 2005/03/01 10:34:03 dedekind Exp $ 10 * $Id: read.c,v 1.42 2005/11/07 11:14:41 gleixner Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -43,7 +43,7 @@ int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
43 } 43 }
44 if (readlen != sizeof(*ri)) { 44 if (readlen != sizeof(*ri)) {
45 jffs2_free_raw_inode(ri); 45 jffs2_free_raw_inode(ri);
46 printk(KERN_WARNING "Short read from 0x%08x: wanted 0x%zx bytes, got 0x%zx\n", 46 printk(KERN_WARNING "Short read from 0x%08x: wanted 0x%zx bytes, got 0x%zx\n",
47 ref_offset(fd->raw), sizeof(*ri), readlen); 47 ref_offset(fd->raw), sizeof(*ri), readlen);
48 return -EIO; 48 return -EIO;
49 } 49 }
@@ -61,7 +61,7 @@ int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
61 } 61 }
62 /* There was a bug where we wrote hole nodes out with csize/dsize 62 /* There was a bug where we wrote hole nodes out with csize/dsize
63 swapped. Deal with it */ 63 swapped. Deal with it */
64 if (ri->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(ri->dsize) && 64 if (ri->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(ri->dsize) &&
65 je32_to_cpu(ri->csize)) { 65 je32_to_cpu(ri->csize)) {
66 ri->dsize = ri->csize; 66 ri->dsize = ri->csize;
67 ri->csize = cpu_to_je32(0); 67 ri->csize = cpu_to_je32(0);
@@ -74,7 +74,7 @@ int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
74 goto out_ri; 74 goto out_ri;
75 }); 75 });
76 76
77 77
78 if (ri->compr == JFFS2_COMPR_ZERO) { 78 if (ri->compr == JFFS2_COMPR_ZERO) {
79 memset(buf, 0, len); 79 memset(buf, 0, len);
80 goto out_ri; 80 goto out_ri;
@@ -82,8 +82,8 @@ int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
82 82
83 /* Cases: 83 /* Cases:
84 Reading whole node and it's uncompressed - read directly to buffer provided, check CRC. 84 Reading whole node and it's uncompressed - read directly to buffer provided, check CRC.
85 Reading whole node and it's compressed - read into comprbuf, check CRC and decompress to buffer provided 85 Reading whole node and it's compressed - read into comprbuf, check CRC and decompress to buffer provided
86 Reading partial node and it's uncompressed - read into readbuf, check CRC, and copy 86 Reading partial node and it's uncompressed - read into readbuf, check CRC, and copy
87 Reading partial node and it's compressed - read into readbuf, check checksum, decompress to decomprbuf and copy 87 Reading partial node and it's compressed - read into readbuf, check checksum, decompress to decomprbuf and copy
88 */ 88 */
89 if (ri->compr == JFFS2_COMPR_NONE && len == je32_to_cpu(ri->dsize)) { 89 if (ri->compr == JFFS2_COMPR_NONE && len == je32_to_cpu(ri->dsize)) {
@@ -129,7 +129,7 @@ int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
129 D2(printk(KERN_DEBUG "Data CRC matches calculated CRC %08x\n", crc)); 129 D2(printk(KERN_DEBUG "Data CRC matches calculated CRC %08x\n", crc));
130 if (ri->compr != JFFS2_COMPR_NONE) { 130 if (ri->compr != JFFS2_COMPR_NONE) {
131 D2(printk(KERN_DEBUG "Decompress %d bytes from %p to %d bytes at %p\n", 131 D2(printk(KERN_DEBUG "Decompress %d bytes from %p to %d bytes at %p\n",
132 je32_to_cpu(ri->csize), readbuf, je32_to_cpu(ri->dsize), decomprbuf)); 132 je32_to_cpu(ri->csize), readbuf, je32_to_cpu(ri->dsize), decomprbuf));
133 ret = jffs2_decompress(c, f, ri->compr | (ri->usercompr << 8), readbuf, decomprbuf, je32_to_cpu(ri->csize), je32_to_cpu(ri->dsize)); 133 ret = jffs2_decompress(c, f, ri->compr | (ri->usercompr << 8), readbuf, decomprbuf, je32_to_cpu(ri->csize), je32_to_cpu(ri->dsize));
134 if (ret) { 134 if (ret) {
135 printk(KERN_WARNING "Error: jffs2_decompress returned %d\n", ret); 135 printk(KERN_WARNING "Error: jffs2_decompress returned %d\n", ret);
@@ -174,7 +174,6 @@ int jffs2_read_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
174 if (frag) { 174 if (frag) {
175 D1(printk(KERN_NOTICE "Eep. Hole in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", f->inocache->ino, frag->ofs, offset)); 175 D1(printk(KERN_NOTICE "Eep. Hole in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", f->inocache->ino, frag->ofs, offset));
176 holesize = min(holesize, frag->ofs - offset); 176 holesize = min(holesize, frag->ofs - offset);
177 D2(jffs2_print_frag_list(f));
178 } 177 }
179 D1(printk(KERN_DEBUG "Filling non-frag hole from %d-%d\n", offset, offset+holesize)); 178 D1(printk(KERN_DEBUG "Filling non-frag hole from %d-%d\n", offset, offset+holesize));
180 memset(buf, 0, holesize); 179 memset(buf, 0, holesize);
@@ -192,7 +191,7 @@ int jffs2_read_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
192 } else { 191 } else {
193 uint32_t readlen; 192 uint32_t readlen;
194 uint32_t fragofs; /* offset within the frag to start reading */ 193 uint32_t fragofs; /* offset within the frag to start reading */
195 194
196 fragofs = offset - frag->ofs; 195 fragofs = offset - frag->ofs;
197 readlen = min(frag->size - fragofs, end - offset); 196 readlen = min(frag->size - fragofs, end - offset);
198 D1(printk(KERN_DEBUG "Reading %d-%d from node at 0x%08x (%d)\n", 197 D1(printk(KERN_DEBUG "Reading %d-%d from node at 0x%08x (%d)\n",
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index 1a96903e3ef3..5f0652df5d47 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -7,11 +7,12 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: readinode.c,v 1.125 2005/07/10 13:13:55 dedekind Exp $ 10 * $Id: readinode.c,v 1.143 2005/11/07 11:14:41 gleixner Exp $
11 * 11 *
12 */ 12 */
13 13
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/sched.h>
15#include <linux/slab.h> 16#include <linux/slab.h>
16#include <linux/fs.h> 17#include <linux/fs.h>
17#include <linux/crc32.h> 18#include <linux/crc32.h>
@@ -20,502 +21,631 @@
20#include <linux/compiler.h> 21#include <linux/compiler.h>
21#include "nodelist.h" 22#include "nodelist.h"
22 23
23static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *list, struct jffs2_node_frag *newfrag); 24/*
24 25 * Put a new tmp_dnode_info into the temporaty RB-tree, keeping the list in
25#if CONFIG_JFFS2_FS_DEBUG >= 2 26 * order of increasing version.
26static void jffs2_print_fragtree(struct rb_root *list, int permitbug) 27 */
28static void jffs2_add_tn_to_tree(struct jffs2_tmp_dnode_info *tn, struct rb_root *list)
27{ 29{
28 struct jffs2_node_frag *this = frag_first(list); 30 struct rb_node **p = &list->rb_node;
29 uint32_t lastofs = 0; 31 struct rb_node * parent = NULL;
30 int buggy = 0; 32 struct jffs2_tmp_dnode_info *this;
31 33
32 while(this) { 34 while (*p) {
33 if (this->node) 35 parent = *p;
34 printk(KERN_DEBUG "frag %04x-%04x: 0x%08x(%d) on flash (*%p). left (%p), right (%p), parent (%p)\n", 36 this = rb_entry(parent, struct jffs2_tmp_dnode_info, rb);
35 this->ofs, this->ofs+this->size, ref_offset(this->node->raw), ref_flags(this->node->raw), 37
36 this, frag_left(this), frag_right(this), frag_parent(this)); 38 /* There may actually be a collision here, but it doesn't
37 else 39 actually matter. As long as the two nodes with the same
38 printk(KERN_DEBUG "frag %04x-%04x: hole (*%p). left (%p} right (%p), parent (%p)\n", this->ofs, 40 version are together, it's all fine. */
39 this->ofs+this->size, this, frag_left(this), frag_right(this), frag_parent(this)); 41 if (tn->version > this->version)
40 if (this->ofs != lastofs) 42 p = &(*p)->rb_left;
41 buggy = 1; 43 else
42 lastofs = this->ofs+this->size; 44 p = &(*p)->rb_right;
43 this = frag_next(this);
44 } 45 }
45 if (buggy && !permitbug) { 46
46 printk(KERN_CRIT "Frag tree got a hole in it\n"); 47 rb_link_node(&tn->rb, parent, p);
47 BUG(); 48 rb_insert_color(&tn->rb, list);
49}
50
51static void jffs2_free_tmp_dnode_info_list(struct rb_root *list)
52{
53 struct rb_node *this;
54 struct jffs2_tmp_dnode_info *tn;
55
56 this = list->rb_node;
57
58 /* Now at bottom of tree */
59 while (this) {
60 if (this->rb_left)
61 this = this->rb_left;
62 else if (this->rb_right)
63 this = this->rb_right;
64 else {
65 tn = rb_entry(this, struct jffs2_tmp_dnode_info, rb);
66 jffs2_free_full_dnode(tn->fn);
67 jffs2_free_tmp_dnode_info(tn);
68
69 this = this->rb_parent;
70 if (!this)
71 break;
72
73 if (this->rb_left == &tn->rb)
74 this->rb_left = NULL;
75 else if (this->rb_right == &tn->rb)
76 this->rb_right = NULL;
77 else BUG();
78 }
48 } 79 }
80 list->rb_node = NULL;
49} 81}
50 82
51void jffs2_print_frag_list(struct jffs2_inode_info *f) 83static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd)
52{ 84{
53 jffs2_print_fragtree(&f->fragtree, 0); 85 struct jffs2_full_dirent *next;
54 86
55 if (f->metadata) { 87 while (fd) {
56 printk(KERN_DEBUG "metadata at 0x%08x\n", ref_offset(f->metadata->raw)); 88 next = fd->next;
89 jffs2_free_full_dirent(fd);
90 fd = next;
57 } 91 }
58} 92}
59#endif
60 93
61#if CONFIG_JFFS2_FS_DEBUG >= 1 94/* Returns first valid node after 'ref'. May return 'ref' */
62static int jffs2_sanitycheck_fragtree(struct jffs2_inode_info *f) 95static struct jffs2_raw_node_ref *jffs2_first_valid_node(struct jffs2_raw_node_ref *ref)
63{ 96{
64 struct jffs2_node_frag *frag; 97 while (ref && ref->next_in_ino) {
65 int bitched = 0; 98 if (!ref_obsolete(ref))
66 99 return ref;
67 for (frag = frag_first(&f->fragtree); frag; frag = frag_next(frag)) { 100 dbg_noderef("node at 0x%08x is obsoleted. Ignoring.\n", ref_offset(ref));
101 ref = ref->next_in_ino;
102 }
103 return NULL;
104}
68 105
69 struct jffs2_full_dnode *fn = frag->node; 106/*
70 if (!fn || !fn->raw) 107 * Helper function for jffs2_get_inode_nodes().
71 continue; 108 * It is called every time an directory entry node is found.
109 *
110 * Returns: 0 on succes;
111 * 1 if the node should be marked obsolete;
112 * negative error code on failure.
113 */
114static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref,
115 struct jffs2_raw_dirent *rd, uint32_t read, struct jffs2_full_dirent **fdp,
116 uint32_t *latest_mctime, uint32_t *mctime_ver)
117{
118 struct jffs2_full_dirent *fd;
119
120 /* The direntry nodes are checked during the flash scanning */
121 BUG_ON(ref_flags(ref) == REF_UNCHECKED);
122 /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
123 BUG_ON(ref_obsolete(ref));
124
125 /* Sanity check */
126 if (unlikely(PAD((rd->nsize + sizeof(*rd))) != PAD(je32_to_cpu(rd->totlen)))) {
127 JFFS2_ERROR("illegal nsize in node at %#08x: nsize %#02x, totlen %#04x\n",
128 ref_offset(ref), rd->nsize, je32_to_cpu(rd->totlen));
129 return 1;
130 }
72 131
73 if (ref_flags(fn->raw) == REF_PRISTINE) { 132 fd = jffs2_alloc_full_dirent(rd->nsize + 1);
133 if (unlikely(!fd))
134 return -ENOMEM;
74 135
75 if (fn->frags > 1) { 136 fd->raw = ref;
76 printk(KERN_WARNING "REF_PRISTINE node at 0x%08x had %d frags. Tell dwmw2\n", ref_offset(fn->raw), fn->frags); 137 fd->version = je32_to_cpu(rd->version);
77 bitched = 1; 138 fd->ino = je32_to_cpu(rd->ino);
78 } 139 fd->type = rd->type;
79 /* A hole node which isn't multi-page should be garbage-collected
80 and merged anyway, so we just check for the frag size here,
81 rather than mucking around with actually reading the node
82 and checking the compression type, which is the real way
83 to tell a hole node. */
84 if (frag->ofs & (PAGE_CACHE_SIZE-1) && frag_prev(frag) && frag_prev(frag)->size < PAGE_CACHE_SIZE && frag_prev(frag)->node) {
85 printk(KERN_WARNING "REF_PRISTINE node at 0x%08x had a previous non-hole frag in the same page. Tell dwmw2\n",
86 ref_offset(fn->raw));
87 bitched = 1;
88 }
89 140
90 if ((frag->ofs+frag->size) & (PAGE_CACHE_SIZE-1) && frag_next(frag) && frag_next(frag)->size < PAGE_CACHE_SIZE && frag_next(frag)->node) { 141 /* Pick out the mctime of the latest dirent */
91 printk(KERN_WARNING "REF_PRISTINE node at 0x%08x (%08x-%08x) had a following non-hole frag in the same page. Tell dwmw2\n", 142 if(fd->version > *mctime_ver && je32_to_cpu(rd->mctime)) {
92 ref_offset(fn->raw), frag->ofs, frag->ofs+frag->size); 143 *mctime_ver = fd->version;
93 bitched = 1; 144 *latest_mctime = je32_to_cpu(rd->mctime);
94 }
95 }
96 } 145 }
97
98 if (bitched) {
99 struct jffs2_node_frag *thisfrag;
100
101 printk(KERN_WARNING "Inode is #%u\n", f->inocache->ino);
102 thisfrag = frag_first(&f->fragtree);
103 while (thisfrag) {
104 if (!thisfrag->node) {
105 printk("Frag @0x%x-0x%x; node-less hole\n",
106 thisfrag->ofs, thisfrag->size + thisfrag->ofs);
107 } else if (!thisfrag->node->raw) {
108 printk("Frag @0x%x-0x%x; raw-less hole\n",
109 thisfrag->ofs, thisfrag->size + thisfrag->ofs);
110 } else {
111 printk("Frag @0x%x-0x%x; raw at 0x%08x(%d) (0x%x-0x%x)\n",
112 thisfrag->ofs, thisfrag->size + thisfrag->ofs,
113 ref_offset(thisfrag->node->raw), ref_flags(thisfrag->node->raw),
114 thisfrag->node->ofs, thisfrag->node->ofs+thisfrag->node->size);
115 }
116 thisfrag = frag_next(thisfrag);
117 }
118 }
119 return bitched;
120}
121#endif /* D1 */
122 146
123static void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *this) 147 /*
124{ 148 * Copy as much of the name as possible from the raw
125 if (this->node) { 149 * dirent we've already read from the flash.
126 this->node->frags--; 150 */
127 if (!this->node->frags) { 151 if (read > sizeof(*rd))
128 /* The node has no valid frags left. It's totally obsoleted */ 152 memcpy(&fd->name[0], &rd->name[0],
129 D2(printk(KERN_DEBUG "Marking old node @0x%08x (0x%04x-0x%04x) obsolete\n", 153 min_t(uint32_t, rd->nsize, (read - sizeof(*rd)) ));
130 ref_offset(this->node->raw), this->node->ofs, this->node->ofs+this->node->size)); 154
131 jffs2_mark_node_obsolete(c, this->node->raw); 155 /* Do we need to copy any more of the name directly from the flash? */
132 jffs2_free_full_dnode(this->node); 156 if (rd->nsize + sizeof(*rd) > read) {
133 } else { 157 /* FIXME: point() */
134 D2(printk(KERN_DEBUG "Marking old node @0x%08x (0x%04x-0x%04x) REF_NORMAL. frags is %d\n", 158 int err;
135 ref_offset(this->node->raw), this->node->ofs, this->node->ofs+this->node->size, 159 int already = read - sizeof(*rd);
136 this->node->frags)); 160
137 mark_ref_normal(this->node->raw); 161 err = jffs2_flash_read(c, (ref_offset(ref)) + read,
162 rd->nsize - already, &read, &fd->name[already]);
163 if (unlikely(read != rd->nsize - already) && likely(!err))
164 return -EIO;
165
166 if (unlikely(err)) {
167 JFFS2_ERROR("read remainder of name: error %d\n", err);
168 jffs2_free_full_dirent(fd);
169 return -EIO;
138 } 170 }
139
140 } 171 }
141 jffs2_free_node_frag(this); 172
173 fd->nhash = full_name_hash(fd->name, rd->nsize);
174 fd->next = NULL;
175 fd->name[rd->nsize] = '\0';
176
177 /*
178 * Wheee. We now have a complete jffs2_full_dirent structure, with
179 * the name in it and everything. Link it into the list
180 */
181 jffs2_add_fd_to_list(c, fd, fdp);
182
183 return 0;
142} 184}
143 185
144/* Given an inode, probably with existing list of fragments, add the new node 186/*
145 * to the fragment list. 187 * Helper function for jffs2_get_inode_nodes().
188 * It is called every time an inode node is found.
189 *
190 * Returns: 0 on succes;
191 * 1 if the node should be marked obsolete;
192 * negative error code on failure.
146 */ 193 */
147int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn) 194static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref,
195 struct jffs2_raw_inode *rd, struct rb_root *tnp, int rdlen,
196 uint32_t *latest_mctime, uint32_t *mctime_ver)
148{ 197{
149 int ret; 198 struct jffs2_tmp_dnode_info *tn;
150 struct jffs2_node_frag *newfrag; 199 uint32_t len, csize;
151 200 int ret = 1;
152 D1(printk(KERN_DEBUG "jffs2_add_full_dnode_to_inode(ino #%u, f %p, fn %p)\n", f->inocache->ino, f, fn));
153 201
154 if (unlikely(!fn->size)) 202 /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
155 return 0; 203 BUG_ON(ref_obsolete(ref));
156 204
157 newfrag = jffs2_alloc_node_frag(); 205 tn = jffs2_alloc_tmp_dnode_info();
158 if (unlikely(!newfrag)) 206 if (!tn) {
207 JFFS2_ERROR("failed to allocate tn (%d bytes).\n", sizeof(*tn));
159 return -ENOMEM; 208 return -ENOMEM;
209 }
160 210
161 D2(printk(KERN_DEBUG "adding node %04x-%04x @0x%08x on flash, newfrag *%p\n", 211 tn->partial_crc = 0;
162 fn->ofs, fn->ofs+fn->size, ref_offset(fn->raw), newfrag)); 212 csize = je32_to_cpu(rd->csize);
163
164 newfrag->ofs = fn->ofs;
165 newfrag->size = fn->size;
166 newfrag->node = fn;
167 newfrag->node->frags = 1;
168 213
169 ret = jffs2_add_frag_to_fragtree(c, &f->fragtree, newfrag); 214 /* If we've never checked the CRCs on this node, check them now */
170 if (ret) 215 if (ref_flags(ref) == REF_UNCHECKED) {
171 return ret; 216 uint32_t crc;
172 217
173 /* If we now share a page with other nodes, mark either previous 218 crc = crc32(0, rd, sizeof(*rd) - 8);
174 or next node REF_NORMAL, as appropriate. */ 219 if (unlikely(crc != je32_to_cpu(rd->node_crc))) {
175 if (newfrag->ofs & (PAGE_CACHE_SIZE-1)) { 220 JFFS2_NOTICE("header CRC failed on node at %#08x: read %#08x, calculated %#08x\n",
176 struct jffs2_node_frag *prev = frag_prev(newfrag); 221 ref_offset(ref), je32_to_cpu(rd->node_crc), crc);
222 goto free_out;
223 }
177 224
178 mark_ref_normal(fn->raw); 225 /* Sanity checks */
179 /* If we don't start at zero there's _always_ a previous */ 226 if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) ||
180 if (prev->node) 227 unlikely(PAD(je32_to_cpu(rd->csize) + sizeof(*rd)) != PAD(je32_to_cpu(rd->totlen)))) {
181 mark_ref_normal(prev->node->raw); 228 JFFS2_WARNING("inode node header CRC is corrupted at %#08x\n", ref_offset(ref));
182 } 229 jffs2_dbg_dump_node(c, ref_offset(ref));
230 goto free_out;
231 }
183 232
184 if ((newfrag->ofs+newfrag->size) & (PAGE_CACHE_SIZE-1)) { 233 if (jffs2_is_writebuffered(c) && csize != 0) {
185 struct jffs2_node_frag *next = frag_next(newfrag); 234 /* At this point we are supposed to check the data CRC
186 235 * of our unchecked node. But thus far, we do not
187 if (next) { 236 * know whether the node is valid or obsolete. To
188 mark_ref_normal(fn->raw); 237 * figure this out, we need to walk all the nodes of
189 if (next->node) 238 * the inode and build the inode fragtree. We don't
190 mark_ref_normal(next->node->raw); 239 * want to spend time checking data of nodes which may
240 * later be found to be obsolete. So we put off the full
241 * data CRC checking until we have read all the inode
242 * nodes and have started building the fragtree.
243 *
244 * The fragtree is being built starting with nodes
245 * having the highest version number, so we'll be able
246 * to detect whether a node is valid (i.e., it is not
247 * overlapped by a node with higher version) or not.
248 * And we'll be able to check only those nodes, which
249 * are not obsolete.
250 *
251 * Of course, this optimization only makes sense in case
252 * of NAND flashes (or other flashes whith
253 * !jffs2_can_mark_obsolete()), since on NOR flashes
254 * nodes are marked obsolete physically.
255 *
256 * Since NAND flashes (or other flashes with
257 * jffs2_is_writebuffered(c)) are anyway read by
258 * fractions of c->wbuf_pagesize, and we have just read
259 * the node header, it is likely that the starting part
260 * of the node data is also read when we read the
261 * header. So we don't mind to check the CRC of the
262 * starting part of the data of the node now, and check
263 * the second part later (in jffs2_check_node_data()).
264 * Of course, we will not need to re-read and re-check
265 * the NAND page which we have just read. This is why we
266 * read the whole NAND page at jffs2_get_inode_nodes(),
267 * while we needed only the node header.
268 */
269 unsigned char *buf;
270
271 /* 'buf' will point to the start of data */
272 buf = (unsigned char *)rd + sizeof(*rd);
273 /* len will be the read data length */
274 len = min_t(uint32_t, rdlen - sizeof(*rd), csize);
275 tn->partial_crc = crc32(0, buf, len);
276
277 dbg_readinode("Calculates CRC (%#08x) for %d bytes, csize %d\n", tn->partial_crc, len, csize);
278
279 /* If we actually calculated the whole data CRC
280 * and it is wrong, drop the node. */
281 if (len >= csize && unlikely(tn->partial_crc != je32_to_cpu(rd->data_crc))) {
282 JFFS2_NOTICE("wrong data CRC in data node at 0x%08x: read %#08x, calculated %#08x.\n",
283 ref_offset(ref), tn->partial_crc, je32_to_cpu(rd->data_crc));
284 goto free_out;
285 }
286
287 } else if (csize == 0) {
288 /*
289 * We checked the header CRC. If the node has no data, adjust
290 * the space accounting now. For other nodes this will be done
291 * later either when the node is marked obsolete or when its
292 * data is checked.
293 */
294 struct jffs2_eraseblock *jeb;
295
296 dbg_readinode("the node has no data.\n");
297 jeb = &c->blocks[ref->flash_offset / c->sector_size];
298 len = ref_totlen(c, jeb, ref);
299
300 spin_lock(&c->erase_completion_lock);
301 jeb->used_size += len;
302 jeb->unchecked_size -= len;
303 c->used_size += len;
304 c->unchecked_size -= len;
305 ref->flash_offset = ref_offset(ref) | REF_NORMAL;
306 spin_unlock(&c->erase_completion_lock);
191 } 307 }
192 } 308 }
193 D2(if (jffs2_sanitycheck_fragtree(f)) { 309
194 printk(KERN_WARNING "Just added node %04x-%04x @0x%08x on flash, newfrag *%p\n", 310 tn->fn = jffs2_alloc_full_dnode();
195 fn->ofs, fn->ofs+fn->size, ref_offset(fn->raw), newfrag); 311 if (!tn->fn) {
196 return 0; 312 JFFS2_ERROR("alloc fn failed\n");
197 }) 313 ret = -ENOMEM;
198 D2(jffs2_print_frag_list(f)); 314 goto free_out;
315 }
316
317 tn->version = je32_to_cpu(rd->version);
318 tn->fn->ofs = je32_to_cpu(rd->offset);
319 tn->data_crc = je32_to_cpu(rd->data_crc);
320 tn->csize = csize;
321 tn->fn->raw = ref;
322
323 /* There was a bug where we wrote hole nodes out with
324 csize/dsize swapped. Deal with it */
325 if (rd->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(rd->dsize) && csize)
326 tn->fn->size = csize;
327 else // normal case...
328 tn->fn->size = je32_to_cpu(rd->dsize);
329
330 dbg_readinode("dnode @%08x: ver %u, offset %#04x, dsize %#04x, csize %#04x\n",
331 ref_offset(ref), je32_to_cpu(rd->version), je32_to_cpu(rd->offset), je32_to_cpu(rd->dsize), csize);
332
333 jffs2_add_tn_to_tree(tn, tnp);
334
199 return 0; 335 return 0;
336
337free_out:
338 jffs2_free_tmp_dnode_info(tn);
339 return ret;
200} 340}
201 341
202/* Doesn't set inode->i_size */ 342/*
203static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *list, struct jffs2_node_frag *newfrag) 343 * Helper function for jffs2_get_inode_nodes().
344 * It is called every time an unknown node is found.
345 *
346 * Returns: 0 on succes;
347 * 1 if the node should be marked obsolete;
348 * negative error code on failure.
349 */
350static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, struct jffs2_unknown_node *un)
204{ 351{
205 struct jffs2_node_frag *this; 352 /* We don't mark unknown nodes as REF_UNCHECKED */
206 uint32_t lastend; 353 BUG_ON(ref_flags(ref) == REF_UNCHECKED);
207 354
208 /* Skip all the nodes which are completed before this one starts */ 355 un->nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(un->nodetype));
209 this = jffs2_lookup_node_frag(list, newfrag->node->ofs);
210 356
211 if (this) { 357 if (crc32(0, un, sizeof(struct jffs2_unknown_node) - 4) != je32_to_cpu(un->hdr_crc)) {
212 D2(printk(KERN_DEBUG "j_a_f_d_t_f: Lookup gave frag 0x%04x-0x%04x; phys 0x%08x (*%p)\n", 358 /* Hmmm. This should have been caught at scan time. */
213 this->ofs, this->ofs+this->size, this->node?(ref_offset(this->node->raw)):0xffffffff, this)); 359 JFFS2_NOTICE("node header CRC failed at %#08x. But it must have been OK earlier.\n", ref_offset(ref));
214 lastend = this->ofs + this->size; 360 jffs2_dbg_dump_node(c, ref_offset(ref));
361 return 1;
215 } else { 362 } else {
216 D2(printk(KERN_DEBUG "j_a_f_d_t_f: Lookup gave no frag\n")); 363 switch(je16_to_cpu(un->nodetype) & JFFS2_COMPAT_MASK) {
217 lastend = 0;
218 }
219
220 /* See if we ran off the end of the list */
221 if (lastend <= newfrag->ofs) {
222 /* We did */
223
224 /* Check if 'this' node was on the same page as the new node.
225 If so, both 'this' and the new node get marked REF_NORMAL so
226 the GC can take a look.
227 */
228 if (lastend && (lastend-1) >> PAGE_CACHE_SHIFT == newfrag->ofs >> PAGE_CACHE_SHIFT) {
229 if (this->node)
230 mark_ref_normal(this->node->raw);
231 mark_ref_normal(newfrag->node->raw);
232 }
233 364
234 if (lastend < newfrag->node->ofs) { 365 case JFFS2_FEATURE_INCOMPAT:
235 /* ... and we need to put a hole in before the new node */ 366 JFFS2_ERROR("unknown INCOMPAT nodetype %#04X at %#08x\n",
236 struct jffs2_node_frag *holefrag = jffs2_alloc_node_frag(); 367 je16_to_cpu(un->nodetype), ref_offset(ref));
237 if (!holefrag) { 368 /* EEP */
238 jffs2_free_node_frag(newfrag); 369 BUG();
239 return -ENOMEM; 370 break;
240 } 371
241 holefrag->ofs = lastend; 372 case JFFS2_FEATURE_ROCOMPAT:
242 holefrag->size = newfrag->node->ofs - lastend; 373 JFFS2_ERROR("unknown ROCOMPAT nodetype %#04X at %#08x\n",
243 holefrag->node = NULL; 374 je16_to_cpu(un->nodetype), ref_offset(ref));
244 if (this) { 375 BUG_ON(!(c->flags & JFFS2_SB_FLAG_RO));
245 /* By definition, the 'this' node has no right-hand child, 376 break;
246 because there are no frags with offset greater than it. 377
247 So that's where we want to put the hole */ 378 case JFFS2_FEATURE_RWCOMPAT_COPY:
248 D2(printk(KERN_DEBUG "Adding hole frag (%p) on right of node at (%p)\n", holefrag, this)); 379 JFFS2_NOTICE("unknown RWCOMPAT_COPY nodetype %#04X at %#08x\n",
249 rb_link_node(&holefrag->rb, &this->rb, &this->rb.rb_right); 380 je16_to_cpu(un->nodetype), ref_offset(ref));
250 } else { 381 break;
251 D2(printk(KERN_DEBUG "Adding hole frag (%p) at root of tree\n", holefrag)); 382
252 rb_link_node(&holefrag->rb, NULL, &list->rb_node); 383 case JFFS2_FEATURE_RWCOMPAT_DELETE:
253 } 384 JFFS2_NOTICE("unknown RWCOMPAT_DELETE nodetype %#04X at %#08x\n",
254 rb_insert_color(&holefrag->rb, list); 385 je16_to_cpu(un->nodetype), ref_offset(ref));
255 this = holefrag; 386 return 1;
256 }
257 if (this) {
258 /* By definition, the 'this' node has no right-hand child,
259 because there are no frags with offset greater than it.
260 So that's where we want to put the hole */
261 D2(printk(KERN_DEBUG "Adding new frag (%p) on right of node at (%p)\n", newfrag, this));
262 rb_link_node(&newfrag->rb, &this->rb, &this->rb.rb_right);
263 } else {
264 D2(printk(KERN_DEBUG "Adding new frag (%p) at root of tree\n", newfrag));
265 rb_link_node(&newfrag->rb, NULL, &list->rb_node);
266 } 387 }
267 rb_insert_color(&newfrag->rb, list);
268 return 0;
269 } 388 }
270 389
271 D2(printk(KERN_DEBUG "j_a_f_d_t_f: dealing with frag 0x%04x-0x%04x; phys 0x%08x (*%p)\n", 390 return 0;
272 this->ofs, this->ofs+this->size, this->node?(ref_offset(this->node->raw)):0xffffffff, this)); 391}
273 392
274 /* OK. 'this' is pointing at the first frag that newfrag->ofs at least partially obsoletes, 393/*
275 * - i.e. newfrag->ofs < this->ofs+this->size && newfrag->ofs >= this->ofs 394 * Helper function for jffs2_get_inode_nodes().
276 */ 395 * The function detects whether more data should be read and reads it if yes.
277 if (newfrag->ofs > this->ofs) { 396 *
278 /* This node isn't completely obsoleted. The start of it remains valid */ 397 * Returns: 0 on succes;
279 398 * negative error code on failure.
280 /* Mark the new node and the partially covered node REF_NORMAL -- let 399 */
281 the GC take a look at them */ 400static int read_more(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref,
282 mark_ref_normal(newfrag->node->raw); 401 int right_size, int *rdlen, unsigned char *buf, unsigned char *bufstart)
283 if (this->node) 402{
284 mark_ref_normal(this->node->raw); 403 int right_len, err, len;
285 404 size_t retlen;
286 if (this->ofs + this->size > newfrag->ofs + newfrag->size) { 405 uint32_t offs;
287 /* The new node splits 'this' frag into two */
288 struct jffs2_node_frag *newfrag2 = jffs2_alloc_node_frag();
289 if (!newfrag2) {
290 jffs2_free_node_frag(newfrag);
291 return -ENOMEM;
292 }
293 D2(printk(KERN_DEBUG "split old frag 0x%04x-0x%04x -->", this->ofs, this->ofs+this->size);
294 if (this->node)
295 printk("phys 0x%08x\n", ref_offset(this->node->raw));
296 else
297 printk("hole\n");
298 )
299
300 /* New second frag pointing to this's node */
301 newfrag2->ofs = newfrag->ofs + newfrag->size;
302 newfrag2->size = (this->ofs+this->size) - newfrag2->ofs;
303 newfrag2->node = this->node;
304 if (this->node)
305 this->node->frags++;
306
307 /* Adjust size of original 'this' */
308 this->size = newfrag->ofs - this->ofs;
309
310 /* Now, we know there's no node with offset
311 greater than this->ofs but smaller than
312 newfrag2->ofs or newfrag->ofs, for obvious
313 reasons. So we can do a tree insert from
314 'this' to insert newfrag, and a tree insert
315 from newfrag to insert newfrag2. */
316 jffs2_fragtree_insert(newfrag, this);
317 rb_insert_color(&newfrag->rb, list);
318
319 jffs2_fragtree_insert(newfrag2, newfrag);
320 rb_insert_color(&newfrag2->rb, list);
321
322 return 0;
323 }
324 /* New node just reduces 'this' frag in size, doesn't split it */
325 this->size = newfrag->ofs - this->ofs;
326 406
327 /* Again, we know it lives down here in the tree */ 407 if (jffs2_is_writebuffered(c)) {
328 jffs2_fragtree_insert(newfrag, this); 408 right_len = c->wbuf_pagesize - (bufstart - buf);
329 rb_insert_color(&newfrag->rb, list); 409 if (right_size + (int)(bufstart - buf) > c->wbuf_pagesize)
330 } else { 410 right_len += c->wbuf_pagesize;
331 /* New frag starts at the same point as 'this' used to. Replace 411 } else
332 it in the tree without doing a delete and insertion */ 412 right_len = right_size;
333 D2(printk(KERN_DEBUG "Inserting newfrag (*%p),%d-%d in before 'this' (*%p),%d-%d\n",
334 newfrag, newfrag->ofs, newfrag->ofs+newfrag->size,
335 this, this->ofs, this->ofs+this->size));
336
337 rb_replace_node(&this->rb, &newfrag->rb, list);
338
339 if (newfrag->ofs + newfrag->size >= this->ofs+this->size) {
340 D2(printk(KERN_DEBUG "Obsoleting node frag %p (%x-%x)\n", this, this->ofs, this->ofs+this->size));
341 jffs2_obsolete_node_frag(c, this);
342 } else {
343 this->ofs += newfrag->size;
344 this->size -= newfrag->size;
345 413
346 jffs2_fragtree_insert(this, newfrag); 414 if (*rdlen == right_len)
347 rb_insert_color(&this->rb, list); 415 return 0;
348 return 0; 416
349 } 417 /* We need to read more data */
418 offs = ref_offset(ref) + *rdlen;
419 if (jffs2_is_writebuffered(c)) {
420 bufstart = buf + c->wbuf_pagesize;
421 len = c->wbuf_pagesize;
422 } else {
423 bufstart = buf + *rdlen;
424 len = right_size - *rdlen;
350 } 425 }
351 /* OK, now we have newfrag added in the correct place in the tree, but 426
352 frag_next(newfrag) may be a fragment which is overlapped by it 427 dbg_readinode("read more %d bytes\n", len);
353 */ 428
354 while ((this = frag_next(newfrag)) && newfrag->ofs + newfrag->size >= this->ofs + this->size) { 429 err = jffs2_flash_read(c, offs, len, &retlen, bufstart);
355 /* 'this' frag is obsoleted completely. */ 430 if (err) {
356 D2(printk(KERN_DEBUG "Obsoleting node frag %p (%x-%x) and removing from tree\n", this, this->ofs, this->ofs+this->size)); 431 JFFS2_ERROR("can not read %d bytes from 0x%08x, "
357 rb_erase(&this->rb, list); 432 "error code: %d.\n", len, offs, err);
358 jffs2_obsolete_node_frag(c, this); 433 return err;
359 } 434 }
360 /* Now we're pointing at the first frag which isn't totally obsoleted by
361 the new frag */
362 435
363 if (!this || newfrag->ofs + newfrag->size == this->ofs) { 436 if (retlen < len) {
364 return 0; 437 JFFS2_ERROR("short read at %#08x: %d instead of %d.\n",
438 offs, retlen, len);
439 return -EIO;
365 } 440 }
366 /* Still some overlap but we don't need to move it in the tree */
367 this->size = (this->ofs + this->size) - (newfrag->ofs + newfrag->size);
368 this->ofs = newfrag->ofs + newfrag->size;
369 441
370 /* And mark them REF_NORMAL so the GC takes a look at them */ 442 *rdlen = right_len;
371 if (this->node)
372 mark_ref_normal(this->node->raw);
373 mark_ref_normal(newfrag->node->raw);
374 443
375 return 0; 444 return 0;
376} 445}
377 446
378void jffs2_truncate_fraglist (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size) 447/* Get tmp_dnode_info and full_dirent for all non-obsolete nodes associated
448 with this ino, returning the former in order of version */
449static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
450 struct rb_root *tnp, struct jffs2_full_dirent **fdp,
451 uint32_t *highest_version, uint32_t *latest_mctime,
452 uint32_t *mctime_ver)
379{ 453{
380 struct jffs2_node_frag *frag = jffs2_lookup_node_frag(list, size); 454 struct jffs2_raw_node_ref *ref, *valid_ref;
455 struct rb_root ret_tn = RB_ROOT;
456 struct jffs2_full_dirent *ret_fd = NULL;
457 unsigned char *buf = NULL;
458 union jffs2_node_union *node;
459 size_t retlen;
460 int len, err;
461
462 *mctime_ver = 0;
463
464 dbg_readinode("ino #%u\n", f->inocache->ino);
465
466 if (jffs2_is_writebuffered(c)) {
467 /*
468 * If we have the write buffer, we assume the minimal I/O unit
469 * is c->wbuf_pagesize. We implement some optimizations which in
470 * this case and we need a temporary buffer of size =
471 * 2*c->wbuf_pagesize bytes (see comments in read_dnode()).
472 * Basically, we want to read not only the node header, but the
473 * whole wbuf (NAND page in case of NAND) or 2, if the node
474 * header overlaps the border between the 2 wbufs.
475 */
476 len = 2*c->wbuf_pagesize;
477 } else {
478 /*
479 * When there is no write buffer, the size of the temporary
480 * buffer is the size of the larges node header.
481 */
482 len = sizeof(union jffs2_node_union);
483 }
381 484
382 D1(printk(KERN_DEBUG "Truncating fraglist to 0x%08x bytes\n", size)); 485 /* FIXME: in case of NOR and available ->point() this
486 * needs to be fixed. */
487 buf = kmalloc(len, GFP_KERNEL);
488 if (!buf)
489 return -ENOMEM;
383 490
384 /* We know frag->ofs <= size. That's what lookup does for us */ 491 spin_lock(&c->erase_completion_lock);
385 if (frag && frag->ofs != size) { 492 valid_ref = jffs2_first_valid_node(f->inocache->nodes);
386 if (frag->ofs+frag->size >= size) { 493 if (!valid_ref && f->inocache->ino != 1)
387 D1(printk(KERN_DEBUG "Truncating frag 0x%08x-0x%08x\n", frag->ofs, frag->ofs+frag->size)); 494 JFFS2_WARNING("Eep. No valid nodes for ino #%u.\n", f->inocache->ino);
388 frag->size = size - frag->ofs; 495 while (valid_ref) {
496 unsigned char *bufstart;
497
498 /* We can hold a pointer to a non-obsolete node without the spinlock,
499 but _obsolete_ nodes may disappear at any time, if the block
500 they're in gets erased. So if we mark 'ref' obsolete while we're
501 not holding the lock, it can go away immediately. For that reason,
502 we find the next valid node first, before processing 'ref'.
503 */
504 ref = valid_ref;
505 valid_ref = jffs2_first_valid_node(ref->next_in_ino);
506 spin_unlock(&c->erase_completion_lock);
507
508 cond_resched();
509
510 /*
511 * At this point we don't know the type of the node we're going
512 * to read, so we do not know the size of its header. In order
513 * to minimize the amount of flash IO we assume the node has
514 * size = JFFS2_MIN_NODE_HEADER.
515 */
516 if (jffs2_is_writebuffered(c)) {
517 /*
518 * We treat 'buf' as 2 adjacent wbufs. We want to
519 * adjust bufstart such as it points to the
520 * beginning of the node within this wbuf.
521 */
522 bufstart = buf + (ref_offset(ref) % c->wbuf_pagesize);
523 /* We will read either one wbuf or 2 wbufs. */
524 len = c->wbuf_pagesize - (bufstart - buf);
525 if (JFFS2_MIN_NODE_HEADER + (int)(bufstart - buf) > c->wbuf_pagesize) {
526 /* The header spans the border of the first wbuf */
527 len += c->wbuf_pagesize;
528 }
529 } else {
530 bufstart = buf;
531 len = JFFS2_MIN_NODE_HEADER;
389 } 532 }
390 frag = frag_next(frag);
391 }
392 while (frag && frag->ofs >= size) {
393 struct jffs2_node_frag *next = frag_next(frag);
394 533
395 D1(printk(KERN_DEBUG "Removing frag 0x%08x-0x%08x\n", frag->ofs, frag->ofs+frag->size)); 534 dbg_readinode("read %d bytes at %#08x(%d).\n", len, ref_offset(ref), ref_flags(ref));
396 frag_erase(frag, list);
397 jffs2_obsolete_node_frag(c, frag);
398 frag = next;
399 }
400}
401 535
402/* Scan the list of all nodes present for this ino, build map of versions, etc. */ 536 /* FIXME: point() */
537 err = jffs2_flash_read(c, ref_offset(ref), len,
538 &retlen, bufstart);
539 if (err) {
540 JFFS2_ERROR("can not read %d bytes from 0x%08x, " "error code: %d.\n", len, ref_offset(ref), err);
541 goto free_out;
542 }
403 543
404static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c, 544 if (retlen < len) {
405 struct jffs2_inode_info *f, 545 JFFS2_ERROR("short read at %#08x: %d instead of %d.\n", ref_offset(ref), retlen, len);
406 struct jffs2_raw_inode *latest_node); 546 err = -EIO;
547 goto free_out;
548 }
407 549
408int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 550 node = (union jffs2_node_union *)bufstart;
409 uint32_t ino, struct jffs2_raw_inode *latest_node)
410{
411 D2(printk(KERN_DEBUG "jffs2_do_read_inode(): getting inocache\n"));
412 551
413 retry_inocache: 552 switch (je16_to_cpu(node->u.nodetype)) {
414 spin_lock(&c->inocache_lock);
415 f->inocache = jffs2_get_ino_cache(c, ino);
416 553
417 D2(printk(KERN_DEBUG "jffs2_do_read_inode(): Got inocache at %p\n", f->inocache)); 554 case JFFS2_NODETYPE_DIRENT:
555
556 if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_dirent)) {
557 err = read_more(c, ref, sizeof(struct jffs2_raw_dirent), &len, buf, bufstart);
558 if (unlikely(err))
559 goto free_out;
560 }
561
562 err = read_direntry(c, ref, &node->d, retlen, &ret_fd, latest_mctime, mctime_ver);
563 if (err == 1) {
564 jffs2_mark_node_obsolete(c, ref);
565 break;
566 } else if (unlikely(err))
567 goto free_out;
568
569 if (je32_to_cpu(node->d.version) > *highest_version)
570 *highest_version = je32_to_cpu(node->d.version);
418 571
419 if (f->inocache) {
420 /* Check its state. We may need to wait before we can use it */
421 switch(f->inocache->state) {
422 case INO_STATE_UNCHECKED:
423 case INO_STATE_CHECKEDABSENT:
424 f->inocache->state = INO_STATE_READING;
425 break; 572 break;
426
427 case INO_STATE_CHECKING:
428 case INO_STATE_GC:
429 /* If it's in either of these states, we need
430 to wait for whoever's got it to finish and
431 put it back. */
432 D1(printk(KERN_DEBUG "jffs2_get_ino_cache_read waiting for ino #%u in state %d\n",
433 ino, f->inocache->state));
434 sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
435 goto retry_inocache;
436 573
437 case INO_STATE_READING: 574 case JFFS2_NODETYPE_INODE:
438 case INO_STATE_PRESENT: 575
439 /* Eep. This should never happen. It can 576 if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_inode)) {
440 happen if Linux calls read_inode() again 577 err = read_more(c, ref, sizeof(struct jffs2_raw_inode), &len, buf, bufstart);
441 before clear_inode() has finished though. */ 578 if (unlikely(err))
442 printk(KERN_WARNING "Eep. Trying to read_inode #%u when it's already in state %d!\n", ino, f->inocache->state); 579 goto free_out;
443 /* Fail. That's probably better than allowing it to succeed */ 580 }
444 f->inocache = NULL; 581
582 err = read_dnode(c, ref, &node->i, &ret_tn, len, latest_mctime, mctime_ver);
583 if (err == 1) {
584 jffs2_mark_node_obsolete(c, ref);
585 break;
586 } else if (unlikely(err))
587 goto free_out;
588
589 if (je32_to_cpu(node->i.version) > *highest_version)
590 *highest_version = je32_to_cpu(node->i.version);
591
445 break; 592 break;
446 593
447 default: 594 default:
448 BUG(); 595 if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_unknown_node)) {
449 } 596 err = read_more(c, ref, sizeof(struct jffs2_unknown_node), &len, buf, bufstart);
450 } 597 if (unlikely(err))
451 spin_unlock(&c->inocache_lock); 598 goto free_out;
599 }
600
601 err = read_unknown(c, ref, &node->u);
602 if (err == 1) {
603 jffs2_mark_node_obsolete(c, ref);
604 break;
605 } else if (unlikely(err))
606 goto free_out;
452 607
453 if (!f->inocache && ino == 1) {
454 /* Special case - no root inode on medium */
455 f->inocache = jffs2_alloc_inode_cache();
456 if (!f->inocache) {
457 printk(KERN_CRIT "jffs2_do_read_inode(): Cannot allocate inocache for root inode\n");
458 return -ENOMEM;
459 } 608 }
460 D1(printk(KERN_DEBUG "jffs2_do_read_inode(): Creating inocache for root inode\n")); 609 spin_lock(&c->erase_completion_lock);
461 memset(f->inocache, 0, sizeof(struct jffs2_inode_cache));
462 f->inocache->ino = f->inocache->nlink = 1;
463 f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
464 f->inocache->state = INO_STATE_READING;
465 jffs2_add_ino_cache(c, f->inocache);
466 } 610 }
467 if (!f->inocache) {
468 printk(KERN_WARNING "jffs2_do_read_inode() on nonexistent ino %u\n", ino);
469 return -ENOENT;
470 }
471
472 return jffs2_do_read_inode_internal(c, f, latest_node);
473}
474 611
475int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) 612 spin_unlock(&c->erase_completion_lock);
476{ 613 *tnp = ret_tn;
477 struct jffs2_raw_inode n; 614 *fdp = ret_fd;
478 struct jffs2_inode_info *f = kmalloc(sizeof(*f), GFP_KERNEL); 615 kfree(buf);
479 int ret;
480 616
481 if (!f) 617 dbg_readinode("nodes of inode #%u were read, the highest version is %u, latest_mctime %u, mctime_ver %u.\n",
482 return -ENOMEM; 618 f->inocache->ino, *highest_version, *latest_mctime, *mctime_ver);
483 619 return 0;
484 memset(f, 0, sizeof(*f));
485 init_MUTEX_LOCKED(&f->sem);
486 f->inocache = ic;
487 620
488 ret = jffs2_do_read_inode_internal(c, f, &n); 621 free_out:
489 if (!ret) { 622 jffs2_free_tmp_dnode_info_list(&ret_tn);
490 up(&f->sem); 623 jffs2_free_full_dirent_list(ret_fd);
491 jffs2_do_clear_inode(c, f); 624 kfree(buf);
492 } 625 return err;
493 kfree(f);
494 return ret;
495} 626}
496 627
497static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c, 628static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
498 struct jffs2_inode_info *f, 629 struct jffs2_inode_info *f,
499 struct jffs2_raw_inode *latest_node) 630 struct jffs2_raw_inode *latest_node)
500{ 631{
501 struct jffs2_tmp_dnode_info *tn = NULL; 632 struct jffs2_tmp_dnode_info *tn;
502 struct rb_root tn_list; 633 struct rb_root tn_list;
503 struct rb_node *rb, *repl_rb; 634 struct rb_node *rb, *repl_rb;
504 struct jffs2_full_dirent *fd_list; 635 struct jffs2_full_dirent *fd_list;
505 struct jffs2_full_dnode *fn = NULL; 636 struct jffs2_full_dnode *fn, *first_fn = NULL;
506 uint32_t crc; 637 uint32_t crc;
507 uint32_t latest_mctime, mctime_ver; 638 uint32_t latest_mctime, mctime_ver;
508 uint32_t mdata_ver = 0;
509 size_t retlen; 639 size_t retlen;
510 int ret; 640 int ret;
511 641
512 D1(printk(KERN_DEBUG "jffs2_do_read_inode_internal(): ino #%u nlink is %d\n", f->inocache->ino, f->inocache->nlink)); 642 dbg_readinode("ino #%u nlink is %d\n", f->inocache->ino, f->inocache->nlink);
513 643
514 /* Grab all nodes relevant to this ino */ 644 /* Grab all nodes relevant to this ino */
515 ret = jffs2_get_inode_nodes(c, f, &tn_list, &fd_list, &f->highest_version, &latest_mctime, &mctime_ver); 645 ret = jffs2_get_inode_nodes(c, f, &tn_list, &fd_list, &f->highest_version, &latest_mctime, &mctime_ver);
516 646
517 if (ret) { 647 if (ret) {
518 printk(KERN_CRIT "jffs2_get_inode_nodes() for ino %u returned %d\n", f->inocache->ino, ret); 648 JFFS2_ERROR("cannot read nodes for ino %u, returned error is %d\n", f->inocache->ino, ret);
519 if (f->inocache->state == INO_STATE_READING) 649 if (f->inocache->state == INO_STATE_READING)
520 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); 650 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
521 return ret; 651 return ret;
@@ -525,42 +655,33 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
525 rb = rb_first(&tn_list); 655 rb = rb_first(&tn_list);
526 656
527 while (rb) { 657 while (rb) {
658 cond_resched();
528 tn = rb_entry(rb, struct jffs2_tmp_dnode_info, rb); 659 tn = rb_entry(rb, struct jffs2_tmp_dnode_info, rb);
529 fn = tn->fn; 660 fn = tn->fn;
530 661 ret = 1;
531 if (f->metadata) { 662 dbg_readinode("consider node ver %u, phys offset "
532 if (likely(tn->version >= mdata_ver)) { 663 "%#08x(%d), range %u-%u.\n", tn->version,
533 D1(printk(KERN_DEBUG "Obsoleting old metadata at 0x%08x\n", ref_offset(f->metadata->raw))); 664 ref_offset(fn->raw), ref_flags(fn->raw),
534 jffs2_mark_node_obsolete(c, f->metadata->raw); 665 fn->ofs, fn->ofs + fn->size);
535 jffs2_free_full_dnode(f->metadata);
536 f->metadata = NULL;
537
538 mdata_ver = 0;
539 } else {
540 /* This should never happen. */
541 printk(KERN_WARNING "Er. New metadata at 0x%08x with ver %d is actually older than previous ver %d at 0x%08x\n",
542 ref_offset(fn->raw), tn->version, mdata_ver, ref_offset(f->metadata->raw));
543 jffs2_mark_node_obsolete(c, fn->raw);
544 jffs2_free_full_dnode(fn);
545 /* Fill in latest_node from the metadata, not this one we're about to free... */
546 fn = f->metadata;
547 goto next_tn;
548 }
549 }
550 666
551 if (fn->size) { 667 if (fn->size) {
552 jffs2_add_full_dnode_to_inode(c, f, fn); 668 ret = jffs2_add_older_frag_to_fragtree(c, f, tn);
553 } else { 669 /* TODO: the error code isn't checked, check it */
554 /* Zero-sized node at end of version list. Just a metadata update */ 670 jffs2_dbg_fragtree_paranoia_check_nolock(f);
555 D1(printk(KERN_DEBUG "metadata @%08x: ver %d\n", ref_offset(fn->raw), tn->version)); 671 BUG_ON(ret < 0);
672 if (!first_fn && ret == 0)
673 first_fn = fn;
674 } else if (!first_fn) {
675 first_fn = fn;
556 f->metadata = fn; 676 f->metadata = fn;
557 mdata_ver = tn->version; 677 ret = 0; /* Prevent freeing the metadata update node */
558 } 678 } else
559 next_tn: 679 jffs2_mark_node_obsolete(c, fn->raw);
680
560 BUG_ON(rb->rb_left); 681 BUG_ON(rb->rb_left);
561 if (rb->rb_parent && rb->rb_parent->rb_left == rb) { 682 if (rb->rb_parent && rb->rb_parent->rb_left == rb) {
562 /* We were then left-hand child of our parent. We need 683 /* We were then left-hand child of our parent. We need
563 to move our own right-hand child into our place. */ 684 * to move our own right-hand child into our place. */
564 repl_rb = rb->rb_right; 685 repl_rb = rb->rb_right;
565 if (repl_rb) 686 if (repl_rb)
566 repl_rb->rb_parent = rb->rb_parent; 687 repl_rb->rb_parent = rb->rb_parent;
@@ -570,7 +691,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
570 rb = rb_next(rb); 691 rb = rb_next(rb);
571 692
572 /* Remove the spent tn from the tree; don't bother rebalancing 693 /* Remove the spent tn from the tree; don't bother rebalancing
573 but put our right-hand child in our own place. */ 694 * but put our right-hand child in our own place. */
574 if (tn->rb.rb_parent) { 695 if (tn->rb.rb_parent) {
575 if (tn->rb.rb_parent->rb_left == &tn->rb) 696 if (tn->rb.rb_parent->rb_left == &tn->rb)
576 tn->rb.rb_parent->rb_left = repl_rb; 697 tn->rb.rb_parent->rb_left = repl_rb;
@@ -581,19 +702,27 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
581 tn->rb.rb_right->rb_parent = NULL; 702 tn->rb.rb_right->rb_parent = NULL;
582 703
583 jffs2_free_tmp_dnode_info(tn); 704 jffs2_free_tmp_dnode_info(tn);
705 if (ret) {
706 dbg_readinode("delete dnode %u-%u.\n",
707 fn->ofs, fn->ofs + fn->size);
708 jffs2_free_full_dnode(fn);
709 }
584 } 710 }
585 D1(jffs2_sanitycheck_fragtree(f)); 711 jffs2_dbg_fragtree_paranoia_check_nolock(f);
586 712
587 if (!fn) { 713 BUG_ON(first_fn && ref_obsolete(first_fn->raw));
714
715 fn = first_fn;
716 if (unlikely(!first_fn)) {
588 /* No data nodes for this inode. */ 717 /* No data nodes for this inode. */
589 if (f->inocache->ino != 1) { 718 if (f->inocache->ino != 1) {
590 printk(KERN_WARNING "jffs2_do_read_inode(): No data nodes found for ino #%u\n", f->inocache->ino); 719 JFFS2_WARNING("no data nodes found for ino #%u\n", f->inocache->ino);
591 if (!fd_list) { 720 if (!fd_list) {
592 if (f->inocache->state == INO_STATE_READING) 721 if (f->inocache->state == INO_STATE_READING)
593 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); 722 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
594 return -EIO; 723 return -EIO;
595 } 724 }
596 printk(KERN_WARNING "jffs2_do_read_inode(): But it has children so we fake some modes for it\n"); 725 JFFS2_NOTICE("but it has children so we fake some modes for it\n");
597 } 726 }
598 latest_node->mode = cpu_to_jemode(S_IFDIR|S_IRUGO|S_IWUSR|S_IXUGO); 727 latest_node->mode = cpu_to_jemode(S_IFDIR|S_IRUGO|S_IWUSR|S_IXUGO);
599 latest_node->version = cpu_to_je32(0); 728 latest_node->version = cpu_to_je32(0);
@@ -608,8 +737,8 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
608 737
609 ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(*latest_node), &retlen, (void *)latest_node); 738 ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(*latest_node), &retlen, (void *)latest_node);
610 if (ret || retlen != sizeof(*latest_node)) { 739 if (ret || retlen != sizeof(*latest_node)) {
611 printk(KERN_NOTICE "MTD read in jffs2_do_read_inode() failed: Returned %d, %zd of %zd bytes read\n", 740 JFFS2_ERROR("failed to read from flash: error %d, %zd of %zd bytes read\n",
612 ret, retlen, sizeof(*latest_node)); 741 ret, retlen, sizeof(*latest_node));
613 /* FIXME: If this fails, there seems to be a memory leak. Find it. */ 742 /* FIXME: If this fails, there seems to be a memory leak. Find it. */
614 up(&f->sem); 743 up(&f->sem);
615 jffs2_do_clear_inode(c, f); 744 jffs2_do_clear_inode(c, f);
@@ -618,7 +747,8 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
618 747
619 crc = crc32(0, latest_node, sizeof(*latest_node)-8); 748 crc = crc32(0, latest_node, sizeof(*latest_node)-8);
620 if (crc != je32_to_cpu(latest_node->node_crc)) { 749 if (crc != je32_to_cpu(latest_node->node_crc)) {
621 printk(KERN_NOTICE "CRC failed for read_inode of inode %u at physical location 0x%x\n", f->inocache->ino, ref_offset(fn->raw)); 750 JFFS2_ERROR("CRC failed for read_inode of inode %u at physical location 0x%x\n",
751 f->inocache->ino, ref_offset(fn->raw));
622 up(&f->sem); 752 up(&f->sem);
623 jffs2_do_clear_inode(c, f); 753 jffs2_do_clear_inode(c, f);
624 return -EIO; 754 return -EIO;
@@ -633,10 +763,10 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
633 } 763 }
634 break; 764 break;
635 765
636 766
637 case S_IFREG: 767 case S_IFREG:
638 /* If it was a regular file, truncate it to the latest node's isize */ 768 /* If it was a regular file, truncate it to the latest node's isize */
639 jffs2_truncate_fraglist(c, &f->fragtree, je32_to_cpu(latest_node->isize)); 769 jffs2_truncate_fragtree(c, &f->fragtree, je32_to_cpu(latest_node->isize));
640 break; 770 break;
641 771
642 case S_IFLNK: 772 case S_IFLNK:
@@ -649,37 +779,33 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
649 779
650 if (f->inocache->state != INO_STATE_CHECKING) { 780 if (f->inocache->state != INO_STATE_CHECKING) {
651 /* Symlink's inode data is the target path. Read it and 781 /* Symlink's inode data is the target path. Read it and
652 * keep in RAM to facilitate quick follow symlink operation. 782 * keep in RAM to facilitate quick follow symlink
653 * We use f->dents field to store the target path, which 783 * operation. */
654 * is somewhat ugly. */ 784 f->target = kmalloc(je32_to_cpu(latest_node->csize) + 1, GFP_KERNEL);
655 f->dents = kmalloc(je32_to_cpu(latest_node->csize) + 1, GFP_KERNEL); 785 if (!f->target) {
656 if (!f->dents) { 786 JFFS2_ERROR("can't allocate %d bytes of memory for the symlink target path cache\n", je32_to_cpu(latest_node->csize));
657 printk(KERN_WARNING "Can't allocate %d bytes of memory "
658 "for the symlink target path cache\n",
659 je32_to_cpu(latest_node->csize));
660 up(&f->sem); 787 up(&f->sem);
661 jffs2_do_clear_inode(c, f); 788 jffs2_do_clear_inode(c, f);
662 return -ENOMEM; 789 return -ENOMEM;
663 } 790 }
664 791
665 ret = jffs2_flash_read(c, ref_offset(fn->raw) + sizeof(*latest_node), 792 ret = jffs2_flash_read(c, ref_offset(fn->raw) + sizeof(*latest_node),
666 je32_to_cpu(latest_node->csize), &retlen, (char *)f->dents); 793 je32_to_cpu(latest_node->csize), &retlen, (char *)f->target);
667 794
668 if (ret || retlen != je32_to_cpu(latest_node->csize)) { 795 if (ret || retlen != je32_to_cpu(latest_node->csize)) {
669 if (retlen != je32_to_cpu(latest_node->csize)) 796 if (retlen != je32_to_cpu(latest_node->csize))
670 ret = -EIO; 797 ret = -EIO;
671 kfree(f->dents); 798 kfree(f->target);
672 f->dents = NULL; 799 f->target = NULL;
673 up(&f->sem); 800 up(&f->sem);
674 jffs2_do_clear_inode(c, f); 801 jffs2_do_clear_inode(c, f);
675 return -ret; 802 return -ret;
676 } 803 }
677 804
678 ((char *)f->dents)[je32_to_cpu(latest_node->csize)] = '\0'; 805 f->target[je32_to_cpu(latest_node->csize)] = '\0';
679 D1(printk(KERN_DEBUG "jffs2_do_read_inode(): symlink's target '%s' cached\n", 806 dbg_readinode("symlink's target '%s' cached\n", f->target);
680 (char *)f->dents));
681 } 807 }
682 808
683 /* fall through... */ 809 /* fall through... */
684 810
685 case S_IFBLK: 811 case S_IFBLK:
@@ -687,14 +813,14 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
687 /* Certain inode types should have only one data node, and it's 813 /* Certain inode types should have only one data node, and it's
688 kept as the metadata node */ 814 kept as the metadata node */
689 if (f->metadata) { 815 if (f->metadata) {
690 printk(KERN_WARNING "Argh. Special inode #%u with mode 0%o had metadata node\n", 816 JFFS2_ERROR("Argh. Special inode #%u with mode 0%o had metadata node\n",
691 f->inocache->ino, jemode_to_cpu(latest_node->mode)); 817 f->inocache->ino, jemode_to_cpu(latest_node->mode));
692 up(&f->sem); 818 up(&f->sem);
693 jffs2_do_clear_inode(c, f); 819 jffs2_do_clear_inode(c, f);
694 return -EIO; 820 return -EIO;
695 } 821 }
696 if (!frag_first(&f->fragtree)) { 822 if (!frag_first(&f->fragtree)) {
697 printk(KERN_WARNING "Argh. Special inode #%u with mode 0%o has no fragments\n", 823 JFFS2_ERROR("Argh. Special inode #%u with mode 0%o has no fragments\n",
698 f->inocache->ino, jemode_to_cpu(latest_node->mode)); 824 f->inocache->ino, jemode_to_cpu(latest_node->mode));
699 up(&f->sem); 825 up(&f->sem);
700 jffs2_do_clear_inode(c, f); 826 jffs2_do_clear_inode(c, f);
@@ -702,7 +828,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
702 } 828 }
703 /* ASSERT: f->fraglist != NULL */ 829 /* ASSERT: f->fraglist != NULL */
704 if (frag_next(frag_first(&f->fragtree))) { 830 if (frag_next(frag_first(&f->fragtree))) {
705 printk(KERN_WARNING "Argh. Special inode #%u with mode 0x%x had more than one node\n", 831 JFFS2_ERROR("Argh. Special inode #%u with mode 0x%x had more than one node\n",
706 f->inocache->ino, jemode_to_cpu(latest_node->mode)); 832 f->inocache->ino, jemode_to_cpu(latest_node->mode));
707 /* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */ 833 /* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */
708 up(&f->sem); 834 up(&f->sem);
@@ -721,6 +847,93 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
721 return 0; 847 return 0;
722} 848}
723 849
850/* Scan the list of all nodes present for this ino, build map of versions, etc. */
851int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
852 uint32_t ino, struct jffs2_raw_inode *latest_node)
853{
854 dbg_readinode("read inode #%u\n", ino);
855
856 retry_inocache:
857 spin_lock(&c->inocache_lock);
858 f->inocache = jffs2_get_ino_cache(c, ino);
859
860 if (f->inocache) {
861 /* Check its state. We may need to wait before we can use it */
862 switch(f->inocache->state) {
863 case INO_STATE_UNCHECKED:
864 case INO_STATE_CHECKEDABSENT:
865 f->inocache->state = INO_STATE_READING;
866 break;
867
868 case INO_STATE_CHECKING:
869 case INO_STATE_GC:
870 /* If it's in either of these states, we need
871 to wait for whoever's got it to finish and
872 put it back. */
873 dbg_readinode("waiting for ino #%u in state %d\n", ino, f->inocache->state);
874 sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
875 goto retry_inocache;
876
877 case INO_STATE_READING:
878 case INO_STATE_PRESENT:
879 /* Eep. This should never happen. It can
880 happen if Linux calls read_inode() again
881 before clear_inode() has finished though. */
882 JFFS2_ERROR("Eep. Trying to read_inode #%u when it's already in state %d!\n", ino, f->inocache->state);
883 /* Fail. That's probably better than allowing it to succeed */
884 f->inocache = NULL;
885 break;
886
887 default:
888 BUG();
889 }
890 }
891 spin_unlock(&c->inocache_lock);
892
893 if (!f->inocache && ino == 1) {
894 /* Special case - no root inode on medium */
895 f->inocache = jffs2_alloc_inode_cache();
896 if (!f->inocache) {
897 JFFS2_ERROR("cannot allocate inocache for root inode\n");
898 return -ENOMEM;
899 }
900 dbg_readinode("creating inocache for root inode\n");
901 memset(f->inocache, 0, sizeof(struct jffs2_inode_cache));
902 f->inocache->ino = f->inocache->nlink = 1;
903 f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
904 f->inocache->state = INO_STATE_READING;
905 jffs2_add_ino_cache(c, f->inocache);
906 }
907 if (!f->inocache) {
908 JFFS2_ERROR("requestied to read an nonexistent ino %u\n", ino);
909 return -ENOENT;
910 }
911
912 return jffs2_do_read_inode_internal(c, f, latest_node);
913}
914
915int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
916{
917 struct jffs2_raw_inode n;
918 struct jffs2_inode_info *f = kmalloc(sizeof(*f), GFP_KERNEL);
919 int ret;
920
921 if (!f)
922 return -ENOMEM;
923
924 memset(f, 0, sizeof(*f));
925 init_MUTEX_LOCKED(&f->sem);
926 f->inocache = ic;
927
928 ret = jffs2_do_read_inode_internal(c, f, &n);
929 if (!ret) {
930 up(&f->sem);
931 jffs2_do_clear_inode(c, f);
932 }
933 kfree (f);
934 return ret;
935}
936
724void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f) 937void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
725{ 938{
726 struct jffs2_full_dirent *fd, *fds; 939 struct jffs2_full_dirent *fd, *fds;
@@ -740,18 +953,16 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
740 953
741 jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL); 954 jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL);
742 955
743 /* For symlink inodes we us f->dents to store the target path name */ 956 if (f->target) {
744 if (S_ISLNK(OFNI_EDONI_2SFFJ(f)->i_mode)) { 957 kfree(f->target);
745 kfree(f->dents); 958 f->target = NULL;
746 f->dents = NULL; 959 }
747 } else {
748 fds = f->dents;
749 960
750 while(fds) { 961 fds = f->dents;
751 fd = fds; 962 while(fds) {
752 fds = fd->next; 963 fd = fds;
753 jffs2_free_full_dirent(fd); 964 fds = fd->next;
754 } 965 jffs2_free_full_dirent(fd);
755 } 966 }
756 967
757 if (f->inocache && f->inocache->state != INO_STATE_CHECKING) { 968 if (f->inocache && f->inocache->state != INO_STATE_CHECKING) {
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
index b63160f83bab..0e7456ec99fd 100644
--- a/fs/jffs2/scan.c
+++ b/fs/jffs2/scan.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: scan.c,v 1.119 2005/02/17 17:51:13 dedekind Exp $ 10 * $Id: scan.c,v 1.125 2005/09/30 13:59:13 dedekind Exp $
11 * 11 *
12 */ 12 */
13#include <linux/kernel.h> 13#include <linux/kernel.h>
@@ -18,22 +18,11 @@
18#include <linux/crc32.h> 18#include <linux/crc32.h>
19#include <linux/compiler.h> 19#include <linux/compiler.h>
20#include "nodelist.h" 20#include "nodelist.h"
21#include "summary.h"
22#include "debug.h"
21 23
22#define DEFAULT_EMPTY_SCAN_SIZE 1024 24#define DEFAULT_EMPTY_SCAN_SIZE 1024
23 25
24#define DIRTY_SPACE(x) do { typeof(x) _x = (x); \
25 c->free_size -= _x; c->dirty_size += _x; \
26 jeb->free_size -= _x ; jeb->dirty_size += _x; \
27 }while(0)
28#define USED_SPACE(x) do { typeof(x) _x = (x); \
29 c->free_size -= _x; c->used_size += _x; \
30 jeb->free_size -= _x ; jeb->used_size += _x; \
31 }while(0)
32#define UNCHECKED_SPACE(x) do { typeof(x) _x = (x); \
33 c->free_size -= _x; c->unchecked_size += _x; \
34 jeb->free_size -= _x ; jeb->unchecked_size += _x; \
35 }while(0)
36
37#define noisy_printk(noise, args...) do { \ 26#define noisy_printk(noise, args...) do { \
38 if (*(noise)) { \ 27 if (*(noise)) { \
39 printk(KERN_NOTICE args); \ 28 printk(KERN_NOTICE args); \
@@ -47,23 +36,16 @@
47static uint32_t pseudo_random; 36static uint32_t pseudo_random;
48 37
49static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 38static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
50 unsigned char *buf, uint32_t buf_size); 39 unsigned char *buf, uint32_t buf_size, struct jffs2_summary *s);
51 40
52/* These helper functions _must_ increase ofs and also do the dirty/used space accounting. 41/* These helper functions _must_ increase ofs and also do the dirty/used space accounting.
53 * Returning an error will abort the mount - bad checksums etc. should just mark the space 42 * Returning an error will abort the mount - bad checksums etc. should just mark the space
54 * as dirty. 43 * as dirty.
55 */ 44 */
56static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 45static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
57 struct jffs2_raw_inode *ri, uint32_t ofs); 46 struct jffs2_raw_inode *ri, uint32_t ofs, struct jffs2_summary *s);
58static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 47static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
59 struct jffs2_raw_dirent *rd, uint32_t ofs); 48 struct jffs2_raw_dirent *rd, uint32_t ofs, struct jffs2_summary *s);
60
61#define BLK_STATE_ALLFF 0
62#define BLK_STATE_CLEAN 1
63#define BLK_STATE_PARTDIRTY 2
64#define BLK_STATE_CLEANMARKER 3
65#define BLK_STATE_ALLDIRTY 4
66#define BLK_STATE_BADBLOCK 5
67 49
68static inline int min_free(struct jffs2_sb_info *c) 50static inline int min_free(struct jffs2_sb_info *c)
69{ 51{
@@ -89,6 +71,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
89 uint32_t empty_blocks = 0, bad_blocks = 0; 71 uint32_t empty_blocks = 0, bad_blocks = 0;
90 unsigned char *flashbuf = NULL; 72 unsigned char *flashbuf = NULL;
91 uint32_t buf_size = 0; 73 uint32_t buf_size = 0;
74 struct jffs2_summary *s = NULL; /* summary info collected by the scan process */
92#ifndef __ECOS 75#ifndef __ECOS
93 size_t pointlen; 76 size_t pointlen;
94 77
@@ -122,21 +105,34 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
122 return -ENOMEM; 105 return -ENOMEM;
123 } 106 }
124 107
108 if (jffs2_sum_active()) {
109 s = kmalloc(sizeof(struct jffs2_summary), GFP_KERNEL);
110 if (!s) {
111 JFFS2_WARNING("Can't allocate memory for summary\n");
112 return -ENOMEM;
113 }
114 memset(s, 0, sizeof(struct jffs2_summary));
115 }
116
125 for (i=0; i<c->nr_blocks; i++) { 117 for (i=0; i<c->nr_blocks; i++) {
126 struct jffs2_eraseblock *jeb = &c->blocks[i]; 118 struct jffs2_eraseblock *jeb = &c->blocks[i];
127 119
128 ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), buf_size); 120 /* reset summary info for next eraseblock scan */
121 jffs2_sum_reset_collected(s);
122
123 ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset),
124 buf_size, s);
129 125
130 if (ret < 0) 126 if (ret < 0)
131 goto out; 127 goto out;
132 128
133 ACCT_PARANOIA_CHECK(jeb); 129 jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
134 130
135 /* Now decide which list to put it on */ 131 /* Now decide which list to put it on */
136 switch(ret) { 132 switch(ret) {
137 case BLK_STATE_ALLFF: 133 case BLK_STATE_ALLFF:
138 /* 134 /*
139 * Empty block. Since we can't be sure it 135 * Empty block. Since we can't be sure it
140 * was entirely erased, we just queue it for erase 136 * was entirely erased, we just queue it for erase
141 * again. It will be marked as such when the erase 137 * again. It will be marked as such when the erase
142 * is complete. Meanwhile we still count it as empty 138 * is complete. Meanwhile we still count it as empty
@@ -162,18 +158,18 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
162 break; 158 break;
163 159
164 case BLK_STATE_CLEAN: 160 case BLK_STATE_CLEAN:
165 /* Full (or almost full) of clean data. Clean list */ 161 /* Full (or almost full) of clean data. Clean list */
166 list_add(&jeb->list, &c->clean_list); 162 list_add(&jeb->list, &c->clean_list);
167 break; 163 break;
168 164
169 case BLK_STATE_PARTDIRTY: 165 case BLK_STATE_PARTDIRTY:
170 /* Some data, but not full. Dirty list. */ 166 /* Some data, but not full. Dirty list. */
171 /* We want to remember the block with most free space 167 /* We want to remember the block with most free space
172 and stick it in the 'nextblock' position to start writing to it. */ 168 and stick it in the 'nextblock' position to start writing to it. */
173 if (jeb->free_size > min_free(c) && 169 if (jeb->free_size > min_free(c) &&
174 (!c->nextblock || c->nextblock->free_size < jeb->free_size)) { 170 (!c->nextblock || c->nextblock->free_size < jeb->free_size)) {
175 /* Better candidate for the next writes to go to */ 171 /* Better candidate for the next writes to go to */
176 if (c->nextblock) { 172 if (c->nextblock) {
177 c->nextblock->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size; 173 c->nextblock->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size;
178 c->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size; 174 c->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size;
179 c->free_size -= c->nextblock->free_size; 175 c->free_size -= c->nextblock->free_size;
@@ -184,9 +180,14 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
184 } else { 180 } else {
185 list_add(&c->nextblock->list, &c->dirty_list); 181 list_add(&c->nextblock->list, &c->dirty_list);
186 } 182 }
183 /* deleting summary information of the old nextblock */
184 jffs2_sum_reset_collected(c->summary);
187 } 185 }
188 c->nextblock = jeb; 186 /* update collected summary infromation for the current nextblock */
189 } else { 187 jffs2_sum_move_collected(c, s);
188 D1(printk(KERN_DEBUG "jffs2_scan_medium(): new nextblock = 0x%08x\n", jeb->offset));
189 c->nextblock = jeb;
190 } else {
190 jeb->dirty_size += jeb->free_size + jeb->wasted_size; 191 jeb->dirty_size += jeb->free_size + jeb->wasted_size;
191 c->dirty_size += jeb->free_size + jeb->wasted_size; 192 c->dirty_size += jeb->free_size + jeb->wasted_size;
192 c->free_size -= jeb->free_size; 193 c->free_size -= jeb->free_size;
@@ -197,30 +198,33 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
197 } else { 198 } else {
198 list_add(&jeb->list, &c->dirty_list); 199 list_add(&jeb->list, &c->dirty_list);
199 } 200 }
200 } 201 }
201 break; 202 break;
202 203
203 case BLK_STATE_ALLDIRTY: 204 case BLK_STATE_ALLDIRTY:
204 /* Nothing valid - not even a clean marker. Needs erasing. */ 205 /* Nothing valid - not even a clean marker. Needs erasing. */
205 /* For now we just put it on the erasing list. We'll start the erases later */ 206 /* For now we just put it on the erasing list. We'll start the erases later */
206 D1(printk(KERN_NOTICE "JFFS2: Erase block at 0x%08x is not formatted. It will be erased\n", jeb->offset)); 207 D1(printk(KERN_NOTICE "JFFS2: Erase block at 0x%08x is not formatted. It will be erased\n", jeb->offset));
207 list_add(&jeb->list, &c->erase_pending_list); 208 list_add(&jeb->list, &c->erase_pending_list);
208 c->nr_erasing_blocks++; 209 c->nr_erasing_blocks++;
209 break; 210 break;
210 211
211 case BLK_STATE_BADBLOCK: 212 case BLK_STATE_BADBLOCK:
212 D1(printk(KERN_NOTICE "JFFS2: Block at 0x%08x is bad\n", jeb->offset)); 213 D1(printk(KERN_NOTICE "JFFS2: Block at 0x%08x is bad\n", jeb->offset));
213 list_add(&jeb->list, &c->bad_list); 214 list_add(&jeb->list, &c->bad_list);
214 c->bad_size += c->sector_size; 215 c->bad_size += c->sector_size;
215 c->free_size -= c->sector_size; 216 c->free_size -= c->sector_size;
216 bad_blocks++; 217 bad_blocks++;
217 break; 218 break;
218 default: 219 default:
219 printk(KERN_WARNING "jffs2_scan_medium(): unknown block state\n"); 220 printk(KERN_WARNING "jffs2_scan_medium(): unknown block state\n");
220 BUG(); 221 BUG();
221 } 222 }
222 } 223 }
223 224
225 if (jffs2_sum_active() && s)
226 kfree(s);
227
224 /* Nextblock dirty is always seen as wasted, because we cannot recycle it now */ 228 /* Nextblock dirty is always seen as wasted, because we cannot recycle it now */
225 if (c->nextblock && (c->nextblock->dirty_size)) { 229 if (c->nextblock && (c->nextblock->dirty_size)) {
226 c->nextblock->wasted_size += c->nextblock->dirty_size; 230 c->nextblock->wasted_size += c->nextblock->dirty_size;
@@ -229,12 +233,12 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
229 c->nextblock->dirty_size = 0; 233 c->nextblock->dirty_size = 0;
230 } 234 }
231#ifdef CONFIG_JFFS2_FS_WRITEBUFFER 235#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
232 if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size & (c->wbuf_pagesize-1))) { 236 if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size % c->wbuf_pagesize)) {
233 /* If we're going to start writing into a block which already 237 /* If we're going to start writing into a block which already
234 contains data, and the end of the data isn't page-aligned, 238 contains data, and the end of the data isn't page-aligned,
235 skip a little and align it. */ 239 skip a little and align it. */
236 240
237 uint32_t skip = c->nextblock->free_size & (c->wbuf_pagesize-1); 241 uint32_t skip = c->nextblock->free_size % c->wbuf_pagesize;
238 242
239 D1(printk(KERN_DEBUG "jffs2_scan_medium(): Skipping %d bytes in nextblock to ensure page alignment\n", 243 D1(printk(KERN_DEBUG "jffs2_scan_medium(): Skipping %d bytes in nextblock to ensure page alignment\n",
240 skip)); 244 skip));
@@ -246,7 +250,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
246 } 250 }
247#endif 251#endif
248 if (c->nr_erasing_blocks) { 252 if (c->nr_erasing_blocks) {
249 if ( !c->used_size && ((c->nr_free_blocks+empty_blocks+bad_blocks)!= c->nr_blocks || bad_blocks == c->nr_blocks) ) { 253 if ( !c->used_size && ((c->nr_free_blocks+empty_blocks+bad_blocks)!= c->nr_blocks || bad_blocks == c->nr_blocks) ) {
250 printk(KERN_NOTICE "Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes\n"); 254 printk(KERN_NOTICE "Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes\n");
251 printk(KERN_NOTICE "empty_blocks %d, bad_blocks %d, c->nr_blocks %d\n",empty_blocks,bad_blocks,c->nr_blocks); 255 printk(KERN_NOTICE "empty_blocks %d, bad_blocks %d, c->nr_blocks %d\n",empty_blocks,bad_blocks,c->nr_blocks);
252 ret = -EIO; 256 ret = -EIO;
@@ -259,13 +263,13 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
259 if (buf_size) 263 if (buf_size)
260 kfree(flashbuf); 264 kfree(flashbuf);
261#ifndef __ECOS 265#ifndef __ECOS
262 else 266 else
263 c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size); 267 c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size);
264#endif 268#endif
265 return ret; 269 return ret;
266} 270}
267 271
268static int jffs2_fill_scan_buf (struct jffs2_sb_info *c, unsigned char *buf, 272int jffs2_fill_scan_buf (struct jffs2_sb_info *c, void *buf,
269 uint32_t ofs, uint32_t len) 273 uint32_t ofs, uint32_t len)
270{ 274{
271 int ret; 275 int ret;
@@ -286,14 +290,36 @@ static int jffs2_fill_scan_buf (struct jffs2_sb_info *c, unsigned char *buf,
286 return 0; 290 return 0;
287} 291}
288 292
293int jffs2_scan_classify_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
294{
295 if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size
296 && (!jeb->first_node || !jeb->first_node->next_phys) )
297 return BLK_STATE_CLEANMARKER;
298
299 /* move blocks with max 4 byte dirty space to cleanlist */
300 else if (!ISDIRTY(c->sector_size - (jeb->used_size + jeb->unchecked_size))) {
301 c->dirty_size -= jeb->dirty_size;
302 c->wasted_size += jeb->dirty_size;
303 jeb->wasted_size += jeb->dirty_size;
304 jeb->dirty_size = 0;
305 return BLK_STATE_CLEAN;
306 } else if (jeb->used_size || jeb->unchecked_size)
307 return BLK_STATE_PARTDIRTY;
308 else
309 return BLK_STATE_ALLDIRTY;
310}
311
289static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 312static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
290 unsigned char *buf, uint32_t buf_size) { 313 unsigned char *buf, uint32_t buf_size, struct jffs2_summary *s) {
291 struct jffs2_unknown_node *node; 314 struct jffs2_unknown_node *node;
292 struct jffs2_unknown_node crcnode; 315 struct jffs2_unknown_node crcnode;
316 struct jffs2_sum_marker *sm;
293 uint32_t ofs, prevofs; 317 uint32_t ofs, prevofs;
294 uint32_t hdr_crc, buf_ofs, buf_len; 318 uint32_t hdr_crc, buf_ofs, buf_len;
295 int err; 319 int err;
296 int noise = 0; 320 int noise = 0;
321
322
297#ifdef CONFIG_JFFS2_FS_WRITEBUFFER 323#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
298 int cleanmarkerfound = 0; 324 int cleanmarkerfound = 0;
299#endif 325#endif
@@ -319,17 +345,53 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
319 } 345 }
320 } 346 }
321#endif 347#endif
348
349 if (jffs2_sum_active()) {
350 sm = kmalloc(sizeof(struct jffs2_sum_marker), GFP_KERNEL);
351 if (!sm) {
352 return -ENOMEM;
353 }
354
355 err = jffs2_fill_scan_buf(c, (unsigned char *) sm, jeb->offset + c->sector_size -
356 sizeof(struct jffs2_sum_marker), sizeof(struct jffs2_sum_marker));
357 if (err) {
358 kfree(sm);
359 return err;
360 }
361
362 if (je32_to_cpu(sm->magic) == JFFS2_SUM_MAGIC ) {
363 err = jffs2_sum_scan_sumnode(c, jeb, je32_to_cpu(sm->offset), &pseudo_random);
364 if (err) {
365 kfree(sm);
366 return err;
367 }
368 }
369
370 kfree(sm);
371
372 ofs = jeb->offset;
373 prevofs = jeb->offset - 1;
374 }
375
322 buf_ofs = jeb->offset; 376 buf_ofs = jeb->offset;
323 377
324 if (!buf_size) { 378 if (!buf_size) {
325 buf_len = c->sector_size; 379 buf_len = c->sector_size;
380
381 if (jffs2_sum_active()) {
382 /* must reread because of summary test */
383 err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len);
384 if (err)
385 return err;
386 }
387
326 } else { 388 } else {
327 buf_len = EMPTY_SCAN_SIZE(c->sector_size); 389 buf_len = EMPTY_SCAN_SIZE(c->sector_size);
328 err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len); 390 err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len);
329 if (err) 391 if (err)
330 return err; 392 return err;
331 } 393 }
332 394
333 /* We temporarily use 'ofs' as a pointer into the buffer/jeb */ 395 /* We temporarily use 'ofs' as a pointer into the buffer/jeb */
334 ofs = 0; 396 ofs = 0;
335 397
@@ -367,10 +429,12 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
367 429
368 noise = 10; 430 noise = 10;
369 431
370scan_more: 432 dbg_summary("no summary found in jeb 0x%08x. Apply original scan.\n",jeb->offset);
433
434scan_more:
371 while(ofs < jeb->offset + c->sector_size) { 435 while(ofs < jeb->offset + c->sector_size) {
372 436
373 D1(ACCT_PARANOIA_CHECK(jeb)); 437 jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
374 438
375 cond_resched(); 439 cond_resched();
376 440
@@ -432,7 +496,7 @@ scan_more:
432 496
433 /* If we're only checking the beginning of a block with a cleanmarker, 497 /* If we're only checking the beginning of a block with a cleanmarker,
434 bail now */ 498 bail now */
435 if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) && 499 if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) &&
436 c->cleanmarker_size && !jeb->dirty_size && !jeb->first_node->next_phys) { 500 c->cleanmarker_size && !jeb->dirty_size && !jeb->first_node->next_phys) {
437 D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE(c->sector_size))); 501 D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE(c->sector_size)));
438 return BLK_STATE_CLEANMARKER; 502 return BLK_STATE_CLEANMARKER;
@@ -441,7 +505,7 @@ scan_more:
441 /* See how much more there is to read in this eraseblock... */ 505 /* See how much more there is to read in this eraseblock... */
442 buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); 506 buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
443 if (!buf_len) { 507 if (!buf_len) {
444 /* No more to read. Break out of main loop without marking 508 /* No more to read. Break out of main loop without marking
445 this range of empty space as dirty (because it's not) */ 509 this range of empty space as dirty (because it's not) */
446 D1(printk(KERN_DEBUG "Empty flash at %08x runs to end of block. Treating as free_space\n", 510 D1(printk(KERN_DEBUG "Empty flash at %08x runs to end of block. Treating as free_space\n",
447 empty_start)); 511 empty_start));
@@ -476,8 +540,8 @@ scan_more:
476 } 540 }
477 if (je16_to_cpu(node->magic) != JFFS2_MAGIC_BITMASK) { 541 if (je16_to_cpu(node->magic) != JFFS2_MAGIC_BITMASK) {
478 /* OK. We're out of possibilities. Whinge and move on */ 542 /* OK. We're out of possibilities. Whinge and move on */
479 noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n", 543 noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n",
480 JFFS2_MAGIC_BITMASK, ofs, 544 JFFS2_MAGIC_BITMASK, ofs,
481 je16_to_cpu(node->magic)); 545 je16_to_cpu(node->magic));
482 DIRTY_SPACE(4); 546 DIRTY_SPACE(4);
483 ofs += 4; 547 ofs += 4;
@@ -492,7 +556,7 @@ scan_more:
492 if (hdr_crc != je32_to_cpu(node->hdr_crc)) { 556 if (hdr_crc != je32_to_cpu(node->hdr_crc)) {
493 noisy_printk(&noise, "jffs2_scan_eraseblock(): Node at 0x%08x {0x%04x, 0x%04x, 0x%08x) has invalid CRC 0x%08x (calculated 0x%08x)\n", 557 noisy_printk(&noise, "jffs2_scan_eraseblock(): Node at 0x%08x {0x%04x, 0x%04x, 0x%08x) has invalid CRC 0x%08x (calculated 0x%08x)\n",
494 ofs, je16_to_cpu(node->magic), 558 ofs, je16_to_cpu(node->magic),
495 je16_to_cpu(node->nodetype), 559 je16_to_cpu(node->nodetype),
496 je32_to_cpu(node->totlen), 560 je32_to_cpu(node->totlen),
497 je32_to_cpu(node->hdr_crc), 561 je32_to_cpu(node->hdr_crc),
498 hdr_crc); 562 hdr_crc);
@@ -501,7 +565,7 @@ scan_more:
501 continue; 565 continue;
502 } 566 }
503 567
504 if (ofs + je32_to_cpu(node->totlen) > 568 if (ofs + je32_to_cpu(node->totlen) >
505 jeb->offset + c->sector_size) { 569 jeb->offset + c->sector_size) {
506 /* Eep. Node goes over the end of the erase block. */ 570 /* Eep. Node goes over the end of the erase block. */
507 printk(KERN_WARNING "Node at 0x%08x with length 0x%08x would run over the end of the erase block\n", 571 printk(KERN_WARNING "Node at 0x%08x with length 0x%08x would run over the end of the erase block\n",
@@ -532,11 +596,11 @@ scan_more:
532 buf_ofs = ofs; 596 buf_ofs = ofs;
533 node = (void *)buf; 597 node = (void *)buf;
534 } 598 }
535 err = jffs2_scan_inode_node(c, jeb, (void *)node, ofs); 599 err = jffs2_scan_inode_node(c, jeb, (void *)node, ofs, s);
536 if (err) return err; 600 if (err) return err;
537 ofs += PAD(je32_to_cpu(node->totlen)); 601 ofs += PAD(je32_to_cpu(node->totlen));
538 break; 602 break;
539 603
540 case JFFS2_NODETYPE_DIRENT: 604 case JFFS2_NODETYPE_DIRENT:
541 if (buf_ofs + buf_len < ofs + je32_to_cpu(node->totlen)) { 605 if (buf_ofs + buf_len < ofs + je32_to_cpu(node->totlen)) {
542 buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); 606 buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
@@ -548,7 +612,7 @@ scan_more:
548 buf_ofs = ofs; 612 buf_ofs = ofs;
549 node = (void *)buf; 613 node = (void *)buf;
550 } 614 }
551 err = jffs2_scan_dirent_node(c, jeb, (void *)node, ofs); 615 err = jffs2_scan_dirent_node(c, jeb, (void *)node, ofs, s);
552 if (err) return err; 616 if (err) return err;
553 ofs += PAD(je32_to_cpu(node->totlen)); 617 ofs += PAD(je32_to_cpu(node->totlen));
554 break; 618 break;
@@ -556,7 +620,7 @@ scan_more:
556 case JFFS2_NODETYPE_CLEANMARKER: 620 case JFFS2_NODETYPE_CLEANMARKER:
557 D1(printk(KERN_DEBUG "CLEANMARKER node found at 0x%08x\n", ofs)); 621 D1(printk(KERN_DEBUG "CLEANMARKER node found at 0x%08x\n", ofs));
558 if (je32_to_cpu(node->totlen) != c->cleanmarker_size) { 622 if (je32_to_cpu(node->totlen) != c->cleanmarker_size) {
559 printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x has totlen 0x%x != normal 0x%x\n", 623 printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x has totlen 0x%x != normal 0x%x\n",
560 ofs, je32_to_cpu(node->totlen), c->cleanmarker_size); 624 ofs, je32_to_cpu(node->totlen), c->cleanmarker_size);
561 DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node))); 625 DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node)));
562 ofs += PAD(sizeof(struct jffs2_unknown_node)); 626 ofs += PAD(sizeof(struct jffs2_unknown_node));
@@ -575,13 +639,15 @@ scan_more:
575 marker_ref->flash_offset = ofs | REF_NORMAL; 639 marker_ref->flash_offset = ofs | REF_NORMAL;
576 marker_ref->__totlen = c->cleanmarker_size; 640 marker_ref->__totlen = c->cleanmarker_size;
577 jeb->first_node = jeb->last_node = marker_ref; 641 jeb->first_node = jeb->last_node = marker_ref;
578 642
579 USED_SPACE(PAD(c->cleanmarker_size)); 643 USED_SPACE(PAD(c->cleanmarker_size));
580 ofs += PAD(c->cleanmarker_size); 644 ofs += PAD(c->cleanmarker_size);
581 } 645 }
582 break; 646 break;
583 647
584 case JFFS2_NODETYPE_PADDING: 648 case JFFS2_NODETYPE_PADDING:
649 if (jffs2_sum_active())
650 jffs2_sum_add_padding_mem(s, je32_to_cpu(node->totlen));
585 DIRTY_SPACE(PAD(je32_to_cpu(node->totlen))); 651 DIRTY_SPACE(PAD(je32_to_cpu(node->totlen)));
586 ofs += PAD(je32_to_cpu(node->totlen)); 652 ofs += PAD(je32_to_cpu(node->totlen));
587 break; 653 break;
@@ -616,8 +682,15 @@ scan_more:
616 } 682 }
617 } 683 }
618 684
685 if (jffs2_sum_active()) {
686 if (PAD(s->sum_size + JFFS2_SUMMARY_FRAME_SIZE) > jeb->free_size) {
687 dbg_summary("There is not enough space for "
688 "summary information, disabling for this jeb!\n");
689 jffs2_sum_disable_collecting(s);
690 }
691 }
619 692
620 D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x\n", jeb->offset, 693 D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x\n", jeb->offset,
621 jeb->free_size, jeb->dirty_size, jeb->unchecked_size, jeb->used_size)); 694 jeb->free_size, jeb->dirty_size, jeb->unchecked_size, jeb->used_size));
622 695
623 /* mark_node_obsolete can add to wasted !! */ 696 /* mark_node_obsolete can add to wasted !! */
@@ -628,24 +701,10 @@ scan_more:
628 jeb->wasted_size = 0; 701 jeb->wasted_size = 0;
629 } 702 }
630 703
631 if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size 704 return jffs2_scan_classify_jeb(c, jeb);
632 && (!jeb->first_node || !jeb->first_node->next_phys) )
633 return BLK_STATE_CLEANMARKER;
634
635 /* move blocks with max 4 byte dirty space to cleanlist */
636 else if (!ISDIRTY(c->sector_size - (jeb->used_size + jeb->unchecked_size))) {
637 c->dirty_size -= jeb->dirty_size;
638 c->wasted_size += jeb->dirty_size;
639 jeb->wasted_size += jeb->dirty_size;
640 jeb->dirty_size = 0;
641 return BLK_STATE_CLEAN;
642 } else if (jeb->used_size || jeb->unchecked_size)
643 return BLK_STATE_PARTDIRTY;
644 else
645 return BLK_STATE_ALLDIRTY;
646} 705}
647 706
648static struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino) 707struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino)
649{ 708{
650 struct jffs2_inode_cache *ic; 709 struct jffs2_inode_cache *ic;
651 710
@@ -671,8 +730,8 @@ static struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info
671 return ic; 730 return ic;
672} 731}
673 732
674static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 733static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
675 struct jffs2_raw_inode *ri, uint32_t ofs) 734 struct jffs2_raw_inode *ri, uint32_t ofs, struct jffs2_summary *s)
676{ 735{
677 struct jffs2_raw_node_ref *raw; 736 struct jffs2_raw_node_ref *raw;
678 struct jffs2_inode_cache *ic; 737 struct jffs2_inode_cache *ic;
@@ -681,11 +740,11 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
681 D1(printk(KERN_DEBUG "jffs2_scan_inode_node(): Node at 0x%08x\n", ofs)); 740 D1(printk(KERN_DEBUG "jffs2_scan_inode_node(): Node at 0x%08x\n", ofs));
682 741
683 /* We do very little here now. Just check the ino# to which we should attribute 742 /* We do very little here now. Just check the ino# to which we should attribute
684 this node; we can do all the CRC checking etc. later. There's a tradeoff here -- 743 this node; we can do all the CRC checking etc. later. There's a tradeoff here --
685 we used to scan the flash once only, reading everything we want from it into 744 we used to scan the flash once only, reading everything we want from it into
686 memory, then building all our in-core data structures and freeing the extra 745 memory, then building all our in-core data structures and freeing the extra
687 information. Now we allow the first part of the mount to complete a lot quicker, 746 information. Now we allow the first part of the mount to complete a lot quicker,
688 but we have to go _back_ to the flash in order to finish the CRC checking, etc. 747 but we have to go _back_ to the flash in order to finish the CRC checking, etc.
689 Which means that the _full_ amount of time to get to proper write mode with GC 748 Which means that the _full_ amount of time to get to proper write mode with GC
690 operational may actually be _longer_ than before. Sucks to be me. */ 749 operational may actually be _longer_ than before. Sucks to be me. */
691 750
@@ -731,7 +790,7 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
731 jeb->last_node->next_phys = raw; 790 jeb->last_node->next_phys = raw;
732 jeb->last_node = raw; 791 jeb->last_node = raw;
733 792
734 D1(printk(KERN_DEBUG "Node is ino #%u, version %d. Range 0x%x-0x%x\n", 793 D1(printk(KERN_DEBUG "Node is ino #%u, version %d. Range 0x%x-0x%x\n",
735 je32_to_cpu(ri->ino), je32_to_cpu(ri->version), 794 je32_to_cpu(ri->ino), je32_to_cpu(ri->version),
736 je32_to_cpu(ri->offset), 795 je32_to_cpu(ri->offset),
737 je32_to_cpu(ri->offset)+je32_to_cpu(ri->dsize))); 796 je32_to_cpu(ri->offset)+je32_to_cpu(ri->dsize)));
@@ -739,11 +798,16 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
739 pseudo_random += je32_to_cpu(ri->version); 798 pseudo_random += je32_to_cpu(ri->version);
740 799
741 UNCHECKED_SPACE(PAD(je32_to_cpu(ri->totlen))); 800 UNCHECKED_SPACE(PAD(je32_to_cpu(ri->totlen)));
801
802 if (jffs2_sum_active()) {
803 jffs2_sum_add_inode_mem(s, ri, ofs - jeb->offset);
804 }
805
742 return 0; 806 return 0;
743} 807}
744 808
745static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 809static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
746 struct jffs2_raw_dirent *rd, uint32_t ofs) 810 struct jffs2_raw_dirent *rd, uint32_t ofs, struct jffs2_summary *s)
747{ 811{
748 struct jffs2_raw_node_ref *raw; 812 struct jffs2_raw_node_ref *raw;
749 struct jffs2_full_dirent *fd; 813 struct jffs2_full_dirent *fd;
@@ -776,7 +840,7 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo
776 crc = crc32(0, fd->name, rd->nsize); 840 crc = crc32(0, fd->name, rd->nsize);
777 if (crc != je32_to_cpu(rd->name_crc)) { 841 if (crc != je32_to_cpu(rd->name_crc)) {
778 printk(KERN_NOTICE "jffs2_scan_dirent_node(): Name CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", 842 printk(KERN_NOTICE "jffs2_scan_dirent_node(): Name CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
779 ofs, je32_to_cpu(rd->name_crc), crc); 843 ofs, je32_to_cpu(rd->name_crc), crc);
780 D1(printk(KERN_NOTICE "Name for which CRC failed is (now) '%s', ino #%d\n", fd->name, je32_to_cpu(rd->ino))); 844 D1(printk(KERN_NOTICE "Name for which CRC failed is (now) '%s', ino #%d\n", fd->name, je32_to_cpu(rd->ino)));
781 jffs2_free_full_dirent(fd); 845 jffs2_free_full_dirent(fd);
782 /* FIXME: Why do we believe totlen? */ 846 /* FIXME: Why do we believe totlen? */
@@ -796,7 +860,7 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo
796 jffs2_free_raw_node_ref(raw); 860 jffs2_free_raw_node_ref(raw);
797 return -ENOMEM; 861 return -ENOMEM;
798 } 862 }
799 863
800 raw->__totlen = PAD(je32_to_cpu(rd->totlen)); 864 raw->__totlen = PAD(je32_to_cpu(rd->totlen));
801 raw->flash_offset = ofs | REF_PRISTINE; 865 raw->flash_offset = ofs | REF_PRISTINE;
802 raw->next_phys = NULL; 866 raw->next_phys = NULL;
@@ -817,6 +881,10 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo
817 USED_SPACE(PAD(je32_to_cpu(rd->totlen))); 881 USED_SPACE(PAD(je32_to_cpu(rd->totlen)));
818 jffs2_add_fd_to_list(c, fd, &ic->scan_dents); 882 jffs2_add_fd_to_list(c, fd, &ic->scan_dents);
819 883
884 if (jffs2_sum_active()) {
885 jffs2_sum_add_dirent_mem(s, rd, ofs - jeb->offset);
886 }
887
820 return 0; 888 return 0;
821} 889}
822 890
@@ -852,76 +920,34 @@ void jffs2_rotate_lists(struct jffs2_sb_info *c)
852 x = count_list(&c->clean_list); 920 x = count_list(&c->clean_list);
853 if (x) { 921 if (x) {
854 rotateby = pseudo_random % x; 922 rotateby = pseudo_random % x;
855 D1(printk(KERN_DEBUG "Rotating clean_list by %d\n", rotateby));
856
857 rotate_list((&c->clean_list), rotateby); 923 rotate_list((&c->clean_list), rotateby);
858
859 D1(printk(KERN_DEBUG "Erase block at front of clean_list is at %08x\n",
860 list_entry(c->clean_list.next, struct jffs2_eraseblock, list)->offset));
861 } else {
862 D1(printk(KERN_DEBUG "Not rotating empty clean_list\n"));
863 } 924 }
864 925
865 x = count_list(&c->very_dirty_list); 926 x = count_list(&c->very_dirty_list);
866 if (x) { 927 if (x) {
867 rotateby = pseudo_random % x; 928 rotateby = pseudo_random % x;
868 D1(printk(KERN_DEBUG "Rotating very_dirty_list by %d\n", rotateby));
869
870 rotate_list((&c->very_dirty_list), rotateby); 929 rotate_list((&c->very_dirty_list), rotateby);
871
872 D1(printk(KERN_DEBUG "Erase block at front of very_dirty_list is at %08x\n",
873 list_entry(c->very_dirty_list.next, struct jffs2_eraseblock, list)->offset));
874 } else {
875 D1(printk(KERN_DEBUG "Not rotating empty very_dirty_list\n"));
876 } 930 }
877 931
878 x = count_list(&c->dirty_list); 932 x = count_list(&c->dirty_list);
879 if (x) { 933 if (x) {
880 rotateby = pseudo_random % x; 934 rotateby = pseudo_random % x;
881 D1(printk(KERN_DEBUG "Rotating dirty_list by %d\n", rotateby));
882
883 rotate_list((&c->dirty_list), rotateby); 935 rotate_list((&c->dirty_list), rotateby);
884
885 D1(printk(KERN_DEBUG "Erase block at front of dirty_list is at %08x\n",
886 list_entry(c->dirty_list.next, struct jffs2_eraseblock, list)->offset));
887 } else {
888 D1(printk(KERN_DEBUG "Not rotating empty dirty_list\n"));
889 } 936 }
890 937
891 x = count_list(&c->erasable_list); 938 x = count_list(&c->erasable_list);
892 if (x) { 939 if (x) {
893 rotateby = pseudo_random % x; 940 rotateby = pseudo_random % x;
894 D1(printk(KERN_DEBUG "Rotating erasable_list by %d\n", rotateby));
895
896 rotate_list((&c->erasable_list), rotateby); 941 rotate_list((&c->erasable_list), rotateby);
897
898 D1(printk(KERN_DEBUG "Erase block at front of erasable_list is at %08x\n",
899 list_entry(c->erasable_list.next, struct jffs2_eraseblock, list)->offset));
900 } else {
901 D1(printk(KERN_DEBUG "Not rotating empty erasable_list\n"));
902 } 942 }
903 943
904 if (c->nr_erasing_blocks) { 944 if (c->nr_erasing_blocks) {
905 rotateby = pseudo_random % c->nr_erasing_blocks; 945 rotateby = pseudo_random % c->nr_erasing_blocks;
906 D1(printk(KERN_DEBUG "Rotating erase_pending_list by %d\n", rotateby));
907
908 rotate_list((&c->erase_pending_list), rotateby); 946 rotate_list((&c->erase_pending_list), rotateby);
909
910 D1(printk(KERN_DEBUG "Erase block at front of erase_pending_list is at %08x\n",
911 list_entry(c->erase_pending_list.next, struct jffs2_eraseblock, list)->offset));
912 } else {
913 D1(printk(KERN_DEBUG "Not rotating empty erase_pending_list\n"));
914 } 947 }
915 948
916 if (c->nr_free_blocks) { 949 if (c->nr_free_blocks) {
917 rotateby = pseudo_random % c->nr_free_blocks; 950 rotateby = pseudo_random % c->nr_free_blocks;
918 D1(printk(KERN_DEBUG "Rotating free_list by %d\n", rotateby));
919
920 rotate_list((&c->free_list), rotateby); 951 rotate_list((&c->free_list), rotateby);
921
922 D1(printk(KERN_DEBUG "Erase block at front of free_list is at %08x\n",
923 list_entry(c->free_list.next, struct jffs2_eraseblock, list)->offset));
924 } else {
925 D1(printk(KERN_DEBUG "Not rotating empty free_list\n"));
926 } 952 }
927} 953}
diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c
new file mode 100644
index 000000000000..fb9cec61fcf2
--- /dev/null
+++ b/fs/jffs2/summary.c
@@ -0,0 +1,730 @@
1/*
2 * JFFS2 -- Journalling Flash File System, Version 2.
3 *
4 * Copyright (C) 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>,
5 * Zoltan Sogor <weth@inf.u-szeged.hu>,
6 * Patrik Kluba <pajko@halom.u-szeged.hu>,
7 * University of Szeged, Hungary
8 *
9 * For licensing information, see the file 'LICENCE' in this directory.
10 *
11 * $Id: summary.c,v 1.4 2005/09/26 11:37:21 havasi Exp $
12 *
13 */
14
15#include <linux/kernel.h>
16#include <linux/sched.h>
17#include <linux/slab.h>
18#include <linux/mtd/mtd.h>
19#include <linux/pagemap.h>
20#include <linux/crc32.h>
21#include <linux/compiler.h>
22#include <linux/vmalloc.h>
23#include "nodelist.h"
24#include "debug.h"
25
26int jffs2_sum_init(struct jffs2_sb_info *c)
27{
28 c->summary = kmalloc(sizeof(struct jffs2_summary), GFP_KERNEL);
29
30 if (!c->summary) {
31 JFFS2_WARNING("Can't allocate memory for summary information!\n");
32 return -ENOMEM;
33 }
34
35 memset(c->summary, 0, sizeof(struct jffs2_summary));
36
37 c->summary->sum_buf = vmalloc(c->sector_size);
38
39 if (!c->summary->sum_buf) {
40 JFFS2_WARNING("Can't allocate buffer for writing out summary information!\n");
41 kfree(c->summary);
42 return -ENOMEM;
43 }
44
45 dbg_summary("returned succesfully\n");
46
47 return 0;
48}
49
50void jffs2_sum_exit(struct jffs2_sb_info *c)
51{
52 dbg_summary("called\n");
53
54 jffs2_sum_disable_collecting(c->summary);
55
56 vfree(c->summary->sum_buf);
57 c->summary->sum_buf = NULL;
58
59 kfree(c->summary);
60 c->summary = NULL;
61}
62
63static int jffs2_sum_add_mem(struct jffs2_summary *s, union jffs2_sum_mem *item)
64{
65 if (!s->sum_list_head)
66 s->sum_list_head = (union jffs2_sum_mem *) item;
67 if (s->sum_list_tail)
68 s->sum_list_tail->u.next = (union jffs2_sum_mem *) item;
69 s->sum_list_tail = (union jffs2_sum_mem *) item;
70
71 switch (je16_to_cpu(item->u.nodetype)) {
72 case JFFS2_NODETYPE_INODE:
73 s->sum_size += JFFS2_SUMMARY_INODE_SIZE;
74 s->sum_num++;
75 dbg_summary("inode (%u) added to summary\n",
76 je32_to_cpu(item->i.inode));
77 break;
78 case JFFS2_NODETYPE_DIRENT:
79 s->sum_size += JFFS2_SUMMARY_DIRENT_SIZE(item->d.nsize);
80 s->sum_num++;
81 dbg_summary("dirent (%u) added to summary\n",
82 je32_to_cpu(item->d.ino));
83 break;
84 default:
85 JFFS2_WARNING("UNKNOWN node type %u\n",
86 je16_to_cpu(item->u.nodetype));
87 return 1;
88 }
89 return 0;
90}
91
92
93/* The following 3 functions are called from scan.c to collect summary info for not closed jeb */
94
95int jffs2_sum_add_padding_mem(struct jffs2_summary *s, uint32_t size)
96{
97 dbg_summary("called with %u\n", size);
98 s->sum_padded += size;
99 return 0;
100}
101
102int jffs2_sum_add_inode_mem(struct jffs2_summary *s, struct jffs2_raw_inode *ri,
103 uint32_t ofs)
104{
105 struct jffs2_sum_inode_mem *temp = kmalloc(sizeof(struct jffs2_sum_inode_mem), GFP_KERNEL);
106
107 if (!temp)
108 return -ENOMEM;
109
110 temp->nodetype = ri->nodetype;
111 temp->inode = ri->ino;
112 temp->version = ri->version;
113 temp->offset = cpu_to_je32(ofs); /* relative offset from the begining of the jeb */
114 temp->totlen = ri->totlen;
115 temp->next = NULL;
116
117 return jffs2_sum_add_mem(s, (union jffs2_sum_mem *)temp);
118}
119
120int jffs2_sum_add_dirent_mem(struct jffs2_summary *s, struct jffs2_raw_dirent *rd,
121 uint32_t ofs)
122{
123 struct jffs2_sum_dirent_mem *temp =
124 kmalloc(sizeof(struct jffs2_sum_dirent_mem) + rd->nsize, GFP_KERNEL);
125
126 if (!temp)
127 return -ENOMEM;
128
129 temp->nodetype = rd->nodetype;
130 temp->totlen = rd->totlen;
131 temp->offset = cpu_to_je32(ofs); /* relative from the begining of the jeb */
132 temp->pino = rd->pino;
133 temp->version = rd->version;
134 temp->ino = rd->ino;
135 temp->nsize = rd->nsize;
136 temp->type = rd->type;
137 temp->next = NULL;
138
139 memcpy(temp->name, rd->name, rd->nsize);
140
141 return jffs2_sum_add_mem(s, (union jffs2_sum_mem *)temp);
142}
143
144/* Cleanup every collected summary information */
145
146static void jffs2_sum_clean_collected(struct jffs2_summary *s)
147{
148 union jffs2_sum_mem *temp;
149
150 if (!s->sum_list_head) {
151 dbg_summary("already empty\n");
152 }
153 while (s->sum_list_head) {
154 temp = s->sum_list_head;
155 s->sum_list_head = s->sum_list_head->u.next;
156 kfree(temp);
157 }
158 s->sum_list_tail = NULL;
159 s->sum_padded = 0;
160 s->sum_num = 0;
161}
162
163void jffs2_sum_reset_collected(struct jffs2_summary *s)
164{
165 dbg_summary("called\n");
166 jffs2_sum_clean_collected(s);
167 s->sum_size = 0;
168}
169
170void jffs2_sum_disable_collecting(struct jffs2_summary *s)
171{
172 dbg_summary("called\n");
173 jffs2_sum_clean_collected(s);
174 s->sum_size = JFFS2_SUMMARY_NOSUM_SIZE;
175}
176
177int jffs2_sum_is_disabled(struct jffs2_summary *s)
178{
179 return (s->sum_size == JFFS2_SUMMARY_NOSUM_SIZE);
180}
181
182/* Move the collected summary information into sb (called from scan.c) */
183
184void jffs2_sum_move_collected(struct jffs2_sb_info *c, struct jffs2_summary *s)
185{
186 dbg_summary("oldsize=0x%x oldnum=%u => newsize=0x%x newnum=%u\n",
187 c->summary->sum_size, c->summary->sum_num,
188 s->sum_size, s->sum_num);
189
190 c->summary->sum_size = s->sum_size;
191 c->summary->sum_num = s->sum_num;
192 c->summary->sum_padded = s->sum_padded;
193 c->summary->sum_list_head = s->sum_list_head;
194 c->summary->sum_list_tail = s->sum_list_tail;
195
196 s->sum_list_head = s->sum_list_tail = NULL;
197}
198
199/* Called from wbuf.c to collect writed node info */
200
201int jffs2_sum_add_kvec(struct jffs2_sb_info *c, const struct kvec *invecs,
202 unsigned long count, uint32_t ofs)
203{
204 union jffs2_node_union *node;
205 struct jffs2_eraseblock *jeb;
206
207 node = invecs[0].iov_base;
208 jeb = &c->blocks[ofs / c->sector_size];
209 ofs -= jeb->offset;
210
211 switch (je16_to_cpu(node->u.nodetype)) {
212 case JFFS2_NODETYPE_INODE: {
213 struct jffs2_sum_inode_mem *temp =
214 kmalloc(sizeof(struct jffs2_sum_inode_mem), GFP_KERNEL);
215
216 if (!temp)
217 goto no_mem;
218
219 temp->nodetype = node->i.nodetype;
220 temp->inode = node->i.ino;
221 temp->version = node->i.version;
222 temp->offset = cpu_to_je32(ofs);
223 temp->totlen = node->i.totlen;
224 temp->next = NULL;
225
226 return jffs2_sum_add_mem(c->summary, (union jffs2_sum_mem *)temp);
227 }
228
229 case JFFS2_NODETYPE_DIRENT: {
230 struct jffs2_sum_dirent_mem *temp =
231 kmalloc(sizeof(struct jffs2_sum_dirent_mem) + node->d.nsize, GFP_KERNEL);
232
233 if (!temp)
234 goto no_mem;
235
236 temp->nodetype = node->d.nodetype;
237 temp->totlen = node->d.totlen;
238 temp->offset = cpu_to_je32(ofs);
239 temp->pino = node->d.pino;
240 temp->version = node->d.version;
241 temp->ino = node->d.ino;
242 temp->nsize = node->d.nsize;
243 temp->type = node->d.type;
244 temp->next = NULL;
245
246 switch (count) {
247 case 1:
248 memcpy(temp->name,node->d.name,node->d.nsize);
249 break;
250
251 case 2:
252 memcpy(temp->name,invecs[1].iov_base,node->d.nsize);
253 break;
254
255 default:
256 BUG(); /* impossible count value */
257 break;
258 }
259
260 return jffs2_sum_add_mem(c->summary, (union jffs2_sum_mem *)temp);
261 }
262
263 case JFFS2_NODETYPE_PADDING:
264 dbg_summary("node PADDING\n");
265 c->summary->sum_padded += je32_to_cpu(node->u.totlen);
266 break;
267
268 case JFFS2_NODETYPE_CLEANMARKER:
269 dbg_summary("node CLEANMARKER\n");
270 break;
271
272 case JFFS2_NODETYPE_SUMMARY:
273 dbg_summary("node SUMMARY\n");
274 break;
275
276 default:
277 /* If you implement a new node type you should also implement
278 summary support for it or disable summary.
279 */
280 BUG();
281 break;
282 }
283
284 return 0;
285
286no_mem:
287 JFFS2_WARNING("MEMORY ALLOCATION ERROR!");
288 return -ENOMEM;
289}
290
291
292/* Process the stored summary information - helper function for jffs2_sum_scan_sumnode() */
293
294static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
295 struct jffs2_raw_summary *summary, uint32_t *pseudo_random)
296{
297 struct jffs2_raw_node_ref *raw;
298 struct jffs2_inode_cache *ic;
299 struct jffs2_full_dirent *fd;
300 void *sp;
301 int i, ino;
302
303 sp = summary->sum;
304
305 for (i=0; i<je32_to_cpu(summary->sum_num); i++) {
306 dbg_summary("processing summary index %d\n", i);
307
308 switch (je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype)) {
309 case JFFS2_NODETYPE_INODE: {
310 struct jffs2_sum_inode_flash *spi;
311 spi = sp;
312
313 ino = je32_to_cpu(spi->inode);
314
315 dbg_summary("Inode at 0x%08x\n",
316 jeb->offset + je32_to_cpu(spi->offset));
317
318 raw = jffs2_alloc_raw_node_ref();
319 if (!raw) {
320 JFFS2_NOTICE("allocation of node reference failed\n");
321 kfree(summary);
322 return -ENOMEM;
323 }
324
325 ic = jffs2_scan_make_ino_cache(c, ino);
326 if (!ic) {
327 JFFS2_NOTICE("scan_make_ino_cache failed\n");
328 jffs2_free_raw_node_ref(raw);
329 kfree(summary);
330 return -ENOMEM;
331 }
332
333 raw->flash_offset = (jeb->offset + je32_to_cpu(spi->offset)) | REF_UNCHECKED;
334 raw->__totlen = PAD(je32_to_cpu(spi->totlen));
335 raw->next_phys = NULL;
336 raw->next_in_ino = ic->nodes;
337
338 ic->nodes = raw;
339 if (!jeb->first_node)
340 jeb->first_node = raw;
341 if (jeb->last_node)
342 jeb->last_node->next_phys = raw;
343 jeb->last_node = raw;
344 *pseudo_random += je32_to_cpu(spi->version);
345
346 UNCHECKED_SPACE(PAD(je32_to_cpu(spi->totlen)));
347
348 sp += JFFS2_SUMMARY_INODE_SIZE;
349
350 break;
351 }
352
353 case JFFS2_NODETYPE_DIRENT: {
354 struct jffs2_sum_dirent_flash *spd;
355 spd = sp;
356
357 dbg_summary("Dirent at 0x%08x\n",
358 jeb->offset + je32_to_cpu(spd->offset));
359
360 fd = jffs2_alloc_full_dirent(spd->nsize+1);
361 if (!fd) {
362 kfree(summary);
363 return -ENOMEM;
364 }
365
366 memcpy(&fd->name, spd->name, spd->nsize);
367 fd->name[spd->nsize] = 0;
368
369 raw = jffs2_alloc_raw_node_ref();
370 if (!raw) {
371 jffs2_free_full_dirent(fd);
372 JFFS2_NOTICE("allocation of node reference failed\n");
373 kfree(summary);
374 return -ENOMEM;
375 }
376
377 ic = jffs2_scan_make_ino_cache(c, je32_to_cpu(spd->pino));
378 if (!ic) {
379 jffs2_free_full_dirent(fd);
380 jffs2_free_raw_node_ref(raw);
381 kfree(summary);
382 return -ENOMEM;
383 }
384
385 raw->__totlen = PAD(je32_to_cpu(spd->totlen));
386 raw->flash_offset = (jeb->offset + je32_to_cpu(spd->offset)) | REF_PRISTINE;
387 raw->next_phys = NULL;
388 raw->next_in_ino = ic->nodes;
389 ic->nodes = raw;
390 if (!jeb->first_node)
391 jeb->first_node = raw;
392 if (jeb->last_node)
393 jeb->last_node->next_phys = raw;
394 jeb->last_node = raw;
395
396 fd->raw = raw;
397 fd->next = NULL;
398 fd->version = je32_to_cpu(spd->version);
399 fd->ino = je32_to_cpu(spd->ino);
400 fd->nhash = full_name_hash(fd->name, spd->nsize);
401 fd->type = spd->type;
402 USED_SPACE(PAD(je32_to_cpu(spd->totlen)));
403 jffs2_add_fd_to_list(c, fd, &ic->scan_dents);
404
405 *pseudo_random += je32_to_cpu(spd->version);
406
407 sp += JFFS2_SUMMARY_DIRENT_SIZE(spd->nsize);
408
409 break;
410 }
411
412 default : {
413 JFFS2_WARNING("Unsupported node type found in summary! Exiting...");
414 kfree(summary);
415 return -EIO;
416 }
417 }
418 }
419
420 kfree(summary);
421 return 0;
422}
423
424/* Process the summary node - called from jffs2_scan_eraseblock() */
425
426int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
427 uint32_t ofs, uint32_t *pseudo_random)
428{
429 struct jffs2_unknown_node crcnode;
430 struct jffs2_raw_node_ref *cache_ref;
431 struct jffs2_raw_summary *summary;
432 int ret, sumsize;
433 uint32_t crc;
434
435 sumsize = c->sector_size - ofs;
436 ofs += jeb->offset;
437
438 dbg_summary("summary found for 0x%08x at 0x%08x (0x%x bytes)\n",
439 jeb->offset, ofs, sumsize);
440
441 summary = kmalloc(sumsize, GFP_KERNEL);
442
443 if (!summary) {
444 return -ENOMEM;
445 }
446
447 ret = jffs2_fill_scan_buf(c, (unsigned char *)summary, ofs, sumsize);
448
449 if (ret) {
450 kfree(summary);
451 return ret;
452 }
453
454 /* OK, now check for node validity and CRC */
455 crcnode.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
456 crcnode.nodetype = cpu_to_je16(JFFS2_NODETYPE_SUMMARY);
457 crcnode.totlen = summary->totlen;
458 crc = crc32(0, &crcnode, sizeof(crcnode)-4);
459
460 if (je32_to_cpu(summary->hdr_crc) != crc) {
461 dbg_summary("Summary node header is corrupt (bad CRC or "
462 "no summary at all)\n");
463 goto crc_err;
464 }
465
466 if (je32_to_cpu(summary->totlen) != sumsize) {
467 dbg_summary("Summary node is corrupt (wrong erasesize?)\n");
468 goto crc_err;
469 }
470
471 crc = crc32(0, summary, sizeof(struct jffs2_raw_summary)-8);
472
473 if (je32_to_cpu(summary->node_crc) != crc) {
474 dbg_summary("Summary node is corrupt (bad CRC)\n");
475 goto crc_err;
476 }
477
478 crc = crc32(0, summary->sum, sumsize - sizeof(struct jffs2_raw_summary));
479
480 if (je32_to_cpu(summary->sum_crc) != crc) {
481 dbg_summary("Summary node data is corrupt (bad CRC)\n");
482 goto crc_err;
483 }
484
485 if ( je32_to_cpu(summary->cln_mkr) ) {
486
487 dbg_summary("Summary : CLEANMARKER node \n");
488
489 if (je32_to_cpu(summary->cln_mkr) != c->cleanmarker_size) {
490 dbg_summary("CLEANMARKER node has totlen 0x%x != normal 0x%x\n",
491 je32_to_cpu(summary->cln_mkr), c->cleanmarker_size);
492 UNCHECKED_SPACE(PAD(je32_to_cpu(summary->cln_mkr)));
493 } else if (jeb->first_node) {
494 dbg_summary("CLEANMARKER node not first node in block "
495 "(0x%08x)\n", jeb->offset);
496 UNCHECKED_SPACE(PAD(je32_to_cpu(summary->cln_mkr)));
497 } else {
498 struct jffs2_raw_node_ref *marker_ref = jffs2_alloc_raw_node_ref();
499
500 if (!marker_ref) {
501 JFFS2_NOTICE("Failed to allocate node ref for clean marker\n");
502 kfree(summary);
503 return -ENOMEM;
504 }
505
506 marker_ref->next_in_ino = NULL;
507 marker_ref->next_phys = NULL;
508 marker_ref->flash_offset = jeb->offset | REF_NORMAL;
509 marker_ref->__totlen = je32_to_cpu(summary->cln_mkr);
510 jeb->first_node = jeb->last_node = marker_ref;
511
512 USED_SPACE( PAD(je32_to_cpu(summary->cln_mkr)) );
513 }
514 }
515
516 if (je32_to_cpu(summary->padded)) {
517 DIRTY_SPACE(je32_to_cpu(summary->padded));
518 }
519
520 ret = jffs2_sum_process_sum_data(c, jeb, summary, pseudo_random);
521 if (ret)
522 return ret;
523
524 /* for PARANOIA_CHECK */
525 cache_ref = jffs2_alloc_raw_node_ref();
526
527 if (!cache_ref) {
528 JFFS2_NOTICE("Failed to allocate node ref for cache\n");
529 return -ENOMEM;
530 }
531
532 cache_ref->next_in_ino = NULL;
533 cache_ref->next_phys = NULL;
534 cache_ref->flash_offset = ofs | REF_NORMAL;
535 cache_ref->__totlen = sumsize;
536
537 if (!jeb->first_node)
538 jeb->first_node = cache_ref;
539 if (jeb->last_node)
540 jeb->last_node->next_phys = cache_ref;
541 jeb->last_node = cache_ref;
542
543 USED_SPACE(sumsize);
544
545 jeb->wasted_size += jeb->free_size;
546 c->wasted_size += jeb->free_size;
547 c->free_size -= jeb->free_size;
548 jeb->free_size = 0;
549
550 return jffs2_scan_classify_jeb(c, jeb);
551
552crc_err:
553 JFFS2_WARNING("Summary node crc error, skipping summary information.\n");
554
555 return 0;
556}
557
558/* Write summary data to flash - helper function for jffs2_sum_write_sumnode() */
559
560static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
561 uint32_t infosize, uint32_t datasize, int padsize)
562{
563 struct jffs2_raw_summary isum;
564 union jffs2_sum_mem *temp;
565 struct jffs2_sum_marker *sm;
566 struct kvec vecs[2];
567 void *wpage;
568 int ret;
569 size_t retlen;
570
571 memset(c->summary->sum_buf, 0xff, datasize);
572 memset(&isum, 0, sizeof(isum));
573
574 isum.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
575 isum.nodetype = cpu_to_je16(JFFS2_NODETYPE_SUMMARY);
576 isum.totlen = cpu_to_je32(infosize);
577 isum.hdr_crc = cpu_to_je32(crc32(0, &isum, sizeof(struct jffs2_unknown_node) - 4));
578 isum.padded = cpu_to_je32(c->summary->sum_padded);
579 isum.cln_mkr = cpu_to_je32(c->cleanmarker_size);
580 isum.sum_num = cpu_to_je32(c->summary->sum_num);
581 wpage = c->summary->sum_buf;
582
583 while (c->summary->sum_num) {
584
585 switch (je16_to_cpu(c->summary->sum_list_head->u.nodetype)) {
586 case JFFS2_NODETYPE_INODE: {
587 struct jffs2_sum_inode_flash *sino_ptr = wpage;
588
589 sino_ptr->nodetype = c->summary->sum_list_head->i.nodetype;
590 sino_ptr->inode = c->summary->sum_list_head->i.inode;
591 sino_ptr->version = c->summary->sum_list_head->i.version;
592 sino_ptr->offset = c->summary->sum_list_head->i.offset;
593 sino_ptr->totlen = c->summary->sum_list_head->i.totlen;
594
595 wpage += JFFS2_SUMMARY_INODE_SIZE;
596
597 break;
598 }
599
600 case JFFS2_NODETYPE_DIRENT: {
601 struct jffs2_sum_dirent_flash *sdrnt_ptr = wpage;
602
603 sdrnt_ptr->nodetype = c->summary->sum_list_head->d.nodetype;
604 sdrnt_ptr->totlen = c->summary->sum_list_head->d.totlen;
605 sdrnt_ptr->offset = c->summary->sum_list_head->d.offset;
606 sdrnt_ptr->pino = c->summary->sum_list_head->d.pino;
607 sdrnt_ptr->version = c->summary->sum_list_head->d.version;
608 sdrnt_ptr->ino = c->summary->sum_list_head->d.ino;
609 sdrnt_ptr->nsize = c->summary->sum_list_head->d.nsize;
610 sdrnt_ptr->type = c->summary->sum_list_head->d.type;
611
612 memcpy(sdrnt_ptr->name, c->summary->sum_list_head->d.name,
613 c->summary->sum_list_head->d.nsize);
614
615 wpage += JFFS2_SUMMARY_DIRENT_SIZE(c->summary->sum_list_head->d.nsize);
616
617 break;
618 }
619
620 default : {
621 BUG(); /* unknown node in summary information */
622 }
623 }
624
625 temp = c->summary->sum_list_head;
626 c->summary->sum_list_head = c->summary->sum_list_head->u.next;
627 kfree(temp);
628
629 c->summary->sum_num--;
630 }
631
632 jffs2_sum_reset_collected(c->summary);
633
634 wpage += padsize;
635
636 sm = wpage;
637 sm->offset = cpu_to_je32(c->sector_size - jeb->free_size);
638 sm->magic = cpu_to_je32(JFFS2_SUM_MAGIC);
639
640 isum.sum_crc = cpu_to_je32(crc32(0, c->summary->sum_buf, datasize));
641 isum.node_crc = cpu_to_je32(crc32(0, &isum, sizeof(isum) - 8));
642
643 vecs[0].iov_base = &isum;
644 vecs[0].iov_len = sizeof(isum);
645 vecs[1].iov_base = c->summary->sum_buf;
646 vecs[1].iov_len = datasize;
647
648 dbg_summary("JFFS2: writing out data to flash to pos : 0x%08x\n",
649 jeb->offset + c->sector_size - jeb->free_size);
650
651 spin_unlock(&c->erase_completion_lock);
652 ret = jffs2_flash_writev(c, vecs, 2, jeb->offset + c->sector_size -
653 jeb->free_size, &retlen, 0);
654 spin_lock(&c->erase_completion_lock);
655
656
657 if (ret || (retlen != infosize)) {
658 JFFS2_WARNING("Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n",
659 infosize, jeb->offset + c->sector_size - jeb->free_size, ret, retlen);
660
661 c->summary->sum_size = JFFS2_SUMMARY_NOSUM_SIZE;
662 WASTED_SPACE(infosize);
663
664 return 1;
665 }
666
667 return 0;
668}
669
670/* Write out summary information - called from jffs2_do_reserve_space */
671
672int jffs2_sum_write_sumnode(struct jffs2_sb_info *c)
673{
674 struct jffs2_raw_node_ref *summary_ref;
675 int datasize, infosize, padsize, ret;
676 struct jffs2_eraseblock *jeb;
677
678 dbg_summary("called\n");
679
680 jeb = c->nextblock;
681
682 if (!c->summary->sum_num || !c->summary->sum_list_head) {
683 JFFS2_WARNING("Empty summary info!!!\n");
684 BUG();
685 }
686
687 datasize = c->summary->sum_size + sizeof(struct jffs2_sum_marker);
688 infosize = sizeof(struct jffs2_raw_summary) + datasize;
689 padsize = jeb->free_size - infosize;
690 infosize += padsize;
691 datasize += padsize;
692
693 /* Is there enough space for summary? */
694 if (padsize < 0) {
695 /* don't try to write out summary for this jeb */
696 jffs2_sum_disable_collecting(c->summary);
697
698 JFFS2_WARNING("Not enough space for summary, padsize = %d\n", padsize);
699 return 0;
700 }
701
702 ret = jffs2_sum_write_data(c, jeb, infosize, datasize, padsize);
703 if (ret)
704 return 0; /* can't write out summary, block is marked as NOSUM_SIZE */
705
706 /* for ACCT_PARANOIA_CHECK */
707 spin_unlock(&c->erase_completion_lock);
708 summary_ref = jffs2_alloc_raw_node_ref();
709 spin_lock(&c->erase_completion_lock);
710
711 if (!summary_ref) {
712 JFFS2_NOTICE("Failed to allocate node ref for summary\n");
713 return -ENOMEM;
714 }
715
716 summary_ref->next_in_ino = NULL;
717 summary_ref->next_phys = NULL;
718 summary_ref->flash_offset = (jeb->offset + c->sector_size - jeb->free_size) | REF_NORMAL;
719 summary_ref->__totlen = infosize;
720
721 if (!jeb->first_node)
722 jeb->first_node = summary_ref;
723 if (jeb->last_node)
724 jeb->last_node->next_phys = summary_ref;
725 jeb->last_node = summary_ref;
726
727 USED_SPACE(infosize);
728
729 return 0;
730}
diff --git a/fs/jffs2/summary.h b/fs/jffs2/summary.h
new file mode 100644
index 000000000000..b7a678be1709
--- /dev/null
+++ b/fs/jffs2/summary.h
@@ -0,0 +1,183 @@
1/*
2 * JFFS2 -- Journalling Flash File System, Version 2.
3 *
4 * Copyright (C) 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>,
5 * Zoltan Sogor <weth@inf.u-szeged.hu>,
6 * Patrik Kluba <pajko@halom.u-szeged.hu>,
7 * University of Szeged, Hungary
8 *
9 * For licensing information, see the file 'LICENCE' in this directory.
10 *
11 * $Id: summary.h,v 1.2 2005/09/26 11:37:21 havasi Exp $
12 *
13 */
14
15#ifndef JFFS2_SUMMARY_H
16#define JFFS2_SUMMARY_H
17
18#include <linux/uio.h>
19#include <linux/jffs2.h>
20
21#define DIRTY_SPACE(x) do { typeof(x) _x = (x); \
22 c->free_size -= _x; c->dirty_size += _x; \
23 jeb->free_size -= _x ; jeb->dirty_size += _x; \
24 }while(0)
25#define USED_SPACE(x) do { typeof(x) _x = (x); \
26 c->free_size -= _x; c->used_size += _x; \
27 jeb->free_size -= _x ; jeb->used_size += _x; \
28 }while(0)
29#define WASTED_SPACE(x) do { typeof(x) _x = (x); \
30 c->free_size -= _x; c->wasted_size += _x; \
31 jeb->free_size -= _x ; jeb->wasted_size += _x; \
32 }while(0)
33#define UNCHECKED_SPACE(x) do { typeof(x) _x = (x); \
34 c->free_size -= _x; c->unchecked_size += _x; \
35 jeb->free_size -= _x ; jeb->unchecked_size += _x; \
36 }while(0)
37
38#define BLK_STATE_ALLFF 0
39#define BLK_STATE_CLEAN 1
40#define BLK_STATE_PARTDIRTY 2
41#define BLK_STATE_CLEANMARKER 3
42#define BLK_STATE_ALLDIRTY 4
43#define BLK_STATE_BADBLOCK 5
44
45#define JFFS2_SUMMARY_NOSUM_SIZE 0xffffffff
46#define JFFS2_SUMMARY_INODE_SIZE (sizeof(struct jffs2_sum_inode_flash))
47#define JFFS2_SUMMARY_DIRENT_SIZE(x) (sizeof(struct jffs2_sum_dirent_flash) + (x))
48
49/* Summary structures used on flash */
50
51struct jffs2_sum_unknown_flash
52{
53 jint16_t nodetype; /* node type */
54};
55
56struct jffs2_sum_inode_flash
57{
58 jint16_t nodetype; /* node type */
59 jint32_t inode; /* inode number */
60 jint32_t version; /* inode version */
61 jint32_t offset; /* offset on jeb */
62 jint32_t totlen; /* record length */
63} __attribute__((packed));
64
65struct jffs2_sum_dirent_flash
66{
67 jint16_t nodetype; /* == JFFS_NODETYPE_DIRENT */
68 jint32_t totlen; /* record length */
69 jint32_t offset; /* offset on jeb */
70 jint32_t pino; /* parent inode */
71 jint32_t version; /* dirent version */
72 jint32_t ino; /* == zero for unlink */
73 uint8_t nsize; /* dirent name size */
74 uint8_t type; /* dirent type */
75 uint8_t name[0]; /* dirent name */
76} __attribute__((packed));
77
78union jffs2_sum_flash
79{
80 struct jffs2_sum_unknown_flash u;
81 struct jffs2_sum_inode_flash i;
82 struct jffs2_sum_dirent_flash d;
83};
84
85/* Summary structures used in the memory */
86
87struct jffs2_sum_unknown_mem
88{
89 union jffs2_sum_mem *next;
90 jint16_t nodetype; /* node type */
91};
92
93struct jffs2_sum_inode_mem
94{
95 union jffs2_sum_mem *next;
96 jint16_t nodetype; /* node type */
97 jint32_t inode; /* inode number */
98 jint32_t version; /* inode version */
99 jint32_t offset; /* offset on jeb */
100 jint32_t totlen; /* record length */
101} __attribute__((packed));
102
103struct jffs2_sum_dirent_mem
104{
105 union jffs2_sum_mem *next;
106 jint16_t nodetype; /* == JFFS_NODETYPE_DIRENT */
107 jint32_t totlen; /* record length */
108 jint32_t offset; /* ofset on jeb */
109 jint32_t pino; /* parent inode */
110 jint32_t version; /* dirent version */
111 jint32_t ino; /* == zero for unlink */
112 uint8_t nsize; /* dirent name size */
113 uint8_t type; /* dirent type */
114 uint8_t name[0]; /* dirent name */
115} __attribute__((packed));
116
117union jffs2_sum_mem
118{
119 struct jffs2_sum_unknown_mem u;
120 struct jffs2_sum_inode_mem i;
121 struct jffs2_sum_dirent_mem d;
122};
123
124/* Summary related information stored in superblock */
125
126struct jffs2_summary
127{
128 uint32_t sum_size; /* collected summary information for nextblock */
129 uint32_t sum_num;
130 uint32_t sum_padded;
131 union jffs2_sum_mem *sum_list_head;
132 union jffs2_sum_mem *sum_list_tail;
133
134 jint32_t *sum_buf; /* buffer for writing out summary */
135};
136
137/* Summary marker is stored at the end of every sumarized erase block */
138
139struct jffs2_sum_marker
140{
141 jint32_t offset; /* offset of the summary node in the jeb */
142 jint32_t magic; /* == JFFS2_SUM_MAGIC */
143};
144
145#define JFFS2_SUMMARY_FRAME_SIZE (sizeof(struct jffs2_raw_summary) + sizeof(struct jffs2_sum_marker))
146
147#ifdef CONFIG_JFFS2_SUMMARY /* SUMMARY SUPPORT ENABLED */
148
149#define jffs2_sum_active() (1)
150int jffs2_sum_init(struct jffs2_sb_info *c);
151void jffs2_sum_exit(struct jffs2_sb_info *c);
152void jffs2_sum_disable_collecting(struct jffs2_summary *s);
153int jffs2_sum_is_disabled(struct jffs2_summary *s);
154void jffs2_sum_reset_collected(struct jffs2_summary *s);
155void jffs2_sum_move_collected(struct jffs2_sb_info *c, struct jffs2_summary *s);
156int jffs2_sum_add_kvec(struct jffs2_sb_info *c, const struct kvec *invecs,
157 unsigned long count, uint32_t to);
158int jffs2_sum_write_sumnode(struct jffs2_sb_info *c);
159int jffs2_sum_add_padding_mem(struct jffs2_summary *s, uint32_t size);
160int jffs2_sum_add_inode_mem(struct jffs2_summary *s, struct jffs2_raw_inode *ri, uint32_t ofs);
161int jffs2_sum_add_dirent_mem(struct jffs2_summary *s, struct jffs2_raw_dirent *rd, uint32_t ofs);
162int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
163 uint32_t ofs, uint32_t *pseudo_random);
164
165#else /* SUMMARY DISABLED */
166
167#define jffs2_sum_active() (0)
168#define jffs2_sum_init(a) (0)
169#define jffs2_sum_exit(a)
170#define jffs2_sum_disable_collecting(a)
171#define jffs2_sum_is_disabled(a) (0)
172#define jffs2_sum_reset_collected(a)
173#define jffs2_sum_add_kvec(a,b,c,d) (0)
174#define jffs2_sum_move_collected(a,b)
175#define jffs2_sum_write_sumnode(a) (0)
176#define jffs2_sum_add_padding_mem(a,b)
177#define jffs2_sum_add_inode_mem(a,b,c)
178#define jffs2_sum_add_dirent_mem(a,b,c)
179#define jffs2_sum_scan_sumnode(a,b,c,d) (0)
180
181#endif /* CONFIG_JFFS2_SUMMARY */
182
183#endif /* JFFS2_SUMMARY_H */
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index aaf9475cfb6a..9e0b5458d9c0 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: super.c,v 1.107 2005/07/12 16:37:08 dedekind Exp $ 10 * $Id: super.c,v 1.110 2005/11/07 11:14:42 gleixner Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -62,7 +62,7 @@ static int jffs2_sync_fs(struct super_block *sb, int wait)
62 62
63 down(&c->alloc_sem); 63 down(&c->alloc_sem);
64 jffs2_flush_wbuf_pad(c); 64 jffs2_flush_wbuf_pad(c);
65 up(&c->alloc_sem); 65 up(&c->alloc_sem);
66 return 0; 66 return 0;
67} 67}
68 68
@@ -112,7 +112,7 @@ static int jffs2_sb_set(struct super_block *sb, void *data)
112} 112}
113 113
114static struct super_block *jffs2_get_sb_mtd(struct file_system_type *fs_type, 114static struct super_block *jffs2_get_sb_mtd(struct file_system_type *fs_type,
115 int flags, const char *dev_name, 115 int flags, const char *dev_name,
116 void *data, struct mtd_info *mtd) 116 void *data, struct mtd_info *mtd)
117{ 117{
118 struct super_block *sb; 118 struct super_block *sb;
@@ -172,7 +172,7 @@ static struct super_block *jffs2_get_sb_mtd(struct file_system_type *fs_type,
172} 172}
173 173
174static struct super_block *jffs2_get_sb_mtdnr(struct file_system_type *fs_type, 174static struct super_block *jffs2_get_sb_mtdnr(struct file_system_type *fs_type,
175 int flags, const char *dev_name, 175 int flags, const char *dev_name,
176 void *data, int mtdnr) 176 void *data, int mtdnr)
177{ 177{
178 struct mtd_info *mtd; 178 struct mtd_info *mtd;
@@ -201,7 +201,7 @@ static struct super_block *jffs2_get_sb(struct file_system_type *fs_type,
201 201
202 /* The preferred way of mounting in future; especially when 202 /* The preferred way of mounting in future; especially when
203 CONFIG_BLK_DEV is implemented - we specify the underlying 203 CONFIG_BLK_DEV is implemented - we specify the underlying
204 MTD device by number or by name, so that we don't require 204 MTD device by number or by name, so that we don't require
205 block device support to be present in the kernel. */ 205 block device support to be present in the kernel. */
206 206
207 /* FIXME: How to do the root fs this way? */ 207 /* FIXME: How to do the root fs this way? */
@@ -225,7 +225,7 @@ static struct super_block *jffs2_get_sb(struct file_system_type *fs_type,
225 } else if (isdigit(dev_name[3])) { 225 } else if (isdigit(dev_name[3])) {
226 /* Mount by MTD device number name */ 226 /* Mount by MTD device number name */
227 char *endptr; 227 char *endptr;
228 228
229 mtdnr = simple_strtoul(dev_name+3, &endptr, 0); 229 mtdnr = simple_strtoul(dev_name+3, &endptr, 0);
230 if (!*endptr) { 230 if (!*endptr) {
231 /* It was a valid number */ 231 /* It was a valid number */
@@ -235,7 +235,7 @@ static struct super_block *jffs2_get_sb(struct file_system_type *fs_type,
235 } 235 }
236 } 236 }
237 237
238 /* Try the old way - the hack where we allowed users to mount 238 /* Try the old way - the hack where we allowed users to mount
239 /dev/mtdblock$(n) but didn't actually _use_ the blkdev */ 239 /dev/mtdblock$(n) but didn't actually _use_ the blkdev */
240 240
241 err = path_lookup(dev_name, LOOKUP_FOLLOW, &nd); 241 err = path_lookup(dev_name, LOOKUP_FOLLOW, &nd);
@@ -282,9 +282,12 @@ static void jffs2_put_super (struct super_block *sb)
282 down(&c->alloc_sem); 282 down(&c->alloc_sem);
283 jffs2_flush_wbuf_pad(c); 283 jffs2_flush_wbuf_pad(c);
284 up(&c->alloc_sem); 284 up(&c->alloc_sem);
285
286 jffs2_sum_exit(c);
287
285 jffs2_free_ino_caches(c); 288 jffs2_free_ino_caches(c);
286 jffs2_free_raw_node_refs(c); 289 jffs2_free_raw_node_refs(c);
287 if (c->mtd->flags & MTD_NO_VIRTBLOCKS) 290 if (jffs2_blocks_use_vmalloc(c))
288 vfree(c->blocks); 291 vfree(c->blocks);
289 else 292 else
290 kfree(c->blocks); 293 kfree(c->blocks);
@@ -321,6 +324,9 @@ static int __init init_jffs2_fs(void)
321#ifdef CONFIG_JFFS2_FS_WRITEBUFFER 324#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
322 " (NAND)" 325 " (NAND)"
323#endif 326#endif
327#ifdef CONFIG_JFFS2_SUMMARY
328 " (SUMMARY) "
329#endif
324 " (C) 2001-2003 Red Hat, Inc.\n"); 330 " (C) 2001-2003 Red Hat, Inc.\n");
325 331
326 jffs2_inode_cachep = kmem_cache_create("jffs2_i", 332 jffs2_inode_cachep = kmem_cache_create("jffs2_i",
@@ -370,5 +376,5 @@ module_exit(exit_jffs2_fs);
370 376
371MODULE_DESCRIPTION("The Journalling Flash File System, v2"); 377MODULE_DESCRIPTION("The Journalling Flash File System, v2");
372MODULE_AUTHOR("Red Hat, Inc."); 378MODULE_AUTHOR("Red Hat, Inc.");
373MODULE_LICENSE("GPL"); // Actually dual-licensed, but it doesn't matter for 379MODULE_LICENSE("GPL"); // Actually dual-licensed, but it doesn't matter for
374 // the sake of this tag. It's Free Software. 380 // the sake of this tag. It's Free Software.
diff --git a/fs/jffs2/symlink.c b/fs/jffs2/symlink.c
index 82ef484f5e12..d55754fe8925 100644
--- a/fs/jffs2/symlink.c
+++ b/fs/jffs2/symlink.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: symlink.c,v 1.16 2005/03/01 10:50:48 dedekind Exp $ 10 * $Id: symlink.c,v 1.19 2005/11/07 11:14:42 gleixner Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -21,7 +21,7 @@
21static void *jffs2_follow_link(struct dentry *dentry, struct nameidata *nd); 21static void *jffs2_follow_link(struct dentry *dentry, struct nameidata *nd);
22 22
23struct inode_operations jffs2_symlink_inode_operations = 23struct inode_operations jffs2_symlink_inode_operations =
24{ 24{
25 .readlink = generic_readlink, 25 .readlink = generic_readlink,
26 .follow_link = jffs2_follow_link, 26 .follow_link = jffs2_follow_link,
27 .setattr = jffs2_setattr 27 .setattr = jffs2_setattr
@@ -30,35 +30,33 @@ struct inode_operations jffs2_symlink_inode_operations =
30static void *jffs2_follow_link(struct dentry *dentry, struct nameidata *nd) 30static void *jffs2_follow_link(struct dentry *dentry, struct nameidata *nd)
31{ 31{
32 struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode); 32 struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode);
33 char *p = (char *)f->dents; 33 char *p = (char *)f->target;
34 34
35 /* 35 /*
36 * We don't acquire the f->sem mutex here since the only data we 36 * We don't acquire the f->sem mutex here since the only data we
37 * use is f->dents which in case of the symlink inode points to the 37 * use is f->target.
38 * symlink's target path.
39 * 38 *
40 * 1. If we are here the inode has already built and f->dents has 39 * 1. If we are here the inode has already built and f->target has
41 * to point to the target path. 40 * to point to the target path.
42 * 2. Nobody uses f->dents (if the inode is symlink's inode). The 41 * 2. Nobody uses f->target (if the inode is symlink's inode). The
43 * exception is inode freeing function which frees f->dents. But 42 * exception is inode freeing function which frees f->target. But
44 * it can't be called while we are here and before VFS has 43 * it can't be called while we are here and before VFS has
45 * stopped using our f->dents string which we provide by means of 44 * stopped using our f->target string which we provide by means of
46 * nd_set_link() call. 45 * nd_set_link() call.
47 */ 46 */
48 47
49 if (!p) { 48 if (!p) {
50 printk(KERN_ERR "jffs2_follow_link(): can't find symlink taerget\n"); 49 printk(KERN_ERR "jffs2_follow_link(): can't find symlink taerget\n");
51 p = ERR_PTR(-EIO); 50 p = ERR_PTR(-EIO);
52 } else {
53 D1(printk(KERN_DEBUG "jffs2_follow_link(): target path is '%s'\n", (char *) f->dents));
54 } 51 }
52 D1(printk(KERN_DEBUG "jffs2_follow_link(): target path is '%s'\n", (char *) f->target));
55 53
56 nd_set_link(nd, p); 54 nd_set_link(nd, p);
57 55
58 /* 56 /*
59 * We unlock the f->sem mutex but VFS will use the f->dents string. This is safe 57 * We will unlock the f->sem mutex but VFS will use the f->target string. This is safe
60 * since the only way that may cause f->dents to be changed is iput() operation. 58 * since the only way that may cause f->target to be changed is iput() operation.
61 * But VFS will not use f->dents after iput() has been called. 59 * But VFS will not use f->target after iput() has been called.
62 */ 60 */
63 return NULL; 61 return NULL;
64} 62}
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index 7bc7f2d571f6..4cebf0e57c46 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -9,7 +9,7 @@
9 * 9 *
10 * For licensing information, see the file 'LICENCE' in this directory. 10 * For licensing information, see the file 'LICENCE' in this directory.
11 * 11 *
12 * $Id: wbuf.c,v 1.92 2005/04/05 12:51:54 dedekind Exp $ 12 * $Id: wbuf.c,v 1.100 2005/09/30 13:59:13 dedekind Exp $
13 * 13 *
14 */ 14 */
15 15
@@ -30,12 +30,12 @@
30static unsigned char *brokenbuf; 30static unsigned char *brokenbuf;
31#endif 31#endif
32 32
33#define PAGE_DIV(x) ( ((unsigned long)(x) / (unsigned long)(c->wbuf_pagesize)) * (unsigned long)(c->wbuf_pagesize) )
34#define PAGE_MOD(x) ( (unsigned long)(x) % (unsigned long)(c->wbuf_pagesize) )
35
33/* max. erase failures before we mark a block bad */ 36/* max. erase failures before we mark a block bad */
34#define MAX_ERASE_FAILURES 2 37#define MAX_ERASE_FAILURES 2
35 38
36/* two seconds timeout for timed wbuf-flushing */
37#define WBUF_FLUSH_TIMEOUT 2 * HZ
38
39struct jffs2_inodirty { 39struct jffs2_inodirty {
40 uint32_t ino; 40 uint32_t ino;
41 struct jffs2_inodirty *next; 41 struct jffs2_inodirty *next;
@@ -139,7 +139,6 @@ static void jffs2_block_refile(struct jffs2_sb_info *c, struct jffs2_eraseblock
139{ 139{
140 D1(printk("About to refile bad block at %08x\n", jeb->offset)); 140 D1(printk("About to refile bad block at %08x\n", jeb->offset));
141 141
142 D2(jffs2_dump_block_lists(c));
143 /* File the existing block on the bad_used_list.... */ 142 /* File the existing block on the bad_used_list.... */
144 if (c->nextblock == jeb) 143 if (c->nextblock == jeb)
145 c->nextblock = NULL; 144 c->nextblock = NULL;
@@ -156,7 +155,6 @@ static void jffs2_block_refile(struct jffs2_sb_info *c, struct jffs2_eraseblock
156 c->nr_erasing_blocks++; 155 c->nr_erasing_blocks++;
157 jffs2_erase_pending_trigger(c); 156 jffs2_erase_pending_trigger(c);
158 } 157 }
159 D2(jffs2_dump_block_lists(c));
160 158
161 /* Adjust its size counts accordingly */ 159 /* Adjust its size counts accordingly */
162 c->wasted_size += jeb->free_size; 160 c->wasted_size += jeb->free_size;
@@ -164,8 +162,9 @@ static void jffs2_block_refile(struct jffs2_sb_info *c, struct jffs2_eraseblock
164 jeb->wasted_size += jeb->free_size; 162 jeb->wasted_size += jeb->free_size;
165 jeb->free_size = 0; 163 jeb->free_size = 0;
166 164
167 ACCT_SANITY_CHECK(c,jeb); 165 jffs2_dbg_dump_block_lists_nolock(c);
168 D1(ACCT_PARANOIA_CHECK(jeb)); 166 jffs2_dbg_acct_sanity_check_nolock(c,jeb);
167 jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
169} 168}
170 169
171/* Recover from failure to write wbuf. Recover the nodes up to the 170/* Recover from failure to write wbuf. Recover the nodes up to the
@@ -189,7 +188,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
189 /* Find the first node to be recovered, by skipping over every 188 /* Find the first node to be recovered, by skipping over every
190 node which ends before the wbuf starts, or which is obsolete. */ 189 node which ends before the wbuf starts, or which is obsolete. */
191 first_raw = &jeb->first_node; 190 first_raw = &jeb->first_node;
192 while (*first_raw && 191 while (*first_raw &&
193 (ref_obsolete(*first_raw) || 192 (ref_obsolete(*first_raw) ||
194 (ref_offset(*first_raw)+ref_totlen(c, jeb, *first_raw)) < c->wbuf_ofs)) { 193 (ref_offset(*first_raw)+ref_totlen(c, jeb, *first_raw)) < c->wbuf_ofs)) {
195 D1(printk(KERN_DEBUG "Skipping node at 0x%08x(%d)-0x%08x which is either before 0x%08x or obsolete\n", 194 D1(printk(KERN_DEBUG "Skipping node at 0x%08x(%d)-0x%08x which is either before 0x%08x or obsolete\n",
@@ -238,7 +237,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
238 ret = c->mtd->read_ecc(c->mtd, start, c->wbuf_ofs - start, &retlen, buf, NULL, c->oobinfo); 237 ret = c->mtd->read_ecc(c->mtd, start, c->wbuf_ofs - start, &retlen, buf, NULL, c->oobinfo);
239 else 238 else
240 ret = c->mtd->read(c->mtd, start, c->wbuf_ofs - start, &retlen, buf); 239 ret = c->mtd->read(c->mtd, start, c->wbuf_ofs - start, &retlen, buf);
241 240
242 if (ret == -EBADMSG && retlen == c->wbuf_ofs - start) { 241 if (ret == -EBADMSG && retlen == c->wbuf_ofs - start) {
243 /* ECC recovered */ 242 /* ECC recovered */
244 ret = 0; 243 ret = 0;
@@ -266,7 +265,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
266 265
267 266
268 /* ... and get an allocation of space from a shiny new block instead */ 267 /* ... and get an allocation of space from a shiny new block instead */
269 ret = jffs2_reserve_space_gc(c, end-start, &ofs, &len); 268 ret = jffs2_reserve_space_gc(c, end-start, &ofs, &len, JFFS2_SUMMARY_NOSUM_SIZE);
270 if (ret) { 269 if (ret) {
271 printk(KERN_WARNING "Failed to allocate space for wbuf recovery. Data loss ensues.\n"); 270 printk(KERN_WARNING "Failed to allocate space for wbuf recovery. Data loss ensues.\n");
272 kfree(buf); 271 kfree(buf);
@@ -275,15 +274,15 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
275 if (end-start >= c->wbuf_pagesize) { 274 if (end-start >= c->wbuf_pagesize) {
276 /* Need to do another write immediately, but it's possible 275 /* Need to do another write immediately, but it's possible
277 that this is just because the wbuf itself is completely 276 that this is just because the wbuf itself is completely
278 full, and there's nothing earlier read back from the 277 full, and there's nothing earlier read back from the
279 flash. Hence 'buf' isn't necessarily what we're writing 278 flash. Hence 'buf' isn't necessarily what we're writing
280 from. */ 279 from. */
281 unsigned char *rewrite_buf = buf?:c->wbuf; 280 unsigned char *rewrite_buf = buf?:c->wbuf;
282 uint32_t towrite = (end-start) - ((end-start)%c->wbuf_pagesize); 281 uint32_t towrite = (end-start) - ((end-start)%c->wbuf_pagesize);
283 282
284 D1(printk(KERN_DEBUG "Write 0x%x bytes at 0x%08x in wbuf recover\n", 283 D1(printk(KERN_DEBUG "Write 0x%x bytes at 0x%08x in wbuf recover\n",
285 towrite, ofs)); 284 towrite, ofs));
286 285
287#ifdef BREAKMEHEADER 286#ifdef BREAKMEHEADER
288 static int breakme; 287 static int breakme;
289 if (breakme++ == 20) { 288 if (breakme++ == 20) {
@@ -391,11 +390,11 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
391 else 390 else
392 jeb->last_node = container_of(first_raw, struct jffs2_raw_node_ref, next_phys); 391 jeb->last_node = container_of(first_raw, struct jffs2_raw_node_ref, next_phys);
393 392
394 ACCT_SANITY_CHECK(c,jeb); 393 jffs2_dbg_acct_sanity_check_nolock(c, jeb);
395 D1(ACCT_PARANOIA_CHECK(jeb)); 394 jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
396 395
397 ACCT_SANITY_CHECK(c,new_jeb); 396 jffs2_dbg_acct_sanity_check_nolock(c, new_jeb);
398 D1(ACCT_PARANOIA_CHECK(new_jeb)); 397 jffs2_dbg_acct_paranoia_check_nolock(c, new_jeb);
399 398
400 spin_unlock(&c->erase_completion_lock); 399 spin_unlock(&c->erase_completion_lock);
401 400
@@ -434,15 +433,15 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
434 this happens, if we have a change to a new block, 433 this happens, if we have a change to a new block,
435 or if fsync forces us to flush the writebuffer. 434 or if fsync forces us to flush the writebuffer.
436 if we have a switch to next page, we will not have 435 if we have a switch to next page, we will not have
437 enough remaining space for this. 436 enough remaining space for this.
438 */ 437 */
439 if (pad && !jffs2_dataflash(c)) { 438 if (pad ) {
440 c->wbuf_len = PAD(c->wbuf_len); 439 c->wbuf_len = PAD(c->wbuf_len);
441 440
442 /* Pad with JFFS2_DIRTY_BITMASK initially. this helps out ECC'd NOR 441 /* Pad with JFFS2_DIRTY_BITMASK initially. this helps out ECC'd NOR
443 with 8 byte page size */ 442 with 8 byte page size */
444 memset(c->wbuf + c->wbuf_len, 0, c->wbuf_pagesize - c->wbuf_len); 443 memset(c->wbuf + c->wbuf_len, 0, c->wbuf_pagesize - c->wbuf_len);
445 444
446 if ( c->wbuf_len + sizeof(struct jffs2_unknown_node) < c->wbuf_pagesize) { 445 if ( c->wbuf_len + sizeof(struct jffs2_unknown_node) < c->wbuf_pagesize) {
447 struct jffs2_unknown_node *padnode = (void *)(c->wbuf + c->wbuf_len); 446 struct jffs2_unknown_node *padnode = (void *)(c->wbuf + c->wbuf_len);
448 padnode->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); 447 padnode->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
@@ -453,7 +452,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
453 } 452 }
454 /* else jffs2_flash_writev has actually filled in the rest of the 453 /* else jffs2_flash_writev has actually filled in the rest of the
455 buffer for us, and will deal with the node refs etc. later. */ 454 buffer for us, and will deal with the node refs etc. later. */
456 455
457#ifdef BREAKME 456#ifdef BREAKME
458 static int breakme; 457 static int breakme;
459 if (breakme++ == 20) { 458 if (breakme++ == 20) {
@@ -462,9 +461,9 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
462 c->mtd->write_ecc(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, 461 c->mtd->write_ecc(c->mtd, c->wbuf_ofs, c->wbuf_pagesize,
463 &retlen, brokenbuf, NULL, c->oobinfo); 462 &retlen, brokenbuf, NULL, c->oobinfo);
464 ret = -EIO; 463 ret = -EIO;
465 } else 464 } else
466#endif 465#endif
467 466
468 if (jffs2_cleanmarker_oob(c)) 467 if (jffs2_cleanmarker_oob(c))
469 ret = c->mtd->write_ecc(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, c->wbuf, NULL, c->oobinfo); 468 ret = c->mtd->write_ecc(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, c->wbuf, NULL, c->oobinfo);
470 else 469 else
@@ -487,7 +486,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
487 spin_lock(&c->erase_completion_lock); 486 spin_lock(&c->erase_completion_lock);
488 487
489 /* Adjust free size of the block if we padded. */ 488 /* Adjust free size of the block if we padded. */
490 if (pad && !jffs2_dataflash(c)) { 489 if (pad) {
491 struct jffs2_eraseblock *jeb; 490 struct jffs2_eraseblock *jeb;
492 491
493 jeb = &c->blocks[c->wbuf_ofs / c->sector_size]; 492 jeb = &c->blocks[c->wbuf_ofs / c->sector_size];
@@ -495,7 +494,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
495 D1(printk(KERN_DEBUG "jffs2_flush_wbuf() adjusting free_size of %sblock at %08x\n", 494 D1(printk(KERN_DEBUG "jffs2_flush_wbuf() adjusting free_size of %sblock at %08x\n",
496 (jeb==c->nextblock)?"next":"", jeb->offset)); 495 (jeb==c->nextblock)?"next":"", jeb->offset));
497 496
498 /* wbuf_pagesize - wbuf_len is the amount of space that's to be 497 /* wbuf_pagesize - wbuf_len is the amount of space that's to be
499 padded. If there is less free space in the block than that, 498 padded. If there is less free space in the block than that,
500 something screwed up */ 499 something screwed up */
501 if (jeb->free_size < (c->wbuf_pagesize - c->wbuf_len)) { 500 if (jeb->free_size < (c->wbuf_pagesize - c->wbuf_len)) {
@@ -523,9 +522,9 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
523 return 0; 522 return 0;
524} 523}
525 524
526/* Trigger garbage collection to flush the write-buffer. 525/* Trigger garbage collection to flush the write-buffer.
527 If ino arg is zero, do it if _any_ real (i.e. not GC) writes are 526 If ino arg is zero, do it if _any_ real (i.e. not GC) writes are
528 outstanding. If ino arg non-zero, do it only if a write for the 527 outstanding. If ino arg non-zero, do it only if a write for the
529 given inode is outstanding. */ 528 given inode is outstanding. */
530int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino) 529int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino)
531{ 530{
@@ -604,15 +603,6 @@ int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c)
604 603
605 return ret; 604 return ret;
606} 605}
607
608#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
609#define PAGE_DIV(x) ( ((unsigned long)(x) / (unsigned long)(c->wbuf_pagesize)) * (unsigned long)(c->wbuf_pagesize) )
610#define PAGE_MOD(x) ( (unsigned long)(x) % (unsigned long)(c->wbuf_pagesize) )
611#else
612#define PAGE_DIV(x) ( (x) & (~(c->wbuf_pagesize - 1)) )
613#define PAGE_MOD(x) ( (x) & (c->wbuf_pagesize - 1) )
614#endif
615
616int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsigned long count, loff_t to, size_t *retlen, uint32_t ino) 606int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsigned long count, loff_t to, size_t *retlen, uint32_t ino)
617{ 607{
618 struct kvec outvecs[3]; 608 struct kvec outvecs[3];
@@ -629,13 +619,13 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
629 /* If not NAND flash, don't bother */ 619 /* If not NAND flash, don't bother */
630 if (!jffs2_is_writebuffered(c)) 620 if (!jffs2_is_writebuffered(c))
631 return jffs2_flash_direct_writev(c, invecs, count, to, retlen); 621 return jffs2_flash_direct_writev(c, invecs, count, to, retlen);
632 622
633 down_write(&c->wbuf_sem); 623 down_write(&c->wbuf_sem);
634 624
635 /* If wbuf_ofs is not initialized, set it to target address */ 625 /* If wbuf_ofs is not initialized, set it to target address */
636 if (c->wbuf_ofs == 0xFFFFFFFF) { 626 if (c->wbuf_ofs == 0xFFFFFFFF) {
637 c->wbuf_ofs = PAGE_DIV(to); 627 c->wbuf_ofs = PAGE_DIV(to);
638 c->wbuf_len = PAGE_MOD(to); 628 c->wbuf_len = PAGE_MOD(to);
639 memset(c->wbuf,0xff,c->wbuf_pagesize); 629 memset(c->wbuf,0xff,c->wbuf_pagesize);
640 } 630 }
641 631
@@ -649,10 +639,10 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
649 memset(c->wbuf,0xff,c->wbuf_pagesize); 639 memset(c->wbuf,0xff,c->wbuf_pagesize);
650 } 640 }
651 } 641 }
652 642
653 /* Sanity checks on target address. 643 /* Sanity checks on target address.
654 It's permitted to write at PAD(c->wbuf_len+c->wbuf_ofs), 644 It's permitted to write at PAD(c->wbuf_len+c->wbuf_ofs),
655 and it's permitted to write at the beginning of a new 645 and it's permitted to write at the beginning of a new
656 erase block. Anything else, and you die. 646 erase block. Anything else, and you die.
657 New block starts at xxx000c (0-b = block header) 647 New block starts at xxx000c (0-b = block header)
658 */ 648 */
@@ -670,8 +660,8 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
670 } 660 }
671 /* set pointer to new block */ 661 /* set pointer to new block */
672 c->wbuf_ofs = PAGE_DIV(to); 662 c->wbuf_ofs = PAGE_DIV(to);
673 c->wbuf_len = PAGE_MOD(to); 663 c->wbuf_len = PAGE_MOD(to);
674 } 664 }
675 665
676 if (to != PAD(c->wbuf_ofs + c->wbuf_len)) { 666 if (to != PAD(c->wbuf_ofs + c->wbuf_len)) {
677 /* We're not writing immediately after the writebuffer. Bad. */ 667 /* We're not writing immediately after the writebuffer. Bad. */
@@ -691,21 +681,21 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
691 invec = 0; 681 invec = 0;
692 outvec = 0; 682 outvec = 0;
693 683
694 /* Fill writebuffer first, if already in use */ 684 /* Fill writebuffer first, if already in use */
695 if (c->wbuf_len) { 685 if (c->wbuf_len) {
696 uint32_t invec_ofs = 0; 686 uint32_t invec_ofs = 0;
697 687
698 /* adjust alignment offset */ 688 /* adjust alignment offset */
699 if (c->wbuf_len != PAGE_MOD(to)) { 689 if (c->wbuf_len != PAGE_MOD(to)) {
700 c->wbuf_len = PAGE_MOD(to); 690 c->wbuf_len = PAGE_MOD(to);
701 /* take care of alignment to next page */ 691 /* take care of alignment to next page */
702 if (!c->wbuf_len) 692 if (!c->wbuf_len)
703 c->wbuf_len = c->wbuf_pagesize; 693 c->wbuf_len = c->wbuf_pagesize;
704 } 694 }
705 695
706 while(c->wbuf_len < c->wbuf_pagesize) { 696 while(c->wbuf_len < c->wbuf_pagesize) {
707 uint32_t thislen; 697 uint32_t thislen;
708 698
709 if (invec == count) 699 if (invec == count)
710 goto alldone; 700 goto alldone;
711 701
@@ -713,17 +703,17 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
713 703
714 if (thislen >= invecs[invec].iov_len) 704 if (thislen >= invecs[invec].iov_len)
715 thislen = invecs[invec].iov_len; 705 thislen = invecs[invec].iov_len;
716 706
717 invec_ofs = thislen; 707 invec_ofs = thislen;
718 708
719 memcpy(c->wbuf + c->wbuf_len, invecs[invec].iov_base, thislen); 709 memcpy(c->wbuf + c->wbuf_len, invecs[invec].iov_base, thislen);
720 c->wbuf_len += thislen; 710 c->wbuf_len += thislen;
721 donelen += thislen; 711 donelen += thislen;
722 /* Get next invec, if actual did not fill the buffer */ 712 /* Get next invec, if actual did not fill the buffer */
723 if (c->wbuf_len < c->wbuf_pagesize) 713 if (c->wbuf_len < c->wbuf_pagesize)
724 invec++; 714 invec++;
725 } 715 }
726 716
727 /* write buffer is full, flush buffer */ 717 /* write buffer is full, flush buffer */
728 ret = __jffs2_flush_wbuf(c, NOPAD); 718 ret = __jffs2_flush_wbuf(c, NOPAD);
729 if (ret) { 719 if (ret) {
@@ -782,10 +772,10 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
782 772
783 /* We did cross a page boundary, so we write some now */ 773 /* We did cross a page boundary, so we write some now */
784 if (jffs2_cleanmarker_oob(c)) 774 if (jffs2_cleanmarker_oob(c))
785 ret = c->mtd->writev_ecc(c->mtd, outvecs, splitvec+1, outvec_to, &wbuf_retlen, NULL, c->oobinfo); 775 ret = c->mtd->writev_ecc(c->mtd, outvecs, splitvec+1, outvec_to, &wbuf_retlen, NULL, c->oobinfo);
786 else 776 else
787 ret = jffs2_flash_direct_writev(c, outvecs, splitvec+1, outvec_to, &wbuf_retlen); 777 ret = jffs2_flash_direct_writev(c, outvecs, splitvec+1, outvec_to, &wbuf_retlen);
788 778
789 if (ret < 0 || wbuf_retlen != PAGE_DIV(totlen)) { 779 if (ret < 0 || wbuf_retlen != PAGE_DIV(totlen)) {
790 /* At this point we have no problem, 780 /* At this point we have no problem,
791 c->wbuf is empty. However refile nextblock to avoid 781 c->wbuf is empty. However refile nextblock to avoid
@@ -802,7 +792,7 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
802 spin_unlock(&c->erase_completion_lock); 792 spin_unlock(&c->erase_completion_lock);
803 goto exit; 793 goto exit;
804 } 794 }
805 795
806 donelen += wbuf_retlen; 796 donelen += wbuf_retlen;
807 c->wbuf_ofs = PAGE_DIV(outvec_to) + PAGE_DIV(totlen); 797 c->wbuf_ofs = PAGE_DIV(outvec_to) + PAGE_DIV(totlen);
808 798
@@ -836,11 +826,17 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
836alldone: 826alldone:
837 *retlen = donelen; 827 *retlen = donelen;
838 828
829 if (jffs2_sum_active()) {
830 int res = jffs2_sum_add_kvec(c, invecs, count, (uint32_t) to);
831 if (res)
832 return res;
833 }
834
839 if (c->wbuf_len && ino) 835 if (c->wbuf_len && ino)
840 jffs2_wbuf_dirties_inode(c, ino); 836 jffs2_wbuf_dirties_inode(c, ino);
841 837
842 ret = 0; 838 ret = 0;
843 839
844exit: 840exit:
845 up_write(&c->wbuf_sem); 841 up_write(&c->wbuf_sem);
846 return ret; 842 return ret;
@@ -855,7 +851,7 @@ int jffs2_flash_write(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *r
855 struct kvec vecs[1]; 851 struct kvec vecs[1];
856 852
857 if (!jffs2_is_writebuffered(c)) 853 if (!jffs2_is_writebuffered(c))
858 return c->mtd->write(c->mtd, ofs, len, retlen, buf); 854 return jffs2_flash_direct_write(c, ofs, len, retlen, buf);
859 855
860 vecs[0].iov_base = (unsigned char *) buf; 856 vecs[0].iov_base = (unsigned char *) buf;
861 vecs[0].iov_len = len; 857 vecs[0].iov_len = len;
@@ -883,18 +879,18 @@ int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *re
883 if ( (ret == -EBADMSG) && (*retlen == len) ) { 879 if ( (ret == -EBADMSG) && (*retlen == len) ) {
884 printk(KERN_WARNING "mtd->read(0x%zx bytes from 0x%llx) returned ECC error\n", 880 printk(KERN_WARNING "mtd->read(0x%zx bytes from 0x%llx) returned ECC error\n",
885 len, ofs); 881 len, ofs);
886 /* 882 /*
887 * We have the raw data without ECC correction in the buffer, maybe 883 * We have the raw data without ECC correction in the buffer, maybe
888 * we are lucky and all data or parts are correct. We check the node. 884 * we are lucky and all data or parts are correct. We check the node.
889 * If data are corrupted node check will sort it out. 885 * If data are corrupted node check will sort it out.
890 * We keep this block, it will fail on write or erase and the we 886 * We keep this block, it will fail on write or erase and the we
891 * mark it bad. Or should we do that now? But we should give him a chance. 887 * mark it bad. Or should we do that now? But we should give him a chance.
892 * Maybe we had a system crash or power loss before the ecc write or 888 * Maybe we had a system crash or power loss before the ecc write or
893 * a erase was completed. 889 * a erase was completed.
894 * So we return success. :) 890 * So we return success. :)
895 */ 891 */
896 ret = 0; 892 ret = 0;
897 } 893 }
898 894
899 /* if no writebuffer available or write buffer empty, return */ 895 /* if no writebuffer available or write buffer empty, return */
900 if (!c->wbuf_pagesize || !c->wbuf_len) 896 if (!c->wbuf_pagesize || !c->wbuf_len)
@@ -909,16 +905,16 @@ int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *re
909 if (owbf > c->wbuf_len) /* is read beyond write buffer ? */ 905 if (owbf > c->wbuf_len) /* is read beyond write buffer ? */
910 goto exit; 906 goto exit;
911 lwbf = c->wbuf_len - owbf; /* number of bytes to copy */ 907 lwbf = c->wbuf_len - owbf; /* number of bytes to copy */
912 if (lwbf > len) 908 if (lwbf > len)
913 lwbf = len; 909 lwbf = len;
914 } else { 910 } else {
915 orbf = (c->wbuf_ofs - ofs); /* offset in read buffer */ 911 orbf = (c->wbuf_ofs - ofs); /* offset in read buffer */
916 if (orbf > len) /* is write beyond write buffer ? */ 912 if (orbf > len) /* is write beyond write buffer ? */
917 goto exit; 913 goto exit;
918 lwbf = len - orbf; /* number of bytes to copy */ 914 lwbf = len - orbf; /* number of bytes to copy */
919 if (lwbf > c->wbuf_len) 915 if (lwbf > c->wbuf_len)
920 lwbf = c->wbuf_len; 916 lwbf = c->wbuf_len;
921 } 917 }
922 if (lwbf > 0) 918 if (lwbf > 0)
923 memcpy(buf+orbf,c->wbuf+owbf,lwbf); 919 memcpy(buf+orbf,c->wbuf+owbf,lwbf);
924 920
@@ -946,7 +942,7 @@ int jffs2_check_oob_empty( struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb
946 printk(KERN_NOTICE "jffs2_check_oob_empty(): allocation of temporary data buffer for oob check failed\n"); 942 printk(KERN_NOTICE "jffs2_check_oob_empty(): allocation of temporary data buffer for oob check failed\n");
947 return -ENOMEM; 943 return -ENOMEM;
948 } 944 }
949 /* 945 /*
950 * if mode = 0, we scan for a total empty oob area, else we have 946 * if mode = 0, we scan for a total empty oob area, else we have
951 * to take care of the cleanmarker in the first page of the block 947 * to take care of the cleanmarker in the first page of the block
952 */ 948 */
@@ -955,41 +951,41 @@ int jffs2_check_oob_empty( struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb
955 D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB failed %d for block at %08x\n", ret, jeb->offset)); 951 D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB failed %d for block at %08x\n", ret, jeb->offset));
956 goto out; 952 goto out;
957 } 953 }
958 954
959 if (retlen < len) { 955 if (retlen < len) {
960 D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB return short read " 956 D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB return short read "
961 "(%zd bytes not %d) for block at %08x\n", retlen, len, jeb->offset)); 957 "(%zd bytes not %d) for block at %08x\n", retlen, len, jeb->offset));
962 ret = -EIO; 958 ret = -EIO;
963 goto out; 959 goto out;
964 } 960 }
965 961
966 /* Special check for first page */ 962 /* Special check for first page */
967 for(i = 0; i < oob_size ; i++) { 963 for(i = 0; i < oob_size ; i++) {
968 /* Yeah, we know about the cleanmarker. */ 964 /* Yeah, we know about the cleanmarker. */
969 if (mode && i >= c->fsdata_pos && 965 if (mode && i >= c->fsdata_pos &&
970 i < c->fsdata_pos + c->fsdata_len) 966 i < c->fsdata_pos + c->fsdata_len)
971 continue; 967 continue;
972 968
973 if (buf[i] != 0xFF) { 969 if (buf[i] != 0xFF) {
974 D2(printk(KERN_DEBUG "Found %02x at %x in OOB for %08x\n", 970 D2(printk(KERN_DEBUG "Found %02x at %x in OOB for %08x\n",
975 buf[page+i], page+i, jeb->offset)); 971 buf[i], i, jeb->offset));
976 ret = 1; 972 ret = 1;
977 goto out; 973 goto out;
978 } 974 }
979 } 975 }
980 976
981 /* we know, we are aligned :) */ 977 /* we know, we are aligned :) */
982 for (page = oob_size; page < len; page += sizeof(long)) { 978 for (page = oob_size; page < len; page += sizeof(long)) {
983 unsigned long dat = *(unsigned long *)(&buf[page]); 979 unsigned long dat = *(unsigned long *)(&buf[page]);
984 if(dat != -1) { 980 if(dat != -1) {
985 ret = 1; 981 ret = 1;
986 goto out; 982 goto out;
987 } 983 }
988 } 984 }
989 985
990out: 986out:
991 kfree(buf); 987 kfree(buf);
992 988
993 return ret; 989 return ret;
994} 990}
995 991
@@ -1071,7 +1067,7 @@ int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_erasebloc
1071 n.totlen = cpu_to_je32(8); 1067 n.totlen = cpu_to_je32(8);
1072 1068
1073 ret = jffs2_flash_write_oob(c, jeb->offset + c->fsdata_pos, c->fsdata_len, &retlen, (unsigned char *)&n); 1069 ret = jffs2_flash_write_oob(c, jeb->offset + c->fsdata_pos, c->fsdata_len, &retlen, (unsigned char *)&n);
1074 1070
1075 if (ret) { 1071 if (ret) {
1076 D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): Write failed for block at %08x: error %d\n", jeb->offset, ret)); 1072 D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): Write failed for block at %08x: error %d\n", jeb->offset, ret));
1077 return ret; 1073 return ret;
@@ -1083,7 +1079,7 @@ int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_erasebloc
1083 return 0; 1079 return 0;
1084} 1080}
1085 1081
1086/* 1082/*
1087 * On NAND we try to mark this block bad. If the block was erased more 1083 * On NAND we try to mark this block bad. If the block was erased more
1088 * than MAX_ERASE_FAILURES we mark it finaly bad. 1084 * than MAX_ERASE_FAILURES we mark it finaly bad.
1089 * Don't care about failures. This block remains on the erase-pending 1085 * Don't care about failures. This block remains on the erase-pending
@@ -1104,7 +1100,7 @@ int jffs2_write_nand_badblock(struct jffs2_sb_info *c, struct jffs2_eraseblock *
1104 1100
1105 D1(printk(KERN_WARNING "jffs2_write_nand_badblock(): Marking bad block at %08x\n", bad_offset)); 1101 D1(printk(KERN_WARNING "jffs2_write_nand_badblock(): Marking bad block at %08x\n", bad_offset));
1106 ret = c->mtd->block_markbad(c->mtd, bad_offset); 1102 ret = c->mtd->block_markbad(c->mtd, bad_offset);
1107 1103
1108 if (ret) { 1104 if (ret) {
1109 D1(printk(KERN_WARNING "jffs2_write_nand_badblock(): Write failed for block at %08x: error %d\n", jeb->offset, ret)); 1105 D1(printk(KERN_WARNING "jffs2_write_nand_badblock(): Write failed for block at %08x: error %d\n", jeb->offset, ret));
1110 return ret; 1106 return ret;
@@ -1128,7 +1124,7 @@ static int jffs2_nand_set_oobinfo(struct jffs2_sb_info *c)
1128 /* Do this only, if we have an oob buffer */ 1124 /* Do this only, if we have an oob buffer */
1129 if (!c->mtd->oobsize) 1125 if (!c->mtd->oobsize)
1130 return 0; 1126 return 0;
1131 1127
1132 /* Cleanmarker is out-of-band, so inline size zero */ 1128 /* Cleanmarker is out-of-band, so inline size zero */
1133 c->cleanmarker_size = 0; 1129 c->cleanmarker_size = 0;
1134 1130
@@ -1154,7 +1150,7 @@ static int jffs2_nand_set_oobinfo(struct jffs2_sb_info *c)
1154 c->fsdata_len = NAND_JFFS2_OOB16_FSDALEN; 1150 c->fsdata_len = NAND_JFFS2_OOB16_FSDALEN;
1155 c->badblock_pos = 15; 1151 c->badblock_pos = 15;
1156 break; 1152 break;
1157 1153
1158 default: 1154 default:
1159 D1(printk(KERN_DEBUG "JFFS2 on NAND. No autoplacment info found\n")); 1155 D1(printk(KERN_DEBUG "JFFS2 on NAND. No autoplacment info found\n"));
1160 return -EINVAL; 1156 return -EINVAL;
@@ -1171,7 +1167,7 @@ int jffs2_nand_flash_setup(struct jffs2_sb_info *c)
1171 init_rwsem(&c->wbuf_sem); 1167 init_rwsem(&c->wbuf_sem);
1172 c->wbuf_pagesize = c->mtd->oobblock; 1168 c->wbuf_pagesize = c->mtd->oobblock;
1173 c->wbuf_ofs = 0xFFFFFFFF; 1169 c->wbuf_ofs = 0xFFFFFFFF;
1174 1170
1175 c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL); 1171 c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
1176 if (!c->wbuf) 1172 if (!c->wbuf)
1177 return -ENOMEM; 1173 return -ENOMEM;
@@ -1197,17 +1193,41 @@ void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c)
1197 1193
1198int jffs2_dataflash_setup(struct jffs2_sb_info *c) { 1194int jffs2_dataflash_setup(struct jffs2_sb_info *c) {
1199 c->cleanmarker_size = 0; /* No cleanmarkers needed */ 1195 c->cleanmarker_size = 0; /* No cleanmarkers needed */
1200 1196
1201 /* Initialize write buffer */ 1197 /* Initialize write buffer */
1202 init_rwsem(&c->wbuf_sem); 1198 init_rwsem(&c->wbuf_sem);
1203 c->wbuf_pagesize = c->sector_size;
1204 c->wbuf_ofs = 0xFFFFFFFF;
1205 1199
1200
1201 c->wbuf_pagesize = c->mtd->erasesize;
1202
1203 /* Find a suitable c->sector_size
1204 * - Not too much sectors
1205 * - Sectors have to be at least 4 K + some bytes
1206 * - All known dataflashes have erase sizes of 528 or 1056
1207 * - we take at least 8 eraseblocks and want to have at least 8K size
1208 * - The concatenation should be a power of 2
1209 */
1210
1211 c->sector_size = 8 * c->mtd->erasesize;
1212
1213 while (c->sector_size < 8192) {
1214 c->sector_size *= 2;
1215 }
1216
1217 /* It may be necessary to adjust the flash size */
1218 c->flash_size = c->mtd->size;
1219
1220 if ((c->flash_size % c->sector_size) != 0) {
1221 c->flash_size = (c->flash_size / c->sector_size) * c->sector_size;
1222 printk(KERN_WARNING "JFFS2 flash size adjusted to %dKiB\n", c->flash_size);
1223 };
1224
1225 c->wbuf_ofs = 0xFFFFFFFF;
1206 c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL); 1226 c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
1207 if (!c->wbuf) 1227 if (!c->wbuf)
1208 return -ENOMEM; 1228 return -ENOMEM;
1209 1229
1210 printk(KERN_INFO "JFFS2 write-buffering enabled (%i)\n", c->wbuf_pagesize); 1230 printk(KERN_INFO "JFFS2 write-buffering enabled buffer (%d) erasesize (%d)\n", c->wbuf_pagesize, c->sector_size);
1211 1231
1212 return 0; 1232 return 0;
1213} 1233}
@@ -1235,3 +1255,23 @@ int jffs2_nor_ecc_flash_setup(struct jffs2_sb_info *c) {
1235void jffs2_nor_ecc_flash_cleanup(struct jffs2_sb_info *c) { 1255void jffs2_nor_ecc_flash_cleanup(struct jffs2_sb_info *c) {
1236 kfree(c->wbuf); 1256 kfree(c->wbuf);
1237} 1257}
1258
1259int jffs2_nor_wbuf_flash_setup(struct jffs2_sb_info *c) {
1260 /* Cleanmarker currently occupies a whole programming region */
1261 c->cleanmarker_size = MTD_PROGREGION_SIZE(c->mtd);
1262
1263 /* Initialize write buffer */
1264 init_rwsem(&c->wbuf_sem);
1265 c->wbuf_pagesize = MTD_PROGREGION_SIZE(c->mtd);
1266 c->wbuf_ofs = 0xFFFFFFFF;
1267
1268 c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
1269 if (!c->wbuf)
1270 return -ENOMEM;
1271
1272 return 0;
1273}
1274
1275void jffs2_nor_wbuf_flash_cleanup(struct jffs2_sb_info *c) {
1276 kfree(c->wbuf);
1277}
diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c
index 69100615d9ae..1342f0158e9b 100644
--- a/fs/jffs2/write.c
+++ b/fs/jffs2/write.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: write.c,v 1.92 2005/04/13 13:22:35 dwmw2 Exp $ 10 * $Id: write.c,v 1.97 2005/11/07 11:14:42 gleixner Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -54,35 +54,7 @@ int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint
54 return 0; 54 return 0;
55} 55}
56 56
57#if CONFIG_JFFS2_FS_DEBUG > 0 57/* jffs2_write_dnode - given a raw_inode, allocate a full_dnode for it,
58static void writecheck(struct jffs2_sb_info *c, uint32_t ofs)
59{
60 unsigned char buf[16];
61 size_t retlen;
62 int ret, i;
63
64 ret = jffs2_flash_read(c, ofs, 16, &retlen, buf);
65 if (ret || (retlen != 16)) {
66 D1(printk(KERN_DEBUG "read failed or short in writecheck(). ret %d, retlen %zd\n", ret, retlen));
67 return;
68 }
69 ret = 0;
70 for (i=0; i<16; i++) {
71 if (buf[i] != 0xff)
72 ret = 1;
73 }
74 if (ret) {
75 printk(KERN_WARNING "ARGH. About to write node to 0x%08x on flash, but there are data already there:\n", ofs);
76 printk(KERN_WARNING "0x%08x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
77 ofs,
78 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7],
79 buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]);
80 }
81}
82#endif
83
84
85/* jffs2_write_dnode - given a raw_inode, allocate a full_dnode for it,
86 write it to the flash, link it into the existing inode/fragment list */ 58 write it to the flash, link it into the existing inode/fragment list */
87 59
88struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const unsigned char *data, uint32_t datalen, uint32_t flash_ofs, int alloc_mode) 60struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const unsigned char *data, uint32_t datalen, uint32_t flash_ofs, int alloc_mode)
@@ -106,7 +78,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
106 vecs[1].iov_base = (unsigned char *)data; 78 vecs[1].iov_base = (unsigned char *)data;
107 vecs[1].iov_len = datalen; 79 vecs[1].iov_len = datalen;
108 80
109 D1(writecheck(c, flash_ofs)); 81 jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len);
110 82
111 if (je32_to_cpu(ri->totlen) != sizeof(*ri) + datalen) { 83 if (je32_to_cpu(ri->totlen) != sizeof(*ri) + datalen) {
112 printk(KERN_WARNING "jffs2_write_dnode: ri->totlen (0x%08x) != sizeof(*ri) (0x%08zx) + datalen (0x%08x)\n", je32_to_cpu(ri->totlen), sizeof(*ri), datalen); 84 printk(KERN_WARNING "jffs2_write_dnode: ri->totlen (0x%08x) != sizeof(*ri) (0x%08zx) + datalen (0x%08x)\n", je32_to_cpu(ri->totlen), sizeof(*ri), datalen);
@@ -114,7 +86,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
114 raw = jffs2_alloc_raw_node_ref(); 86 raw = jffs2_alloc_raw_node_ref();
115 if (!raw) 87 if (!raw)
116 return ERR_PTR(-ENOMEM); 88 return ERR_PTR(-ENOMEM);
117 89
118 fn = jffs2_alloc_full_dnode(); 90 fn = jffs2_alloc_full_dnode();
119 if (!fn) { 91 if (!fn) {
120 jffs2_free_raw_node_ref(raw); 92 jffs2_free_raw_node_ref(raw);
@@ -138,7 +110,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
138 if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(ri->version) < f->highest_version)) { 110 if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(ri->version) < f->highest_version)) {
139 BUG_ON(!retried); 111 BUG_ON(!retried);
140 D1(printk(KERN_DEBUG "jffs2_write_dnode : dnode_version %d, " 112 D1(printk(KERN_DEBUG "jffs2_write_dnode : dnode_version %d, "
141 "highest version %d -> updating dnode\n", 113 "highest version %d -> updating dnode\n",
142 je32_to_cpu(ri->version), f->highest_version)); 114 je32_to_cpu(ri->version), f->highest_version));
143 ri->version = cpu_to_je32(++f->highest_version); 115 ri->version = cpu_to_je32(++f->highest_version);
144 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); 116 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
@@ -148,7 +120,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
148 (alloc_mode==ALLOC_GC)?0:f->inocache->ino); 120 (alloc_mode==ALLOC_GC)?0:f->inocache->ino);
149 121
150 if (ret || (retlen != sizeof(*ri) + datalen)) { 122 if (ret || (retlen != sizeof(*ri) + datalen)) {
151 printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n", 123 printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n",
152 sizeof(*ri)+datalen, flash_ofs, ret, retlen); 124 sizeof(*ri)+datalen, flash_ofs, ret, retlen);
153 125
154 /* Mark the space as dirtied */ 126 /* Mark the space as dirtied */
@@ -156,10 +128,10 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
156 /* Doesn't belong to any inode */ 128 /* Doesn't belong to any inode */
157 raw->next_in_ino = NULL; 129 raw->next_in_ino = NULL;
158 130
159 /* Don't change raw->size to match retlen. We may have 131 /* Don't change raw->size to match retlen. We may have
160 written the node header already, and only the data will 132 written the node header already, and only the data will
161 seem corrupted, in which case the scan would skip over 133 seem corrupted, in which case the scan would skip over
162 any node we write before the original intended end of 134 any node we write before the original intended end of
163 this node */ 135 this node */
164 raw->flash_offset |= REF_OBSOLETE; 136 raw->flash_offset |= REF_OBSOLETE;
165 jffs2_add_physical_node_ref(c, raw); 137 jffs2_add_physical_node_ref(c, raw);
@@ -176,26 +148,28 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
176 retried = 1; 148 retried = 1;
177 149
178 D1(printk(KERN_DEBUG "Retrying failed write.\n")); 150 D1(printk(KERN_DEBUG "Retrying failed write.\n"));
179 151
180 ACCT_SANITY_CHECK(c,jeb); 152 jffs2_dbg_acct_sanity_check(c,jeb);
181 D1(ACCT_PARANOIA_CHECK(jeb)); 153 jffs2_dbg_acct_paranoia_check(c, jeb);
182 154
183 if (alloc_mode == ALLOC_GC) { 155 if (alloc_mode == ALLOC_GC) {
184 ret = jffs2_reserve_space_gc(c, sizeof(*ri) + datalen, &flash_ofs, &dummy); 156 ret = jffs2_reserve_space_gc(c, sizeof(*ri) + datalen, &flash_ofs,
157 &dummy, JFFS2_SUMMARY_INODE_SIZE);
185 } else { 158 } else {
186 /* Locking pain */ 159 /* Locking pain */
187 up(&f->sem); 160 up(&f->sem);
188 jffs2_complete_reservation(c); 161 jffs2_complete_reservation(c);
189 162
190 ret = jffs2_reserve_space(c, sizeof(*ri) + datalen, &flash_ofs, &dummy, alloc_mode); 163 ret = jffs2_reserve_space(c, sizeof(*ri) + datalen, &flash_ofs,
164 &dummy, alloc_mode, JFFS2_SUMMARY_INODE_SIZE);
191 down(&f->sem); 165 down(&f->sem);
192 } 166 }
193 167
194 if (!ret) { 168 if (!ret) {
195 D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs)); 169 D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs));
196 170
197 ACCT_SANITY_CHECK(c,jeb); 171 jffs2_dbg_acct_sanity_check(c,jeb);
198 D1(ACCT_PARANOIA_CHECK(jeb)); 172 jffs2_dbg_acct_paranoia_check(c, jeb);
199 173
200 goto retry; 174 goto retry;
201 } 175 }
@@ -207,9 +181,9 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
207 return ERR_PTR(ret?ret:-EIO); 181 return ERR_PTR(ret?ret:-EIO);
208 } 182 }
209 /* Mark the space used */ 183 /* Mark the space used */
210 /* If node covers at least a whole page, or if it starts at the 184 /* If node covers at least a whole page, or if it starts at the
211 beginning of a page and runs to the end of the file, or if 185 beginning of a page and runs to the end of the file, or if
212 it's a hole node, mark it REF_PRISTINE, else REF_NORMAL. 186 it's a hole node, mark it REF_PRISTINE, else REF_NORMAL.
213 */ 187 */
214 if ((je32_to_cpu(ri->dsize) >= PAGE_CACHE_SIZE) || 188 if ((je32_to_cpu(ri->dsize) >= PAGE_CACHE_SIZE) ||
215 ( ((je32_to_cpu(ri->offset)&(PAGE_CACHE_SIZE-1))==0) && 189 ( ((je32_to_cpu(ri->offset)&(PAGE_CACHE_SIZE-1))==0) &&
@@ -227,12 +201,12 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
227 spin_unlock(&c->erase_completion_lock); 201 spin_unlock(&c->erase_completion_lock);
228 202
229 D1(printk(KERN_DEBUG "jffs2_write_dnode wrote node at 0x%08x(%d) with dsize 0x%x, csize 0x%x, node_crc 0x%08x, data_crc 0x%08x, totlen 0x%08x\n", 203 D1(printk(KERN_DEBUG "jffs2_write_dnode wrote node at 0x%08x(%d) with dsize 0x%x, csize 0x%x, node_crc 0x%08x, data_crc 0x%08x, totlen 0x%08x\n",
230 flash_ofs, ref_flags(raw), je32_to_cpu(ri->dsize), 204 flash_ofs, ref_flags(raw), je32_to_cpu(ri->dsize),
231 je32_to_cpu(ri->csize), je32_to_cpu(ri->node_crc), 205 je32_to_cpu(ri->csize), je32_to_cpu(ri->node_crc),
232 je32_to_cpu(ri->data_crc), je32_to_cpu(ri->totlen))); 206 je32_to_cpu(ri->data_crc), je32_to_cpu(ri->totlen)));
233 207
234 if (retried) { 208 if (retried) {
235 ACCT_SANITY_CHECK(c,NULL); 209 jffs2_dbg_acct_sanity_check(c,NULL);
236 } 210 }
237 211
238 return fn; 212 return fn;
@@ -247,10 +221,9 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
247 int retried = 0; 221 int retried = 0;
248 int ret; 222 int ret;
249 223
250 D1(printk(KERN_DEBUG "jffs2_write_dirent(ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x)\n", 224 D1(printk(KERN_DEBUG "jffs2_write_dirent(ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x)\n",
251 je32_to_cpu(rd->pino), name, name, je32_to_cpu(rd->ino), 225 je32_to_cpu(rd->pino), name, name, je32_to_cpu(rd->ino),
252 je32_to_cpu(rd->name_crc))); 226 je32_to_cpu(rd->name_crc)));
253 D1(writecheck(c, flash_ofs));
254 227
255 D1(if(je32_to_cpu(rd->hdr_crc) != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) { 228 D1(if(je32_to_cpu(rd->hdr_crc) != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) {
256 printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dirent()\n"); 229 printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dirent()\n");
@@ -262,7 +235,9 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
262 vecs[0].iov_len = sizeof(*rd); 235 vecs[0].iov_len = sizeof(*rd);
263 vecs[1].iov_base = (unsigned char *)name; 236 vecs[1].iov_base = (unsigned char *)name;
264 vecs[1].iov_len = namelen; 237 vecs[1].iov_len = namelen;
265 238
239 jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len);
240
266 raw = jffs2_alloc_raw_node_ref(); 241 raw = jffs2_alloc_raw_node_ref();
267 242
268 if (!raw) 243 if (!raw)
@@ -301,7 +276,7 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
301 ret = jffs2_flash_writev(c, vecs, 2, flash_ofs, &retlen, 276 ret = jffs2_flash_writev(c, vecs, 2, flash_ofs, &retlen,
302 (alloc_mode==ALLOC_GC)?0:je32_to_cpu(rd->pino)); 277 (alloc_mode==ALLOC_GC)?0:je32_to_cpu(rd->pino));
303 if (ret || (retlen != sizeof(*rd) + namelen)) { 278 if (ret || (retlen != sizeof(*rd) + namelen)) {
304 printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n", 279 printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n",
305 sizeof(*rd)+namelen, flash_ofs, ret, retlen); 280 sizeof(*rd)+namelen, flash_ofs, ret, retlen);
306 /* Mark the space as dirtied */ 281 /* Mark the space as dirtied */
307 if (retlen) { 282 if (retlen) {
@@ -322,24 +297,26 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
322 297
323 D1(printk(KERN_DEBUG "Retrying failed write.\n")); 298 D1(printk(KERN_DEBUG "Retrying failed write.\n"));
324 299
325 ACCT_SANITY_CHECK(c,jeb); 300 jffs2_dbg_acct_sanity_check(c,jeb);
326 D1(ACCT_PARANOIA_CHECK(jeb)); 301 jffs2_dbg_acct_paranoia_check(c, jeb);
327 302
328 if (alloc_mode == ALLOC_GC) { 303 if (alloc_mode == ALLOC_GC) {
329 ret = jffs2_reserve_space_gc(c, sizeof(*rd) + namelen, &flash_ofs, &dummy); 304 ret = jffs2_reserve_space_gc(c, sizeof(*rd) + namelen, &flash_ofs,
305 &dummy, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
330 } else { 306 } else {
331 /* Locking pain */ 307 /* Locking pain */
332 up(&f->sem); 308 up(&f->sem);
333 jffs2_complete_reservation(c); 309 jffs2_complete_reservation(c);
334 310
335 ret = jffs2_reserve_space(c, sizeof(*rd) + namelen, &flash_ofs, &dummy, alloc_mode); 311 ret = jffs2_reserve_space(c, sizeof(*rd) + namelen, &flash_ofs,
312 &dummy, alloc_mode, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
336 down(&f->sem); 313 down(&f->sem);
337 } 314 }
338 315
339 if (!ret) { 316 if (!ret) {
340 D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs)); 317 D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs));
341 ACCT_SANITY_CHECK(c,jeb); 318 jffs2_dbg_acct_sanity_check(c,jeb);
342 D1(ACCT_PARANOIA_CHECK(jeb)); 319 jffs2_dbg_acct_paranoia_check(c, jeb);
343 goto retry; 320 goto retry;
344 } 321 }
345 D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret)); 322 D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret));
@@ -359,7 +336,7 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
359 spin_unlock(&c->erase_completion_lock); 336 spin_unlock(&c->erase_completion_lock);
360 337
361 if (retried) { 338 if (retried) {
362 ACCT_SANITY_CHECK(c,NULL); 339 jffs2_dbg_acct_sanity_check(c,NULL);
363 } 340 }
364 341
365 return fd; 342 return fd;
@@ -369,7 +346,7 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
369 we don't have to go digging in struct inode or its equivalent. It should set: 346 we don't have to go digging in struct inode or its equivalent. It should set:
370 mode, uid, gid, (starting)isize, atime, ctime, mtime */ 347 mode, uid, gid, (starting)isize, atime, ctime, mtime */
371int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 348int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
372 struct jffs2_raw_inode *ri, unsigned char *buf, 349 struct jffs2_raw_inode *ri, unsigned char *buf,
373 uint32_t offset, uint32_t writelen, uint32_t *retlen) 350 uint32_t offset, uint32_t writelen, uint32_t *retlen)
374{ 351{
375 int ret = 0; 352 int ret = 0;
@@ -377,7 +354,7 @@ int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
377 354
378 D1(printk(KERN_DEBUG "jffs2_write_inode_range(): Ino #%u, ofs 0x%x, len 0x%x\n", 355 D1(printk(KERN_DEBUG "jffs2_write_inode_range(): Ino #%u, ofs 0x%x, len 0x%x\n",
379 f->inocache->ino, offset, writelen)); 356 f->inocache->ino, offset, writelen));
380 357
381 while(writelen) { 358 while(writelen) {
382 struct jffs2_full_dnode *fn; 359 struct jffs2_full_dnode *fn;
383 unsigned char *comprbuf = NULL; 360 unsigned char *comprbuf = NULL;
@@ -389,7 +366,8 @@ int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
389 retry: 366 retry:
390 D2(printk(KERN_DEBUG "jffs2_commit_write() loop: 0x%x to write to 0x%x\n", writelen, offset)); 367 D2(printk(KERN_DEBUG "jffs2_commit_write() loop: 0x%x to write to 0x%x\n", writelen, offset));
391 368
392 ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, &alloclen, ALLOC_NORMAL); 369 ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN, &phys_ofs,
370 &alloclen, ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
393 if (ret) { 371 if (ret) {
394 D1(printk(KERN_DEBUG "jffs2_reserve_space returned %d\n", ret)); 372 D1(printk(KERN_DEBUG "jffs2_reserve_space returned %d\n", ret));
395 break; 373 break;
@@ -473,10 +451,11 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
473 uint32_t alloclen, phys_ofs; 451 uint32_t alloclen, phys_ofs;
474 int ret; 452 int ret;
475 453
476 /* Try to reserve enough space for both node and dirent. 454 /* Try to reserve enough space for both node and dirent.
477 * Just the node will do for now, though 455 * Just the node will do for now, though
478 */ 456 */
479 ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL); 457 ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL,
458 JFFS2_SUMMARY_INODE_SIZE);
480 D1(printk(KERN_DEBUG "jffs2_do_create(): reserved 0x%x bytes\n", alloclen)); 459 D1(printk(KERN_DEBUG "jffs2_do_create(): reserved 0x%x bytes\n", alloclen));
481 if (ret) { 460 if (ret) {
482 up(&f->sem); 461 up(&f->sem);
@@ -498,15 +477,16 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
498 jffs2_complete_reservation(c); 477 jffs2_complete_reservation(c);
499 return PTR_ERR(fn); 478 return PTR_ERR(fn);
500 } 479 }
501 /* No data here. Only a metadata node, which will be 480 /* No data here. Only a metadata node, which will be
502 obsoleted by the first data write 481 obsoleted by the first data write
503 */ 482 */
504 f->metadata = fn; 483 f->metadata = fn;
505 484
506 up(&f->sem); 485 up(&f->sem);
507 jffs2_complete_reservation(c); 486 jffs2_complete_reservation(c);
508 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL); 487 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen,
509 488 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
489
510 if (ret) { 490 if (ret) {
511 /* Eep. */ 491 /* Eep. */
512 D1(printk(KERN_DEBUG "jffs2_reserve_space() for dirent failed\n")); 492 D1(printk(KERN_DEBUG "jffs2_reserve_space() for dirent failed\n"));
@@ -539,9 +519,9 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
539 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL); 519 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL);
540 520
541 jffs2_free_raw_dirent(rd); 521 jffs2_free_raw_dirent(rd);
542 522
543 if (IS_ERR(fd)) { 523 if (IS_ERR(fd)) {
544 /* dirent failed to write. Delete the inode normally 524 /* dirent failed to write. Delete the inode normally
545 as if it were the final unlink() */ 525 as if it were the final unlink() */
546 jffs2_complete_reservation(c); 526 jffs2_complete_reservation(c);
547 up(&dir_f->sem); 527 up(&dir_f->sem);
@@ -560,14 +540,15 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
560 540
561 541
562int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, 542int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
563 const char *name, int namelen, struct jffs2_inode_info *dead_f) 543 const char *name, int namelen, struct jffs2_inode_info *dead_f,
544 uint32_t time)
564{ 545{
565 struct jffs2_raw_dirent *rd; 546 struct jffs2_raw_dirent *rd;
566 struct jffs2_full_dirent *fd; 547 struct jffs2_full_dirent *fd;
567 uint32_t alloclen, phys_ofs; 548 uint32_t alloclen, phys_ofs;
568 int ret; 549 int ret;
569 550
570 if (1 /* alternative branch needs testing */ || 551 if (1 /* alternative branch needs testing */ ||
571 !jffs2_can_mark_obsolete(c)) { 552 !jffs2_can_mark_obsolete(c)) {
572 /* We can't mark stuff obsolete on the medium. We need to write a deletion dirent */ 553 /* We can't mark stuff obsolete on the medium. We need to write a deletion dirent */
573 554
@@ -575,7 +556,8 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
575 if (!rd) 556 if (!rd)
576 return -ENOMEM; 557 return -ENOMEM;
577 558
578 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_DELETION); 559 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen,
560 ALLOC_DELETION, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
579 if (ret) { 561 if (ret) {
580 jffs2_free_raw_dirent(rd); 562 jffs2_free_raw_dirent(rd);
581 return ret; 563 return ret;
@@ -588,18 +570,18 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
588 rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT); 570 rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
589 rd->totlen = cpu_to_je32(sizeof(*rd) + namelen); 571 rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
590 rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)); 572 rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
591 573
592 rd->pino = cpu_to_je32(dir_f->inocache->ino); 574 rd->pino = cpu_to_je32(dir_f->inocache->ino);
593 rd->version = cpu_to_je32(++dir_f->highest_version); 575 rd->version = cpu_to_je32(++dir_f->highest_version);
594 rd->ino = cpu_to_je32(0); 576 rd->ino = cpu_to_je32(0);
595 rd->mctime = cpu_to_je32(get_seconds()); 577 rd->mctime = cpu_to_je32(time);
596 rd->nsize = namelen; 578 rd->nsize = namelen;
597 rd->type = DT_UNKNOWN; 579 rd->type = DT_UNKNOWN;
598 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); 580 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
599 rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); 581 rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
600 582
601 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_DELETION); 583 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_DELETION);
602 584
603 jffs2_free_raw_dirent(rd); 585 jffs2_free_raw_dirent(rd);
604 586
605 if (IS_ERR(fd)) { 587 if (IS_ERR(fd)) {
@@ -618,7 +600,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
618 down(&dir_f->sem); 600 down(&dir_f->sem);
619 601
620 while ((*prev) && (*prev)->nhash <= nhash) { 602 while ((*prev) && (*prev)->nhash <= nhash) {
621 if ((*prev)->nhash == nhash && 603 if ((*prev)->nhash == nhash &&
622 !memcmp((*prev)->name, name, namelen) && 604 !memcmp((*prev)->name, name, namelen) &&
623 !(*prev)->name[namelen]) { 605 !(*prev)->name[namelen]) {
624 struct jffs2_full_dirent *this = *prev; 606 struct jffs2_full_dirent *this = *prev;
@@ -639,7 +621,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
639 /* dead_f is NULL if this was a rename not a real unlink */ 621 /* dead_f is NULL if this was a rename not a real unlink */
640 /* Also catch the !f->inocache case, where there was a dirent 622 /* Also catch the !f->inocache case, where there was a dirent
641 pointing to an inode which didn't exist. */ 623 pointing to an inode which didn't exist. */
642 if (dead_f && dead_f->inocache) { 624 if (dead_f && dead_f->inocache) {
643 625
644 down(&dead_f->sem); 626 down(&dead_f->sem);
645 627
@@ -647,9 +629,9 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
647 while (dead_f->dents) { 629 while (dead_f->dents) {
648 /* There can be only deleted ones */ 630 /* There can be only deleted ones */
649 fd = dead_f->dents; 631 fd = dead_f->dents;
650 632
651 dead_f->dents = fd->next; 633 dead_f->dents = fd->next;
652 634
653 if (fd->ino) { 635 if (fd->ino) {
654 printk(KERN_WARNING "Deleting inode #%u with active dentry \"%s\"->ino #%u\n", 636 printk(KERN_WARNING "Deleting inode #%u with active dentry \"%s\"->ino #%u\n",
655 dead_f->inocache->ino, fd->name, fd->ino); 637 dead_f->inocache->ino, fd->name, fd->ino);
@@ -673,7 +655,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
673} 655}
674 656
675 657
676int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, uint8_t type, const char *name, int namelen) 658int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, uint8_t type, const char *name, int namelen, uint32_t time)
677{ 659{
678 struct jffs2_raw_dirent *rd; 660 struct jffs2_raw_dirent *rd;
679 struct jffs2_full_dirent *fd; 661 struct jffs2_full_dirent *fd;
@@ -684,12 +666,13 @@ int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint
684 if (!rd) 666 if (!rd)
685 return -ENOMEM; 667 return -ENOMEM;
686 668
687 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL); 669 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen,
670 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
688 if (ret) { 671 if (ret) {
689 jffs2_free_raw_dirent(rd); 672 jffs2_free_raw_dirent(rd);
690 return ret; 673 return ret;
691 } 674 }
692 675
693 down(&dir_f->sem); 676 down(&dir_f->sem);
694 677
695 /* Build a deletion node */ 678 /* Build a deletion node */
@@ -701,7 +684,7 @@ int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint
701 rd->pino = cpu_to_je32(dir_f->inocache->ino); 684 rd->pino = cpu_to_je32(dir_f->inocache->ino);
702 rd->version = cpu_to_je32(++dir_f->highest_version); 685 rd->version = cpu_to_je32(++dir_f->highest_version);
703 rd->ino = cpu_to_je32(ino); 686 rd->ino = cpu_to_je32(ino);
704 rd->mctime = cpu_to_je32(get_seconds()); 687 rd->mctime = cpu_to_je32(time);
705 rd->nsize = namelen; 688 rd->nsize = namelen;
706 689
707 rd->type = type; 690 rd->type = type;
@@ -710,7 +693,7 @@ int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint
710 rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); 693 rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
711 694
712 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL); 695 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL);
713 696
714 jffs2_free_raw_dirent(rd); 697 jffs2_free_raw_dirent(rd);
715 698
716 if (IS_ERR(fd)) { 699 if (IS_ERR(fd)) {
diff --git a/fs/jffs2/writev.c b/fs/jffs2/writev.c
index f079f8388566..c638ae1008de 100644
--- a/fs/jffs2/writev.c
+++ b/fs/jffs2/writev.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: writev.c,v 1.6 2004/11/16 20:36:12 dwmw2 Exp $ 10 * $Id: writev.c,v 1.8 2005/09/09 15:11:58 havasi Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -42,9 +42,40 @@ static inline int mtd_fake_writev(struct mtd_info *mtd, const struct kvec *vecs,
42int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct kvec *vecs, 42int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct kvec *vecs,
43 unsigned long count, loff_t to, size_t *retlen) 43 unsigned long count, loff_t to, size_t *retlen)
44{ 44{
45 if (!jffs2_is_writebuffered(c)) {
46 if (jffs2_sum_active()) {
47 int res;
48 res = jffs2_sum_add_kvec(c, vecs, count, (uint32_t) to);
49 if (res) {
50 return res;
51 }
52 }
53 }
54
45 if (c->mtd->writev) 55 if (c->mtd->writev)
46 return c->mtd->writev(c->mtd, vecs, count, to, retlen); 56 return c->mtd->writev(c->mtd, vecs, count, to, retlen);
47 else 57 else {
48 return mtd_fake_writev(c->mtd, vecs, count, to, retlen); 58 return mtd_fake_writev(c->mtd, vecs, count, to, retlen);
59 }
49} 60}
50 61
62int jffs2_flash_direct_write(struct jffs2_sb_info *c, loff_t ofs, size_t len,
63 size_t *retlen, const u_char *buf)
64{
65 int ret;
66 ret = c->mtd->write(c->mtd, ofs, len, retlen, buf);
67
68 if (jffs2_sum_active()) {
69 struct kvec vecs[1];
70 int res;
71
72 vecs[0].iov_base = (unsigned char *) buf;
73 vecs[0].iov_len = len;
74
75 res = jffs2_sum_add_kvec(c, vecs, 1, (uint32_t) ofs);
76 if (res) {
77 return res;
78 }
79 }
80 return ret;
81}
diff --git a/include/linux/jffs2.h b/include/linux/jffs2.h
index 419fc953ac16..cf792bb3c726 100644
--- a/include/linux/jffs2.h
+++ b/include/linux/jffs2.h
@@ -5,10 +5,10 @@
5 * 5 *
6 * Created by David Woodhouse <dwmw2@infradead.org> 6 * Created by David Woodhouse <dwmw2@infradead.org>
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in the 8 * For licensing information, see the file 'LICENCE' in the
9 * jffs2 directory. 9 * jffs2 directory.
10 * 10 *
11 * $Id: jffs2.h,v 1.34 2004/11/16 20:36:14 dwmw2 Exp $ 11 * $Id: jffs2.h,v 1.38 2005/09/26 11:37:23 havasi Exp $
12 * 12 *
13 */ 13 */
14 14
@@ -28,6 +28,9 @@
28#define JFFS2_EMPTY_BITMASK 0xffff 28#define JFFS2_EMPTY_BITMASK 0xffff
29#define JFFS2_DIRTY_BITMASK 0x0000 29#define JFFS2_DIRTY_BITMASK 0x0000
30 30
31/* Summary node MAGIC marker */
32#define JFFS2_SUM_MAGIC 0x02851885
33
31/* We only allow a single char for length, and 0xFF is empty flash so 34/* We only allow a single char for length, and 0xFF is empty flash so
32 we don't want it confused with a real length. Hence max 254. 35 we don't want it confused with a real length. Hence max 254.
33*/ 36*/
@@ -43,8 +46,6 @@
43#define JFFS2_COMPR_COPY 0x04 46#define JFFS2_COMPR_COPY 0x04
44#define JFFS2_COMPR_DYNRUBIN 0x05 47#define JFFS2_COMPR_DYNRUBIN 0x05
45#define JFFS2_COMPR_ZLIB 0x06 48#define JFFS2_COMPR_ZLIB 0x06
46#define JFFS2_COMPR_LZO 0x07
47#define JFFS2_COMPR_LZARI 0x08
48/* Compatibility flags. */ 49/* Compatibility flags. */
49#define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */ 50#define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */
50#define JFFS2_NODE_ACCURATE 0x2000 51#define JFFS2_NODE_ACCURATE 0x2000
@@ -62,15 +63,17 @@
62#define JFFS2_NODETYPE_CLEANMARKER (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3) 63#define JFFS2_NODETYPE_CLEANMARKER (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3)
63#define JFFS2_NODETYPE_PADDING (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 4) 64#define JFFS2_NODETYPE_PADDING (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 4)
64 65
66#define JFFS2_NODETYPE_SUMMARY (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 6)
67
65// Maybe later... 68// Maybe later...
66//#define JFFS2_NODETYPE_CHECKPOINT (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3) 69//#define JFFS2_NODETYPE_CHECKPOINT (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3)
67//#define JFFS2_NODETYPE_OPTIONS (JFFS2_FEATURE_RWCOMPAT_COPY | JFFS2_NODE_ACCURATE | 4) 70//#define JFFS2_NODETYPE_OPTIONS (JFFS2_FEATURE_RWCOMPAT_COPY | JFFS2_NODE_ACCURATE | 4)
68 71
69 72
70#define JFFS2_INO_FLAG_PREREAD 1 /* Do read_inode() for this one at 73#define JFFS2_INO_FLAG_PREREAD 1 /* Do read_inode() for this one at
71 mount time, don't wait for it to 74 mount time, don't wait for it to
72 happen later */ 75 happen later */
73#define JFFS2_INO_FLAG_USERCOMPR 2 /* User has requested a specific 76#define JFFS2_INO_FLAG_USERCOMPR 2 /* User has requested a specific
74 compression type */ 77 compression type */
75 78
76 79
@@ -101,7 +104,7 @@ struct jffs2_unknown_node
101struct jffs2_raw_dirent 104struct jffs2_raw_dirent
102{ 105{
103 jint16_t magic; 106 jint16_t magic;
104 jint16_t nodetype; /* == JFFS_NODETYPE_DIRENT */ 107 jint16_t nodetype; /* == JFFS2_NODETYPE_DIRENT */
105 jint32_t totlen; 108 jint32_t totlen;
106 jint32_t hdr_crc; 109 jint32_t hdr_crc;
107 jint32_t pino; 110 jint32_t pino;
@@ -117,7 +120,7 @@ struct jffs2_raw_dirent
117} __attribute__((packed)); 120} __attribute__((packed));
118 121
119/* The JFFS2 raw inode structure: Used for storage on physical media. */ 122/* The JFFS2 raw inode structure: Used for storage on physical media. */
120/* The uid, gid, atime, mtime and ctime members could be longer, but 123/* The uid, gid, atime, mtime and ctime members could be longer, but
121 are left like this for space efficiency. If and when people decide 124 are left like this for space efficiency. If and when people decide
122 they really need them extended, it's simple enough to add support for 125 they really need them extended, it's simple enough to add support for
123 a new type of raw node. 126 a new type of raw node.
@@ -125,7 +128,7 @@ struct jffs2_raw_dirent
125struct jffs2_raw_inode 128struct jffs2_raw_inode
126{ 129{
127 jint16_t magic; /* A constant magic number. */ 130 jint16_t magic; /* A constant magic number. */
128 jint16_t nodetype; /* == JFFS_NODETYPE_INODE */ 131 jint16_t nodetype; /* == JFFS2_NODETYPE_INODE */
129 jint32_t totlen; /* Total length of this node (inc data, etc.) */ 132 jint32_t totlen; /* Total length of this node (inc data, etc.) */
130 jint32_t hdr_crc; 133 jint32_t hdr_crc;
131 jint32_t ino; /* Inode number. */ 134 jint32_t ino; /* Inode number. */
@@ -148,9 +151,25 @@ struct jffs2_raw_inode
148 uint8_t data[0]; 151 uint8_t data[0];
149} __attribute__((packed)); 152} __attribute__((packed));
150 153
151union jffs2_node_union { 154struct jffs2_raw_summary
155{
156 jint16_t magic;
157 jint16_t nodetype; /* = JFFS2_NODETYPE_SUMMARY */
158 jint32_t totlen;
159 jint32_t hdr_crc;
160 jint32_t sum_num; /* number of sum entries*/
161 jint32_t cln_mkr; /* clean marker size, 0 = no cleanmarker */
162 jint32_t padded; /* sum of the size of padding nodes */
163 jint32_t sum_crc; /* summary information crc */
164 jint32_t node_crc; /* node crc */
165 jint32_t sum[0]; /* inode summary info */
166} __attribute__((packed));
167
168union jffs2_node_union
169{
152 struct jffs2_raw_inode i; 170 struct jffs2_raw_inode i;
153 struct jffs2_raw_dirent d; 171 struct jffs2_raw_dirent d;
172 struct jffs2_raw_summary s;
154 struct jffs2_unknown_node u; 173 struct jffs2_unknown_node u;
155}; 174};
156 175
diff --git a/include/linux/jffs2_fs_i.h b/include/linux/jffs2_fs_i.h
index 6dbb1cce6646..ef85ab56302b 100644
--- a/include/linux/jffs2_fs_i.h
+++ b/include/linux/jffs2_fs_i.h
@@ -1,4 +1,4 @@
1/* $Id: jffs2_fs_i.h,v 1.17 2004/11/11 23:51:27 dwmw2 Exp $ */ 1/* $Id: jffs2_fs_i.h,v 1.19 2005/11/07 11:14:52 gleixner Exp $ */
2 2
3#ifndef _JFFS2_FS_I 3#ifndef _JFFS2_FS_I
4#define _JFFS2_FS_I 4#define _JFFS2_FS_I
@@ -25,13 +25,16 @@ struct jffs2_inode_info {
25 /* There may be one datanode which isn't referenced by any of the 25 /* There may be one datanode which isn't referenced by any of the
26 above fragments, if it contains a metadata update but no actual 26 above fragments, if it contains a metadata update but no actual
27 data - or if this is a directory inode */ 27 data - or if this is a directory inode */
28 /* This also holds the _only_ dnode for symlinks/device nodes, 28 /* This also holds the _only_ dnode for symlinks/device nodes,
29 etc. */ 29 etc. */
30 struct jffs2_full_dnode *metadata; 30 struct jffs2_full_dnode *metadata;
31 31
32 /* Directory entries */ 32 /* Directory entries */
33 struct jffs2_full_dirent *dents; 33 struct jffs2_full_dirent *dents;
34 34
35 /* The target path if this is the inode of a symlink */
36 unsigned char *target;
37
35 /* Some stuff we just have to keep in-core at all times, for each inode. */ 38 /* Some stuff we just have to keep in-core at all times, for each inode. */
36 struct jffs2_inode_cache *inocache; 39 struct jffs2_inode_cache *inocache;
37 40
diff --git a/include/linux/jffs2_fs_sb.h b/include/linux/jffs2_fs_sb.h
index 1e21546622de..4bcfb5570221 100644
--- a/include/linux/jffs2_fs_sb.h
+++ b/include/linux/jffs2_fs_sb.h
@@ -1,4 +1,4 @@
1/* $Id: jffs2_fs_sb.h,v 1.52 2005/05/19 16:12:17 gleixner Exp $ */ 1/* $Id: jffs2_fs_sb.h,v 1.54 2005/09/21 13:37:34 dedekind Exp $ */
2 2
3#ifndef _JFFS2_FS_SB 3#ifndef _JFFS2_FS_SB
4#define _JFFS2_FS_SB 4#define _JFFS2_FS_SB
@@ -20,7 +20,7 @@
20struct jffs2_inodirty; 20struct jffs2_inodirty;
21 21
22/* A struct for the overall file system control. Pointers to 22/* A struct for the overall file system control. Pointers to
23 jffs2_sb_info structs are named `c' in the source code. 23 jffs2_sb_info structs are named `c' in the source code.
24 Nee jffs_control 24 Nee jffs_control
25*/ 25*/
26struct jffs2_sb_info { 26struct jffs2_sb_info {
@@ -35,7 +35,7 @@ struct jffs2_sb_info {
35 struct completion gc_thread_start; /* GC thread start completion */ 35 struct completion gc_thread_start; /* GC thread start completion */
36 struct completion gc_thread_exit; /* GC thread exit completion port */ 36 struct completion gc_thread_exit; /* GC thread exit completion port */
37 37
38 struct semaphore alloc_sem; /* Used to protect all the following 38 struct semaphore alloc_sem; /* Used to protect all the following
39 fields, and also to protect against 39 fields, and also to protect against
40 out-of-order writing of nodes. And GC. */ 40 out-of-order writing of nodes. And GC. */
41 uint32_t cleanmarker_size; /* Size of an _inline_ CLEANMARKER 41 uint32_t cleanmarker_size; /* Size of an _inline_ CLEANMARKER
@@ -64,7 +64,7 @@ struct jffs2_sb_info {
64 uint32_t nospc_dirty_size; 64 uint32_t nospc_dirty_size;
65 65
66 uint32_t nr_blocks; 66 uint32_t nr_blocks;
67 struct jffs2_eraseblock *blocks; /* The whole array of blocks. Used for getting blocks 67 struct jffs2_eraseblock *blocks; /* The whole array of blocks. Used for getting blocks
68 * from the offset (blocks[ofs / sector_size]) */ 68 * from the offset (blocks[ofs / sector_size]) */
69 struct jffs2_eraseblock *nextblock; /* The block we're currently filling */ 69 struct jffs2_eraseblock *nextblock; /* The block we're currently filling */
70 70
@@ -82,25 +82,26 @@ struct jffs2_sb_info {
82 struct list_head bad_list; /* Bad blocks. */ 82 struct list_head bad_list; /* Bad blocks. */
83 struct list_head bad_used_list; /* Bad blocks with valid data in. */ 83 struct list_head bad_used_list; /* Bad blocks with valid data in. */
84 84
85 spinlock_t erase_completion_lock; /* Protect free_list and erasing_list 85 spinlock_t erase_completion_lock; /* Protect free_list and erasing_list
86 against erase completion handler */ 86 against erase completion handler */
87 wait_queue_head_t erase_wait; /* For waiting for erases to complete */ 87 wait_queue_head_t erase_wait; /* For waiting for erases to complete */
88 88
89 wait_queue_head_t inocache_wq; 89 wait_queue_head_t inocache_wq;
90 struct jffs2_inode_cache **inocache_list; 90 struct jffs2_inode_cache **inocache_list;
91 spinlock_t inocache_lock; 91 spinlock_t inocache_lock;
92 92
93 /* Sem to allow jffs2_garbage_collect_deletion_dirent to 93 /* Sem to allow jffs2_garbage_collect_deletion_dirent to
94 drop the erase_completion_lock while it's holding a pointer 94 drop the erase_completion_lock while it's holding a pointer
95 to an obsoleted node. I don't like this. Alternatives welcomed. */ 95 to an obsoleted node. I don't like this. Alternatives welcomed. */
96 struct semaphore erase_free_sem; 96 struct semaphore erase_free_sem;
97 97
98 uint32_t wbuf_pagesize; /* 0 for NOR and other flashes with no wbuf */
99
98#ifdef CONFIG_JFFS2_FS_WRITEBUFFER 100#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
99 /* Write-behind buffer for NAND flash */ 101 /* Write-behind buffer for NAND flash */
100 unsigned char *wbuf; 102 unsigned char *wbuf;
101 uint32_t wbuf_ofs; 103 uint32_t wbuf_ofs;
102 uint32_t wbuf_len; 104 uint32_t wbuf_len;
103 uint32_t wbuf_pagesize;
104 struct jffs2_inodirty *wbuf_inodes; 105 struct jffs2_inodirty *wbuf_inodes;
105 106
106 struct rw_semaphore wbuf_sem; /* Protects the write buffer */ 107 struct rw_semaphore wbuf_sem; /* Protects the write buffer */
@@ -112,6 +113,8 @@ struct jffs2_sb_info {
112 uint32_t fsdata_len; 113 uint32_t fsdata_len;
113#endif 114#endif
114 115
116 struct jffs2_summary *summary; /* Summary information */
117
115 /* OS-private pointer for getting back to master superblock info */ 118 /* OS-private pointer for getting back to master superblock info */
116 void *os_priv; 119 void *os_priv;
117}; 120};
diff --git a/include/linux/mtd/bbm.h b/include/linux/mtd/bbm.h
new file mode 100644
index 000000000000..7a7fbe87fef0
--- /dev/null
+++ b/include/linux/mtd/bbm.h
@@ -0,0 +1,122 @@
1/*
2 * linux/include/linux/mtd/bbm.h
3 *
4 * NAND family Bad Block Management (BBM) header file
5 * - Bad Block Table (BBT) implementation
6 *
7 * Copyright (c) 2005 Samsung Electronics
8 * Kyungmin Park <kyungmin.park@samsung.com>
9 *
10 * Copyright (c) 2000-2005
11 * Thomas Gleixner <tglx@linuxtronix.de>
12 *
13 */
14#ifndef __LINUX_MTD_BBM_H
15#define __LINUX_MTD_BBM_H
16
17/* The maximum number of NAND chips in an array */
18#define NAND_MAX_CHIPS 8
19
20/**
21 * struct nand_bbt_descr - bad block table descriptor
22 * @param options options for this descriptor
23 * @param pages the page(s) where we find the bbt, used with
24 * option BBT_ABSPAGE when bbt is searched,
25 * then we store the found bbts pages here.
26 * Its an array and supports up to 8 chips now
27 * @param offs offset of the pattern in the oob area of the page
28 * @param veroffs offset of the bbt version counter in the oob are of the page
29 * @param version version read from the bbt page during scan
30 * @param len length of the pattern, if 0 no pattern check is performed
31 * @param maxblocks maximum number of blocks to search for a bbt. This number of
32 * blocks is reserved at the end of the device
33 * where the tables are written.
34 * @param reserved_block_code if non-0, this pattern denotes a reserved
35 * (rather than bad) block in the stored bbt
36 * @param pattern pattern to identify bad block table or factory marked
37 * good / bad blocks, can be NULL, if len = 0
38 *
39 * Descriptor for the bad block table marker and the descriptor for the
40 * pattern which identifies good and bad blocks. The assumption is made
41 * that the pattern and the version count are always located in the oob area
42 * of the first block.
43 */
44struct nand_bbt_descr {
45 int options;
46 int pages[NAND_MAX_CHIPS];
47 int offs;
48 int veroffs;
49 uint8_t version[NAND_MAX_CHIPS];
50 int len;
51 int maxblocks;
52 int reserved_block_code;
53 uint8_t *pattern;
54};
55
56/* Options for the bad block table descriptors */
57
58/* The number of bits used per block in the bbt on the device */
59#define NAND_BBT_NRBITS_MSK 0x0000000F
60#define NAND_BBT_1BIT 0x00000001
61#define NAND_BBT_2BIT 0x00000002
62#define NAND_BBT_4BIT 0x00000004
63#define NAND_BBT_8BIT 0x00000008
64/* The bad block table is in the last good block of the device */
65#define NAND_BBT_LASTBLOCK 0x00000010
66/* The bbt is at the given page, else we must scan for the bbt */
67#define NAND_BBT_ABSPAGE 0x00000020
68/* The bbt is at the given page, else we must scan for the bbt */
69#define NAND_BBT_SEARCH 0x00000040
70/* bbt is stored per chip on multichip devices */
71#define NAND_BBT_PERCHIP 0x00000080
72/* bbt has a version counter at offset veroffs */
73#define NAND_BBT_VERSION 0x00000100
74/* Create a bbt if none axists */
75#define NAND_BBT_CREATE 0x00000200
76/* Search good / bad pattern through all pages of a block */
77#define NAND_BBT_SCANALLPAGES 0x00000400
78/* Scan block empty during good / bad block scan */
79#define NAND_BBT_SCANEMPTY 0x00000800
80/* Write bbt if neccecary */
81#define NAND_BBT_WRITE 0x00001000
82/* Read and write back block contents when writing bbt */
83#define NAND_BBT_SAVECONTENT 0x00002000
84/* Search good / bad pattern on the first and the second page */
85#define NAND_BBT_SCAN2NDPAGE 0x00004000
86
87/* The maximum number of blocks to scan for a bbt */
88#define NAND_BBT_SCAN_MAXBLOCKS 4
89
90/*
91 * Constants for oob configuration
92 */
93#define ONENAND_BADBLOCK_POS 0
94
95/**
96 * struct bbt_info - [GENERIC] Bad Block Table data structure
97 * @param bbt_erase_shift [INTERN] number of address bits in a bbt entry
98 * @param badblockpos [INTERN] position of the bad block marker in the oob area
99 * @param bbt [INTERN] bad block table pointer
100 * @param badblock_pattern [REPLACEABLE] bad block scan pattern used for initial bad block scan
101 * @param priv [OPTIONAL] pointer to private bbm date
102 */
103struct bbm_info {
104 int bbt_erase_shift;
105 int badblockpos;
106 int options;
107
108 uint8_t *bbt;
109
110 int (*isbad_bbt)(struct mtd_info *mtd, loff_t ofs, int allowbbt);
111
112 /* TODO Add more NAND specific fileds */
113 struct nand_bbt_descr *badblock_pattern;
114
115 void *priv;
116};
117
118/* OneNAND BBT interface */
119extern int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd);
120extern int onenand_default_bbt(struct mtd_info *mtd);
121
122#endif /* __LINUX_MTD_BBM_H */
diff --git a/include/linux/mtd/blktrans.h b/include/linux/mtd/blktrans.h
index 4ebc2e5a16e2..f46afec6fbf8 100644
--- a/include/linux/mtd/blktrans.h
+++ b/include/linux/mtd/blktrans.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: blktrans.h,v 1.5 2003/06/23 12:00:08 dwmw2 Exp $ 2 * $Id: blktrans.h,v 1.6 2005/11/07 11:14:54 gleixner Exp $
3 * 3 *
4 * (C) 2003 David Woodhouse <dwmw2@infradead.org> 4 * (C) 2003 David Woodhouse <dwmw2@infradead.org>
5 * 5 *
@@ -67,6 +67,6 @@ extern int register_mtd_blktrans(struct mtd_blktrans_ops *tr);
67extern int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr); 67extern int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr);
68extern int add_mtd_blktrans_dev(struct mtd_blktrans_dev *dev); 68extern int add_mtd_blktrans_dev(struct mtd_blktrans_dev *dev);
69extern int del_mtd_blktrans_dev(struct mtd_blktrans_dev *dev); 69extern int del_mtd_blktrans_dev(struct mtd_blktrans_dev *dev);
70 70
71 71
72#endif /* __MTD_TRANS_H__ */ 72#endif /* __MTD_TRANS_H__ */
diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h
index e6b6a1c66bd5..39f1430bd6d5 100644
--- a/include/linux/mtd/cfi.h
+++ b/include/linux/mtd/cfi.h
@@ -1,7 +1,7 @@
1 1
2/* Common Flash Interface structures 2/* Common Flash Interface structures
3 * See http://support.intel.com/design/flash/technote/index.htm 3 * See http://support.intel.com/design/flash/technote/index.htm
4 * $Id: cfi.h,v 1.54 2005/06/06 23:04:36 tpoynor Exp $ 4 * $Id: cfi.h,v 1.56 2005/11/07 11:14:54 gleixner Exp $
5 */ 5 */
6 6
7#ifndef __MTD_CFI_H__ 7#ifndef __MTD_CFI_H__
@@ -82,8 +82,8 @@ static inline int cfi_interleave_supported(int i)
82} 82}
83 83
84 84
85/* NB: these values must represents the number of bytes needed to meet the 85/* NB: these values must represents the number of bytes needed to meet the
86 * device type (x8, x16, x32). Eg. a 32 bit device is 4 x 8 bytes. 86 * device type (x8, x16, x32). Eg. a 32 bit device is 4 x 8 bytes.
87 * These numbers are used in calculations. 87 * These numbers are used in calculations.
88 */ 88 */
89#define CFI_DEVICETYPE_X8 (8 / 8) 89#define CFI_DEVICETYPE_X8 (8 / 8)
@@ -173,6 +173,15 @@ struct cfi_intelext_regioninfo {
173 struct cfi_intelext_blockinfo BlockTypes[1]; 173 struct cfi_intelext_blockinfo BlockTypes[1];
174} __attribute__((packed)); 174} __attribute__((packed));
175 175
176struct cfi_intelext_programming_regioninfo {
177 uint8_t ProgRegShift;
178 uint8_t Reserved1;
179 uint8_t ControlValid;
180 uint8_t Reserved2;
181 uint8_t ControlInvalid;
182 uint8_t Reserved3;
183} __attribute__((packed));
184
176/* Vendor-Specific PRI for AMD/Fujitsu Extended Command Set (0x0002) */ 185/* Vendor-Specific PRI for AMD/Fujitsu Extended Command Set (0x0002) */
177 186
178struct cfi_pri_amdstd { 187struct cfi_pri_amdstd {
@@ -250,7 +259,7 @@ static inline uint32_t cfi_build_cmd_addr(uint32_t cmd_ofs, int interleave, int
250/* 259/*
251 * Transforms the CFI command for the given geometry (bus width & interleave). 260 * Transforms the CFI command for the given geometry (bus width & interleave).
252 * It looks too long to be inline, but in the common case it should almost all 261 * It looks too long to be inline, but in the common case it should almost all
253 * get optimised away. 262 * get optimised away.
254 */ 263 */
255static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cfi_private *cfi) 264static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cfi_private *cfi)
256{ 265{
@@ -259,7 +268,7 @@ static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cf
259 unsigned long onecmd; 268 unsigned long onecmd;
260 int i; 269 int i;
261 270
262 /* We do it this way to give the compiler a fighting chance 271 /* We do it this way to give the compiler a fighting chance
263 of optimising away all the crap for 'bankwidth' larger than 272 of optimising away all the crap for 'bankwidth' larger than
264 an unsigned long, in the common case where that support is 273 an unsigned long, in the common case where that support is
265 disabled */ 274 disabled */
@@ -270,7 +279,7 @@ static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cf
270 wordwidth = map_bankwidth(map); 279 wordwidth = map_bankwidth(map);
271 words_per_bus = 1; 280 words_per_bus = 1;
272 } 281 }
273 282
274 chip_mode = map_bankwidth(map) / cfi_interleave(cfi); 283 chip_mode = map_bankwidth(map) / cfi_interleave(cfi);
275 chips_per_word = wordwidth * cfi_interleave(cfi) / map_bankwidth(map); 284 chips_per_word = wordwidth * cfi_interleave(cfi) / map_bankwidth(map);
276 285
@@ -289,7 +298,7 @@ static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cf
289 break; 298 break;
290 } 299 }
291 300
292 /* Now replicate it across the size of an unsigned long, or 301 /* Now replicate it across the size of an unsigned long, or
293 just to the bus width as appropriate */ 302 just to the bus width as appropriate */
294 switch (chips_per_word) { 303 switch (chips_per_word) {
295 default: BUG(); 304 default: BUG();
@@ -305,7 +314,7 @@ static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cf
305 ; 314 ;
306 } 315 }
307 316
308 /* And finally, for the multi-word case, replicate it 317 /* And finally, for the multi-word case, replicate it
309 in all words in the structure */ 318 in all words in the structure */
310 for (i=0; i < words_per_bus; i++) { 319 for (i=0; i < words_per_bus; i++) {
311 val.x[i] = onecmd; 320 val.x[i] = onecmd;
@@ -316,14 +325,14 @@ static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cf
316#define CMD(x) cfi_build_cmd((x), map, cfi) 325#define CMD(x) cfi_build_cmd((x), map, cfi)
317 326
318 327
319static inline unsigned char cfi_merge_status(map_word val, struct map_info *map, 328static inline unsigned long cfi_merge_status(map_word val, struct map_info *map,
320 struct cfi_private *cfi) 329 struct cfi_private *cfi)
321{ 330{
322 int wordwidth, words_per_bus, chip_mode, chips_per_word; 331 int wordwidth, words_per_bus, chip_mode, chips_per_word;
323 unsigned long onestat, res = 0; 332 unsigned long onestat, res = 0;
324 int i; 333 int i;
325 334
326 /* We do it this way to give the compiler a fighting chance 335 /* We do it this way to give the compiler a fighting chance
327 of optimising away all the crap for 'bankwidth' larger than 336 of optimising away all the crap for 'bankwidth' larger than
328 an unsigned long, in the common case where that support is 337 an unsigned long, in the common case where that support is
329 disabled */ 338 disabled */
@@ -334,7 +343,7 @@ static inline unsigned char cfi_merge_status(map_word val, struct map_info *map,
334 wordwidth = map_bankwidth(map); 343 wordwidth = map_bankwidth(map);
335 words_per_bus = 1; 344 words_per_bus = 1;
336 } 345 }
337 346
338 chip_mode = map_bankwidth(map) / cfi_interleave(cfi); 347 chip_mode = map_bankwidth(map) / cfi_interleave(cfi);
339 chips_per_word = wordwidth * cfi_interleave(cfi) / map_bankwidth(map); 348 chips_per_word = wordwidth * cfi_interleave(cfi) / map_bankwidth(map);
340 349
diff --git a/include/linux/mtd/doc2000.h b/include/linux/mtd/doc2000.h
index 953e64fb8ac5..386a52cf8b1b 100644
--- a/include/linux/mtd/doc2000.h
+++ b/include/linux/mtd/doc2000.h
@@ -1,12 +1,12 @@
1/* 1/*
2 * Linux driver for Disk-On-Chip devices 2 * Linux driver for Disk-On-Chip devices
3 * 3 *
4 * Copyright (C) 1999 Machine Vision Holdings, Inc. 4 * Copyright (C) 1999 Machine Vision Holdings, Inc.
5 * Copyright (C) 2001-2003 David Woodhouse <dwmw2@infradead.org> 5 * Copyright (C) 2001-2003 David Woodhouse <dwmw2@infradead.org>
6 * Copyright (C) 2002-2003 Greg Ungerer <gerg@snapgear.com> 6 * Copyright (C) 2002-2003 Greg Ungerer <gerg@snapgear.com>
7 * Copyright (C) 2002-2003 SnapGear Inc 7 * Copyright (C) 2002-2003 SnapGear Inc
8 * 8 *
9 * $Id: doc2000.h,v 1.24 2005/01/05 12:40:38 dwmw2 Exp $ 9 * $Id: doc2000.h,v 1.25 2005/11/07 11:14:54 gleixner Exp $
10 * 10 *
11 * Released under GPL 11 * Released under GPL
12 */ 12 */
@@ -75,10 +75,10 @@
75#define DoC_Mplus_CtrlConfirm 0x1076 75#define DoC_Mplus_CtrlConfirm 0x1076
76#define DoC_Mplus_Power 0x1fff 76#define DoC_Mplus_Power 0x1fff
77 77
78/* How to access the device? 78/* How to access the device?
79 * On ARM, it'll be mmap'd directly with 32-bit wide accesses. 79 * On ARM, it'll be mmap'd directly with 32-bit wide accesses.
80 * On PPC, it's mmap'd and 16-bit wide. 80 * On PPC, it's mmap'd and 16-bit wide.
81 * Others use readb/writeb 81 * Others use readb/writeb
82 */ 82 */
83#if defined(__arm__) 83#if defined(__arm__)
84#define ReadDOC_(adr, reg) ((unsigned char)(*(volatile __u32 *)(((unsigned long)adr)+((reg)<<2)))) 84#define ReadDOC_(adr, reg) ((unsigned char)(*(volatile __u32 *)(((unsigned long)adr)+((reg)<<2))))
@@ -172,7 +172,7 @@ struct DiskOnChip {
172 unsigned long totlen; 172 unsigned long totlen;
173 unsigned char ChipID; /* Type of DiskOnChip */ 173 unsigned char ChipID; /* Type of DiskOnChip */
174 int ioreg; 174 int ioreg;
175 175
176 unsigned long mfr; /* Flash IDs - only one type of flash per device */ 176 unsigned long mfr; /* Flash IDs - only one type of flash per device */
177 unsigned long id; 177 unsigned long id;
178 int chipshift; 178 int chipshift;
@@ -180,10 +180,10 @@ struct DiskOnChip {
180 char pageadrlen; 180 char pageadrlen;
181 char interleave; /* Internal interleaving - Millennium Plus style */ 181 char interleave; /* Internal interleaving - Millennium Plus style */
182 unsigned long erasesize; 182 unsigned long erasesize;
183 183
184 int curfloor; 184 int curfloor;
185 int curchip; 185 int curchip;
186 186
187 int numchips; 187 int numchips;
188 struct Nand *chips; 188 struct Nand *chips;
189 struct mtd_info *nextdoc; 189 struct mtd_info *nextdoc;
diff --git a/include/linux/mtd/flashchip.h b/include/linux/mtd/flashchip.h
index 675776fa3e27..a293a3b78e05 100644
--- a/include/linux/mtd/flashchip.h
+++ b/include/linux/mtd/flashchip.h
@@ -1,12 +1,12 @@
1 1
2/* 2/*
3 * struct flchip definition 3 * struct flchip definition
4 * 4 *
5 * Contains information about the location and state of a given flash device 5 * Contains information about the location and state of a given flash device
6 * 6 *
7 * (C) 2000 Red Hat. GPLd. 7 * (C) 2000 Red Hat. GPLd.
8 * 8 *
9 * $Id: flashchip.h,v 1.17 2005/03/14 18:27:15 bjd Exp $ 9 * $Id: flashchip.h,v 1.18 2005/11/07 11:14:54 gleixner Exp $
10 * 10 *
11 */ 11 */
12 12
@@ -15,11 +15,11 @@
15 15
16/* For spinlocks. sched.h includes spinlock.h from whichever directory it 16/* For spinlocks. sched.h includes spinlock.h from whichever directory it
17 * happens to be in - so we don't have to care whether we're on 2.2, which 17 * happens to be in - so we don't have to care whether we're on 2.2, which
18 * has asm/spinlock.h, or 2.4, which has linux/spinlock.h 18 * has asm/spinlock.h, or 2.4, which has linux/spinlock.h
19 */ 19 */
20#include <linux/sched.h> 20#include <linux/sched.h>
21 21
22typedef enum { 22typedef enum {
23 FL_READY, 23 FL_READY,
24 FL_STATUS, 24 FL_STATUS,
25 FL_CFI_QUERY, 25 FL_CFI_QUERY,
@@ -45,7 +45,7 @@ typedef enum {
45 45
46 46
47 47
48/* NOTE: confusingly, this can be used to refer to more than one chip at a time, 48/* NOTE: confusingly, this can be used to refer to more than one chip at a time,
49 if they're interleaved. This can even refer to individual partitions on 49 if they're interleaved. This can even refer to individual partitions on
50 the same physical chip when present. */ 50 the same physical chip when present. */
51 51
diff --git a/include/linux/mtd/ftl.h b/include/linux/mtd/ftl.h
index 3678459b4535..d99609113307 100644
--- a/include/linux/mtd/ftl.h
+++ b/include/linux/mtd/ftl.h
@@ -1,6 +1,6 @@
1/* 1/*
2 * $Id: ftl.h,v 1.6 2003/01/24 13:20:04 dwmw2 Exp $ 2 * $Id: ftl.h,v 1.7 2005/11/07 11:14:54 gleixner Exp $
3 * 3 *
4 * Derived from (and probably identical to): 4 * Derived from (and probably identical to):
5 * ftl.h 1.7 1999/10/25 20:23:17 5 * ftl.h 1.7 1999/10/25 20:23:17
6 * 6 *
@@ -12,7 +12,7 @@
12 * Software distributed under the License is distributed on an "AS IS" 12 * Software distributed under the License is distributed on an "AS IS"
13 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 13 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14 * the License for the specific language governing rights and 14 * the License for the specific language governing rights and
15 * limitations under the License. 15 * limitations under the License.
16 * 16 *
17 * The initial developer of the original code is David A. Hinds 17 * The initial developer of the original code is David A. Hinds
18 * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds 18 * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
diff --git a/include/linux/mtd/gen_probe.h b/include/linux/mtd/gen_probe.h
index 3d7bdec14f97..256e7342ed1e 100644
--- a/include/linux/mtd/gen_probe.h
+++ b/include/linux/mtd/gen_probe.h
@@ -1,14 +1,14 @@
1/* 1/*
2 * (C) 2001, 2001 Red Hat, Inc. 2 * (C) 2001, 2001 Red Hat, Inc.
3 * GPL'd 3 * GPL'd
4 * $Id: gen_probe.h,v 1.3 2004/10/20 22:10:33 dwmw2 Exp $ 4 * $Id: gen_probe.h,v 1.4 2005/11/07 11:14:54 gleixner Exp $
5 */ 5 */
6 6
7#ifndef __LINUX_MTD_GEN_PROBE_H__ 7#ifndef __LINUX_MTD_GEN_PROBE_H__
8#define __LINUX_MTD_GEN_PROBE_H__ 8#define __LINUX_MTD_GEN_PROBE_H__
9 9
10#include <linux/mtd/flashchip.h> 10#include <linux/mtd/flashchip.h>
11#include <linux/mtd/map.h> 11#include <linux/mtd/map.h>
12#include <linux/mtd/cfi.h> 12#include <linux/mtd/cfi.h>
13#include <linux/bitops.h> 13#include <linux/bitops.h>
14 14
diff --git a/include/linux/mtd/jedec.h b/include/linux/mtd/jedec.h
index 2ba0f700ddbc..9006feb218b9 100644
--- a/include/linux/mtd/jedec.h
+++ b/include/linux/mtd/jedec.h
@@ -1,13 +1,13 @@
1 1
2/* JEDEC Flash Interface. 2/* JEDEC Flash Interface.
3 * This is an older type of interface for self programming flash. It is 3 * This is an older type of interface for self programming flash. It is
4 * commonly use in older AMD chips and is obsolete compared with CFI. 4 * commonly use in older AMD chips and is obsolete compared with CFI.
5 * It is called JEDEC because the JEDEC association distributes the ID codes 5 * It is called JEDEC because the JEDEC association distributes the ID codes
6 * for the chips. 6 * for the chips.
7 * 7 *
8 * See the AMD flash databook for information on how to operate the interface. 8 * See the AMD flash databook for information on how to operate the interface.
9 * 9 *
10 * $Id: jedec.h,v 1.3 2003/05/21 11:51:01 dwmw2 Exp $ 10 * $Id: jedec.h,v 1.4 2005/11/07 11:14:54 gleixner Exp $
11 */ 11 */
12 12
13#ifndef __LINUX_MTD_JEDEC_H__ 13#ifndef __LINUX_MTD_JEDEC_H__
@@ -33,16 +33,16 @@ struct jedec_flash_chip
33 __u16 jedec; 33 __u16 jedec;
34 unsigned long size; 34 unsigned long size;
35 unsigned long sectorsize; 35 unsigned long sectorsize;
36 36
37 // *(__u8*)(base + (adder << addrshift)) = data << datashift 37 // *(__u8*)(base + (adder << addrshift)) = data << datashift
38 // Address size = size << addrshift 38 // Address size = size << addrshift
39 unsigned long base; // Byte 0 of the flash, will be unaligned 39 unsigned long base; // Byte 0 of the flash, will be unaligned
40 unsigned int datashift; // Useful for 32bit/16bit accesses 40 unsigned int datashift; // Useful for 32bit/16bit accesses
41 unsigned int addrshift; 41 unsigned int addrshift;
42 unsigned long offset; // linerized start. base==offset for unbanked, uninterleaved flash 42 unsigned long offset; // linerized start. base==offset for unbanked, uninterleaved flash
43 43
44 __u32 capabilities; 44 __u32 capabilities;
45 45
46 // These markers are filled in by the flash_chip_scan function 46 // These markers are filled in by the flash_chip_scan function
47 unsigned long start; 47 unsigned long start;
48 unsigned long length; 48 unsigned long length;
@@ -51,16 +51,16 @@ struct jedec_flash_chip
51struct jedec_private 51struct jedec_private
52{ 52{
53 unsigned long size; // Total size of all the devices 53 unsigned long size; // Total size of all the devices
54 54
55 /* Bank handling. If sum(bank_fill) == size then this is linear flash. 55 /* Bank handling. If sum(bank_fill) == size then this is linear flash.
56 Otherwise the mapping has holes in it. bank_fill may be used to 56 Otherwise the mapping has holes in it. bank_fill may be used to
57 find the holes, but in the common symetric case 57 find the holes, but in the common symetric case
58 bank_fill[0] == bank_fill[*], thus addresses may be computed 58 bank_fill[0] == bank_fill[*], thus addresses may be computed
59 mathmatically. bank_fill must be powers of two */ 59 mathmatically. bank_fill must be powers of two */
60 unsigned is_banked; 60 unsigned is_banked;
61 unsigned long bank_fill[MAX_JEDEC_CHIPS]; 61 unsigned long bank_fill[MAX_JEDEC_CHIPS];
62 62
63 struct jedec_flash_chip chips[MAX_JEDEC_CHIPS]; 63 struct jedec_flash_chip chips[MAX_JEDEC_CHIPS];
64}; 64};
65 65
66#endif 66#endif
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
index fc28841f3409..fedfbc8a287f 100644
--- a/include/linux/mtd/map.h
+++ b/include/linux/mtd/map.h
@@ -1,6 +1,6 @@
1 1
2/* Overhauled routines for dealing with different mmap regions of flash */ 2/* Overhauled routines for dealing with different mmap regions of flash */
3/* $Id: map.h,v 1.52 2005/05/25 10:29:41 gleixner Exp $ */ 3/* $Id: map.h,v 1.54 2005/11/07 11:14:54 gleixner Exp $ */
4 4
5#ifndef __LINUX_MTD_MAP_H__ 5#ifndef __LINUX_MTD_MAP_H__
6#define __LINUX_MTD_MAP_H__ 6#define __LINUX_MTD_MAP_H__
@@ -170,14 +170,14 @@ typedef union {
170 to a chip probe routine -- either JEDEC or CFI probe or both -- via 170 to a chip probe routine -- either JEDEC or CFI probe or both -- via
171 do_map_probe(). If a chip is recognised, the probe code will invoke the 171 do_map_probe(). If a chip is recognised, the probe code will invoke the
172 appropriate chip driver (if present) and return a struct mtd_info. 172 appropriate chip driver (if present) and return a struct mtd_info.
173 At which point, you fill in the mtd->module with your own module 173 At which point, you fill in the mtd->module with your own module
174 address, and register it with the MTD core code. Or you could partition 174 address, and register it with the MTD core code. Or you could partition
175 it and register the partitions instead, or keep it for your own private 175 it and register the partitions instead, or keep it for your own private
176 use; whatever. 176 use; whatever.
177 177
178 The mtd->priv field will point to the struct map_info, and any further 178 The mtd->priv field will point to the struct map_info, and any further
179 private data required by the chip driver is linked from the 179 private data required by the chip driver is linked from the
180 mtd->priv->fldrv_priv field. This allows the map driver to get at 180 mtd->priv->fldrv_priv field. This allows the map driver to get at
181 the destructor function map->fldrv_destroy() when it's tired 181 the destructor function map->fldrv_destroy() when it's tired
182 of living. 182 of living.
183*/ 183*/
@@ -214,7 +214,7 @@ struct map_info {
214 If there is no cache to care about this can be set to NULL. */ 214 If there is no cache to care about this can be set to NULL. */
215 void (*inval_cache)(struct map_info *, unsigned long, ssize_t); 215 void (*inval_cache)(struct map_info *, unsigned long, ssize_t);
216 216
217 /* set_vpp() must handle being reentered -- enable, enable, disable 217 /* set_vpp() must handle being reentered -- enable, enable, disable
218 must leave it enabled. */ 218 must leave it enabled. */
219 void (*set_vpp)(struct map_info *, int); 219 void (*set_vpp)(struct map_info *, int);
220 220
@@ -353,7 +353,7 @@ static inline map_word map_word_ff(struct map_info *map)
353{ 353{
354 map_word r; 354 map_word r;
355 int i; 355 int i;
356 356
357 if (map_bankwidth(map) < MAP_FF_LIMIT) { 357 if (map_bankwidth(map) < MAP_FF_LIMIT) {
358 int bw = 8 * map_bankwidth(map); 358 int bw = 8 * map_bankwidth(map);
359 r.x[0] = (1 << bw) - 1; 359 r.x[0] = (1 << bw) - 1;
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index c50c3f3927d9..e95d0463a3e5 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: mtd.h,v 1.59 2005/04/11 10:19:02 gleixner Exp $ 2 * $Id: mtd.h,v 1.61 2005/11/07 11:14:54 gleixner Exp $
3 * 3 *
4 * Copyright (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> et al. 4 * Copyright (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> et al.
5 * 5 *
@@ -72,7 +72,17 @@ struct mtd_info {
72 u_int32_t oobsize; // Amount of OOB data per block (e.g. 16) 72 u_int32_t oobsize; // Amount of OOB data per block (e.g. 16)
73 u_int32_t ecctype; 73 u_int32_t ecctype;
74 u_int32_t eccsize; 74 u_int32_t eccsize;
75 75
76 /*
77 * Reuse some of the above unused fields in the case of NOR flash
78 * with configurable programming regions to avoid modifying the
79 * user visible structure layout/size. Only valid when the
80 * MTD_PROGRAM_REGIONS flag is set.
81 * (Maybe we should have an union for those?)
82 */
83#define MTD_PROGREGION_SIZE(mtd) (mtd)->oobblock
84#define MTD_PROGREGION_CTRLMODE_VALID(mtd) (mtd)->oobsize
85#define MTD_PROGREGION_CTRLMODE_INVALID(mtd) (mtd)->ecctype
76 86
77 // Kernel-only stuff starts here. 87 // Kernel-only stuff starts here.
78 char *name; 88 char *name;
@@ -80,13 +90,13 @@ struct mtd_info {
80 90
81 // oobinfo is a nand_oobinfo structure, which can be set by iotcl (MEMSETOOBINFO) 91 // oobinfo is a nand_oobinfo structure, which can be set by iotcl (MEMSETOOBINFO)
82 struct nand_oobinfo oobinfo; 92 struct nand_oobinfo oobinfo;
83 u_int32_t oobavail; // Number of bytes in OOB area available for fs 93 u_int32_t oobavail; // Number of bytes in OOB area available for fs
84 94
85 /* Data for variable erase regions. If numeraseregions is zero, 95 /* Data for variable erase regions. If numeraseregions is zero,
86 * it means that the whole device has erasesize as given above. 96 * it means that the whole device has erasesize as given above.
87 */ 97 */
88 int numeraseregions; 98 int numeraseregions;
89 struct mtd_erase_region_info *eraseregions; 99 struct mtd_erase_region_info *eraseregions;
90 100
91 /* This really shouldn't be here. It can go away in 2.5 */ 101 /* This really shouldn't be here. It can go away in 2.5 */
92 u_int32_t bank_size; 102 u_int32_t bank_size;
@@ -109,10 +119,10 @@ struct mtd_info {
109 int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); 119 int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
110 int (*write_oob) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); 120 int (*write_oob) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
111 121
112 /* 122 /*
113 * Methods to access the protection register area, present in some 123 * Methods to access the protection register area, present in some
114 * flash devices. The user data is one time programmable but the 124 * flash devices. The user data is one time programmable but the
115 * factory data is read only. 125 * factory data is read only.
116 */ 126 */
117 int (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len); 127 int (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);
118 int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); 128 int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
@@ -123,14 +133,14 @@ struct mtd_info {
123 133
124 /* kvec-based read/write methods. We need these especially for NAND flash, 134 /* kvec-based read/write methods. We need these especially for NAND flash,
125 with its limited number of write cycles per erase. 135 with its limited number of write cycles per erase.
126 NB: The 'count' parameter is the number of _vectors_, each of 136 NB: The 'count' parameter is the number of _vectors_, each of
127 which contains an (ofs, len) tuple. 137 which contains an (ofs, len) tuple.
128 */ 138 */
129 int (*readv) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen); 139 int (*readv) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen);
130 int (*readv_ecc) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, 140 int (*readv_ecc) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from,
131 size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel); 141 size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
132 int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen); 142 int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen);
133 int (*writev_ecc) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, 143 int (*writev_ecc) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to,
134 size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel); 144 size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
135 145
136 /* Sync */ 146 /* Sync */
@@ -194,7 +204,7 @@ int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs,
194#define MTD_WRITEECC(mtd, args...) (*(mtd->write_ecc))(mtd, args) 204#define MTD_WRITEECC(mtd, args...) (*(mtd->write_ecc))(mtd, args)
195#define MTD_READOOB(mtd, args...) (*(mtd->read_oob))(mtd, args) 205#define MTD_READOOB(mtd, args...) (*(mtd->read_oob))(mtd, args)
196#define MTD_WRITEOOB(mtd, args...) (*(mtd->write_oob))(mtd, args) 206#define MTD_WRITEOOB(mtd, args...) (*(mtd->write_oob))(mtd, args)
197#define MTD_SYNC(mtd) do { if (mtd->sync) (*(mtd->sync))(mtd); } while (0) 207#define MTD_SYNC(mtd) do { if (mtd->sync) (*(mtd->sync))(mtd); } while (0)
198 208
199 209
200#ifdef CONFIG_MTD_PARTITIONS 210#ifdef CONFIG_MTD_PARTITIONS
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 9b5b76217584..da5e67b3fc70 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -5,7 +5,7 @@
5 * Steven J. Hill <sjhill@realitydiluted.com> 5 * Steven J. Hill <sjhill@realitydiluted.com>
6 * Thomas Gleixner <tglx@linutronix.de> 6 * Thomas Gleixner <tglx@linutronix.de>
7 * 7 *
8 * $Id: nand.h,v 1.73 2005/05/31 19:39:17 gleixner Exp $ 8 * $Id: nand.h,v 1.74 2005/09/15 13:58:50 vwool Exp $
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as 11 * it under the terms of the GNU General Public License version 2 as
@@ -24,7 +24,7 @@
24 * bat later if I did something naughty. 24 * bat later if I did something naughty.
25 * 10-11-2000 SJH Added private NAND flash structure for driver 25 * 10-11-2000 SJH Added private NAND flash structure for driver
26 * 10-24-2000 SJH Added prototype for 'nand_scan' function 26 * 10-24-2000 SJH Added prototype for 'nand_scan' function
27 * 10-29-2001 TG changed nand_chip structure to support 27 * 10-29-2001 TG changed nand_chip structure to support
28 * hardwarespecific function for accessing control lines 28 * hardwarespecific function for accessing control lines
29 * 02-21-2002 TG added support for different read/write adress and 29 * 02-21-2002 TG added support for different read/write adress and
30 * ready/busy line access function 30 * ready/busy line access function
@@ -36,21 +36,21 @@
36 * CONFIG_MTD_NAND_ECC_JFFS2 is not set 36 * CONFIG_MTD_NAND_ECC_JFFS2 is not set
37 * 08-10-2002 TG extensions to nand_chip structure to support HW-ECC 37 * 08-10-2002 TG extensions to nand_chip structure to support HW-ECC
38 * 38 *
39 * 08-29-2002 tglx nand_chip structure: data_poi for selecting 39 * 08-29-2002 tglx nand_chip structure: data_poi for selecting
40 * internal / fs-driver buffer 40 * internal / fs-driver buffer
41 * support for 6byte/512byte hardware ECC 41 * support for 6byte/512byte hardware ECC
42 * read_ecc, write_ecc extended for different oob-layout 42 * read_ecc, write_ecc extended for different oob-layout
43 * oob layout selections: NAND_NONE_OOB, NAND_JFFS2_OOB, 43 * oob layout selections: NAND_NONE_OOB, NAND_JFFS2_OOB,
44 * NAND_YAFFS_OOB 44 * NAND_YAFFS_OOB
45 * 11-25-2002 tglx Added Manufacturer code FUJITSU, NATIONAL 45 * 11-25-2002 tglx Added Manufacturer code FUJITSU, NATIONAL
46 * Split manufacturer and device ID structures 46 * Split manufacturer and device ID structures
47 * 47 *
48 * 02-08-2004 tglx added option field to nand structure for chip anomalities 48 * 02-08-2004 tglx added option field to nand structure for chip anomalities
49 * 05-25-2004 tglx added bad block table support, ST-MICRO manufacturer id 49 * 05-25-2004 tglx added bad block table support, ST-MICRO manufacturer id
50 * update of nand_chip structure description 50 * update of nand_chip structure description
51 * 01-17-2005 dmarlin added extended commands for AG-AND device and added option 51 * 01-17-2005 dmarlin added extended commands for AG-AND device and added option
52 * for BBT_AUTO_REFRESH. 52 * for BBT_AUTO_REFRESH.
53 * 01-20-2005 dmarlin added optional pointer to hardware specific callback for 53 * 01-20-2005 dmarlin added optional pointer to hardware specific callback for
54 * extra error status checks. 54 * extra error status checks.
55 */ 55 */
56#ifndef __LINUX_MTD_NAND_H 56#ifndef __LINUX_MTD_NAND_H
@@ -120,8 +120,8 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_
120#define NAND_CMD_CACHEDPROG 0x15 120#define NAND_CMD_CACHEDPROG 0x15
121 121
122/* Extended commands for AG-AND device */ 122/* Extended commands for AG-AND device */
123/* 123/*
124 * Note: the command for NAND_CMD_DEPLETE1 is really 0x00 but 124 * Note: the command for NAND_CMD_DEPLETE1 is really 0x00 but
125 * there is no way to distinguish that from NAND_CMD_READ0 125 * there is no way to distinguish that from NAND_CMD_READ0
126 * until the remaining sequence of commands has been completed 126 * until the remaining sequence of commands has been completed
127 * so add a high order bit and mask it off in the command. 127 * so add a high order bit and mask it off in the command.
@@ -145,7 +145,7 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_
145#define NAND_STATUS_READY 0x40 145#define NAND_STATUS_READY 0x40
146#define NAND_STATUS_WP 0x80 146#define NAND_STATUS_WP 0x80
147 147
148/* 148/*
149 * Constants for ECC_MODES 149 * Constants for ECC_MODES
150 */ 150 */
151 151
@@ -191,12 +191,12 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_
191#define NAND_CACHEPRG 0x00000008 191#define NAND_CACHEPRG 0x00000008
192/* Chip has copy back function */ 192/* Chip has copy back function */
193#define NAND_COPYBACK 0x00000010 193#define NAND_COPYBACK 0x00000010
194/* AND Chip which has 4 banks and a confusing page / block 194/* AND Chip which has 4 banks and a confusing page / block
195 * assignment. See Renesas datasheet for further information */ 195 * assignment. See Renesas datasheet for further information */
196#define NAND_IS_AND 0x00000020 196#define NAND_IS_AND 0x00000020
197/* Chip has a array of 4 pages which can be read without 197/* Chip has a array of 4 pages which can be read without
198 * additional ready /busy waits */ 198 * additional ready /busy waits */
199#define NAND_4PAGE_ARRAY 0x00000040 199#define NAND_4PAGE_ARRAY 0x00000040
200/* Chip requires that BBT is periodically rewritten to prevent 200/* Chip requires that BBT is periodically rewritten to prevent
201 * bits from adjacent blocks from 'leaking' in altering data. 201 * bits from adjacent blocks from 'leaking' in altering data.
202 * This happens with the Renesas AG-AND chips, possibly others. */ 202 * This happens with the Renesas AG-AND chips, possibly others. */
@@ -219,8 +219,8 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_
219/* Use a flash based bad block table. This option is passed to the 219/* Use a flash based bad block table. This option is passed to the
220 * default bad block table function. */ 220 * default bad block table function. */
221#define NAND_USE_FLASH_BBT 0x00010000 221#define NAND_USE_FLASH_BBT 0x00010000
222/* The hw ecc generator provides a syndrome instead a ecc value on read 222/* The hw ecc generator provides a syndrome instead a ecc value on read
223 * This can only work if we have the ecc bytes directly behind the 223 * This can only work if we have the ecc bytes directly behind the
224 * data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */ 224 * data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */
225#define NAND_HWECC_SYNDROME 0x00020000 225#define NAND_HWECC_SYNDROME 0x00020000
226/* This option skips the bbt scan during initialization. */ 226/* This option skips the bbt scan during initialization. */
@@ -244,6 +244,7 @@ typedef enum {
244 FL_ERASING, 244 FL_ERASING,
245 FL_SYNCING, 245 FL_SYNCING,
246 FL_CACHEDPRG, 246 FL_CACHEDPRG,
247 FL_PM_SUSPENDED,
247} nand_state_t; 248} nand_state_t;
248 249
249/* Keep gcc happy */ 250/* Keep gcc happy */
@@ -251,7 +252,7 @@ struct nand_chip;
251 252
252/** 253/**
253 * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independend devices 254 * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independend devices
254 * @lock: protection lock 255 * @lock: protection lock
255 * @active: the mtd device which holds the controller currently 256 * @active: the mtd device which holds the controller currently
256 * @wq: wait queue to sleep on if a NAND operation is in progress 257 * @wq: wait queue to sleep on if a NAND operation is in progress
257 * used instead of the per chip wait queue when a hw controller is available 258 * used instead of the per chip wait queue when a hw controller is available
@@ -264,8 +265,8 @@ struct nand_hw_control {
264 265
265/** 266/**
266 * struct nand_chip - NAND Private Flash Chip Data 267 * struct nand_chip - NAND Private Flash Chip Data
267 * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the flash device 268 * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the flash device
268 * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the flash device 269 * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the flash device
269 * @read_byte: [REPLACEABLE] read one byte from the chip 270 * @read_byte: [REPLACEABLE] read one byte from the chip
270 * @write_byte: [REPLACEABLE] write one byte to the chip 271 * @write_byte: [REPLACEABLE] write one byte to the chip
271 * @read_word: [REPLACEABLE] read one word from the chip 272 * @read_word: [REPLACEABLE] read one word from the chip
@@ -288,7 +289,7 @@ struct nand_hw_control {
288 * be provided if a hardware ECC is available 289 * be provided if a hardware ECC is available
289 * @erase_cmd: [INTERN] erase command write function, selectable due to AND support 290 * @erase_cmd: [INTERN] erase command write function, selectable due to AND support
290 * @scan_bbt: [REPLACEABLE] function to scan bad block table 291 * @scan_bbt: [REPLACEABLE] function to scan bad block table
291 * @eccmode: [BOARDSPECIFIC] mode of ecc, see defines 292 * @eccmode: [BOARDSPECIFIC] mode of ecc, see defines
292 * @eccsize: [INTERN] databytes used per ecc-calculation 293 * @eccsize: [INTERN] databytes used per ecc-calculation
293 * @eccbytes: [INTERN] number of ecc bytes per ecc-calculation step 294 * @eccbytes: [INTERN] number of ecc bytes per ecc-calculation step
294 * @eccsteps: [INTERN] number of ecc calculation steps per page 295 * @eccsteps: [INTERN] number of ecc calculation steps per page
@@ -300,7 +301,7 @@ struct nand_hw_control {
300 * @phys_erase_shift: [INTERN] number of address bits in a physical eraseblock 301 * @phys_erase_shift: [INTERN] number of address bits in a physical eraseblock
301 * @bbt_erase_shift: [INTERN] number of address bits in a bbt entry 302 * @bbt_erase_shift: [INTERN] number of address bits in a bbt entry
302 * @chip_shift: [INTERN] number of address bits in one chip 303 * @chip_shift: [INTERN] number of address bits in one chip
303 * @data_buf: [INTERN] internal buffer for one page + oob 304 * @data_buf: [INTERN] internal buffer for one page + oob
304 * @oob_buf: [INTERN] oob buffer for one eraseblock 305 * @oob_buf: [INTERN] oob buffer for one eraseblock
305 * @oobdirty: [INTERN] indicates that oob_buf must be reinitialized 306 * @oobdirty: [INTERN] indicates that oob_buf must be reinitialized
306 * @data_poi: [INTERN] pointer to a data buffer 307 * @data_poi: [INTERN] pointer to a data buffer
@@ -315,22 +316,22 @@ struct nand_hw_control {
315 * @bbt: [INTERN] bad block table pointer 316 * @bbt: [INTERN] bad block table pointer
316 * @bbt_td: [REPLACEABLE] bad block table descriptor for flash lookup 317 * @bbt_td: [REPLACEABLE] bad block table descriptor for flash lookup
317 * @bbt_md: [REPLACEABLE] bad block table mirror descriptor 318 * @bbt_md: [REPLACEABLE] bad block table mirror descriptor
318 * @badblock_pattern: [REPLACEABLE] bad block scan pattern used for initial bad block scan 319 * @badblock_pattern: [REPLACEABLE] bad block scan pattern used for initial bad block scan
319 * @controller: [OPTIONAL] a pointer to a hardware controller structure which is shared among multiple independend devices 320 * @controller: [OPTIONAL] a pointer to a hardware controller structure which is shared among multiple independend devices
320 * @priv: [OPTIONAL] pointer to private chip date 321 * @priv: [OPTIONAL] pointer to private chip date
321 * @errstat: [OPTIONAL] hardware specific function to perform additional error status checks 322 * @errstat: [OPTIONAL] hardware specific function to perform additional error status checks
322 * (determine if errors are correctable) 323 * (determine if errors are correctable)
323 */ 324 */
324 325
325struct nand_chip { 326struct nand_chip {
326 void __iomem *IO_ADDR_R; 327 void __iomem *IO_ADDR_R;
327 void __iomem *IO_ADDR_W; 328 void __iomem *IO_ADDR_W;
328 329
329 u_char (*read_byte)(struct mtd_info *mtd); 330 u_char (*read_byte)(struct mtd_info *mtd);
330 void (*write_byte)(struct mtd_info *mtd, u_char byte); 331 void (*write_byte)(struct mtd_info *mtd, u_char byte);
331 u16 (*read_word)(struct mtd_info *mtd); 332 u16 (*read_word)(struct mtd_info *mtd);
332 void (*write_word)(struct mtd_info *mtd, u16 word); 333 void (*write_word)(struct mtd_info *mtd, u16 word);
333 334
334 void (*write_buf)(struct mtd_info *mtd, const u_char *buf, int len); 335 void (*write_buf)(struct mtd_info *mtd, const u_char *buf, int len);
335 void (*read_buf)(struct mtd_info *mtd, u_char *buf, int len); 336 void (*read_buf)(struct mtd_info *mtd, u_char *buf, int len);
336 int (*verify_buf)(struct mtd_info *mtd, const u_char *buf, int len); 337 int (*verify_buf)(struct mtd_info *mtd, const u_char *buf, int len);
@@ -395,7 +396,7 @@ struct nand_chip {
395 * @name: Identify the device type 396 * @name: Identify the device type
396 * @id: device ID code 397 * @id: device ID code
397 * @pagesize: Pagesize in bytes. Either 256 or 512 or 0 398 * @pagesize: Pagesize in bytes. Either 256 or 512 or 0
398 * If the pagesize is 0, then the real pagesize 399 * If the pagesize is 0, then the real pagesize
399 * and the eraseize are determined from the 400 * and the eraseize are determined from the
400 * extended id bytes in the chip 401 * extended id bytes in the chip
401 * @erasesize: Size of an erase block in the flash device. 402 * @erasesize: Size of an erase block in the flash device.
@@ -424,7 +425,7 @@ struct nand_manufacturers {
424extern struct nand_flash_dev nand_flash_ids[]; 425extern struct nand_flash_dev nand_flash_ids[];
425extern struct nand_manufacturers nand_manuf_ids[]; 426extern struct nand_manufacturers nand_manuf_ids[];
426 427
427/** 428/**
428 * struct nand_bbt_descr - bad block table descriptor 429 * struct nand_bbt_descr - bad block table descriptor
429 * @options: options for this descriptor 430 * @options: options for this descriptor
430 * @pages: the page(s) where we find the bbt, used with option BBT_ABSPAGE 431 * @pages: the page(s) where we find the bbt, used with option BBT_ABSPAGE
@@ -435,14 +436,14 @@ extern struct nand_manufacturers nand_manuf_ids[];
435 * @version: version read from the bbt page during scan 436 * @version: version read from the bbt page during scan
436 * @len: length of the pattern, if 0 no pattern check is performed 437 * @len: length of the pattern, if 0 no pattern check is performed
437 * @maxblocks: maximum number of blocks to search for a bbt. This number of 438 * @maxblocks: maximum number of blocks to search for a bbt. This number of
438 * blocks is reserved at the end of the device where the tables are 439 * blocks is reserved at the end of the device where the tables are
439 * written. 440 * written.
440 * @reserved_block_code: if non-0, this pattern denotes a reserved (rather than 441 * @reserved_block_code: if non-0, this pattern denotes a reserved (rather than
441 * bad) block in the stored bbt 442 * bad) block in the stored bbt
442 * @pattern: pattern to identify bad block table or factory marked good / 443 * @pattern: pattern to identify bad block table or factory marked good /
443 * bad blocks, can be NULL, if len = 0 444 * bad blocks, can be NULL, if len = 0
444 * 445 *
445 * Descriptor for the bad block table marker and the descriptor for the 446 * Descriptor for the bad block table marker and the descriptor for the
446 * pattern which identifies good and bad blocks. The assumption is made 447 * pattern which identifies good and bad blocks. The assumption is made
447 * that the pattern and the version count are always located in the oob area 448 * that the pattern and the version count are always located in the oob area
448 * of the first block. 449 * of the first block.
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
new file mode 100644
index 000000000000..f1fd4215686a
--- /dev/null
+++ b/include/linux/mtd/onenand.h
@@ -0,0 +1,155 @@
1/*
2 * linux/include/linux/mtd/onenand.h
3 *
4 * Copyright (C) 2005 Samsung Electronics
5 * Kyungmin Park <kyungmin.park@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef __LINUX_MTD_ONENAND_H
13#define __LINUX_MTD_ONENAND_H
14
15#include <linux/spinlock.h>
16#include <linux/mtd/onenand_regs.h>
17#include <linux/mtd/bbm.h>
18
19#define MAX_BUFFERRAM 2
20#define MAX_ONENAND_PAGESIZE (2048 + 64)
21
22/* Scan and identify a OneNAND device */
23extern int onenand_scan(struct mtd_info *mtd, int max_chips);
24/* Free resources held by the OneNAND device */
25extern void onenand_release(struct mtd_info *mtd);
26
27/**
28 * onenand_state_t - chip states
29 * Enumeration for OneNAND flash chip state
30 */
31typedef enum {
32 FL_READY,
33 FL_READING,
34 FL_WRITING,
35 FL_ERASING,
36 FL_SYNCING,
37 FL_UNLOCKING,
38 FL_LOCKING,
39 FL_PM_SUSPENDED,
40} onenand_state_t;
41
42/**
43 * struct onenand_bufferram - OneNAND BufferRAM Data
44 * @param block block address in BufferRAM
45 * @param page page address in BufferRAM
46 * @param valid valid flag
47 */
48struct onenand_bufferram {
49 int block;
50 int page;
51 int valid;
52};
53
54/**
55 * struct onenand_chip - OneNAND Private Flash Chip Data
56 * @param base [BOARDSPECIFIC] address to access OneNAND
57 * @param chipsize [INTERN] the size of one chip for multichip arrays
58 * @param device_id [INTERN] device ID
59 * @param verstion_id [INTERN] version ID
60 * @param options [BOARDSPECIFIC] various chip options. They can partly be set to inform onenand_scan about
61 * @param erase_shift [INTERN] number of address bits in a block
62 * @param page_shift [INTERN] number of address bits in a page
63 * @param ppb_shift [INTERN] number of address bits in a pages per block
64 * @param page_mask [INTERN] a page per block mask
65 * @param bufferam_index [INTERN] BufferRAM index
66 * @param bufferam [INTERN] BufferRAM info
67 * @param readw [REPLACEABLE] hardware specific function for read short
68 * @param writew [REPLACEABLE] hardware specific function for write short
69 * @param command [REPLACEABLE] hardware specific function for writing commands to the chip
70 * @param wait [REPLACEABLE] hardware specific function for wait on ready
71 * @param read_bufferram [REPLACEABLE] hardware specific function for BufferRAM Area
72 * @param write_bufferram [REPLACEABLE] hardware specific function for BufferRAM Area
73 * @param read_word [REPLACEABLE] hardware specific function for read register of OneNAND
74 * @param write_word [REPLACEABLE] hardware specific function for write register of OneNAND
75 * @param scan_bbt [REPLACEALBE] hardware specific function for scaning Bad block Table
76 * @param chip_lock [INTERN] spinlock used to protect access to this structure and the chip
77 * @param wq [INTERN] wait queue to sleep on if a OneNAND operation is in progress
78 * @param state [INTERN] the current state of the OneNAND device
79 * @param autooob [REPLACEABLE] the default (auto)placement scheme
80 * @param bbm [REPLACEABLE] pointer to Bad Block Management
81 * @param priv [OPTIONAL] pointer to private chip date
82 */
83struct onenand_chip {
84 void __iomem *base;
85 unsigned int chipsize;
86 unsigned int device_id;
87 unsigned int density_mask;
88 unsigned int options;
89
90 unsigned int erase_shift;
91 unsigned int page_shift;
92 unsigned int ppb_shift; /* Pages per block shift */
93 unsigned int page_mask;
94
95 unsigned int bufferram_index;
96 struct onenand_bufferram bufferram[MAX_BUFFERRAM];
97
98 int (*command)(struct mtd_info *mtd, int cmd, loff_t address, size_t len);
99 int (*wait)(struct mtd_info *mtd, int state);
100 int (*read_bufferram)(struct mtd_info *mtd, int area,
101 unsigned char *buffer, int offset, size_t count);
102 int (*write_bufferram)(struct mtd_info *mtd, int area,
103 const unsigned char *buffer, int offset, size_t count);
104 unsigned short (*read_word)(void __iomem *addr);
105 void (*write_word)(unsigned short value, void __iomem *addr);
106 void (*mmcontrol)(struct mtd_info *mtd, int sync_read);
107 int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
108 int (*scan_bbt)(struct mtd_info *mtd);
109
110 spinlock_t chip_lock;
111 wait_queue_head_t wq;
112 onenand_state_t state;
113
114 struct nand_oobinfo *autooob;
115
116 void *bbm;
117
118 void *priv;
119};
120
121/*
122 * Helper macros
123 */
124#define ONENAND_CURRENT_BUFFERRAM(this) (this->bufferram_index)
125#define ONENAND_NEXT_BUFFERRAM(this) (this->bufferram_index ^ 1)
126#define ONENAND_SET_NEXT_BUFFERRAM(this) (this->bufferram_index ^= 1)
127
128#define ONENAND_GET_SYS_CFG1(this) \
129 (this->read_word(this->base + ONENAND_REG_SYS_CFG1))
130#define ONENAND_SET_SYS_CFG1(v, this) \
131 (this->write_word(v, this->base + ONENAND_REG_SYS_CFG1))
132
133/*
134 * Options bits
135 */
136#define ONENAND_CONT_LOCK (0x0001)
137
138
139/*
140 * OneNAND Flash Manufacturer ID Codes
141 */
142#define ONENAND_MFR_SAMSUNG 0xec
143#define ONENAND_MFR_UNKNOWN 0x00
144
145/**
146 * struct nand_manufacturers - NAND Flash Manufacturer ID Structure
147 * @param name: Manufacturer name
148 * @param id: manufacturer ID code of device.
149*/
150struct onenand_manufacturers {
151 int id;
152 char *name;
153};
154
155#endif /* __LINUX_MTD_ONENAND_H */
diff --git a/include/linux/mtd/onenand_regs.h b/include/linux/mtd/onenand_regs.h
new file mode 100644
index 000000000000..d7832ef8ed63
--- /dev/null
+++ b/include/linux/mtd/onenand_regs.h
@@ -0,0 +1,180 @@
1/*
2 * linux/include/linux/mtd/onenand_regs.h
3 *
4 * OneNAND Register header file
5 *
6 * Copyright (C) 2005 Samsung Electronics
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef __ONENAND_REG_H
14#define __ONENAND_REG_H
15
16/* Memory Address Map Translation (Word order) */
17#define ONENAND_MEMORY_MAP(x) ((x) << 1)
18
19/*
20 * External BufferRAM area
21 */
22#define ONENAND_BOOTRAM ONENAND_MEMORY_MAP(0x0000)
23#define ONENAND_DATARAM ONENAND_MEMORY_MAP(0x0200)
24#define ONENAND_SPARERAM ONENAND_MEMORY_MAP(0x8010)
25
26/*
27 * OneNAND Registers
28 */
29#define ONENAND_REG_MANUFACTURER_ID ONENAND_MEMORY_MAP(0xF000)
30#define ONENAND_REG_DEVICE_ID ONENAND_MEMORY_MAP(0xF001)
31#define ONENAND_REG_VERSION_ID ONENAND_MEMORY_MAP(0xF002)
32#define ONENAND_REG_DATA_BUFFER_SIZE ONENAND_MEMORY_MAP(0xF003)
33#define ONENAND_REG_BOOT_BUFFER_SIZE ONENAND_MEMORY_MAP(0xF004)
34#define ONENAND_REG_NUM_BUFFERS ONENAND_MEMORY_MAP(0xF005)
35#define ONENAND_REG_TECHNOLOGY ONENAND_MEMORY_MAP(0xF006)
36
37#define ONENAND_REG_START_ADDRESS1 ONENAND_MEMORY_MAP(0xF100)
38#define ONENAND_REG_START_ADDRESS2 ONENAND_MEMORY_MAP(0xF101)
39#define ONENAND_REG_START_ADDRESS3 ONENAND_MEMORY_MAP(0xF102)
40#define ONENAND_REG_START_ADDRESS4 ONENAND_MEMORY_MAP(0xF103)
41#define ONENAND_REG_START_ADDRESS5 ONENAND_MEMORY_MAP(0xF104)
42#define ONENAND_REG_START_ADDRESS6 ONENAND_MEMORY_MAP(0xF105)
43#define ONENAND_REG_START_ADDRESS7 ONENAND_MEMORY_MAP(0xF106)
44#define ONENAND_REG_START_ADDRESS8 ONENAND_MEMORY_MAP(0xF107)
45
46#define ONENAND_REG_START_BUFFER ONENAND_MEMORY_MAP(0xF200)
47#define ONENAND_REG_COMMAND ONENAND_MEMORY_MAP(0xF220)
48#define ONENAND_REG_SYS_CFG1 ONENAND_MEMORY_MAP(0xF221)
49#define ONENAND_REG_SYS_CFG2 ONENAND_MEMORY_MAP(0xF222)
50#define ONENAND_REG_CTRL_STATUS ONENAND_MEMORY_MAP(0xF240)
51#define ONENAND_REG_INTERRUPT ONENAND_MEMORY_MAP(0xF241)
52#define ONENAND_REG_START_BLOCK_ADDRESS ONENAND_MEMORY_MAP(0xF24C)
53#define ONENAND_REG_END_BLOCK_ADDRESS ONENAND_MEMORY_MAP(0xF24D)
54#define ONENAND_REG_WP_STATUS ONENAND_MEMORY_MAP(0xF24E)
55
56#define ONENAND_REG_ECC_STATUS ONENAND_MEMORY_MAP(0xFF00)
57#define ONENAND_REG_ECC_M0 ONENAND_MEMORY_MAP(0xFF01)
58#define ONENAND_REG_ECC_S0 ONENAND_MEMORY_MAP(0xFF02)
59#define ONENAND_REG_ECC_M1 ONENAND_MEMORY_MAP(0xFF03)
60#define ONENAND_REG_ECC_S1 ONENAND_MEMORY_MAP(0xFF04)
61#define ONENAND_REG_ECC_M2 ONENAND_MEMORY_MAP(0xFF05)
62#define ONENAND_REG_ECC_S2 ONENAND_MEMORY_MAP(0xFF06)
63#define ONENAND_REG_ECC_M3 ONENAND_MEMORY_MAP(0xFF07)
64#define ONENAND_REG_ECC_S3 ONENAND_MEMORY_MAP(0xFF08)
65
66/*
67 * Device ID Register F001h (R)
68 */
69#define ONENAND_DEVICE_DENSITY_SHIFT (4)
70#define ONENAND_DEVICE_IS_DDP (1 << 3)
71#define ONENAND_DEVICE_IS_DEMUX (1 << 2)
72#define ONENAND_DEVICE_VCC_MASK (0x3)
73
74#define ONENAND_DEVICE_DENSITY_512Mb (0x002)
75
76/*
77 * Version ID Register F002h (R)
78 */
79#define ONENAND_VERSION_PROCESS_SHIFT (8)
80
81/*
82 * Start Address 1 F100h (R/W)
83 */
84#define ONENAND_DDP_SHIFT (15)
85
86/*
87 * Start Address 8 F107h (R/W)
88 */
89#define ONENAND_FPA_MASK (0x3f)
90#define ONENAND_FPA_SHIFT (2)
91#define ONENAND_FSA_MASK (0x03)
92
93/*
94 * Start Buffer Register F200h (R/W)
95 */
96#define ONENAND_BSA_MASK (0x03)
97#define ONENAND_BSA_SHIFT (8)
98#define ONENAND_BSA_BOOTRAM (0 << 2)
99#define ONENAND_BSA_DATARAM0 (2 << 2)
100#define ONENAND_BSA_DATARAM1 (3 << 2)
101#define ONENAND_BSC_MASK (0x03)
102
103/*
104 * Command Register F220h (R/W)
105 */
106#define ONENAND_CMD_READ (0x00)
107#define ONENAND_CMD_READOOB (0x13)
108#define ONENAND_CMD_PROG (0x80)
109#define ONENAND_CMD_PROGOOB (0x1A)
110#define ONENAND_CMD_UNLOCK (0x23)
111#define ONENAND_CMD_LOCK (0x2A)
112#define ONENAND_CMD_LOCK_TIGHT (0x2C)
113#define ONENAND_CMD_ERASE (0x94)
114#define ONENAND_CMD_RESET (0xF0)
115#define ONENAND_CMD_READID (0x90)
116
117/* NOTE: Those are not *REAL* commands */
118#define ONENAND_CMD_BUFFERRAM (0x1978)
119
120/*
121 * System Configuration 1 Register F221h (R, R/W)
122 */
123#define ONENAND_SYS_CFG1_SYNC_READ (1 << 15)
124#define ONENAND_SYS_CFG1_BRL_7 (7 << 12)
125#define ONENAND_SYS_CFG1_BRL_6 (6 << 12)
126#define ONENAND_SYS_CFG1_BRL_5 (5 << 12)
127#define ONENAND_SYS_CFG1_BRL_4 (4 << 12)
128#define ONENAND_SYS_CFG1_BRL_3 (3 << 12)
129#define ONENAND_SYS_CFG1_BRL_10 (2 << 12)
130#define ONENAND_SYS_CFG1_BRL_9 (1 << 12)
131#define ONENAND_SYS_CFG1_BRL_8 (0 << 12)
132#define ONENAND_SYS_CFG1_BRL_SHIFT (12)
133#define ONENAND_SYS_CFG1_BL_32 (4 << 9)
134#define ONENAND_SYS_CFG1_BL_16 (3 << 9)
135#define ONENAND_SYS_CFG1_BL_8 (2 << 9)
136#define ONENAND_SYS_CFG1_BL_4 (1 << 9)
137#define ONENAND_SYS_CFG1_BL_CONT (0 << 9)
138#define ONENAND_SYS_CFG1_BL_SHIFT (9)
139#define ONENAND_SYS_CFG1_NO_ECC (1 << 8)
140#define ONENAND_SYS_CFG1_RDY (1 << 7)
141#define ONENAND_SYS_CFG1_INT (1 << 6)
142#define ONENAND_SYS_CFG1_IOBE (1 << 5)
143#define ONENAND_SYS_CFG1_RDY_CONF (1 << 4)
144
145/*
146 * Controller Status Register F240h (R)
147 */
148#define ONENAND_CTRL_ONGO (1 << 15)
149#define ONENAND_CTRL_LOCK (1 << 14)
150#define ONENAND_CTRL_LOAD (1 << 13)
151#define ONENAND_CTRL_PROGRAM (1 << 12)
152#define ONENAND_CTRL_ERASE (1 << 11)
153#define ONENAND_CTRL_ERROR (1 << 10)
154#define ONENAND_CTRL_RSTB (1 << 7)
155
156/*
157 * Interrupt Status Register F241h (R)
158 */
159#define ONENAND_INT_MASTER (1 << 15)
160#define ONENAND_INT_READ (1 << 7)
161#define ONENAND_INT_WRITE (1 << 6)
162#define ONENAND_INT_ERASE (1 << 5)
163#define ONENAND_INT_RESET (1 << 4)
164#define ONENAND_INT_CLEAR (0 << 0)
165
166/*
167 * NAND Flash Write Protection Status Register F24Eh (R)
168 */
169#define ONENAND_WP_US (1 << 2)
170#define ONENAND_WP_LS (1 << 1)
171#define ONENAND_WP_LTS (1 << 0)
172
173/*
174 * ECC Status Reigser FF00h (R)
175 */
176#define ONENAND_ECC_1BIT (1 << 0)
177#define ONENAND_ECC_2BIT (1 << 1)
178#define ONENAND_ECC_2BIT_ALL (0xAAAA)
179
180#endif /* __ONENAND_REG_H */
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h
index 50b2edfc8f11..b03f512d51b9 100644
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * This code is GPL 6 * This code is GPL
7 * 7 *
8 * $Id: partitions.h,v 1.16 2004/11/16 18:34:40 dwmw2 Exp $ 8 * $Id: partitions.h,v 1.17 2005/11/07 11:14:55 gleixner Exp $
9 */ 9 */
10 10
11#ifndef MTD_PARTITIONS_H 11#ifndef MTD_PARTITIONS_H
@@ -16,25 +16,25 @@
16 16
17/* 17/*
18 * Partition definition structure: 18 * Partition definition structure:
19 * 19 *
20 * An array of struct partition is passed along with a MTD object to 20 * An array of struct partition is passed along with a MTD object to
21 * add_mtd_partitions() to create them. 21 * add_mtd_partitions() to create them.
22 * 22 *
23 * For each partition, these fields are available: 23 * For each partition, these fields are available:
24 * name: string that will be used to label the partition's MTD device. 24 * name: string that will be used to label the partition's MTD device.
25 * size: the partition size; if defined as MTDPART_SIZ_FULL, the partition 25 * size: the partition size; if defined as MTDPART_SIZ_FULL, the partition
26 * will extend to the end of the master MTD device. 26 * will extend to the end of the master MTD device.
27 * offset: absolute starting position within the master MTD device; if 27 * offset: absolute starting position within the master MTD device; if
28 * defined as MTDPART_OFS_APPEND, the partition will start where the 28 * defined as MTDPART_OFS_APPEND, the partition will start where the
29 * previous one ended; if MTDPART_OFS_NXTBLK, at the next erase block. 29 * previous one ended; if MTDPART_OFS_NXTBLK, at the next erase block.
30 * mask_flags: contains flags that have to be masked (removed) from the 30 * mask_flags: contains flags that have to be masked (removed) from the
31 * master MTD flag set for the corresponding MTD partition. 31 * master MTD flag set for the corresponding MTD partition.
32 * For example, to force a read-only partition, simply adding 32 * For example, to force a read-only partition, simply adding
33 * MTD_WRITEABLE to the mask_flags will do the trick. 33 * MTD_WRITEABLE to the mask_flags will do the trick.
34 * 34 *
35 * Note: writeable partitions require their size and offset be 35 * Note: writeable partitions require their size and offset be
36 * erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK). 36 * erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK).
37 */ 37 */
38 38
39struct mtd_partition { 39struct mtd_partition {
40 char *name; /* identifier string */ 40 char *name; /* identifier string */
@@ -66,7 +66,7 @@ struct mtd_part_parser {
66 66
67extern int register_mtd_parser(struct mtd_part_parser *parser); 67extern int register_mtd_parser(struct mtd_part_parser *parser);
68extern int deregister_mtd_parser(struct mtd_part_parser *parser); 68extern int deregister_mtd_parser(struct mtd_part_parser *parser);
69extern int parse_mtd_partitions(struct mtd_info *master, const char **types, 69extern int parse_mtd_partitions(struct mtd_info *master, const char **types,
70 struct mtd_partition **pparts, unsigned long origin); 70 struct mtd_partition **pparts, unsigned long origin);
71 71
72#define put_partition_parser(p) do { module_put((p)->owner); } while(0) 72#define put_partition_parser(p) do { module_put((p)->owner); } while(0)
diff --git a/include/linux/mtd/physmap.h b/include/linux/mtd/physmap.h
index 05aa4970677f..c7b8bcdef013 100644
--- a/include/linux/mtd/physmap.h
+++ b/include/linux/mtd/physmap.h
@@ -1,8 +1,8 @@
1/* 1/*
2 * For boards with physically mapped flash and using 2 * For boards with physically mapped flash and using
3 * drivers/mtd/maps/physmap.c mapping driver. 3 * drivers/mtd/maps/physmap.c mapping driver.
4 * 4 *
5 * $Id: physmap.h,v 1.3 2004/07/21 00:16:15 jwboyer Exp $ 5 * $Id: physmap.h,v 1.4 2005/11/07 11:14:55 gleixner Exp $
6 * 6 *
7 * Copyright (C) 2003 MontaVista Software Inc. 7 * Copyright (C) 2003 MontaVista Software Inc.
8 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net 8 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
@@ -18,7 +18,7 @@
18 18
19#include <linux/config.h> 19#include <linux/config.h>
20 20
21#if defined(CONFIG_MTD_PHYSMAP) 21#if defined(CONFIG_MTD_PHYSMAP)
22 22
23#include <linux/mtd/mtd.h> 23#include <linux/mtd/mtd.h>
24#include <linux/mtd/map.h> 24#include <linux/mtd/map.h>
@@ -44,12 +44,12 @@ static inline void physmap_configure(unsigned long addr, unsigned long size, int
44#if defined(CONFIG_MTD_PARTITIONS) 44#if defined(CONFIG_MTD_PARTITIONS)
45 45
46/* 46/*
47 * Machines that wish to do flash partition may want to call this function in 47 * Machines that wish to do flash partition may want to call this function in
48 * their setup routine. 48 * their setup routine.
49 * 49 *
50 * physmap_set_partitions(mypartitions, num_parts); 50 * physmap_set_partitions(mypartitions, num_parts);
51 * 51 *
52 * Note that one can always override this hard-coded partition with 52 * Note that one can always override this hard-coded partition with
53 * command line partition (you need to enable CONFIG_MTD_CMDLINE_PARTS). 53 * command line partition (you need to enable CONFIG_MTD_CMDLINE_PARTS).
54 */ 54 */
55void physmap_set_partitions(struct mtd_partition *parts, int num_parts); 55void physmap_set_partitions(struct mtd_partition *parts, int num_parts);
diff --git a/include/linux/mtd/pmc551.h b/include/linux/mtd/pmc551.h
index 113e3087f68a..a7f6d20ad407 100644
--- a/include/linux/mtd/pmc551.h
+++ b/include/linux/mtd/pmc551.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: pmc551.h,v 1.5 2003/01/24 16:49:53 dwmw2 Exp $ 2 * $Id: pmc551.h,v 1.6 2005/11/07 11:14:55 gleixner Exp $
3 * 3 *
4 * PMC551 PCI Mezzanine Ram Device 4 * PMC551 PCI Mezzanine Ram Device
5 * 5 *
@@ -7,7 +7,7 @@
7 * Mark Ferrell 7 * Mark Ferrell
8 * Copyright 1999,2000 Nortel Networks 8 * Copyright 1999,2000 Nortel Networks
9 * 9 *
10 * License: 10 * License:
11 * As part of this driver was derrived from the slram.c driver it falls 11 * As part of this driver was derrived from the slram.c driver it falls
12 * under the same license, which is GNU General Public License v2 12 * under the same license, which is GNU General Public License v2
13 */ 13 */
@@ -17,7 +17,7 @@
17 17
18#include <linux/mtd/mtd.h> 18#include <linux/mtd/mtd.h>
19 19
20#define PMC551_VERSION "$Id: pmc551.h,v 1.5 2003/01/24 16:49:53 dwmw2 Exp $\n"\ 20#define PMC551_VERSION "$Id: pmc551.h,v 1.6 2005/11/07 11:14:55 gleixner Exp $\n"\
21 "Ramix PMC551 PCI Mezzanine Ram Driver. (C) 1999,2000 Nortel Networks.\n" 21 "Ramix PMC551 PCI Mezzanine Ram Driver. (C) 1999,2000 Nortel Networks.\n"
22 22
23/* 23/*
@@ -30,7 +30,7 @@ struct mypriv {
30 u32 curr_map0; 30 u32 curr_map0;
31 u32 asize; 31 u32 asize;
32 struct mtd_info *nextpmc551; 32 struct mtd_info *nextpmc551;
33}; 33};
34 34
35/* 35/*
36 * Function Prototypes 36 * Function Prototypes
@@ -39,7 +39,7 @@ static int pmc551_erase(struct mtd_info *, struct erase_info *);
39static void pmc551_unpoint(struct mtd_info *, u_char *, loff_t, size_t); 39static void pmc551_unpoint(struct mtd_info *, u_char *, loff_t, size_t);
40static int pmc551_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf); 40static int pmc551_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf);
41static int pmc551_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *); 41static int pmc551_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *);
42static int pmc551_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); 42static int pmc551_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
43 43
44 44
45/* 45/*
@@ -50,7 +50,7 @@ static int pmc551_write(struct mtd_info *, loff_t, size_t, size_t *, const u_cha
50#endif 50#endif
51 51
52#ifndef PCI_DEVICE_ID_V3_SEMI_V370PDC 52#ifndef PCI_DEVICE_ID_V3_SEMI_V370PDC
53#define PCI_DEVICE_ID_V3_SEMI_V370PDC 0x0200 53#define PCI_DEVICE_ID_V3_SEMI_V370PDC 0x0200
54#endif 54#endif
55 55
56 56
diff --git a/include/linux/mtd/xip.h b/include/linux/mtd/xip.h
index 7b7deef6b180..220d50bb71cd 100644
--- a/include/linux/mtd/xip.h
+++ b/include/linux/mtd/xip.h
@@ -12,7 +12,7 @@
12 * it under the terms of the GNU General Public License version 2 as 12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation. 13 * published by the Free Software Foundation.
14 * 14 *
15 * $Id: xip.h,v 1.2 2004/12/01 15:49:10 nico Exp $ 15 * $Id: xip.h,v 1.5 2005/11/07 11:14:55 gleixner Exp $
16 */ 16 */
17 17
18#ifndef __LINUX_MTD_XIP_H__ 18#ifndef __LINUX_MTD_XIP_H__
@@ -23,19 +23,19 @@
23#ifdef CONFIG_MTD_XIP 23#ifdef CONFIG_MTD_XIP
24 24
25/* 25/*
26 * Function that are modifying the flash state away from array mode must
27 * obviously not be running from flash. The __xipram is therefore marking
28 * those functions so they get relocated to ram.
29 */
30#define __xipram __attribute__ ((__section__ (".data")))
31
32/*
33 * We really don't want gcc to guess anything. 26 * We really don't want gcc to guess anything.
34 * We absolutely _need_ proper inlining. 27 * We absolutely _need_ proper inlining.
35 */ 28 */
36#include <linux/compiler.h> 29#include <linux/compiler.h>
37 30
38/* 31/*
32 * Function that are modifying the flash state away from array mode must
33 * obviously not be running from flash. The __xipram is therefore marking
34 * those functions so they get relocated to ram.
35 */
36#define __xipram noinline __attribute__ ((__section__ (".data")))
37
38/*
39 * Each architecture has to provide the following macros. They must access 39 * Each architecture has to provide the following macros. They must access
40 * the hardware directly and not rely on any other (XIP) functions since they 40 * the hardware directly and not rely on any other (XIP) functions since they
41 * won't be available when used (flash not in array mode). 41 * won't be available when used (flash not in array mode).
@@ -60,9 +60,9 @@
60 * overflowing. 60 * overflowing.
61 * 61 *
62 * xip_iprefetch() 62 * xip_iprefetch()
63 * 63 *
64 * Macro to fill instruction prefetch 64 * Macro to fill instruction prefetch
65 * e.g. a series of nops: asm volatile (".rep 8; nop; .endr"); 65 * e.g. a series of nops: asm volatile (".rep 8; nop; .endr");
66 */ 66 */
67 67
68#include <asm/mtd-xip.h> 68#include <asm/mtd-xip.h>
diff --git a/include/linux/rslib.h b/include/linux/rslib.h
index 980c8f74d8dc..ace25acfdc97 100644
--- a/include/linux/rslib.h
+++ b/include/linux/rslib.h
@@ -1,15 +1,15 @@
1/* 1/*
2 * include/linux/rslib.h 2 * include/linux/rslib.h
3 * 3 *
4 * Overview: 4 * Overview:
5 * Generic Reed Solomon encoder / decoder library 5 * Generic Reed Solomon encoder / decoder library
6 * 6 *
7 * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de) 7 * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
8 * 8 *
9 * RS code lifted from reed solomon library written by Phil Karn 9 * RS code lifted from reed solomon library written by Phil Karn
10 * Copyright 2002 Phil Karn, KA9Q 10 * Copyright 2002 Phil Karn, KA9Q
11 * 11 *
12 * $Id: rslib.h,v 1.3 2004/10/05 22:08:22 gleixner Exp $ 12 * $Id: rslib.h,v 1.4 2005/11/07 11:14:52 gleixner Exp $
13 * 13 *
14 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as 15 * it under the terms of the GNU General Public License version 2 as
@@ -21,20 +21,20 @@
21 21
22#include <linux/list.h> 22#include <linux/list.h>
23 23
24/** 24/**
25 * struct rs_control - rs control structure 25 * struct rs_control - rs control structure
26 * 26 *
27 * @mm: Bits per symbol 27 * @mm: Bits per symbol
28 * @nn: Symbols per block (= (1<<mm)-1) 28 * @nn: Symbols per block (= (1<<mm)-1)
29 * @alpha_to: log lookup table 29 * @alpha_to: log lookup table
30 * @index_of: Antilog lookup table 30 * @index_of: Antilog lookup table
31 * @genpoly: Generator polynomial 31 * @genpoly: Generator polynomial
32 * @nroots: Number of generator roots = number of parity symbols 32 * @nroots: Number of generator roots = number of parity symbols
33 * @fcr: First consecutive root, index form 33 * @fcr: First consecutive root, index form
34 * @prim: Primitive element, index form 34 * @prim: Primitive element, index form
35 * @iprim: prim-th root of 1, index form 35 * @iprim: prim-th root of 1, index form
36 * @gfpoly: The primitive generator polynominal 36 * @gfpoly: The primitive generator polynominal
37 * @users: Users of this structure 37 * @users: Users of this structure
38 * @list: List entry for the rs control list 38 * @list: List entry for the rs control list
39*/ 39*/
40struct rs_control { 40struct rs_control {
@@ -58,7 +58,7 @@ int encode_rs8(struct rs_control *rs, uint8_t *data, int len, uint16_t *par,
58 uint16_t invmsk); 58 uint16_t invmsk);
59#endif 59#endif
60#ifdef CONFIG_REED_SOLOMON_DEC8 60#ifdef CONFIG_REED_SOLOMON_DEC8
61int decode_rs8(struct rs_control *rs, uint8_t *data, uint16_t *par, int len, 61int decode_rs8(struct rs_control *rs, uint8_t *data, uint16_t *par, int len,
62 uint16_t *s, int no_eras, int *eras_pos, uint16_t invmsk, 62 uint16_t *s, int no_eras, int *eras_pos, uint16_t invmsk,
63 uint16_t *corr); 63 uint16_t *corr);
64#endif 64#endif
@@ -75,7 +75,7 @@ int decode_rs16(struct rs_control *rs, uint16_t *data, uint16_t *par, int len,
75#endif 75#endif
76 76
77/* Create or get a matching rs control structure */ 77/* Create or get a matching rs control structure */
78struct rs_control *init_rs(int symsize, int gfpoly, int fcr, int prim, 78struct rs_control *init_rs(int symsize, int gfpoly, int fcr, int prim,
79 int nroots); 79 int nroots);
80 80
81/* Release a rs control structure */ 81/* Release a rs control structure */
@@ -87,9 +87,9 @@ void free_rs(struct rs_control *rs);
87 * @x: the value to reduce 87 * @x: the value to reduce
88 * 88 *
89 * where 89 * where
90 * rs->mm = number of bits per symbol 90 * rs->mm = number of bits per symbol
91 * rs->nn = (2^rs->mm) - 1 91 * rs->nn = (2^rs->mm) - 1
92 * 92 *
93 * Simple arithmetic modulo would return a wrong result for values 93 * Simple arithmetic modulo would return a wrong result for values
94 * >= 3 * rs->nn 94 * >= 3 * rs->nn
95*/ 95*/
diff --git a/include/mtd/inftl-user.h b/include/mtd/inftl-user.h
index bda4f2c8f728..9b1e2526b45e 100644
--- a/include/mtd/inftl-user.h
+++ b/include/mtd/inftl-user.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * $Id: inftl-user.h,v 1.1 2004/05/05 15:17:00 dwmw2 Exp $ 2 * $Id: inftl-user.h,v 1.2 2005/11/07 11:14:56 gleixner Exp $
3 * 3 *
4 * Parts of INFTL headers shared with userspace 4 * Parts of INFTL headers shared with userspace
5 * 5 *
6 */ 6 */
7 7
diff --git a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h
index 428d9122940b..b5994ea56a5a 100644
--- a/include/mtd/mtd-abi.h
+++ b/include/mtd/mtd-abi.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * $Id: mtd-abi.h,v 1.11 2005/05/19 16:08:58 gleixner Exp $ 2 * $Id: mtd-abi.h,v 1.13 2005/11/07 11:14:56 gleixner Exp $
3 * 3 *
4 * Portions of MTD ABI definition which are shared by kernel and user space 4 * Portions of MTD ABI definition which are shared by kernel and user space
5 */ 5 */
6 6
7#ifndef __MTD_ABI_H__ 7#ifndef __MTD_ABI_H__
@@ -42,6 +42,7 @@ struct mtd_oob_buf {
42#define MTD_OOB 64 // Out-of-band data (NAND flash) 42#define MTD_OOB 64 // Out-of-band data (NAND flash)
43#define MTD_ECC 128 // Device capable of automatic ECC 43#define MTD_ECC 128 // Device capable of automatic ECC
44#define MTD_NO_VIRTBLOCKS 256 // Virtual blocks not allowed 44#define MTD_NO_VIRTBLOCKS 256 // Virtual blocks not allowed
45#define MTD_PROGRAM_REGIONS 512 // Configurable Programming Regions
45 46
46// Some common devices / combinations of capabilities 47// Some common devices / combinations of capabilities
47#define MTD_CAP_ROM 0 48#define MTD_CAP_ROM 0
@@ -80,7 +81,7 @@ struct mtd_info_user {
80}; 81};
81 82
82struct region_info_user { 83struct region_info_user {
83 uint32_t offset; /* At which this region starts, 84 uint32_t offset; /* At which this region starts,
84 * from the beginning of the MTD */ 85 * from the beginning of the MTD */
85 uint32_t erasesize; /* For this region */ 86 uint32_t erasesize; /* For this region */
86 uint32_t numblocks; /* Number of blocks in this region */ 87 uint32_t numblocks; /* Number of blocks in this region */
diff --git a/include/mtd/nftl-user.h b/include/mtd/nftl-user.h
index 924ec0459e9c..b2bca18e7311 100644
--- a/include/mtd/nftl-user.h
+++ b/include/mtd/nftl-user.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * $Id: nftl-user.h,v 1.1 2004/05/05 14:44:57 dwmw2 Exp $ 2 * $Id: nftl-user.h,v 1.2 2005/11/07 11:14:56 gleixner Exp $
3 * 3 *
4 * Parts of NFTL headers shared with userspace 4 * Parts of NFTL headers shared with userspace
5 * 5 *
6 */ 6 */
7 7
diff --git a/lib/reed_solomon/Makefile b/lib/reed_solomon/Makefile
index 747a2de29346..c3d7136827ed 100644
--- a/lib/reed_solomon/Makefile
+++ b/lib/reed_solomon/Makefile
@@ -1,5 +1,5 @@
1# 1#
2# This is a modified version of reed solomon lib, 2# This is a modified version of reed solomon lib,
3# 3#
4 4
5obj-$(CONFIG_REED_SOLOMON) += reed_solomon.o 5obj-$(CONFIG_REED_SOLOMON) += reed_solomon.o
diff --git a/lib/reed_solomon/decode_rs.c b/lib/reed_solomon/decode_rs.c
index d401decd6289..a58df56f09b6 100644
--- a/lib/reed_solomon/decode_rs.c
+++ b/lib/reed_solomon/decode_rs.c
@@ -1,22 +1,22 @@
1/* 1/*
2 * lib/reed_solomon/decode_rs.c 2 * lib/reed_solomon/decode_rs.c
3 * 3 *
4 * Overview: 4 * Overview:
5 * Generic Reed Solomon encoder / decoder library 5 * Generic Reed Solomon encoder / decoder library
6 * 6 *
7 * Copyright 2002, Phil Karn, KA9Q 7 * Copyright 2002, Phil Karn, KA9Q
8 * May be used under the terms of the GNU General Public License (GPL) 8 * May be used under the terms of the GNU General Public License (GPL)
9 * 9 *
10 * Adaption to the kernel by Thomas Gleixner (tglx@linutronix.de) 10 * Adaption to the kernel by Thomas Gleixner (tglx@linutronix.de)
11 * 11 *
12 * $Id: decode_rs.c,v 1.6 2004/10/22 15:41:47 gleixner Exp $ 12 * $Id: decode_rs.c,v 1.7 2005/11/07 11:14:59 gleixner Exp $
13 * 13 *
14 */ 14 */
15 15
16/* Generic data width independent code which is included by the 16/* Generic data width independent code which is included by the
17 * wrappers. 17 * wrappers.
18 */ 18 */
19{ 19{
20 int deg_lambda, el, deg_omega; 20 int deg_lambda, el, deg_omega;
21 int i, j, r, k, pad; 21 int i, j, r, k, pad;
22 int nn = rs->nn; 22 int nn = rs->nn;
@@ -41,9 +41,9 @@
41 pad = nn - nroots - len; 41 pad = nn - nroots - len;
42 if (pad < 0 || pad >= nn) 42 if (pad < 0 || pad >= nn)
43 return -ERANGE; 43 return -ERANGE;
44 44
45 /* Does the caller provide the syndrome ? */ 45 /* Does the caller provide the syndrome ? */
46 if (s != NULL) 46 if (s != NULL)
47 goto decode; 47 goto decode;
48 48
49 /* form the syndromes; i.e., evaluate data(x) at roots of 49 /* form the syndromes; i.e., evaluate data(x) at roots of
@@ -54,11 +54,11 @@
54 for (j = 1; j < len; j++) { 54 for (j = 1; j < len; j++) {
55 for (i = 0; i < nroots; i++) { 55 for (i = 0; i < nroots; i++) {
56 if (syn[i] == 0) { 56 if (syn[i] == 0) {
57 syn[i] = (((uint16_t) data[j]) ^ 57 syn[i] = (((uint16_t) data[j]) ^
58 invmsk) & msk; 58 invmsk) & msk;
59 } else { 59 } else {
60 syn[i] = ((((uint16_t) data[j]) ^ 60 syn[i] = ((((uint16_t) data[j]) ^
61 invmsk) & msk) ^ 61 invmsk) & msk) ^
62 alpha_to[rs_modnn(rs, index_of[syn[i]] + 62 alpha_to[rs_modnn(rs, index_of[syn[i]] +
63 (fcr + i) * prim)]; 63 (fcr + i) * prim)];
64 } 64 }
@@ -70,7 +70,7 @@
70 if (syn[i] == 0) { 70 if (syn[i] == 0) {
71 syn[i] = ((uint16_t) par[j]) & msk; 71 syn[i] = ((uint16_t) par[j]) & msk;
72 } else { 72 } else {
73 syn[i] = (((uint16_t) par[j]) & msk) ^ 73 syn[i] = (((uint16_t) par[j]) & msk) ^
74 alpha_to[rs_modnn(rs, index_of[syn[i]] + 74 alpha_to[rs_modnn(rs, index_of[syn[i]] +
75 (fcr+i)*prim)]; 75 (fcr+i)*prim)];
76 } 76 }
@@ -99,14 +99,14 @@
99 99
100 if (no_eras > 0) { 100 if (no_eras > 0) {
101 /* Init lambda to be the erasure locator polynomial */ 101 /* Init lambda to be the erasure locator polynomial */
102 lambda[1] = alpha_to[rs_modnn(rs, 102 lambda[1] = alpha_to[rs_modnn(rs,
103 prim * (nn - 1 - eras_pos[0]))]; 103 prim * (nn - 1 - eras_pos[0]))];
104 for (i = 1; i < no_eras; i++) { 104 for (i = 1; i < no_eras; i++) {
105 u = rs_modnn(rs, prim * (nn - 1 - eras_pos[i])); 105 u = rs_modnn(rs, prim * (nn - 1 - eras_pos[i]));
106 for (j = i + 1; j > 0; j--) { 106 for (j = i + 1; j > 0; j--) {
107 tmp = index_of[lambda[j - 1]]; 107 tmp = index_of[lambda[j - 1]];
108 if (tmp != nn) { 108 if (tmp != nn) {
109 lambda[j] ^= 109 lambda[j] ^=
110 alpha_to[rs_modnn(rs, u + tmp)]; 110 alpha_to[rs_modnn(rs, u + tmp)];
111 } 111 }
112 } 112 }
@@ -127,8 +127,8 @@
127 discr_r = 0; 127 discr_r = 0;
128 for (i = 0; i < r; i++) { 128 for (i = 0; i < r; i++) {
129 if ((lambda[i] != 0) && (s[r - i - 1] != nn)) { 129 if ((lambda[i] != 0) && (s[r - i - 1] != nn)) {
130 discr_r ^= 130 discr_r ^=
131 alpha_to[rs_modnn(rs, 131 alpha_to[rs_modnn(rs,
132 index_of[lambda[i]] + 132 index_of[lambda[i]] +
133 s[r - i - 1])]; 133 s[r - i - 1])];
134 } 134 }
@@ -143,7 +143,7 @@
143 t[0] = lambda[0]; 143 t[0] = lambda[0];
144 for (i = 0; i < nroots; i++) { 144 for (i = 0; i < nroots; i++) {
145 if (b[i] != nn) { 145 if (b[i] != nn) {
146 t[i + 1] = lambda[i + 1] ^ 146 t[i + 1] = lambda[i + 1] ^
147 alpha_to[rs_modnn(rs, discr_r + 147 alpha_to[rs_modnn(rs, discr_r +
148 b[i])]; 148 b[i])];
149 } else 149 } else
@@ -229,7 +229,7 @@
229 num1 = 0; 229 num1 = 0;
230 for (i = deg_omega; i >= 0; i--) { 230 for (i = deg_omega; i >= 0; i--) {
231 if (omega[i] != nn) 231 if (omega[i] != nn)
232 num1 ^= alpha_to[rs_modnn(rs, omega[i] + 232 num1 ^= alpha_to[rs_modnn(rs, omega[i] +
233 i * root[j])]; 233 i * root[j])];
234 } 234 }
235 num2 = alpha_to[rs_modnn(rs, root[j] * (fcr - 1) + nn)]; 235 num2 = alpha_to[rs_modnn(rs, root[j] * (fcr - 1) + nn)];
@@ -239,13 +239,13 @@
239 * lambda_pr of lambda[i] */ 239 * lambda_pr of lambda[i] */
240 for (i = min(deg_lambda, nroots - 1) & ~1; i >= 0; i -= 2) { 240 for (i = min(deg_lambda, nroots - 1) & ~1; i >= 0; i -= 2) {
241 if (lambda[i + 1] != nn) { 241 if (lambda[i + 1] != nn) {
242 den ^= alpha_to[rs_modnn(rs, lambda[i + 1] + 242 den ^= alpha_to[rs_modnn(rs, lambda[i + 1] +
243 i * root[j])]; 243 i * root[j])];
244 } 244 }
245 } 245 }
246 /* Apply error to data */ 246 /* Apply error to data */
247 if (num1 != 0 && loc[j] >= pad) { 247 if (num1 != 0 && loc[j] >= pad) {
248 uint16_t cor = alpha_to[rs_modnn(rs,index_of[num1] + 248 uint16_t cor = alpha_to[rs_modnn(rs,index_of[num1] +
249 index_of[num2] + 249 index_of[num2] +
250 nn - index_of[den])]; 250 nn - index_of[den])];
251 /* Store the error correction pattern, if a 251 /* Store the error correction pattern, if a
diff --git a/lib/reed_solomon/encode_rs.c b/lib/reed_solomon/encode_rs.c
index 237bf65ae886..0b5b1a6728ec 100644
--- a/lib/reed_solomon/encode_rs.c
+++ b/lib/reed_solomon/encode_rs.c
@@ -1,19 +1,19 @@
1/* 1/*
2 * lib/reed_solomon/encode_rs.c 2 * lib/reed_solomon/encode_rs.c
3 * 3 *
4 * Overview: 4 * Overview:
5 * Generic Reed Solomon encoder / decoder library 5 * Generic Reed Solomon encoder / decoder library
6 * 6 *
7 * Copyright 2002, Phil Karn, KA9Q 7 * Copyright 2002, Phil Karn, KA9Q
8 * May be used under the terms of the GNU General Public License (GPL) 8 * May be used under the terms of the GNU General Public License (GPL)
9 * 9 *
10 * Adaption to the kernel by Thomas Gleixner (tglx@linutronix.de) 10 * Adaption to the kernel by Thomas Gleixner (tglx@linutronix.de)
11 * 11 *
12 * $Id: encode_rs.c,v 1.4 2004/10/22 15:41:47 gleixner Exp $ 12 * $Id: encode_rs.c,v 1.5 2005/11/07 11:14:59 gleixner Exp $
13 * 13 *
14 */ 14 */
15 15
16/* Generic data width independent code which is included by the 16/* Generic data width independent code which is included by the
17 * wrappers. 17 * wrappers.
18 * int encode_rsX (struct rs_control *rs, uintX_t *data, int len, uintY_t *par) 18 * int encode_rsX (struct rs_control *rs, uintX_t *data, int len, uintY_t *par)
19 */ 19 */
@@ -35,16 +35,16 @@
35 for (i = 0; i < len; i++) { 35 for (i = 0; i < len; i++) {
36 fb = index_of[((((uint16_t) data[i])^invmsk) & msk) ^ par[0]]; 36 fb = index_of[((((uint16_t) data[i])^invmsk) & msk) ^ par[0]];
37 /* feedback term is non-zero */ 37 /* feedback term is non-zero */
38 if (fb != nn) { 38 if (fb != nn) {
39 for (j = 1; j < nroots; j++) { 39 for (j = 1; j < nroots; j++) {
40 par[j] ^= alpha_to[rs_modnn(rs, fb + 40 par[j] ^= alpha_to[rs_modnn(rs, fb +
41 genpoly[nroots - j])]; 41 genpoly[nroots - j])];
42 } 42 }
43 } 43 }
44 /* Shift */ 44 /* Shift */
45 memmove(&par[0], &par[1], sizeof(uint16_t) * (nroots - 1)); 45 memmove(&par[0], &par[1], sizeof(uint16_t) * (nroots - 1));
46 if (fb != nn) { 46 if (fb != nn) {
47 par[nroots - 1] = alpha_to[rs_modnn(rs, 47 par[nroots - 1] = alpha_to[rs_modnn(rs,
48 fb + genpoly[0])]; 48 fb + genpoly[0])];
49 } else { 49 } else {
50 par[nroots - 1] = 0; 50 par[nroots - 1] = 0;
diff --git a/lib/reed_solomon/reed_solomon.c b/lib/reed_solomon/reed_solomon.c
index 6604e3b1940c..f5fef948a415 100644
--- a/lib/reed_solomon/reed_solomon.c
+++ b/lib/reed_solomon/reed_solomon.c
@@ -1,22 +1,22 @@
1/* 1/*
2 * lib/reed_solomon/rslib.c 2 * lib/reed_solomon/rslib.c
3 * 3 *
4 * Overview: 4 * Overview:
5 * Generic Reed Solomon encoder / decoder library 5 * Generic Reed Solomon encoder / decoder library
6 * 6 *
7 * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de) 7 * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
8 * 8 *
9 * Reed Solomon code lifted from reed solomon library written by Phil Karn 9 * Reed Solomon code lifted from reed solomon library written by Phil Karn
10 * Copyright 2002 Phil Karn, KA9Q 10 * Copyright 2002 Phil Karn, KA9Q
11 * 11 *
12 * $Id: rslib.c,v 1.5 2004/10/22 15:41:47 gleixner Exp $ 12 * $Id: rslib.c,v 1.7 2005/11/07 11:14:59 gleixner Exp $
13 * 13 *
14 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as 15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation. 16 * published by the Free Software Foundation.
17 * 17 *
18 * Description: 18 * Description:
19 * 19 *
20 * The generic Reed Solomon library provides runtime configurable 20 * The generic Reed Solomon library provides runtime configurable
21 * encoding / decoding of RS codes. 21 * encoding / decoding of RS codes.
22 * Each user must call init_rs to get a pointer to a rs_control 22 * Each user must call init_rs to get a pointer to a rs_control
@@ -25,11 +25,11 @@
25 * If a structure is generated then the polynomial arrays for 25 * If a structure is generated then the polynomial arrays for
26 * fast encoding / decoding are built. This can take some time so 26 * fast encoding / decoding are built. This can take some time so
27 * make sure not to call this function from a time critical path. 27 * make sure not to call this function from a time critical path.
28 * Usually a module / driver should initialize the necessary 28 * Usually a module / driver should initialize the necessary
29 * rs_control structure on module / driver init and release it 29 * rs_control structure on module / driver init and release it
30 * on exit. 30 * on exit.
31 * The encoding puts the calculated syndrome into a given syndrome 31 * The encoding puts the calculated syndrome into a given syndrome
32 * buffer. 32 * buffer.
33 * The decoding is a two step process. The first step calculates 33 * The decoding is a two step process. The first step calculates
34 * the syndrome over the received (data + syndrome) and calls the 34 * the syndrome over the received (data + syndrome) and calls the
35 * second stage, which does the decoding / error correction itself. 35 * second stage, which does the decoding / error correction itself.
@@ -51,7 +51,7 @@ static LIST_HEAD (rslist);
51/* Protection for the list */ 51/* Protection for the list */
52static DECLARE_MUTEX(rslistlock); 52static DECLARE_MUTEX(rslistlock);
53 53
54/** 54/**
55 * rs_init - Initialize a Reed-Solomon codec 55 * rs_init - Initialize a Reed-Solomon codec
56 * 56 *
57 * @symsize: symbol size, bits (1-8) 57 * @symsize: symbol size, bits (1-8)
@@ -63,7 +63,7 @@ static DECLARE_MUTEX(rslistlock);
63 * Allocate a control structure and the polynom arrays for faster 63 * Allocate a control structure and the polynom arrays for faster
64 * en/decoding. Fill the arrays according to the given parameters 64 * en/decoding. Fill the arrays according to the given parameters
65 */ 65 */
66static struct rs_control *rs_init(int symsize, int gfpoly, int fcr, 66static struct rs_control *rs_init(int symsize, int gfpoly, int fcr,
67 int prim, int nroots) 67 int prim, int nroots)
68{ 68{
69 struct rs_control *rs; 69 struct rs_control *rs;
@@ -124,15 +124,15 @@ static struct rs_control *rs_init(int symsize, int gfpoly, int fcr,
124 /* Multiply rs->genpoly[] by @**(root + x) */ 124 /* Multiply rs->genpoly[] by @**(root + x) */
125 for (j = i; j > 0; j--) { 125 for (j = i; j > 0; j--) {
126 if (rs->genpoly[j] != 0) { 126 if (rs->genpoly[j] != 0) {
127 rs->genpoly[j] = rs->genpoly[j -1] ^ 127 rs->genpoly[j] = rs->genpoly[j -1] ^
128 rs->alpha_to[rs_modnn(rs, 128 rs->alpha_to[rs_modnn(rs,
129 rs->index_of[rs->genpoly[j]] + root)]; 129 rs->index_of[rs->genpoly[j]] + root)];
130 } else 130 } else
131 rs->genpoly[j] = rs->genpoly[j - 1]; 131 rs->genpoly[j] = rs->genpoly[j - 1];
132 } 132 }
133 /* rs->genpoly[0] can never be zero */ 133 /* rs->genpoly[0] can never be zero */
134 rs->genpoly[0] = 134 rs->genpoly[0] =
135 rs->alpha_to[rs_modnn(rs, 135 rs->alpha_to[rs_modnn(rs,
136 rs->index_of[rs->genpoly[0]] + root)]; 136 rs->index_of[rs->genpoly[0]] + root)];
137 } 137 }
138 /* convert rs->genpoly[] to index form for quicker encoding */ 138 /* convert rs->genpoly[] to index form for quicker encoding */
@@ -153,7 +153,7 @@ errrs:
153} 153}
154 154
155 155
156/** 156/**
157 * free_rs - Free the rs control structure, if its not longer used 157 * free_rs - Free the rs control structure, if its not longer used
158 * 158 *
159 * @rs: the control structure which is not longer used by the 159 * @rs: the control structure which is not longer used by the
@@ -173,19 +173,19 @@ void free_rs(struct rs_control *rs)
173 up(&rslistlock); 173 up(&rslistlock);
174} 174}
175 175
176/** 176/**
177 * init_rs - Find a matching or allocate a new rs control structure 177 * init_rs - Find a matching or allocate a new rs control structure
178 * 178 *
179 * @symsize: the symbol size (number of bits) 179 * @symsize: the symbol size (number of bits)
180 * @gfpoly: the extended Galois field generator polynomial coefficients, 180 * @gfpoly: the extended Galois field generator polynomial coefficients,
181 * with the 0th coefficient in the low order bit. The polynomial 181 * with the 0th coefficient in the low order bit. The polynomial
182 * must be primitive; 182 * must be primitive;
183 * @fcr: the first consecutive root of the rs code generator polynomial 183 * @fcr: the first consecutive root of the rs code generator polynomial
184 * in index form 184 * in index form
185 * @prim: primitive element to generate polynomial roots 185 * @prim: primitive element to generate polynomial roots
186 * @nroots: RS code generator polynomial degree (number of roots) 186 * @nroots: RS code generator polynomial degree (number of roots)
187 */ 187 */
188struct rs_control *init_rs(int symsize, int gfpoly, int fcr, int prim, 188struct rs_control *init_rs(int symsize, int gfpoly, int fcr, int prim,
189 int nroots) 189 int nroots)
190{ 190{
191 struct list_head *tmp; 191 struct list_head *tmp;
@@ -198,9 +198,9 @@ struct rs_control *init_rs(int symsize, int gfpoly, int fcr, int prim,
198 return NULL; 198 return NULL;
199 if (prim <= 0 || prim >= (1<<symsize)) 199 if (prim <= 0 || prim >= (1<<symsize))
200 return NULL; 200 return NULL;
201 if (nroots < 0 || nroots >= (1<<symsize) || nroots > 8) 201 if (nroots < 0 || nroots >= (1<<symsize))
202 return NULL; 202 return NULL;
203 203
204 down(&rslistlock); 204 down(&rslistlock);
205 205
206 /* Walk through the list and look for a matching entry */ 206 /* Walk through the list and look for a matching entry */
@@ -211,9 +211,9 @@ struct rs_control *init_rs(int symsize, int gfpoly, int fcr, int prim,
211 if (gfpoly != rs->gfpoly) 211 if (gfpoly != rs->gfpoly)
212 continue; 212 continue;
213 if (fcr != rs->fcr) 213 if (fcr != rs->fcr)
214 continue; 214 continue;
215 if (prim != rs->prim) 215 if (prim != rs->prim)
216 continue; 216 continue;
217 if (nroots != rs->nroots) 217 if (nroots != rs->nroots)
218 continue; 218 continue;
219 /* We have a matching one already */ 219 /* We have a matching one already */
@@ -227,18 +227,18 @@ struct rs_control *init_rs(int symsize, int gfpoly, int fcr, int prim,
227 rs->users = 1; 227 rs->users = 1;
228 list_add(&rs->list, &rslist); 228 list_add(&rs->list, &rslist);
229 } 229 }
230out: 230out:
231 up(&rslistlock); 231 up(&rslistlock);
232 return rs; 232 return rs;
233} 233}
234 234
235#ifdef CONFIG_REED_SOLOMON_ENC8 235#ifdef CONFIG_REED_SOLOMON_ENC8
236/** 236/**
237 * encode_rs8 - Calculate the parity for data values (8bit data width) 237 * encode_rs8 - Calculate the parity for data values (8bit data width)
238 * 238 *
239 * @rs: the rs control structure 239 * @rs: the rs control structure
240 * @data: data field of a given type 240 * @data: data field of a given type
241 * @len: data length 241 * @len: data length
242 * @par: parity data, must be initialized by caller (usually all 0) 242 * @par: parity data, must be initialized by caller (usually all 0)
243 * @invmsk: invert data mask (will be xored on data) 243 * @invmsk: invert data mask (will be xored on data)
244 * 244 *
@@ -246,7 +246,7 @@ out:
246 * symbol size > 8. The calling code must take care of encoding of the 246 * symbol size > 8. The calling code must take care of encoding of the
247 * syndrome result for storage itself. 247 * syndrome result for storage itself.
248 */ 248 */
249int encode_rs8(struct rs_control *rs, uint8_t *data, int len, uint16_t *par, 249int encode_rs8(struct rs_control *rs, uint8_t *data, int len, uint16_t *par,
250 uint16_t invmsk) 250 uint16_t invmsk)
251{ 251{
252#include "encode_rs.c" 252#include "encode_rs.c"
@@ -255,7 +255,7 @@ EXPORT_SYMBOL_GPL(encode_rs8);
255#endif 255#endif
256 256
257#ifdef CONFIG_REED_SOLOMON_DEC8 257#ifdef CONFIG_REED_SOLOMON_DEC8
258/** 258/**
259 * decode_rs8 - Decode codeword (8bit data width) 259 * decode_rs8 - Decode codeword (8bit data width)
260 * 260 *
261 * @rs: the rs control structure 261 * @rs: the rs control structure
@@ -273,7 +273,7 @@ EXPORT_SYMBOL_GPL(encode_rs8);
273 * syndrome result and the received parity before calling this code. 273 * syndrome result and the received parity before calling this code.
274 */ 274 */
275int decode_rs8(struct rs_control *rs, uint8_t *data, uint16_t *par, int len, 275int decode_rs8(struct rs_control *rs, uint8_t *data, uint16_t *par, int len,
276 uint16_t *s, int no_eras, int *eras_pos, uint16_t invmsk, 276 uint16_t *s, int no_eras, int *eras_pos, uint16_t invmsk,
277 uint16_t *corr) 277 uint16_t *corr)
278{ 278{
279#include "decode_rs.c" 279#include "decode_rs.c"
@@ -287,13 +287,13 @@ EXPORT_SYMBOL_GPL(decode_rs8);
287 * 287 *
288 * @rs: the rs control structure 288 * @rs: the rs control structure
289 * @data: data field of a given type 289 * @data: data field of a given type
290 * @len: data length 290 * @len: data length
291 * @par: parity data, must be initialized by caller (usually all 0) 291 * @par: parity data, must be initialized by caller (usually all 0)
292 * @invmsk: invert data mask (will be xored on data, not on parity!) 292 * @invmsk: invert data mask (will be xored on data, not on parity!)
293 * 293 *
294 * Each field in the data array contains up to symbol size bits of valid data. 294 * Each field in the data array contains up to symbol size bits of valid data.
295 */ 295 */
296int encode_rs16(struct rs_control *rs, uint16_t *data, int len, uint16_t *par, 296int encode_rs16(struct rs_control *rs, uint16_t *data, int len, uint16_t *par,
297 uint16_t invmsk) 297 uint16_t invmsk)
298{ 298{
299#include "encode_rs.c" 299#include "encode_rs.c"
@@ -302,7 +302,7 @@ EXPORT_SYMBOL_GPL(encode_rs16);
302#endif 302#endif
303 303
304#ifdef CONFIG_REED_SOLOMON_DEC16 304#ifdef CONFIG_REED_SOLOMON_DEC16
305/** 305/**
306 * decode_rs16 - Decode codeword (16bit data width) 306 * decode_rs16 - Decode codeword (16bit data width)
307 * 307 *
308 * @rs: the rs control structure 308 * @rs: the rs control structure
@@ -312,13 +312,13 @@ EXPORT_SYMBOL_GPL(encode_rs16);
312 * @s: syndrome data field (if NULL, syndrome is calculated) 312 * @s: syndrome data field (if NULL, syndrome is calculated)
313 * @no_eras: number of erasures 313 * @no_eras: number of erasures
314 * @eras_pos: position of erasures, can be NULL 314 * @eras_pos: position of erasures, can be NULL
315 * @invmsk: invert data mask (will be xored on data, not on parity!) 315 * @invmsk: invert data mask (will be xored on data, not on parity!)
316 * @corr: buffer to store correction bitmask on eras_pos 316 * @corr: buffer to store correction bitmask on eras_pos
317 * 317 *
318 * Each field in the data array contains up to symbol size bits of valid data. 318 * Each field in the data array contains up to symbol size bits of valid data.
319 */ 319 */
320int decode_rs16(struct rs_control *rs, uint16_t *data, uint16_t *par, int len, 320int decode_rs16(struct rs_control *rs, uint16_t *data, uint16_t *par, int len,
321 uint16_t *s, int no_eras, int *eras_pos, uint16_t invmsk, 321 uint16_t *s, int no_eras, int *eras_pos, uint16_t invmsk,
322 uint16_t *corr) 322 uint16_t *corr)
323{ 323{
324#include "decode_rs.c" 324#include "decode_rs.c"