aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/Kconfig32
-rw-r--r--drivers/mtd/afs.c16
-rw-r--r--drivers/mtd/cmdlinepart.c56
-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/mtd_blkdevs.c24
-rw-r--r--drivers/mtd/mtdblock.c44
-rw-r--r--drivers/mtd/mtdchar.c60
-rw-r--r--drivers/mtd/mtdconcat.c6
-rw-r--r--drivers/mtd/mtdcore.c18
-rw-r--r--drivers/mtd/mtdpart.c92
-rw-r--r--drivers/mtd/nftlcore.c80
-rw-r--r--drivers/mtd/nftlmount.c56
-rw-r--r--drivers/mtd/redboot.c4
-rw-r--r--drivers/mtd/rfd_ftl.c114
16 files changed, 399 insertions, 399 deletions
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 3dbfbafb3481..f6b775e63ac8 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -1,4 +1,4 @@
1# $Id: Kconfig,v 1.10 2005/07/11 10:39:27 gleixner 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
@@ -257,8 +257,8 @@ config RFD_FTL
257 tristate "Resident Flash Disk (Flash Translation Layer) support" 257 tristate "Resident Flash Disk (Flash Translation Layer) support"
258 depends on MTD 258 depends on MTD
259 ---help--- 259 ---help---
260 This provides support for the flash translation layer known 260 This provides support for the flash translation layer known
261 as the Resident Flash Disk (RFD), as used by the Embedded BIOS 261 as the Resident Flash Disk (RFD), as used by the Embedded BIOS
262 of General Software. There is a blurb at: 262 of General Software. There is a blurb at:
263 263
264 http://www.gensw.com/pages/prod/bios/rfd.htm 264 http://www.gensw.com/pages/prod/bios/rfd.htm
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/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/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 39eb53f6551f..8db8618c18d2 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 }
@@ -223,7 +223,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
223 "Virtual Unit Chain %d!\n", thisVUC); 223 "Virtual Unit Chain %d!\n", thisVUC);
224 return BLOCK_NIL; 224 return BLOCK_NIL;
225 } 225 }
226 226
227 /* 227 /*
228 * Scan to find the Erase Unit which holds the actual data for each 228 * Scan to find the Erase Unit which holds the actual data for each
229 * 512-byte block within the Chain. 229 * 512-byte block within the Chain.
@@ -264,7 +264,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
264 "Unit Chain 0x%x\n", thisVUC); 264 "Unit Chain 0x%x\n", thisVUC);
265 return BLOCK_NIL; 265 return BLOCK_NIL;
266 } 266 }
267 267
268 thisEUN = inftl->PUtable[thisEUN]; 268 thisEUN = inftl->PUtable[thisEUN];
269 } 269 }
270 270
@@ -295,15 +295,15 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
295 */ 295 */
296 if (BlockMap[block] == BLOCK_NIL) 296 if (BlockMap[block] == BLOCK_NIL)
297 continue; 297 continue;
298 298
299 ret = MTD_READ(inftl->mbd.mtd, (inftl->EraseSize * 299 ret = MTD_READ(inftl->mbd.mtd, (inftl->EraseSize *
300 BlockMap[block]) + (block * SECTORSIZE), SECTORSIZE, 300 BlockMap[block]) + (block * SECTORSIZE), SECTORSIZE,
301 &retlen, movebuf); 301 &retlen, movebuf);
302 if (ret < 0) { 302 if (ret < 0) {
303 ret = MTD_READ(inftl->mbd.mtd, (inftl->EraseSize * 303 ret = MTD_READ(inftl->mbd.mtd, (inftl->EraseSize *
304 BlockMap[block]) + (block * SECTORSIZE), 304 BlockMap[block]) + (block * SECTORSIZE),
305 SECTORSIZE, &retlen, movebuf); 305 SECTORSIZE, &retlen, movebuf);
306 if (ret != -EIO) 306 if (ret != -EIO)
307 DEBUG(MTD_DEBUG_LEVEL1, "INFTL: error went " 307 DEBUG(MTD_DEBUG_LEVEL1, "INFTL: error went "
308 "away on retry?\n"); 308 "away on retry?\n");
309 } 309 }
@@ -355,7 +355,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
355static u16 INFTL_makefreeblock(struct INFTLrecord *inftl, unsigned pendingblock) 355static u16 INFTL_makefreeblock(struct INFTLrecord *inftl, unsigned pendingblock)
356{ 356{
357 /* 357 /*
358 * This is the part that needs some cleverness applied. 358 * This is the part that needs some cleverness applied.
359 * For now, I'm doing the minimum applicable to actually 359 * For now, I'm doing the minimum applicable to actually
360 * get the thing to work. 360 * get the thing to work.
361 * Wear-levelling and other clever stuff needs to be implemented 361 * Wear-levelling and other clever stuff needs to be implemented
@@ -414,7 +414,7 @@ static int nrbits(unsigned int val, int bitcount)
414} 414}
415 415
416/* 416/*
417 * INFTL_findwriteunit: Return the unit number into which we can write 417 * INFTL_findwriteunit: Return the unit number into which we can write
418 * for this block. Make it available if it isn't already. 418 * for this block. Make it available if it isn't already.
419 */ 419 */
420static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block) 420static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
@@ -463,10 +463,10 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
463 * Invalid block. Don't use it any more. 463 * Invalid block. Don't use it any more.
464 * Must implement. 464 * Must implement.
465 */ 465 */
466 break; 466 break;
467 } 467 }
468 468
469 if (!silly--) { 469 if (!silly--) {
470 printk(KERN_WARNING "INFTL: infinite loop in " 470 printk(KERN_WARNING "INFTL: infinite loop in "
471 "Virtual Unit Chain 0x%x\n", thisVUC); 471 "Virtual Unit Chain 0x%x\n", thisVUC);
472 return 0xffff; 472 return 0xffff;
@@ -482,7 +482,7 @@ hitused:
482 482
483 483
484 /* 484 /*
485 * OK. We didn't find one in the existing chain, or there 485 * OK. We didn't find one in the existing chain, or there
486 * is no existing chain. Allocate a new one. 486 * is no existing chain. Allocate a new one.
487 */ 487 */
488 writeEUN = INFTL_findfreeblock(inftl, 0); 488 writeEUN = INFTL_findfreeblock(inftl, 0);
@@ -506,8 +506,8 @@ hitused:
506 if (writeEUN == BLOCK_NIL) { 506 if (writeEUN == BLOCK_NIL) {
507 /* 507 /*
508 * Ouch. This should never happen - we should 508 * Ouch. This should never happen - we should
509 * always be able to make some room somehow. 509 * always be able to make some room somehow.
510 * If we get here, we've allocated more storage 510 * If we get here, we've allocated more storage
511 * space than actual media, or our makefreeblock 511 * space than actual media, or our makefreeblock
512 * routine is missing something. 512 * routine is missing something.
513 */ 513 */
@@ -518,7 +518,7 @@ hitused:
518 INFTL_dumpVUchains(inftl); 518 INFTL_dumpVUchains(inftl);
519#endif 519#endif
520 return BLOCK_NIL; 520 return BLOCK_NIL;
521 } 521 }
522 } 522 }
523 523
524 /* 524 /*
@@ -543,7 +543,7 @@ hitused:
543 parity |= (nrbits(prev_block, 16) & 0x1) ? 0x2 : 0; 543 parity |= (nrbits(prev_block, 16) & 0x1) ? 0x2 : 0;
544 parity |= (nrbits(anac, 8) & 0x1) ? 0x4 : 0; 544 parity |= (nrbits(anac, 8) & 0x1) ? 0x4 : 0;
545 parity |= (nrbits(nacs, 8) & 0x1) ? 0x8 : 0; 545 parity |= (nrbits(nacs, 8) & 0x1) ? 0x8 : 0;
546 546
547 oob.u.a.virtualUnitNo = cpu_to_le16(thisVUC); 547 oob.u.a.virtualUnitNo = cpu_to_le16(thisVUC);
548 oob.u.a.prevUnitNo = cpu_to_le16(prev_block); 548 oob.u.a.prevUnitNo = cpu_to_le16(prev_block);
549 oob.u.a.ANAC = anac; 549 oob.u.a.ANAC = anac;
@@ -562,7 +562,7 @@ hitused:
562 oob.u.b.parityPerField = parity; 562 oob.u.b.parityPerField = parity;
563 oob.u.b.discarded = 0xaa; 563 oob.u.b.discarded = 0xaa;
564 564
565 MTD_WRITEOOB(inftl->mbd.mtd, writeEUN * inftl->EraseSize + 565 MTD_WRITEOOB(inftl->mbd.mtd, writeEUN * inftl->EraseSize +
566 SECTORSIZE * 4 + 8, 8, &retlen, (char *)&oob.u); 566 SECTORSIZE * 4 + 8, 8, &retlen, (char *)&oob.u);
567 567
568 inftl->PUtable[writeEUN] = inftl->VUtable[thisVUC]; 568 inftl->PUtable[writeEUN] = inftl->VUtable[thisVUC];
@@ -602,7 +602,7 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
602 "Virtual Unit Chain %d!\n", thisVUC); 602 "Virtual Unit Chain %d!\n", thisVUC);
603 return; 603 return;
604 } 604 }
605 605
606 /* 606 /*
607 * Scan through the Erase Units to determine whether any data is in 607 * Scan through the Erase Units to determine whether any data is in
608 * each of the 512-byte blocks within the Chain. 608 * each of the 512-byte blocks within the Chain.
@@ -642,7 +642,7 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
642 "Unit Chain 0x%x\n", thisVUC); 642 "Unit Chain 0x%x\n", thisVUC);
643 return; 643 return;
644 } 644 }
645 645
646 thisEUN = inftl->PUtable[thisEUN]; 646 thisEUN = inftl->PUtable[thisEUN];
647 } 647 }
648 648
@@ -758,7 +758,7 @@ foundit:
758 return 0; 758 return 0;
759} 759}
760 760
761static int inftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block, 761static int inftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block,
762 char *buffer) 762 char *buffer)
763{ 763{
764 struct INFTLrecord *inftl = (void *)mbd; 764 struct INFTLrecord *inftl = (void *)mbd;
@@ -893,7 +893,7 @@ extern char inftlmountrev[];
893 893
894static int __init init_inftl(void) 894static int __init init_inftl(void)
895{ 895{
896 printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.18 $, " 896 printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.19 $, "
897 "inftlmount.c %s\n", inftlmountrev); 897 "inftlmount.c %s\n", inftlmountrev);
898 898
899 return register_mtd_blktrans(&inftl_tr); 899 return register_mtd_blktrans(&inftl_tr);
diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c
index e066445320a3..b26aea1f640a 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.17 2005/08/08 08:56:19 dwmw2 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.17 $"; 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{
@@ -578,7 +578,7 @@ int INFTL_mount(struct INFTLrecord *s)
578 printk(KERN_ERR "INFTL: Out of memory.\n"); 578 printk(KERN_ERR "INFTL: Out of memory.\n");
579 return -ENOMEM; 579 return -ENOMEM;
580 } 580 }
581 581
582 memset(ANACtable, 0, s->nb_blocks); 582 memset(ANACtable, 0, s->nb_blocks);
583 583
584 /* 584 /*
@@ -600,7 +600,7 @@ int INFTL_mount(struct INFTLrecord *s)
600 600
601 for (chain_length = 0; ; chain_length++) { 601 for (chain_length = 0; ; chain_length++) {
602 602
603 if ((chain_length == 0) && 603 if ((chain_length == 0) &&
604 (s->PUtable[block] != BLOCK_NOTEXPLORED)) { 604 (s->PUtable[block] != BLOCK_NOTEXPLORED)) {
605 /* Nothing to do here, onto next block */ 605 /* Nothing to do here, onto next block */
606 break; 606 break;
@@ -747,7 +747,7 @@ int INFTL_mount(struct INFTLrecord *s)
747 "in virtual chain %d\n", 747 "in virtual chain %d\n",
748 s->PUtable[block], logical_block); 748 s->PUtable[block], logical_block);
749 s->PUtable[block] = BLOCK_NIL; 749 s->PUtable[block] = BLOCK_NIL;
750 750
751 } 751 }
752 if (ANACtable[block] != ANAC) { 752 if (ANACtable[block] != ANAC) {
753 /* 753 /*
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index d6cb3d194efb..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.26 2005/07/29 19:42:04 tpoynor 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 *
@@ -85,7 +85,7 @@ static int mtd_blktrans_thread(void *arg)
85 daemonize("%sd", tr->name); 85 daemonize("%sd", tr->name);
86 86
87 /* daemonize() doesn't do this for us since some kernel threads 87 /* daemonize() doesn't do this for us since some kernel threads
88 actually want to deal with signals. We can't just call 88 actually want to deal with signals. We can't just call
89 exit_sighand() since that'll cause an oops when we finally 89 exit_sighand() since that'll cause an oops when we finally
90 do exit. */ 90 do exit. */
91 spin_lock_irq(&current->sighand->siglock); 91 spin_lock_irq(&current->sighand->siglock);
@@ -94,7 +94,7 @@ static int mtd_blktrans_thread(void *arg)
94 spin_unlock_irq(&current->sighand->siglock); 94 spin_unlock_irq(&current->sighand->siglock);
95 95
96 spin_lock_irq(rq->queue_lock); 96 spin_lock_irq(rq->queue_lock);
97 97
98 while (!tr->blkcore_priv->exiting) { 98 while (!tr->blkcore_priv->exiting) {
99 struct request *req; 99 struct request *req;
100 struct mtd_blktrans_dev *dev; 100 struct mtd_blktrans_dev *dev;
@@ -157,7 +157,7 @@ static int blktrans_open(struct inode *i, struct file *f)
157 if (!try_module_get(tr->owner)) 157 if (!try_module_get(tr->owner))
158 goto out_tr; 158 goto out_tr;
159 159
160 /* FIXME: Locking. A hot pluggable device can go away 160 /* FIXME: Locking. A hot pluggable device can go away
161 (del_mtd_device can be called for it) without its module 161 (del_mtd_device can be called for it) without its module
162 being unloaded. */ 162 being unloaded. */
163 dev->mtd->usecount++; 163 dev->mtd->usecount++;
@@ -195,7 +195,7 @@ static int blktrans_release(struct inode *i, struct file *f)
195} 195}
196 196
197 197
198static int blktrans_ioctl(struct inode *inode, struct file *file, 198static int blktrans_ioctl(struct inode *inode, struct file *file,
199 unsigned int cmd, unsigned long arg) 199 unsigned int cmd, unsigned long arg)
200{ 200{
201 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;
@@ -264,7 +264,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
264 /* Required number was free */ 264 /* Required number was free */
265 list_add_tail(&new->list, &d->list); 265 list_add_tail(&new->list, &d->list);
266 goto added; 266 goto added;
267 } 267 }
268 last_devnum = d->devnum; 268 last_devnum = d->devnum;
269 } 269 }
270 if (new->devnum == -1) 270 if (new->devnum == -1)
@@ -288,7 +288,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
288 gd->major = tr->major; 288 gd->major = tr->major;
289 gd->first_minor = (new->devnum) << tr->part_bits; 289 gd->first_minor = (new->devnum) << tr->part_bits;
290 gd->fops = &mtd_blktrans_ops; 290 gd->fops = &mtd_blktrans_ops;
291 291
292 if (tr->part_bits) 292 if (tr->part_bits)
293 if (new->devnum < 26) 293 if (new->devnum < 26)
294 snprintf(gd->disk_name, sizeof(gd->disk_name), 294 snprintf(gd->disk_name, sizeof(gd->disk_name),
@@ -314,7 +314,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
314 set_disk_ro(gd, 1); 314 set_disk_ro(gd, 1);
315 315
316 add_disk(gd); 316 add_disk(gd);
317 317
318 return 0; 318 return 0;
319} 319}
320 320
@@ -329,7 +329,7 @@ int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
329 329
330 del_gendisk(old->blkcore_priv); 330 del_gendisk(old->blkcore_priv);
331 put_disk(old->blkcore_priv); 331 put_disk(old->blkcore_priv);
332 332
333 return 0; 333 return 0;
334} 334}
335 335
@@ -368,12 +368,12 @@ static struct mtd_notifier blktrans_notifier = {
368 .add = blktrans_notify_add, 368 .add = blktrans_notify_add,
369 .remove = blktrans_notify_remove, 369 .remove = blktrans_notify_remove,
370}; 370};
371 371
372int register_mtd_blktrans(struct mtd_blktrans_ops *tr) 372int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
373{ 373{
374 int ret, i; 374 int ret, i;
375 375
376 /* Register the notifier if/when the first device type is 376 /* Register the notifier if/when the first device type is
377 registered, to prevent the link/init ordering from fucking 377 registered, to prevent the link/init ordering from fucking
378 us over. */ 378 us over. */
379 if (!blktrans_notifier.list.next) 379 if (!blktrans_notifier.list.next)
@@ -416,7 +416,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
416 kfree(tr->blkcore_priv); 416 kfree(tr->blkcore_priv);
417 up(&mtd_table_mutex); 417 up(&mtd_table_mutex);
418 return ret; 418 return ret;
419 } 419 }
420 420
421 INIT_LIST_HEAD(&tr->devs); 421 INIT_LIST_HEAD(&tr->devs);
422 list_add(&tr->list, &blktrans_majors); 422 list_add(&tr->list, &blktrans_majors);
diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
index bee8aba9e5bb..e84756644fd1 100644
--- a/drivers/mtd/mtdblock.c
+++ b/drivers/mtd/mtdblock.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Direct MTD block device access 2 * Direct MTD block device access
3 * 3 *
4 * $Id: mtdblock.c,v 1.67 2005/11/06 10:04:37 gleixner 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>
@@ -32,7 +32,7 @@ static struct mtdblk_dev {
32 32
33/* 33/*
34 * Cache stuff... 34 * Cache stuff...
35 * 35 *
36 * 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
37 * 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
38 * 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
@@ -46,7 +46,7 @@ static void erase_callback(struct erase_info *done)
46 wake_up(wait_q); 46 wake_up(wait_q);
47} 47}
48 48
49static int erase_write (struct mtd_info *mtd, unsigned long pos, 49static int erase_write (struct mtd_info *mtd, unsigned long pos,
50 int len, const char *buf) 50 int len, const char *buf)
51{ 51{
52 struct erase_info erase; 52 struct erase_info erase;
@@ -104,18 +104,18 @@ static int write_cached_data (struct mtdblk_dev *mtdblk)
104 return 0; 104 return 0;
105 105
106 DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: writing cached data for \"%s\" " 106 DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: writing cached data for \"%s\" "
107 "at 0x%lx, size 0x%x\n", mtd->name, 107 "at 0x%lx, size 0x%x\n", mtd->name,
108 mtdblk->cache_offset, mtdblk->cache_size); 108 mtdblk->cache_offset, mtdblk->cache_size);
109 109
110 ret = erase_write (mtd, mtdblk->cache_offset, 110 ret = erase_write (mtd, mtdblk->cache_offset,
111 mtdblk->cache_size, mtdblk->cache_data); 111 mtdblk->cache_size, mtdblk->cache_data);
112 if (ret) 112 if (ret)
113 return ret; 113 return ret;
114 114
115 /* 115 /*
116 * Here we could argubly set the cache state to STATE_CLEAN. 116 * Here we could argubly set the cache state to STATE_CLEAN.
117 * However this could lead to inconsistency since we will not 117 * However this could lead to inconsistency since we will not
118 * 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
119 * means. Let's declare it empty and leave buffering tasks to 119 * means. Let's declare it empty and leave buffering tasks to
120 * the buffer cache instead. 120 * the buffer cache instead.
121 */ 121 */
@@ -124,7 +124,7 @@ static int write_cached_data (struct mtdblk_dev *mtdblk)
124} 124}
125 125
126 126
127static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos, 127static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
128 int len, const char *buf) 128 int len, const char *buf)
129{ 129{
130 struct mtd_info *mtd = mtdblk->mtd; 130 struct mtd_info *mtd = mtdblk->mtd;
@@ -134,7 +134,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
134 134
135 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",
136 mtd->name, pos, len); 136 mtd->name, pos, len);
137 137
138 if (!sect_size) 138 if (!sect_size)
139 return MTD_WRITE (mtd, pos, len, &retlen, buf); 139 return MTD_WRITE (mtd, pos, len, &retlen, buf);
140 140
@@ -142,11 +142,11 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
142 unsigned long sect_start = (pos/sect_size)*sect_size; 142 unsigned long sect_start = (pos/sect_size)*sect_size;
143 unsigned int offset = pos - sect_start; 143 unsigned int offset = pos - sect_start;
144 unsigned int size = sect_size - offset; 144 unsigned int size = sect_size - offset;
145 if( size > len ) 145 if( size > len )
146 size = len; 146 size = len;
147 147
148 if (size == sect_size) { 148 if (size == sect_size) {
149 /* 149 /*
150 * We are covering a whole sector. Thus there is no 150 * We are covering a whole sector. Thus there is no
151 * need to bother with the cache while it may still be 151 * need to bother with the cache while it may still be
152 * useful for other partial writes. 152 * useful for other partial writes.
@@ -160,7 +160,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
160 if (mtdblk->cache_state == STATE_DIRTY && 160 if (mtdblk->cache_state == STATE_DIRTY &&
161 mtdblk->cache_offset != sect_start) { 161 mtdblk->cache_offset != sect_start) {
162 ret = write_cached_data(mtdblk); 162 ret = write_cached_data(mtdblk);
163 if (ret) 163 if (ret)
164 return ret; 164 return ret;
165 } 165 }
166 166
@@ -193,7 +193,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
193} 193}
194 194
195 195
196static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos, 196static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
197 int len, char *buf) 197 int len, char *buf)
198{ 198{
199 struct mtd_info *mtd = mtdblk->mtd; 199 struct mtd_info *mtd = mtdblk->mtd;
@@ -201,9 +201,9 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
201 size_t retlen; 201 size_t retlen;
202 int ret; 202 int ret;
203 203
204 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",
205 mtd->name, pos, len); 205 mtd->name, pos, len);
206 206
207 if (!sect_size) 207 if (!sect_size)
208 return MTD_READ (mtd, pos, len, &retlen, buf); 208 return MTD_READ (mtd, pos, len, &retlen, buf);
209 209
@@ -211,7 +211,7 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
211 unsigned long sect_start = (pos/sect_size)*sect_size; 211 unsigned long sect_start = (pos/sect_size)*sect_size;
212 unsigned int offset = pos - sect_start; 212 unsigned int offset = pos - sect_start;
213 unsigned int size = sect_size - offset; 213 unsigned int size = sect_size - offset;
214 if (size > len) 214 if (size > len)
215 size = len; 215 size = len;
216 216
217 /* 217 /*
@@ -269,12 +269,12 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
269 int dev = mbd->devnum; 269 int dev = mbd->devnum;
270 270
271 DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n"); 271 DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n");
272 272
273 if (mtdblks[dev]) { 273 if (mtdblks[dev]) {
274 mtdblks[dev]->count++; 274 mtdblks[dev]->count++;
275 return 0; 275 return 0;
276 } 276 }
277 277
278 /* OK, it's not open. Create cache info for it */ 278 /* OK, it's not open. Create cache info for it */
279 mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL); 279 mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL);
280 if (!mtdblk) 280 if (!mtdblk)
@@ -293,7 +293,7 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
293 } 293 }
294 294
295 mtdblks[dev] = mtdblk; 295 mtdblks[dev] = mtdblk;
296 296
297 DEBUG(MTD_DEBUG_LEVEL1, "ok\n"); 297 DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
298 298
299 return 0; 299 return 0;
@@ -321,7 +321,7 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd)
321 DEBUG(MTD_DEBUG_LEVEL1, "ok\n"); 321 DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
322 322
323 return 0; 323 return 0;
324} 324}
325 325
326static int mtdblock_flush(struct mtd_blktrans_dev *dev) 326static int mtdblock_flush(struct mtd_blktrans_dev *dev)
327{ 327{
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index d1ffd246ad55..6f044584bdc6 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: mtdchar.c,v 1.75 2005/11/06 10:04:37 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 *
@@ -28,7 +28,7 @@ static void mtd_notify_add(struct mtd_info* mtd)
28 28
29 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),
30 NULL, "mtd%d", mtd->index); 30 NULL, "mtd%d", mtd->index);
31 31
32 class_device_create(mtd_class, NULL, 32 class_device_create(mtd_class, NULL,
33 MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1), 33 MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
34 NULL, "mtd%dro", mtd->index); 34 NULL, "mtd%dro", mtd->index);
@@ -108,23 +108,23 @@ static int mtd_open(struct inode *inode, struct file *file)
108 return -EACCES; 108 return -EACCES;
109 109
110 mtd = get_mtd_device(NULL, devnum); 110 mtd = get_mtd_device(NULL, devnum);
111 111
112 if (!mtd) 112 if (!mtd)
113 return -ENODEV; 113 return -ENODEV;
114 114
115 if (MTD_ABSENT == mtd->type) { 115 if (MTD_ABSENT == mtd->type) {
116 put_mtd_device(mtd); 116 put_mtd_device(mtd);
117 return -ENODEV; 117 return -ENODEV;
118 } 118 }
119 119
120 file->private_data = mtd; 120 file->private_data = mtd;
121 121
122 /* 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 */
123 if ((file->f_mode & 2) && !(mtd->flags & MTD_WRITEABLE)) { 123 if ((file->f_mode & 2) && !(mtd->flags & MTD_WRITEABLE)) {
124 put_mtd_device(mtd); 124 put_mtd_device(mtd);
125 return -EACCES; 125 return -EACCES;
126 } 126 }
127 127
128 return 0; 128 return 0;
129} /* mtd_open */ 129} /* mtd_open */
130 130
@@ -137,10 +137,10 @@ static int mtd_close(struct inode *inode, struct file *file)
137 DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n"); 137 DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n");
138 138
139 mtd = TO_MTD(file); 139 mtd = TO_MTD(file);
140 140
141 if (mtd->sync) 141 if (mtd->sync)
142 mtd->sync(mtd); 142 mtd->sync(mtd);
143 143
144 put_mtd_device(mtd); 144 put_mtd_device(mtd);
145 145
146 return 0; 146 return 0;
@@ -159,7 +159,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
159 int ret=0; 159 int ret=0;
160 int len; 160 int len;
161 char *kbuf; 161 char *kbuf;
162 162
163 DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n"); 163 DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n");
164 164
165 if (*ppos + count > mtd->size) 165 if (*ppos + count > mtd->size)
@@ -167,11 +167,11 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
167 167
168 if (!count) 168 if (!count)
169 return 0; 169 return 0;
170 170
171 /* 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
172 and pass them directly to the MTD functions */ 172 and pass them directly to the MTD functions */
173 while (count) { 173 while (count) {
174 if (count > MAX_KMALLOC_SIZE) 174 if (count > MAX_KMALLOC_SIZE)
175 len = MAX_KMALLOC_SIZE; 175 len = MAX_KMALLOC_SIZE;
176 else 176 else
177 len = count; 177 len = count;
@@ -179,7 +179,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
179 kbuf=kmalloc(len,GFP_KERNEL); 179 kbuf=kmalloc(len,GFP_KERNEL);
180 if (!kbuf) 180 if (!kbuf)
181 return -ENOMEM; 181 return -ENOMEM;
182 182
183 switch (MTD_MODE(file)) { 183 switch (MTD_MODE(file)) {
184 case MTD_MODE_OTP_FACT: 184 case MTD_MODE_OTP_FACT:
185 ret = mtd->read_fact_prot_reg(mtd, *ppos, len, &retlen, kbuf); 185 ret = mtd->read_fact_prot_reg(mtd, *ppos, len, &retlen, kbuf);
@@ -192,7 +192,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
192 } 192 }
193 /* Nand returns -EBADMSG on ecc errors, but it returns 193 /* Nand returns -EBADMSG on ecc errors, but it returns
194 * the data. For our userspace tools it is important 194 * the data. For our userspace tools it is important
195 * to dump areas with ecc errors ! 195 * to dump areas with ecc errors !
196 * Userspace software which accesses NAND this way 196 * Userspace software which accesses NAND this way
197 * must be aware of the fact that it deals with NAND 197 * must be aware of the fact that it deals with NAND
198 */ 198 */
@@ -214,7 +214,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
214 kfree(kbuf); 214 kfree(kbuf);
215 return ret; 215 return ret;
216 } 216 }
217 217
218 kfree(kbuf); 218 kfree(kbuf);
219 } 219 }
220 220
@@ -231,10 +231,10 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
231 int len; 231 int len;
232 232
233 DEBUG(MTD_DEBUG_LEVEL0,"MTD_write\n"); 233 DEBUG(MTD_DEBUG_LEVEL0,"MTD_write\n");
234 234
235 if (*ppos == mtd->size) 235 if (*ppos == mtd->size)
236 return -ENOSPC; 236 return -ENOSPC;
237 237
238 if (*ppos + count > mtd->size) 238 if (*ppos + count > mtd->size)
239 count = mtd->size - *ppos; 239 count = mtd->size - *ppos;
240 240
@@ -242,7 +242,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
242 return 0; 242 return 0;
243 243
244 while (count) { 244 while (count) {
245 if (count > MAX_KMALLOC_SIZE) 245 if (count > MAX_KMALLOC_SIZE)
246 len = MAX_KMALLOC_SIZE; 246 len = MAX_KMALLOC_SIZE;
247 else 247 else
248 len = count; 248 len = count;
@@ -257,7 +257,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
257 kfree(kbuf); 257 kfree(kbuf);
258 return -EFAULT; 258 return -EFAULT;
259 } 259 }
260 260
261 switch (MTD_MODE(file)) { 261 switch (MTD_MODE(file)) {
262 case MTD_MODE_OTP_FACT: 262 case MTD_MODE_OTP_FACT:
263 ret = -EROFS; 263 ret = -EROFS;
@@ -282,7 +282,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
282 kfree(kbuf); 282 kfree(kbuf);
283 return ret; 283 return ret;
284 } 284 }
285 285
286 kfree(kbuf); 286 kfree(kbuf);
287 } 287 }
288 288
@@ -306,7 +306,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
306 void __user *argp = (void __user *)arg; 306 void __user *argp = (void __user *)arg;
307 int ret = 0; 307 int ret = 0;
308 u_long size; 308 u_long size;
309 309
310 DEBUG(MTD_DEBUG_LEVEL0, "MTD_ioctl\n"); 310 DEBUG(MTD_DEBUG_LEVEL0, "MTD_ioctl\n");
311 311
312 size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT; 312 size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
@@ -318,7 +318,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
318 if (!access_ok(VERIFY_WRITE, argp, size)) 318 if (!access_ok(VERIFY_WRITE, argp, size))
319 return -EFAULT; 319 return -EFAULT;
320 } 320 }
321 321
322 switch (cmd) { 322 switch (cmd) {
323 case MEMGETREGIONCOUNT: 323 case MEMGETREGIONCOUNT:
324 if (copy_to_user(argp, &(mtd->numeraseregions), sizeof(int))) 324 if (copy_to_user(argp, &(mtd->numeraseregions), sizeof(int)))
@@ -370,11 +370,11 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
370 erase->mtd = mtd; 370 erase->mtd = mtd;
371 erase->callback = mtdchar_erase_callback; 371 erase->callback = mtdchar_erase_callback;
372 erase->priv = (unsigned long)&waitq; 372 erase->priv = (unsigned long)&waitq;
373 373
374 /* 374 /*
375 FIXME: Allow INTERRUPTIBLE. Which means 375 FIXME: Allow INTERRUPTIBLE. Which means
376 not having the wait_queue head on the stack. 376 not having the wait_queue head on the stack.
377 377
378 If the wq_head is on the stack, and we 378 If the wq_head is on the stack, and we
379 leave because we got interrupted, then the 379 leave because we got interrupted, then the
380 wq_head is no longer there when the 380 wq_head is no longer there when the
@@ -402,13 +402,13 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
402 struct mtd_oob_buf buf; 402 struct mtd_oob_buf buf;
403 void *databuf; 403 void *databuf;
404 ssize_t retlen; 404 ssize_t retlen;
405 405
406 if(!(file->f_mode & 2)) 406 if(!(file->f_mode & 2))
407 return -EPERM; 407 return -EPERM;
408 408
409 if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf))) 409 if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf)))
410 return -EFAULT; 410 return -EFAULT;
411 411
412 if (buf.length > 0x4096) 412 if (buf.length > 0x4096)
413 return -EINVAL; 413 return -EINVAL;
414 414
@@ -424,7 +424,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
424 databuf = kmalloc(buf.length, GFP_KERNEL); 424 databuf = kmalloc(buf.length, GFP_KERNEL);
425 if (!databuf) 425 if (!databuf)
426 return -ENOMEM; 426 return -ENOMEM;
427 427
428 if (copy_from_user(databuf, buf.ptr, buf.length)) { 428 if (copy_from_user(databuf, buf.ptr, buf.length)) {
429 kfree(databuf); 429 kfree(databuf);
430 return -EFAULT; 430 return -EFAULT;
@@ -448,7 +448,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
448 448
449 if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf))) 449 if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf)))
450 return -EFAULT; 450 return -EFAULT;
451 451
452 if (buf.length > 0x4096) 452 if (buf.length > 0x4096)
453 return -EINVAL; 453 return -EINVAL;
454 454
@@ -464,14 +464,14 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
464 databuf = kmalloc(buf.length, GFP_KERNEL); 464 databuf = kmalloc(buf.length, GFP_KERNEL);
465 if (!databuf) 465 if (!databuf)
466 return -ENOMEM; 466 return -ENOMEM;
467 467
468 ret = (mtd->read_oob)(mtd, buf.start, buf.length, &retlen, databuf); 468 ret = (mtd->read_oob)(mtd, buf.start, buf.length, &retlen, databuf);
469 469
470 if (put_user(retlen, (uint32_t __user *)argp)) 470 if (put_user(retlen, (uint32_t __user *)argp))
471 ret = -EFAULT; 471 ret = -EFAULT;
472 else if (retlen && copy_to_user(buf.ptr, databuf, retlen)) 472 else if (retlen && copy_to_user(buf.ptr, databuf, retlen))
473 ret = -EFAULT; 473 ret = -EFAULT;
474 474
475 kfree(databuf); 475 kfree(databuf);
476 break; 476 break;
477 } 477 }
@@ -521,7 +521,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
521 case MEMGETBADBLOCK: 521 case MEMGETBADBLOCK:
522 { 522 {
523 loff_t offs; 523 loff_t offs;
524 524
525 if (copy_from_user(&offs, argp, sizeof(loff_t))) 525 if (copy_from_user(&offs, argp, sizeof(loff_t)))
526 return -EFAULT; 526 return -EFAULT;
527 if (!mtd->block_isbad) 527 if (!mtd->block_isbad)
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index eaaafb1de625..b1bf8c411de7 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * This code is GPL 8 * This code is GPL
9 * 9 *
10 * $Id: mtdconcat.c,v 1.10 2005/11/06 10:04:37 gleixner Exp $ 10 * $Id: mtdconcat.c,v 1.11 2005/11/07 11:14:20 gleixner Exp $
11 */ 11 */
12 12
13#include <linux/kernel.h> 13#include <linux/kernel.h>
@@ -44,7 +44,7 @@ struct mtd_concat {
44 */ 44 */
45#define CONCAT(x) ((struct mtd_concat *)(x)) 45#define CONCAT(x) ((struct mtd_concat *)(x))
46 46
47/* 47/*
48 * MTD methods which look up the relevant subdevice, translate the 48 * MTD methods which look up the relevant subdevice, translate the
49 * effective address and pass through to the subdevice. 49 * effective address and pass through to the subdevice.
50 */ 50 */
@@ -878,7 +878,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
878 return &concat->mtd; 878 return &concat->mtd;
879} 879}
880 880
881/* 881/*
882 * This function destroys an MTD object obtained from concat_mtd_devs() 882 * This function destroys an MTD object obtained from concat_mtd_devs()
883 */ 883 */
884 884
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 2c16e051c61a..dade02ab0687 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: mtdcore.c,v 1.46 2005/08/11 17:13:43 gleixner 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;
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index e9168b5cd518..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.54 2005/09/30 14:49:08 dedekind 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)
@@ -477,8 +477,8 @@ int add_mtd_partitions(struct mtd_info *master,
477 if (slave->mtd.size == MTDPART_SIZ_FULL) 477 if (slave->mtd.size == MTDPART_SIZ_FULL)
478 slave->mtd.size = master->size - slave->offset; 478 slave->mtd.size = master->size - slave->offset;
479 cur_offset = slave->offset + slave->mtd.size; 479 cur_offset = slave->offset + slave->mtd.size;
480 480
481 printk (KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset, 481 printk (KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset,
482 slave->offset + slave->mtd.size, slave->mtd.name); 482 slave->offset + slave->mtd.size, slave->mtd.name);
483 483
484 /* let's do some sanity checks */ 484 /* let's do some sanity checks */
@@ -498,7 +498,7 @@ int add_mtd_partitions(struct mtd_info *master,
498 /* Deal with variable erase size stuff */ 498 /* Deal with variable erase size stuff */
499 int i; 499 int i;
500 struct mtd_erase_region_info *regions = master->eraseregions; 500 struct mtd_erase_region_info *regions = master->eraseregions;
501 501
502 /* Find the first erase regions which is part of this partition. */ 502 /* Find the first erase regions which is part of this partition. */
503 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++)
504 ; 504 ;
@@ -513,7 +513,7 @@ int add_mtd_partitions(struct mtd_info *master,
513 slave->mtd.erasesize = master->erasesize; 513 slave->mtd.erasesize = master->erasesize;
514 } 514 }
515 515
516 if ((slave->mtd.flags & MTD_WRITEABLE) && 516 if ((slave->mtd.flags & MTD_WRITEABLE) &&
517 (slave->offset % slave->mtd.erasesize)) { 517 (slave->offset % slave->mtd.erasesize)) {
518 /* Doesn't start on a boundary of major erase size */ 518 /* Doesn't start on a boundary of major erase size */
519 /* 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 */
@@ -521,14 +521,14 @@ int add_mtd_partitions(struct mtd_info *master,
521 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",
522 parts[i].name); 522 parts[i].name);
523 } 523 }
524 if ((slave->mtd.flags & MTD_WRITEABLE) && 524 if ((slave->mtd.flags & MTD_WRITEABLE) &&
525 (slave->mtd.size % slave->mtd.erasesize)) { 525 (slave->mtd.size % slave->mtd.erasesize)) {
526 slave->mtd.flags &= ~MTD_WRITEABLE; 526 slave->mtd.flags &= ~MTD_WRITEABLE;
527 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",
528 parts[i].name); 528 parts[i].name);
529 } 529 }
530 530
531 /* copy oobinfo from master */ 531 /* copy oobinfo from master */
532 memcpy(&slave->mtd.oobinfo, &master->oobinfo, sizeof(slave->mtd.oobinfo)); 532 memcpy(&slave->mtd.oobinfo, &master->oobinfo, sizeof(slave->mtd.oobinfo));
533 533
534 if(parts[i].mtdp) 534 if(parts[i].mtdp)
@@ -589,12 +589,12 @@ int deregister_mtd_parser(struct mtd_part_parser *p)
589 return 0; 589 return 0;
590} 590}
591 591
592int parse_mtd_partitions(struct mtd_info *master, const char **types, 592int parse_mtd_partitions(struct mtd_info *master, const char **types,
593 struct mtd_partition **pparts, unsigned long origin) 593 struct mtd_partition **pparts, unsigned long origin)
594{ 594{
595 struct mtd_part_parser *parser; 595 struct mtd_part_parser *parser;
596 int ret = 0; 596 int ret = 0;
597 597
598 for ( ; ret <= 0 && *types; types++) { 598 for ( ; ret <= 0 && *types; types++) {
599 parser = get_partition_parser(*types); 599 parser = get_partition_parser(*types);
600#ifdef CONFIG_KMOD 600#ifdef CONFIG_KMOD
@@ -608,7 +608,7 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types,
608 } 608 }
609 ret = (*parser->parse_fn)(master, pparts, origin); 609 ret = (*parser->parse_fn)(master, pparts, origin);
610 if (ret > 0) { 610 if (ret > 0) {
611 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",
612 ret, parser->name, master->name); 612 ret, parser->name, master->name);
613 } 613 }
614 put_partition_parser(parser); 614 put_partition_parser(parser);
diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
index b2014043634f..89d662999e7b 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 }
@@ -178,7 +178,7 @@ static u16 NFTL_findfreeblock(struct NFTLrecord *nftl, int desperate )
178 178
179 if (!silly--) { 179 if (!silly--) {
180 printk("Argh! No free blocks found! LastFreeEUN = %d, " 180 printk("Argh! No free blocks found! LastFreeEUN = %d, "
181 "FirstEUN = %d\n", nftl->LastFreeEUN, 181 "FirstEUN = %d\n", nftl->LastFreeEUN,
182 le16_to_cpu(nftl->MediaHdr.FirstPhysicalEUN)); 182 le16_to_cpu(nftl->MediaHdr.FirstPhysicalEUN));
183 return 0xffff; 183 return 0xffff;
184 } 184 }
@@ -210,7 +210,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
210 "Virtual Unit Chain %d!\n", thisVUC); 210 "Virtual Unit Chain %d!\n", thisVUC);
211 return BLOCK_NIL; 211 return BLOCK_NIL;
212 } 212 }
213 213
214 /* Scan to find the Erase Unit which holds the actual data for each 214 /* Scan to find the Erase Unit which holds the actual data for each
215 512-byte block within the Chain. 215 512-byte block within the Chain.
216 */ 216 */
@@ -227,7 +227,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
227 if (block == 2) { 227 if (block == 2) {
228 foldmark = oob.u.c.FoldMark | oob.u.c.FoldMark1; 228 foldmark = oob.u.c.FoldMark | oob.u.c.FoldMark1;
229 if (foldmark == FOLD_MARK_IN_PROGRESS) { 229 if (foldmark == FOLD_MARK_IN_PROGRESS) {
230 DEBUG(MTD_DEBUG_LEVEL1, 230 DEBUG(MTD_DEBUG_LEVEL1,
231 "Write Inhibited on EUN %d\n", thisEUN); 231 "Write Inhibited on EUN %d\n", thisEUN);
232 inplace = 0; 232 inplace = 0;
233 } else { 233 } else {
@@ -249,7 +249,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
249 if (!BlockFreeFound[block]) 249 if (!BlockFreeFound[block])
250 BlockMap[block] = thisEUN; 250 BlockMap[block] = thisEUN;
251 else 251 else
252 printk(KERN_WARNING 252 printk(KERN_WARNING
253 "SECTOR_USED found after SECTOR_FREE " 253 "SECTOR_USED found after SECTOR_FREE "
254 "in Virtual Unit Chain %d for block %d\n", 254 "in Virtual Unit Chain %d for block %d\n",
255 thisVUC, block); 255 thisVUC, block);
@@ -258,7 +258,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
258 if (!BlockFreeFound[block]) 258 if (!BlockFreeFound[block])
259 BlockMap[block] = BLOCK_NIL; 259 BlockMap[block] = BLOCK_NIL;
260 else 260 else
261 printk(KERN_WARNING 261 printk(KERN_WARNING
262 "SECTOR_DELETED found after SECTOR_FREE " 262 "SECTOR_DELETED found after SECTOR_FREE "
263 "in Virtual Unit Chain %d for block %d\n", 263 "in Virtual Unit Chain %d for block %d\n",
264 thisVUC, block); 264 thisVUC, block);
@@ -277,14 +277,14 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
277 thisVUC); 277 thisVUC);
278 return BLOCK_NIL; 278 return BLOCK_NIL;
279 } 279 }
280 280
281 thisEUN = nftl->ReplUnitTable[thisEUN]; 281 thisEUN = nftl->ReplUnitTable[thisEUN];
282 } 282 }
283 283
284 if (inplace) { 284 if (inplace) {
285 /* We're being asked to be a fold-in-place. Check 285 /* We're being asked to be a fold-in-place. Check
286 that all blocks which actually have data associated 286 that all blocks which actually have data associated
287 with them (i.e. BlockMap[block] != BLOCK_NIL) are 287 with them (i.e. BlockMap[block] != BLOCK_NIL) are
288 either already present or SECTOR_FREE in the target 288 either already present or SECTOR_FREE in the target
289 block. If not, we're going to have to fold out-of-place 289 block. If not, we're going to have to fold out-of-place
290 anyway. 290 anyway.
@@ -297,7 +297,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
297 "block %d was %x lastEUN, " 297 "block %d was %x lastEUN, "
298 "and is in EUN %d (%s) %d\n", 298 "and is in EUN %d (%s) %d\n",
299 thisVUC, block, BlockLastState[block], 299 thisVUC, block, BlockLastState[block],
300 BlockMap[block], 300 BlockMap[block],
301 BlockMap[block]== targetEUN ? "==" : "!=", 301 BlockMap[block]== targetEUN ? "==" : "!=",
302 targetEUN); 302 targetEUN);
303 inplace = 0; 303 inplace = 0;
@@ -314,17 +314,17 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
314 inplace = 0; 314 inplace = 0;
315 } 315 }
316 } 316 }
317 317
318 if (!inplace) { 318 if (!inplace) {
319 DEBUG(MTD_DEBUG_LEVEL1, "Cannot fold Virtual Unit Chain %d in place. " 319 DEBUG(MTD_DEBUG_LEVEL1, "Cannot fold Virtual Unit Chain %d in place. "
320 "Trying out-of-place\n", thisVUC); 320 "Trying out-of-place\n", thisVUC);
321 /* We need to find a targetEUN to fold into. */ 321 /* We need to find a targetEUN to fold into. */
322 targetEUN = NFTL_findfreeblock(nftl, 1); 322 targetEUN = NFTL_findfreeblock(nftl, 1);
323 if (targetEUN == BLOCK_NIL) { 323 if (targetEUN == BLOCK_NIL) {
324 /* Ouch. Now we're screwed. We need to do a 324 /* Ouch. Now we're screwed. We need to do a
325 fold-in-place of another chain to make room 325 fold-in-place of another chain to make room
326 for this one. We need a better way of selecting 326 for this one. We need a better way of selecting
327 which chain to fold, because makefreeblock will 327 which chain to fold, because makefreeblock will
328 only ask us to fold the same one again. 328 only ask us to fold the same one again.
329 */ 329 */
330 printk(KERN_WARNING 330 printk(KERN_WARNING
@@ -338,7 +338,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
338 chain by selecting the longer one */ 338 chain by selecting the longer one */
339 oob.u.c.FoldMark = oob.u.c.FoldMark1 = cpu_to_le16(FOLD_MARK_IN_PROGRESS); 339 oob.u.c.FoldMark = oob.u.c.FoldMark1 = cpu_to_le16(FOLD_MARK_IN_PROGRESS);
340 oob.u.c.unused = 0xffffffff; 340 oob.u.c.unused = 0xffffffff;
341 MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 2 * 512 + 8, 341 MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 2 * 512 + 8,
342 8, &retlen, (char *)&oob.u); 342 8, &retlen, (char *)&oob.u);
343 } 343 }
344 344
@@ -361,14 +361,14 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
361 happen in case of media errors or deleted blocks) */ 361 happen in case of media errors or deleted blocks) */
362 if (BlockMap[block] == BLOCK_NIL) 362 if (BlockMap[block] == BLOCK_NIL)
363 continue; 363 continue;
364 364
365 ret = MTD_READ(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block]) + (block * 512), 365 ret = MTD_READ(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block]) + (block * 512),
366 512, &retlen, movebuf); 366 512, &retlen, movebuf);
367 if (ret < 0) { 367 if (ret < 0) {
368 ret = MTD_READ(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block]) 368 ret = MTD_READ(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block])
369 + (block * 512), 512, &retlen, 369 + (block * 512), 512, &retlen,
370 movebuf); 370 movebuf);
371 if (ret != -EIO) 371 if (ret != -EIO)
372 printk("Error went away on retry.\n"); 372 printk("Error went away on retry.\n");
373 } 373 }
374 memset(&oob, 0xff, sizeof(struct nftl_oob)); 374 memset(&oob, 0xff, sizeof(struct nftl_oob));
@@ -376,18 +376,18 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
376 MTD_WRITEECC(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + (block * 512), 376 MTD_WRITEECC(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + (block * 512),
377 512, &retlen, movebuf, (char *)&oob, &nftl->oobinfo); 377 512, &retlen, movebuf, (char *)&oob, &nftl->oobinfo);
378 } 378 }
379 379
380 /* add the header so that it is now a valid chain */ 380 /* add the header so that it is now a valid chain */
381 oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum 381 oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum
382 = cpu_to_le16(thisVUC); 382 = cpu_to_le16(thisVUC);
383 oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum = 0xffff; 383 oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum = 0xffff;
384 384
385 MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 8, 385 MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 8,
386 8, &retlen, (char *)&oob.u); 386 8, &retlen, (char *)&oob.u);
387 387
388 /* OK. We've moved the whole lot into the new block. Now we have to free the original blocks. */ 388 /* OK. We've moved the whole lot into the new block. Now we have to free the original blocks. */
389 389
390 /* At this point, we have two different chains for this Virtual Unit, and no way to tell 390 /* At this point, we have two different chains for this Virtual Unit, and no way to tell
391 them apart. If we crash now, we get confused. However, both contain the same data, so we 391 them apart. If we crash now, we get confused. However, both contain the same data, so we
392 shouldn't actually lose data in this case. It's just that when we load up on a medium which 392 shouldn't actually lose data in this case. It's just that when we load up on a medium which
393 has duplicate chains, we need to free one of the chains because it's not necessary any more. 393 has duplicate chains, we need to free one of the chains because it's not necessary any more.
@@ -395,7 +395,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
395 thisEUN = nftl->EUNtable[thisVUC]; 395 thisEUN = nftl->EUNtable[thisVUC];
396 DEBUG(MTD_DEBUG_LEVEL1,"Want to erase\n"); 396 DEBUG(MTD_DEBUG_LEVEL1,"Want to erase\n");
397 397
398 /* For each block in the old chain (except the targetEUN of course), 398 /* For each block in the old chain (except the targetEUN of course),
399 free it and make it available for future use */ 399 free it and make it available for future use */
400 while (thisEUN <= nftl->lastEUN && thisEUN != targetEUN) { 400 while (thisEUN <= nftl->lastEUN && thisEUN != targetEUN) {
401 unsigned int EUNtmp; 401 unsigned int EUNtmp;
@@ -413,7 +413,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
413 } 413 }
414 thisEUN = EUNtmp; 414 thisEUN = EUNtmp;
415 } 415 }
416 416
417 /* Make this the new start of chain for thisVUC */ 417 /* Make this the new start of chain for thisVUC */
418 nftl->ReplUnitTable[targetEUN] = BLOCK_NIL; 418 nftl->ReplUnitTable[targetEUN] = BLOCK_NIL;
419 nftl->EUNtable[thisVUC] = targetEUN; 419 nftl->EUNtable[thisVUC] = targetEUN;
@@ -423,7 +423,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
423 423
424static u16 NFTL_makefreeblock( struct NFTLrecord *nftl , unsigned pendingblock) 424static u16 NFTL_makefreeblock( struct NFTLrecord *nftl , unsigned pendingblock)
425{ 425{
426 /* This is the part that needs some cleverness applied. 426 /* This is the part that needs some cleverness applied.
427 For now, I'm doing the minimum applicable to actually 427 For now, I'm doing the minimum applicable to actually
428 get the thing to work. 428 get the thing to work.
429 Wear-levelling and other clever stuff needs to be implemented 429 Wear-levelling and other clever stuff needs to be implemented
@@ -470,7 +470,7 @@ static u16 NFTL_makefreeblock( struct NFTLrecord *nftl , unsigned pendingblock)
470 return NFTL_foldchain (nftl, LongestChain, pendingblock); 470 return NFTL_foldchain (nftl, LongestChain, pendingblock);
471} 471}
472 472
473/* NFTL_findwriteunit: Return the unit number into which we can write 473/* NFTL_findwriteunit: Return the unit number into which we can write
474 for this block. Make it available if it isn't already 474 for this block. Make it available if it isn't already
475*/ 475*/
476static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block) 476static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
@@ -488,7 +488,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
488 a free space for the block in question. 488 a free space for the block in question.
489 */ 489 */
490 490
491 /* This condition catches the 0x[7f]fff cases, as well as 491 /* This condition catches the 0x[7f]fff cases, as well as
492 being a sanity check for past-end-of-media access 492 being a sanity check for past-end-of-media access
493 */ 493 */
494 lastEUN = BLOCK_NIL; 494 lastEUN = BLOCK_NIL;
@@ -503,7 +503,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
503 503
504 MTD_READOOB(nftl->mbd.mtd, (writeEUN * nftl->EraseSize) + blockofs, 504 MTD_READOOB(nftl->mbd.mtd, (writeEUN * nftl->EraseSize) + blockofs,
505 8, &retlen, (char *)&bci); 505 8, &retlen, (char *)&bci);
506 506
507 DEBUG(MTD_DEBUG_LEVEL2, "Status of block %d in EUN %d is %x\n", 507 DEBUG(MTD_DEBUG_LEVEL2, "Status of block %d in EUN %d is %x\n",
508 block , writeEUN, le16_to_cpu(bci.Status)); 508 block , writeEUN, le16_to_cpu(bci.Status));
509 509
@@ -518,10 +518,10 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
518 break; 518 break;
519 default: 519 default:
520 // Invalid block. Don't use it any more. Must implement. 520 // Invalid block. Don't use it any more. Must implement.
521 break; 521 break;
522 } 522 }
523 523
524 if (!silly--) { 524 if (!silly--) {
525 printk(KERN_WARNING 525 printk(KERN_WARNING
526 "Infinite loop in Virtual Unit Chain 0x%x\n", 526 "Infinite loop in Virtual Unit Chain 0x%x\n",
527 thisVUC); 527 thisVUC);
@@ -532,7 +532,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
532 writeEUN = nftl->ReplUnitTable[writeEUN]; 532 writeEUN = nftl->ReplUnitTable[writeEUN];
533 } 533 }
534 534
535 /* OK. We didn't find one in the existing chain, or there 535 /* OK. We didn't find one in the existing chain, or there
536 is no existing chain. */ 536 is no existing chain. */
537 537
538 /* Try to find an already-free block */ 538 /* Try to find an already-free block */
@@ -546,12 +546,12 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
546 546
547 /* First remember the start of this chain */ 547 /* First remember the start of this chain */
548 //u16 startEUN = nftl->EUNtable[thisVUC]; 548 //u16 startEUN = nftl->EUNtable[thisVUC];
549 549
550 //printk("Write to VirtualUnitChain %d, calling makefreeblock()\n", thisVUC); 550 //printk("Write to VirtualUnitChain %d, calling makefreeblock()\n", thisVUC);
551 writeEUN = NFTL_makefreeblock(nftl, 0xffff); 551 writeEUN = NFTL_makefreeblock(nftl, 0xffff);
552 552
553 if (writeEUN == BLOCK_NIL) { 553 if (writeEUN == BLOCK_NIL) {
554 /* OK, we accept that the above comment is 554 /* OK, we accept that the above comment is
555 lying - there may have been free blocks 555 lying - there may have been free blocks
556 last time we called NFTL_findfreeblock(), 556 last time we called NFTL_findfreeblock(),
557 but they are reserved for when we're 557 but they are reserved for when we're
@@ -562,21 +562,21 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
562 } 562 }
563 if (writeEUN == BLOCK_NIL) { 563 if (writeEUN == BLOCK_NIL) {
564 /* Ouch. This should never happen - we should 564 /* Ouch. This should never happen - we should
565 always be able to make some room somehow. 565 always be able to make some room somehow.
566 If we get here, we've allocated more storage 566 If we get here, we've allocated more storage
567 space than actual media, or our makefreeblock 567 space than actual media, or our makefreeblock
568 routine is missing something. 568 routine is missing something.
569 */ 569 */
570 printk(KERN_WARNING "Cannot make free space.\n"); 570 printk(KERN_WARNING "Cannot make free space.\n");
571 return BLOCK_NIL; 571 return BLOCK_NIL;
572 } 572 }
573 //printk("Restarting scan\n"); 573 //printk("Restarting scan\n");
574 lastEUN = BLOCK_NIL; 574 lastEUN = BLOCK_NIL;
575 continue; 575 continue;
576 } 576 }
577 577
578 /* We've found a free block. Insert it into the chain. */ 578 /* We've found a free block. Insert it into the chain. */
579 579
580 if (lastEUN != BLOCK_NIL) { 580 if (lastEUN != BLOCK_NIL) {
581 thisVUC |= 0x8000; /* It's a replacement block */ 581 thisVUC |= 0x8000; /* It's a replacement block */
582 } else { 582 } else {
@@ -749,7 +749,7 @@ extern char nftlmountrev[];
749 749
750static int __init init_nftl(void) 750static int __init init_nftl(void)
751{ 751{
752 printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.97 $, nftlmount.c %s\n", nftlmountrev); 752 printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.98 $, nftlmount.c %s\n", nftlmountrev);
753 753
754 return register_mtd_blktrans(&nftl_tr); 754 return register_mtd_blktrans(&nftl_tr);
755} 755}
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/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
index 7b9f359f04b7..041ee59ea77d 100644
--- a/drivers/mtd/rfd_ftl.c
+++ b/drivers/mtd/rfd_ftl.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2005 Sean Young <sean@mess.org> 4 * Copyright (C) 2005 Sean Young <sean@mess.org>
5 * 5 *
6 * $Id: rfd_ftl.c,v 1.4 2005/07/31 22:49:14 sean Exp $ 6 * $Id: rfd_ftl.c,v 1.5 2005/11/07 11:14:21 gleixner Exp $
7 * 7 *
8 * This type of flash translation layer (FTL) is used by the Embedded BIOS 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: 9 * by General Software. It is known as the Resident Flash Disk (RFD), see:
@@ -95,7 +95,7 @@ static int build_block_map(struct partition *part, int block_no)
95{ 95{
96 struct block *block = &part->blocks[block_no]; 96 struct block *block = &part->blocks[block_no];
97 int i; 97 int i;
98 98
99 block->offset = part->block_size * block_no; 99 block->offset = part->block_size * block_no;
100 100
101 if (le16_to_cpu(part->header_cache[0]) != RFD_MAGIC) { 101 if (le16_to_cpu(part->header_cache[0]) != RFD_MAGIC) {
@@ -109,12 +109,12 @@ static int build_block_map(struct partition *part, int block_no)
109 109
110 for (i=0; i<part->data_sectors_per_block; i++) { 110 for (i=0; i<part->data_sectors_per_block; i++) {
111 u16 entry; 111 u16 entry;
112 112
113 entry = le16_to_cpu(part->header_cache[HEADER_MAP_OFFSET + i]); 113 entry = le16_to_cpu(part->header_cache[HEADER_MAP_OFFSET + i]);
114 114
115 if (entry == SECTOR_DELETED) 115 if (entry == SECTOR_DELETED)
116 continue; 116 continue;
117 117
118 if (entry == SECTOR_FREE) { 118 if (entry == SECTOR_FREE) {
119 block->free_sectors++; 119 block->free_sectors++;
120 continue; 120 continue;
@@ -122,9 +122,9 @@ static int build_block_map(struct partition *part, int block_no)
122 122
123 if (entry == SECTOR_ZERO) 123 if (entry == SECTOR_ZERO)
124 entry = 0; 124 entry = 0;
125 125
126 if (entry >= part->sector_count) { 126 if (entry >= part->sector_count) {
127 printk(KERN_NOTICE PREFIX 127 printk(KERN_NOTICE PREFIX
128 "'%s': unit #%d: entry %d corrupt, " 128 "'%s': unit #%d: entry %d corrupt, "
129 "sector %d out of range\n", 129 "sector %d out of range\n",
130 part->mbd.mtd->name, block_no, i, entry); 130 part->mbd.mtd->name, block_no, i, entry);
@@ -132,14 +132,14 @@ static int build_block_map(struct partition *part, int block_no)
132 } 132 }
133 133
134 if (part->sector_map[entry] != -1) { 134 if (part->sector_map[entry] != -1) {
135 printk(KERN_NOTICE PREFIX 135 printk(KERN_NOTICE PREFIX
136 "'%s': more than one entry for sector %d\n", 136 "'%s': more than one entry for sector %d\n",
137 part->mbd.mtd->name, entry); 137 part->mbd.mtd->name, entry);
138 part->errors = 1; 138 part->errors = 1;
139 continue; 139 continue;
140 } 140 }
141 141
142 part->sector_map[entry] = block->offset + 142 part->sector_map[entry] = block->offset +
143 (i + part->header_sectors_per_block) * SECTOR_SIZE; 143 (i + part->header_sectors_per_block) * SECTOR_SIZE;
144 144
145 block->used_sectors++; 145 block->used_sectors++;
@@ -165,14 +165,14 @@ static int scan_header(struct partition *part)
165 return -ENOENT; 165 return -ENOENT;
166 166
167 /* each erase block has three bytes header, followed by the map */ 167 /* each erase block has three bytes header, followed by the map */
168 part->header_sectors_per_block = 168 part->header_sectors_per_block =
169 ((HEADER_MAP_OFFSET + sectors_per_block) * 169 ((HEADER_MAP_OFFSET + sectors_per_block) *
170 sizeof(u16) + SECTOR_SIZE - 1) / SECTOR_SIZE; 170 sizeof(u16) + SECTOR_SIZE - 1) / SECTOR_SIZE;
171 171
172 part->data_sectors_per_block = sectors_per_block - 172 part->data_sectors_per_block = sectors_per_block -
173 part->header_sectors_per_block; 173 part->header_sectors_per_block;
174 174
175 part->header_size = (HEADER_MAP_OFFSET + 175 part->header_size = (HEADER_MAP_OFFSET +
176 part->data_sectors_per_block) * sizeof(u16); 176 part->data_sectors_per_block) * sizeof(u16);
177 177
178 part->cylinders = (part->data_sectors_per_block * 178 part->cylinders = (part->data_sectors_per_block *
@@ -188,7 +188,7 @@ static int scan_header(struct partition *part)
188 if (!part->header_cache) 188 if (!part->header_cache)
189 goto err; 189 goto err;
190 190
191 part->blocks = kcalloc(part->total_blocks, sizeof(struct block), 191 part->blocks = kcalloc(part->total_blocks, sizeof(struct block),
192 GFP_KERNEL); 192 GFP_KERNEL);
193 if (!part->blocks) 193 if (!part->blocks)
194 goto err; 194 goto err;
@@ -200,18 +200,18 @@ static int scan_header(struct partition *part)
200 goto err; 200 goto err;
201 } 201 }
202 202
203 for (i=0; i<part->sector_count; i++) 203 for (i=0; i<part->sector_count; i++)
204 part->sector_map[i] = -1; 204 part->sector_map[i] = -1;
205 205
206 for (i=0, blocks_found=0; i<part->total_blocks; i++) { 206 for (i=0, blocks_found=0; i<part->total_blocks; i++) {
207 rc = part->mbd.mtd->read(part->mbd.mtd, 207 rc = part->mbd.mtd->read(part->mbd.mtd,
208 i * part->block_size, part->header_size, 208 i * part->block_size, part->header_size,
209 &retlen, (u_char*)part->header_cache); 209 &retlen, (u_char*)part->header_cache);
210 210
211 if (!rc && retlen != part->header_size) 211 if (!rc && retlen != part->header_size)
212 rc = -EIO; 212 rc = -EIO;
213 213
214 if (rc) 214 if (rc)
215 goto err; 215 goto err;
216 216
217 if (!build_block_map(part, i)) 217 if (!build_block_map(part, i))
@@ -226,7 +226,7 @@ static int scan_header(struct partition *part)
226 } 226 }
227 227
228 if (part->reserved_block == -1) { 228 if (part->reserved_block == -1) {
229 printk(KERN_NOTICE PREFIX "'%s': no empty erase unit found\n", 229 printk(KERN_NOTICE PREFIX "'%s': no empty erase unit found\n",
230 part->mbd.mtd->name); 230 part->mbd.mtd->name);
231 231
232 part->errors = 1; 232 part->errors = 1;
@@ -248,7 +248,7 @@ static int rfd_ftl_readsect(struct mtd_blktrans_dev *dev, u_long sector, char *b
248 u_long addr; 248 u_long addr;
249 size_t retlen; 249 size_t retlen;
250 int rc; 250 int rc;
251 251
252 if (sector >= part->sector_count) 252 if (sector >= part->sector_count)
253 return -EIO; 253 return -EIO;
254 254
@@ -266,9 +266,9 @@ static int rfd_ftl_readsect(struct mtd_blktrans_dev *dev, u_long sector, char *b
266 } 266 }
267 } else 267 } else
268 memset(buf, 0, SECTOR_SIZE); 268 memset(buf, 0, SECTOR_SIZE);
269 269
270 return 0; 270 return 0;
271} 271}
272 272
273static void erase_callback(struct erase_info *erase) 273static void erase_callback(struct erase_info *erase)
274{ 274{
@@ -288,7 +288,7 @@ static void erase_callback(struct erase_info *erase)
288 288
289 if (erase->state != MTD_ERASE_DONE) { 289 if (erase->state != MTD_ERASE_DONE) {
290 printk(KERN_WARNING PREFIX "erase failed at 0x%x on '%s', " 290 printk(KERN_WARNING PREFIX "erase failed at 0x%x on '%s', "
291 "state %d\n", erase->addr, 291 "state %d\n", erase->addr,
292 part->mbd.mtd->name, erase->state); 292 part->mbd.mtd->name, erase->state);
293 293
294 part->blocks[i].state = BLOCK_FAILED; 294 part->blocks[i].state = BLOCK_FAILED;
@@ -307,17 +307,17 @@ static void erase_callback(struct erase_info *erase)
307 part->blocks[i].used_sectors = 0; 307 part->blocks[i].used_sectors = 0;
308 part->blocks[i].erases++; 308 part->blocks[i].erases++;
309 309
310 rc = part->mbd.mtd->write(part->mbd.mtd, 310 rc = part->mbd.mtd->write(part->mbd.mtd,
311 part->blocks[i].offset, sizeof(magic), &retlen, 311 part->blocks[i].offset, sizeof(magic), &retlen,
312 (u_char*)&magic); 312 (u_char*)&magic);
313 313
314 if (!rc && retlen != sizeof(magic)) 314 if (!rc && retlen != sizeof(magic))
315 rc = -EIO; 315 rc = -EIO;
316 316
317 if (rc) { 317 if (rc) {
318 printk(KERN_NOTICE PREFIX "'%s': unable to write RFD " 318 printk(KERN_NOTICE PREFIX "'%s': unable to write RFD "
319 "header at 0x%lx\n", 319 "header at 0x%lx\n",
320 part->mbd.mtd->name, 320 part->mbd.mtd->name,
321 part->blocks[i].offset); 321 part->blocks[i].offset);
322 part->blocks[i].state = BLOCK_FAILED; 322 part->blocks[i].state = BLOCK_FAILED;
323 } 323 }
@@ -374,17 +374,17 @@ static int move_block_contents(struct partition *part, int block_no, u_long *old
374 map = kmalloc(part->header_size, GFP_KERNEL); 374 map = kmalloc(part->header_size, GFP_KERNEL);
375 if (!map) 375 if (!map)
376 goto err2; 376 goto err2;
377 377
378 rc = part->mbd.mtd->read(part->mbd.mtd, 378 rc = part->mbd.mtd->read(part->mbd.mtd,
379 part->blocks[block_no].offset, part->header_size, 379 part->blocks[block_no].offset, part->header_size,
380 &retlen, (u_char*)map); 380 &retlen, (u_char*)map);
381 381
382 if (!rc && retlen != part->header_size) 382 if (!rc && retlen != part->header_size)
383 rc = -EIO; 383 rc = -EIO;
384 384
385 if (rc) { 385 if (rc) {
386 printk(KERN_NOTICE PREFIX "error reading '%s' at " 386 printk(KERN_NOTICE PREFIX "error reading '%s' at "
387 "0x%lx\n", part->mbd.mtd->name, 387 "0x%lx\n", part->mbd.mtd->name,
388 part->blocks[block_no].offset); 388 part->blocks[block_no].offset);
389 389
390 goto err; 390 goto err;
@@ -398,11 +398,11 @@ static int move_block_contents(struct partition *part, int block_no, u_long *old
398 if (entry == SECTOR_FREE || entry == SECTOR_DELETED) 398 if (entry == SECTOR_FREE || entry == SECTOR_DELETED)
399 continue; 399 continue;
400 400
401 if (entry == SECTOR_ZERO) 401 if (entry == SECTOR_ZERO)
402 entry = 0; 402 entry = 0;
403 403
404 /* already warned about and ignored in build_block_map() */ 404 /* already warned about and ignored in build_block_map() */
405 if (entry >= part->sector_count) 405 if (entry >= part->sector_count)
406 continue; 406 continue;
407 407
408 addr = part->blocks[block_no].offset + 408 addr = part->blocks[block_no].offset +
@@ -418,7 +418,7 @@ static int move_block_contents(struct partition *part, int block_no, u_long *old
418 } 418 }
419 rc = part->mbd.mtd->read(part->mbd.mtd, addr, 419 rc = part->mbd.mtd->read(part->mbd.mtd, addr,
420 SECTOR_SIZE, &retlen, sector_data); 420 SECTOR_SIZE, &retlen, sector_data);
421 421
422 if (!rc && retlen != SECTOR_SIZE) 422 if (!rc && retlen != SECTOR_SIZE)
423 rc = -EIO; 423 rc = -EIO;
424 424
@@ -429,11 +429,11 @@ static int move_block_contents(struct partition *part, int block_no, u_long *old
429 429
430 goto err; 430 goto err;
431 } 431 }
432 432
433 rc = rfd_ftl_writesect((struct mtd_blktrans_dev*)part, 433 rc = rfd_ftl_writesect((struct mtd_blktrans_dev*)part,
434 entry, sector_data); 434 entry, sector_data);
435 435
436 if (rc) 436 if (rc)
437 goto err; 437 goto err;
438 } 438 }
439 439
@@ -447,11 +447,11 @@ err3:
447 return rc; 447 return rc;
448} 448}
449 449
450static int reclaim_block(struct partition *part, u_long *old_sector) 450static int reclaim_block(struct partition *part, u_long *old_sector)
451{ 451{
452 int block, best_block, score, old_sector_block; 452 int block, best_block, score, old_sector_block;
453 int rc; 453 int rc;
454 454
455 /* we have a race if sync doesn't exist */ 455 /* we have a race if sync doesn't exist */
456 if (part->mbd.mtd->sync) 456 if (part->mbd.mtd->sync)
457 part->mbd.mtd->sync(part->mbd.mtd); 457 part->mbd.mtd->sync(part->mbd.mtd);
@@ -474,16 +474,16 @@ static int reclaim_block(struct partition *part, u_long *old_sector)
474 * more removed sectors is more efficient (have to move 474 * more removed sectors is more efficient (have to move
475 * less). 475 * less).
476 */ 476 */
477 if (part->blocks[block].free_sectors) 477 if (part->blocks[block].free_sectors)
478 return 0; 478 return 0;
479 479
480 this_score = part->blocks[block].used_sectors; 480 this_score = part->blocks[block].used_sectors;
481 481
482 if (block == old_sector_block) 482 if (block == old_sector_block)
483 this_score--; 483 this_score--;
484 else { 484 else {
485 /* no point in moving a full block */ 485 /* no point in moving a full block */
486 if (part->blocks[block].used_sectors == 486 if (part->blocks[block].used_sectors ==
487 part->data_sectors_per_block) 487 part->data_sectors_per_block)
488 continue; 488 continue;
489 } 489 }
@@ -529,7 +529,7 @@ static int find_free_block(const struct partition *part)
529 stop = block; 529 stop = block;
530 530
531 do { 531 do {
532 if (part->blocks[block].free_sectors && 532 if (part->blocks[block].free_sectors &&
533 block != part->reserved_block) 533 block != part->reserved_block)
534 return block; 534 return block;
535 535
@@ -563,7 +563,7 @@ static int find_writeable_block(struct partition *part, u_long *old_sector)
563 } 563 }
564 } 564 }
565 565
566 rc = part->mbd.mtd->read(part->mbd.mtd, part->blocks[block].offset, 566 rc = part->mbd.mtd->read(part->mbd.mtd, part->blocks[block].offset,
567 part->header_size, &retlen, (u_char*)part->header_cache); 567 part->header_size, &retlen, (u_char*)part->header_cache);
568 568
569 if (!rc && retlen != part->header_size) 569 if (!rc && retlen != part->header_size)
@@ -571,7 +571,7 @@ static int find_writeable_block(struct partition *part, u_long *old_sector)
571 571
572 if (rc) { 572 if (rc) {
573 printk(KERN_NOTICE PREFIX "'%s': unable to read header at " 573 printk(KERN_NOTICE PREFIX "'%s': unable to read header at "
574 "0x%lx\n", part->mbd.mtd->name, 574 "0x%lx\n", part->mbd.mtd->name,
575 part->blocks[block].offset); 575 part->blocks[block].offset);
576 goto err; 576 goto err;
577 } 577 }
@@ -580,7 +580,7 @@ static int find_writeable_block(struct partition *part, u_long *old_sector)
580 580
581err: 581err:
582 return rc; 582 return rc;
583} 583}
584 584
585static int mark_sector_deleted(struct partition *part, u_long old_addr) 585static int mark_sector_deleted(struct partition *part, u_long old_addr)
586{ 586{
@@ -590,7 +590,7 @@ static int mark_sector_deleted(struct partition *part, u_long old_addr)
590 u16 del = const_cpu_to_le16(SECTOR_DELETED); 590 u16 del = const_cpu_to_le16(SECTOR_DELETED);
591 591
592 block = old_addr / part->block_size; 592 block = old_addr / part->block_size;
593 offset = (old_addr % part->block_size) / SECTOR_SIZE - 593 offset = (old_addr % part->block_size) / SECTOR_SIZE -
594 part->header_sectors_per_block; 594 part->header_sectors_per_block;
595 595
596 addr = part->blocks[block].offset + 596 addr = part->blocks[block].offset +
@@ -604,7 +604,7 @@ static int mark_sector_deleted(struct partition *part, u_long old_addr)
604 if (rc) { 604 if (rc) {
605 printk(KERN_WARNING PREFIX "error writing '%s' at " 605 printk(KERN_WARNING PREFIX "error writing '%s' at "
606 "0x%lx\n", part->mbd.mtd->name, addr); 606 "0x%lx\n", part->mbd.mtd->name, addr);
607 if (rc) 607 if (rc)
608 goto err; 608 goto err;
609 } 609 }
610 if (block == part->current_block) 610 if (block == part->current_block)
@@ -627,7 +627,7 @@ static int find_free_sector(const struct partition *part, const struct block *bl
627 i = stop = part->data_sectors_per_block - block->free_sectors; 627 i = stop = part->data_sectors_per_block - block->free_sectors;
628 628
629 do { 629 do {
630 if (le16_to_cpu(part->header_cache[HEADER_MAP_OFFSET + i]) 630 if (le16_to_cpu(part->header_cache[HEADER_MAP_OFFSET + i])
631 == SECTOR_FREE) 631 == SECTOR_FREE)
632 return i; 632 return i;
633 633
@@ -653,7 +653,7 @@ static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf,
653 !part->blocks[part->current_block].free_sectors) { 653 !part->blocks[part->current_block].free_sectors) {
654 654
655 rc = find_writeable_block(part, old_addr); 655 rc = find_writeable_block(part, old_addr);
656 if (rc) 656 if (rc)
657 goto err; 657 goto err;
658 } 658 }
659 659
@@ -665,10 +665,10 @@ static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf,
665 rc = -ENOSPC; 665 rc = -ENOSPC;
666 goto err; 666 goto err;
667 } 667 }
668 668
669 addr = (i + part->header_sectors_per_block) * SECTOR_SIZE + 669 addr = (i + part->header_sectors_per_block) * SECTOR_SIZE +
670 block->offset; 670 block->offset;
671 rc = part->mbd.mtd->write(part->mbd.mtd, 671 rc = part->mbd.mtd->write(part->mbd.mtd,
672 addr, SECTOR_SIZE, &retlen, (u_char*)buf); 672 addr, SECTOR_SIZE, &retlen, (u_char*)buf);
673 673
674 if (!rc && retlen != SECTOR_SIZE) 674 if (!rc && retlen != SECTOR_SIZE)
@@ -677,7 +677,7 @@ static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf,
677 if (rc) { 677 if (rc) {
678 printk(KERN_WARNING PREFIX "error writing '%s' at 0x%lx\n", 678 printk(KERN_WARNING PREFIX "error writing '%s' at 0x%lx\n",
679 part->mbd.mtd->name, addr); 679 part->mbd.mtd->name, addr);
680 if (rc) 680 if (rc)
681 goto err; 681 goto err;
682 } 682 }
683 683
@@ -697,7 +697,7 @@ static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf,
697 if (rc) { 697 if (rc) {
698 printk(KERN_WARNING PREFIX "error writing '%s' at 0x%lx\n", 698 printk(KERN_WARNING PREFIX "error writing '%s' at 0x%lx\n",
699 part->mbd.mtd->name, addr); 699 part->mbd.mtd->name, addr);
700 if (rc) 700 if (rc)
701 goto err; 701 goto err;
702 } 702 }
703 block->used_sectors++; 703 block->used_sectors++;
@@ -738,7 +738,7 @@ static int rfd_ftl_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *
738 break; 738 break;
739 } 739 }
740 740
741 if (i == SECTOR_SIZE) 741 if (i == SECTOR_SIZE)
742 part->sector_map[sector] = -1; 742 part->sector_map[sector] = -1;
743 743
744 if (old_addr != -1) 744 if (old_addr != -1)
@@ -801,7 +801,7 @@ static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
801 801
802 if (!add_mtd_blktrans_dev((void*)part)) 802 if (!add_mtd_blktrans_dev((void*)part))
803 return; 803 return;
804 } 804 }
805 805
806 kfree(part); 806 kfree(part);
807} 807}
@@ -828,7 +828,7 @@ struct mtd_blktrans_ops rfd_ftl_tr = {
828 .major = RFD_FTL_MAJOR, 828 .major = RFD_FTL_MAJOR,
829 .part_bits = PART_BITS, 829 .part_bits = PART_BITS,
830 .readsect = rfd_ftl_readsect, 830 .readsect = rfd_ftl_readsect,
831 .writesect = rfd_ftl_writesect, 831 .writesect = rfd_ftl_writesect,
832 .getgeo = rfd_ftl_getgeo, 832 .getgeo = rfd_ftl_getgeo,
833 .add_mtd = rfd_ftl_add_mtd, 833 .add_mtd = rfd_ftl_add_mtd,
834 .remove_dev = rfd_ftl_remove_dev, 834 .remove_dev = rfd_ftl_remove_dev,