Whamcloud - gitweb
b=20668
[fs/lustre-release.git] / lustre / kernel_patches / patches / mtd-2.6-suse-lnxi.patch
1 Index: linux-2.6.5/drivers/mtd/Kconfig
2 ===================================================================
3 --- linux-2.6.5.orig/drivers/mtd/Kconfig        2004-04-03 22:36:26.000000000 -0500
4 +++ linux-2.6.5/drivers/mtd/Kconfig     2005-02-01 17:11:17.000000000 -0500
5 @@ -1,4 +1,4 @@
6 -# $Id: Kconfig,v 1.3 2003/05/28 11:02:23 dwmw2 Exp $
7 +# $Id: Kconfig,v 1.6 2004/08/09 13:19:42 dwmw2 Exp $
8  
9  menu "Memory Technology Devices (MTD)"
10  
11 @@ -28,7 +28,7 @@
12           Determines the verbosity level of the MTD debugging messages.
13  
14  config MTD_PARTITIONS
15 -       tristate "MTD partitioning support"
16 +       bool "MTD partitioning support"
17         depends on MTD
18         help
19           If you have a device which needs to divide its flash chip(s) up
20 @@ -68,9 +68,23 @@
21           SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for 
22           example.
23  
24 +config MTD_REDBOOT_PARTS_UNALLOCATED
25 +       bool "  Include unallocated flash regions"
26 +       depends on MTD_REDBOOT_PARTS
27 +       help
28 +         If you need to register each unallocated flash region as a MTD
29 +         'partition', enable this option.
30 +
31 +config MTD_REDBOOT_PARTS_READONLY
32 +       bool "  Force read-only for RedBoot system images"
33 +       depends on MTD_REDBOOT_PARTS
34 +       help
35 +         If you need to force read-only for 'RedBoot', 'RedBoot Config' and
36 +         'FIS directory' images, enable this option.
37 +
38  config MTD_CMDLINE_PARTS
39 -       tristate "Command line partition table parsing"
40 -       depends on MTD_PARTITIONS
41 +       bool "Command line partition table parsing"
42 +       depends on MTD_PARTITIONS = "y"
43         ---help---
44           Allow generic configuration of the MTD paritition tables via the kernel
45           command line. Multiple flash resources are supported for hardware where
46 Index: linux-2.6.5/drivers/mtd/Makefile
47 ===================================================================
48 --- linux-2.6.5.orig/drivers/mtd/Makefile       2004-04-03 22:36:57.000000000 -0500
49 +++ linux-2.6.5/drivers/mtd/Makefile    2005-02-01 17:11:17.000000000 -0500
50 @@ -1,28 +1,14 @@
51  #
52  # Makefile for the memory technology device drivers.
53  #
54 -# $Id: Makefile.common,v 1.2 2003/05/23 11:38:29 dwmw2 Exp $
55 -
56 -#                       *** BIG UGLY NOTE ***
57 -#
58 -# The shiny new inter_module_xxx has introduced yet another ugly link
59 -# order dependency, which I'd previously taken great care to avoid.
60 -# We now have to ensure that the chip drivers are initialised before the
61 -# map drivers, and that the doc200[01] drivers are initialised before
62 -# docprobe.
63 -#
64 -# We'll hopefully merge the doc200[01] drivers and docprobe back into
65 -# a single driver some time soon, but the CFI drivers are going to have
66 -# to stay like that.
67 -#
68 -# Urgh.
69 -# 
70 -# dwmw2 21/11/0
71 +# $Id: Makefile.common,v 1.5 2004/08/10 20:51:49 dwmw2 Exp $
72  
73  # Core functionality.
74 -obj-$(CONFIG_MTD)              += mtdcore.o
75 +mtd-y                          := mtdcore.o
76 +mtd-$(CONFIG_MTD_PARTITIONS)   += mtdpart.o
77 +obj-$(CONFIG_MTD)              += $(mtd-y)
78 +
79  obj-$(CONFIG_MTD_CONCAT)       += mtdconcat.o
80 -obj-$(CONFIG_MTD_PARTITIONS)   += mtdpart.o
81  obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
82  obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o
83  obj-$(CONFIG_MTD_AFS_PARTS)    += afs.o
84 Index: linux-2.6.5/drivers/mtd/afs.c
85 ===================================================================
86 --- linux-2.6.5.orig/drivers/mtd/afs.c  2004-04-03 22:38:15.000000000 -0500
87 +++ linux-2.6.5/drivers/mtd/afs.c       2005-02-01 17:11:17.000000000 -0500
88 @@ -21,7 +21,7 @@
89     This is access code for flashes using ARM's flash partitioning 
90     standards.
91  
92 -   $Id: afs.c,v 1.12 2003/06/13 15:31:06 rmk Exp $
93 +   $Id: afs.c,v 1.13 2004/02/27 22:09:59 rmk Exp $
94  
95  ======================================================================*/
96  
97 Index: linux-2.6.5/drivers/mtd/chips/Kconfig
98 ===================================================================
99 --- linux-2.6.5.orig/drivers/mtd/chips/Kconfig  2004-04-03 22:36:54.000000000 -0500
100 +++ linux-2.6.5/drivers/mtd/chips/Kconfig       2005-02-01 17:11:17.000000000 -0500
101 @@ -1,5 +1,5 @@
102  # drivers/mtd/chips/Kconfig
103 -# $Id: Kconfig,v 1.3 2003/05/28 15:13:24 dwmw2 Exp $
104 +# $Id: Kconfig,v 1.9 2004/07/16 15:32:14 dwmw2 Exp $
105  
106  menu "RAM/ROM/Flash chip drivers"
107         depends on MTD!=n
108 @@ -85,59 +85,72 @@
109           arrangements of CFI chips. If unsure, say 'N' and all options 
110           which are supported by the current code will be enabled.
111  
112 -config MTD_CFI_B1
113 -       bool "Support  8-bit buswidth"
114 -       depends on MTD_CFI_GEOMETRY
115 +config MTD_MAP_BANK_WIDTH_1
116 +       bool "Support  8-bit buswidth" if MTD_CFI_GEOMETRY
117 +       default y
118         help
119           If you wish to support CFI devices on a physical bus which is
120           8 bits wide, say 'Y'.
121  
122 -config MTD_CFI_B2
123 -       bool "Support 16-bit buswidth"
124 -       depends on MTD_CFI_GEOMETRY
125 +config MTD_MAP_BANK_WIDTH_2
126 +       bool "Support 16-bit buswidth" if MTD_CFI_GEOMETRY
127 +       default y
128         help
129           If you wish to support CFI devices on a physical bus which is
130           16 bits wide, say 'Y'.
131  
132 -config MTD_CFI_B4
133 -       bool "Support 32-bit buswidth"
134 -       depends on MTD_CFI_GEOMETRY
135 +config MTD_MAP_BANK_WIDTH_4
136 +       bool "Support 32-bit buswidth" if MTD_CFI_GEOMETRY
137 +       default y
138         help
139           If you wish to support CFI devices on a physical bus which is
140           32 bits wide, say 'Y'.
141  
142 -config MTD_CFI_B8
143 -       bool "Support 64-bit buswidth"
144 -       depends on MTD_CFI_GEOMETRY
145 +config MTD_MAP_BANK_WIDTH_8
146 +       bool "Support 64-bit buswidth" if MTD_CFI_GEOMETRY
147 +       default n
148         help
149           If you wish to support CFI devices on a physical bus which is
150           64 bits wide, say 'Y'.
151  
152 +config MTD_MAP_BANK_WIDTH_16
153 +       bool "Support 128-bit buswidth" if MTD_CFI_GEOMETRY
154 +       default n
155 +       help
156 +         If you wish to support CFI devices on a physical bus which is
157 +         128 bits wide, say 'Y'.
158 +
159 +config MTD_MAP_BANK_WIDTH_32
160 +       bool "Support 256-bit buswidth" if MTD_CFI_GEOMETRY
161 +       default n
162 +       help
163 +         If you wish to support CFI devices on a physical bus which is
164 +         256 bits wide, say 'Y'.
165 +
166  config MTD_CFI_I1
167 -       bool "Support 1-chip flash interleave" if !MTD_CFI_B1
168 -       depends on MTD_CFI_GEOMETRY
169 -       default y if MTD_CFI_B1
170 +       bool "Support 1-chip flash interleave" if MTD_CFI_GEOMETRY
171 +       default y
172         help
173           If your flash chips are not interleaved - i.e. you only have one
174           flash chip addressed by each bus cycle, then say 'Y'.
175  
176  config MTD_CFI_I2
177 -       bool "Support 2-chip flash interleave"
178 -       depends on MTD_CFI_GEOMETRY
179 +       bool "Support 2-chip flash interleave" if MTD_CFI_GEOMETRY
180 +       default y
181         help
182           If your flash chips are interleaved in pairs - i.e. you have two
183           flash chips addressed by each bus cycle, then say 'Y'.
184  
185  config MTD_CFI_I4
186 -       bool "Support 4-chip flash interleave"
187 -       depends on MTD_CFI_GEOMETRY
188 +       bool "Support 4-chip flash interleave" if MTD_CFI_GEOMETRY
189 +       default n
190         help
191           If your flash chips are interleaved in fours - i.e. you have four
192           flash chips addressed by each bus cycle, then say 'Y'.
193  
194  config MTD_CFI_I8
195 -       bool "Support 8-chip flash interleave"
196 -       depends on MTD_CFI_GEOMETRY
197 +       bool "Support 8-chip flash interleave" if MTD_CFI_GEOMETRY
198 +       default n
199         help
200           If your flash chips are interleaved in eights - i.e. you have eight
201           flash chips addressed by each bus cycle, then say 'Y'.
202 @@ -160,6 +173,27 @@
203           provides support for one of those command sets, used on chips 
204           including the AMD Am29LV320.
205  
206 +config MTD_CFI_AMDSTD_RETRY
207 +       int "Retry failed commands (erase/program)"
208 +       depends on MTD_CFI_AMDSTD
209 +       default "0"
210 +       help
211 +         Some chips, when attached to a shared bus, don't properly filter
212 +         bus traffic that is destined to other devices.  This broken
213 +         behavior causes erase and program sequences to be aborted when
214 +         the sequences are mixed with traffic for other devices.
215 +
216 +         SST49LF040 (and related) chips are know to be broken.
217 +
218 +config MTD_CFI_AMDSTD_RETRY_MAX
219 +       int "Max retries of failed commands (erase/program)"
220 +       depends on MTD_CFI_AMDSTD_RETRY
221 +       default "0"
222 +       help
223 +         If you have an SST49LF040 (or related chip) then this value should
224 +         be set to at least 1.  This can also be adjusted at driver load
225 +         time with the retry_cmd_max module parameter.
226 +
227  config MTD_CFI_STAA
228         tristate "Support for ST (Advanced Architecture) flash chips"
229         depends on MTD_GEN_PROBE
230 @@ -168,6 +202,11 @@
231           sets which a CFI-compliant chip may claim to implement. This code
232           provides support for one of those command sets.
233  
234 +config MTD_CFI_UTIL
235 +       tristate
236 +       default y if MTD_CFI_INTELEXT=y || MTD_CFI_AMDSTD=y || MTD_CFI_STAA=y
237 +       default m if MTD_CFI_INTELEXT=m || MTD_CFI_AMDSTD=m || MTD_CFI_STAA=m
238 +
239  config MTD_RAM
240         tristate "Support for RAM chips in bus mapping"
241         depends on MTD
242 @@ -194,6 +233,7 @@
243           with this driver will return -ENODEV upon access.
244  
245  config MTD_OBSOLETE_CHIPS
246 +       depends on MTD && BROKEN
247         bool "Older (theoretically obsoleted now) drivers for non-CFI chips"
248         help
249           This option does not enable any code directly, but will allow you to
250 Index: linux-2.6.5/drivers/mtd/chips/Makefile
251 ===================================================================
252 --- linux-2.6.5.orig/drivers/mtd/chips/Makefile 2004-04-03 22:36:53.000000000 -0500
253 +++ linux-2.6.5/drivers/mtd/chips/Makefile      2005-02-01 17:11:17.000000000 -0500
254 @@ -1,18 +1,19 @@
255  #
256  # linux/drivers/chips/Makefile
257  #
258 -# $Id: Makefile.common,v 1.1 2003/05/21 15:00:01 dwmw2 Exp $
259 +# $Id: Makefile.common,v 1.4 2004/07/12 16:07:30 dwmw2 Exp $
260  
261  #                       *** BIG UGLY NOTE ***
262  #
263  # The removal of get_module_symbol() and replacement with
264  # inter_module_register() et al has introduced a link order dependency
265  # here where previously there was none.  We now have to ensure that
266 -# the CFI command set drivers are linked before cfi_probe.o
267 +# the CFI command set drivers are linked before gen_probe.o
268  
269  obj-$(CONFIG_MTD)              += chipreg.o
270  obj-$(CONFIG_MTD_AMDSTD)       += amd_flash.o 
271  obj-$(CONFIG_MTD_CFI)          += cfi_probe.o
272 +obj-$(CONFIG_MTD_CFI_UTIL)     += cfi_util.o
273  obj-$(CONFIG_MTD_CFI_STAA)     += cfi_cmdset_0020.o
274  obj-$(CONFIG_MTD_CFI_AMDSTD)   += cfi_cmdset_0002.o
275  obj-$(CONFIG_MTD_CFI_INTELEXT) += cfi_cmdset_0001.o
276 Index: linux-2.6.5/drivers/mtd/chips/amd_flash.c
277 ===================================================================
278 --- linux-2.6.5.orig/drivers/mtd/chips/amd_flash.c      2004-04-03 22:36:53.000000000 -0500
279 +++ linux-2.6.5/drivers/mtd/chips/amd_flash.c   2005-02-01 17:11:17.000000000 -0500
280 @@ -3,7 +3,7 @@
281   *
282   * Author: Jonas Holmberg <jonas.holmberg@axis.com>
283   *
284 - * $Id: amd_flash.c,v 1.23 2003/06/12 09:24:13 dwmw2 Exp $
285 + * $Id: amd_flash.c,v 1.25 2004/08/09 13:19:43 dwmw2 Exp $
286   *
287   * Copyright (c) 2001 Axis Communications AB
288   *
289 @@ -718,7 +718,7 @@
290                        "memory for MTD erase region info\n", map->name);
291                 kfree(mtd);
292                 map->fldrv_priv = NULL;
293 -               return 0;
294 +               return NULL;
295         }
296  
297         reg_idx = 0;
298 @@ -780,8 +780,8 @@
299         map->fldrv_priv = private;
300  
301         map->fldrv = &amd_flash_chipdrv;
302 -       MOD_INC_USE_COUNT;
303  
304 +       __module_get(THIS_MODULE);
305         return mtd;
306  }
307  
308 @@ -1307,9 +1307,7 @@
309         }
310                 
311         instr->state = MTD_ERASE_DONE;
312 -       if (instr->callback) {
313 -               instr->callback(instr);
314 -       }
315 +       mtd_erase_callback(instr);
316         
317         return 0;
318  }
319 Index: linux-2.6.5/drivers/mtd/chips/cfi_cmdset_0001.c
320 ===================================================================
321 --- linux-2.6.5.orig/drivers/mtd/chips/cfi_cmdset_0001.c        2004-04-03 22:36:54.000000000 -0500
322 +++ linux-2.6.5/drivers/mtd/chips/cfi_cmdset_0001.c     2005-02-01 17:11:17.000000000 -0500
323 @@ -4,7 +4,7 @@
324   *
325   * (C) 2000 Red Hat. GPL'd
326   *
327 - * $Id: cfi_cmdset_0001.c,v 1.126 2003/06/23 07:45:48 dwmw2 Exp $
328 + * $Id: cfi_cmdset_0001.c,v 1.156 2004/09/17 11:45:05 eric Exp $
329   *
330   * 
331   * 10/10/2000  Nicolas Pitre <nico@cam.org>
332 @@ -34,12 +34,20 @@
333  #include <linux/mtd/compatmac.h>
334  #include <linux/mtd/cfi.h>
335  
336 +/* #define CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE */
337 +
338  // debugging, turns off buffer write mode if set to 1
339  #define FORCE_WORD_WRITE 0
340  
341 +#define MANUFACTURER_INTEL     0x0089
342 +#define I82802AB       0x00ad
343 +#define I82802AC       0x00ac
344 +#define MANUFACTURER_ST         0x0020
345 +#define M50LPW080       0x002F
346 +
347  static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
348 -static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
349 -static int cfi_intelext_read_fact_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
350 +//static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
351 +//static int cfi_intelext_read_fact_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
352  static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
353  static int cfi_intelext_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
354  static int cfi_intelext_erase_varsize(struct mtd_info *, struct erase_info *);
355 @@ -53,13 +61,19 @@
356  
357  struct mtd_info *cfi_cmdset_0001(struct map_info *, int);
358  
359 -static struct mtd_info *cfi_intelext_setup (struct map_info *);
360 +static struct mtd_info *cfi_intelext_setup (struct mtd_info *);
361 +static int cfi_intelext_partition_fixup(struct map_info *, struct cfi_private **);
362  
363  static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len,
364                      size_t *retlen, u_char **mtdbuf);
365  static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from,
366                         size_t len);
367  
368 +static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode);
369 +static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr);
370 +#include "fwh_lock.h"
371 +
372 +
373  
374  /*
375   *  *********** SETUP AND PROBE BITS  ***********
376 @@ -79,17 +93,18 @@
377  static void cfi_tell_features(struct cfi_pri_intelext *extp)
378  {
379         int i;
380 -       printk("  Feature/Command Support: %4.4X\n", extp->FeatureSupport);
381 -       printk("     - Chip Erase:         %s\n", extp->FeatureSupport&1?"supported":"unsupported");
382 -       printk("     - Suspend Erase:      %s\n", extp->FeatureSupport&2?"supported":"unsupported");
383 -       printk("     - Suspend Program:    %s\n", extp->FeatureSupport&4?"supported":"unsupported");
384 -       printk("     - Legacy Lock/Unlock: %s\n", extp->FeatureSupport&8?"supported":"unsupported");
385 -       printk("     - Queued Erase:       %s\n", extp->FeatureSupport&16?"supported":"unsupported");
386 -       printk("     - Instant block lock: %s\n", extp->FeatureSupport&32?"supported":"unsupported");
387 -       printk("     - Protection Bits:    %s\n", extp->FeatureSupport&64?"supported":"unsupported");
388 -       printk("     - Page-mode read:     %s\n", extp->FeatureSupport&128?"supported":"unsupported");
389 -       printk("     - Synchronous read:   %s\n", extp->FeatureSupport&256?"supported":"unsupported");
390 -       for (i=9; i<32; i++) {
391 +       printk("  Feature/Command Support:      %4.4X\n", extp->FeatureSupport);
392 +       printk("     - Chip Erase:              %s\n", extp->FeatureSupport&1?"supported":"unsupported");
393 +       printk("     - Suspend Erase:           %s\n", extp->FeatureSupport&2?"supported":"unsupported");
394 +       printk("     - Suspend Program:         %s\n", extp->FeatureSupport&4?"supported":"unsupported");
395 +       printk("     - Legacy Lock/Unlock:      %s\n", extp->FeatureSupport&8?"supported":"unsupported");
396 +       printk("     - Queued Erase:            %s\n", extp->FeatureSupport&16?"supported":"unsupported");
397 +       printk("     - Instant block lock:      %s\n", extp->FeatureSupport&32?"supported":"unsupported");
398 +       printk("     - Protection Bits:         %s\n", extp->FeatureSupport&64?"supported":"unsupported");
399 +       printk("     - Page-mode read:          %s\n", extp->FeatureSupport&128?"supported":"unsupported");
400 +       printk("     - Synchronous read:        %s\n", extp->FeatureSupport&256?"supported":"unsupported");
401 +       printk("     - Simultaneous operations: %s\n", extp->FeatureSupport&512?"supported":"unsupported");
402 +       for (i=10; i<32; i++) {
403                 if (extp->FeatureSupport & (1<<i)) 
404                         printk("     - Unknown Bit %X:      supported\n", i);
405         }
406 @@ -110,13 +125,93 @@
407         }
408         
409         printk("  Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n", 
410 -              extp->VccOptimal >> 8, extp->VccOptimal & 0xf);
411 +              extp->VccOptimal >> 4, extp->VccOptimal & 0xf);
412         if (extp->VppOptimal)
413                 printk("  Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n", 
414 -                      extp->VppOptimal >> 8, extp->VppOptimal & 0xf);
415 +                      extp->VppOptimal >> 4, extp->VppOptimal & 0xf);
416 +}
417 +#endif
418 +
419 +#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
420 +/* Some Intel Strata Flash prior to FPO revision C has bugs in this area */ 
421 +static void fixup_intel_strataflash(struct mtd_info *mtd, void* param)
422 +{
423 +       struct map_info *map = mtd->priv;
424 +       struct cfi_private *cfi = map->fldrv_priv;
425 +       struct cfi_pri_amdstd *extp = cfi->cmdset_priv;
426 +
427 +       printk(KERN_WARNING "cfi_cmdset_0001: Suspend "
428 +                           "erase on write disabled.\n");
429 +       extp->SuspendCmdSupport &= ~1;
430  }
431  #endif
432  
433 +static void fixup_st_m28w320ct(struct mtd_info *mtd, void* param)
434 +{
435 +       struct map_info *map = mtd->priv;
436 +       struct cfi_private *cfi = map->fldrv_priv;
437 +       
438 +       cfi->cfiq->BufWriteTimeoutTyp = 0;      /* Not supported */
439 +       cfi->cfiq->BufWriteTimeoutMax = 0;      /* Not supported */
440 +}
441 +
442 +static void fixup_st_m28w320cb(struct mtd_info *mtd, void* param)
443 +{
444 +       struct map_info *map = mtd->priv;
445 +       struct cfi_private *cfi = map->fldrv_priv;
446 +       
447 +       /* Note this is done after the region info is endian swapped */
448 +       cfi->cfiq->EraseRegionInfo[1] =
449 +               (cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e;
450 +};
451 +
452 +static void fixup_use_point(struct mtd_info *mtd, void *param)
453 +{
454 +       struct map_info *map = mtd->priv;
455 +       if (!mtd->point && map_is_linear(map)) {
456 +               mtd->point   = cfi_intelext_point;
457 +               mtd->unpoint = cfi_intelext_unpoint;
458 +       }
459 +}
460 +
461 +static void fixup_use_write_buffers(struct mtd_info *mtd, void *param)
462 +{
463 +       struct map_info *map = mtd->priv;
464 +       struct cfi_private *cfi = map->fldrv_priv;
465 +       if (cfi->cfiq->BufWriteTimeoutTyp) {
466 +               printk(KERN_INFO "Using buffer write method\n" );
467 +               mtd->write = cfi_intelext_write_buffers;
468 +       }
469 +}
470 +
471 +static struct cfi_fixup cfi_fixup_table[] = {
472 +#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
473 +       { CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash, NULL }, 
474 +#endif
475 +#if !FORCE_WORD_WRITE
476 +       { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL },
477 +#endif
478 +       { CFI_MFR_ST, 0x00ba, /* M28W320CT */ fixup_st_m28w320ct, NULL },
479 +       { CFI_MFR_ST, 0x00bb, /* M28W320CB */ fixup_st_m28w320cb, NULL },
480 +       { 0, 0, NULL, NULL }
481 +};
482 +
483 +static struct cfi_fixup jedec_fixup_table[] = {
484 +       { MANUFACTURER_INTEL, I82802AB,   fixup_use_fwh_lock, NULL, },
485 +       { MANUFACTURER_INTEL, I82802AC,   fixup_use_fwh_lock, NULL, },
486 +       { MANUFACTURER_ST,    M50LPW080,  fixup_use_fwh_lock, NULL, },
487 +       { 0, 0, NULL, NULL }
488 +};
489 +static struct cfi_fixup fixup_table[] = {
490 +       /* The CFI vendor ids and the JEDEC vendor IDs appear
491 +        * to be common.  It is like the devices id's are as
492 +        * well.  This table is to pick all cases where
493 +        * we know that is the case.
494 +        */
495 +       { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_point, NULL },
496 +       { 0, 0, NULL, NULL }
497 +};
498 +
499  /* This routine is made available to other mtd code via
500   * inter_module_register.  It must only be accessed through
501   * inter_module_get which will bump the use count of this module.  The
502 @@ -127,9 +222,30 @@
503  struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
504  {
505         struct cfi_private *cfi = map->fldrv_priv;
506 +       struct mtd_info *mtd;
507         int i;
508 -       __u32 base = cfi->chips[0].start;
509  
510 +       mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
511 +       if (!mtd) {
512 +               printk(KERN_ERR "Failed to allocate memory for MTD device\n");
513 +               return NULL;
514 +       }
515 +       memset(mtd, 0, sizeof(*mtd));
516 +       mtd->priv = map;
517 +       mtd->type = MTD_NORFLASH;
518 +
519 +       /* Fill in the default mtd operations */
520 +       mtd->erase   = cfi_intelext_erase_varsize;
521 +       mtd->read    = cfi_intelext_read;
522 +       mtd->write   = cfi_intelext_write_words;
523 +       mtd->sync    = cfi_intelext_sync;
524 +       mtd->lock    = cfi_intelext_lock;
525 +       mtd->unlock  = cfi_intelext_unlock;
526 +       mtd->suspend = cfi_intelext_suspend;
527 +       mtd->resume  = cfi_intelext_resume;
528 +       mtd->flags   = MTD_CAP_NORFLASH;
529 +       mtd->name    = map->name;
530 +       
531         if (cfi->cfi_mode == CFI_MODE_CFI) {
532                 /* 
533                  * It's a real CFI chip, not one for which the probe
534 @@ -138,33 +254,10 @@
535                  */
536                 __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
537                 struct cfi_pri_intelext *extp;
538 -               int ofs_factor = cfi->interleave * cfi->device_type;
539 -
540 -               //printk(" Intel/Sharp Extended Query Table at 0x%4.4X\n", adr);
541 -               if (!adr)
542 -                       return NULL;
543  
544 -               /* Switch it into Query Mode */
545 -               cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
546 -
547 -               extp = kmalloc(sizeof(*extp), GFP_KERNEL);
548 +               extp = (struct cfi_pri_intelext*)cfi_read_pri(map, adr, sizeof(*extp), "Intel/Sharp");
549                 if (!extp) {
550 -                       printk(KERN_ERR "Failed to allocate memory\n");
551 -                       return NULL;
552 -               }
553 -               
554 -               /* Read in the Extended Query Table */
555 -               for (i=0; i<sizeof(*extp); i++) {
556 -                       ((unsigned char *)extp)[i] = 
557 -                               cfi_read_query(map, (base+((adr+i)*ofs_factor)));
558 -               }
559 -               
560 -               if (extp->MajorVersion != '1' || 
561 -                   (extp->MinorVersion < '0' || extp->MinorVersion > '3')) {
562 -                       printk(KERN_WARNING "  Unknown IntelExt Extended Query "
563 -                              "version %c.%c.\n",  extp->MajorVersion,
564 -                              extp->MinorVersion);
565 -                       kfree(extp);
566 +                       kfree(mtd);
567                         return NULL;
568                 }
569                 
570 @@ -172,6 +265,11 @@
571                 extp->FeatureSupport = le32_to_cpu(extp->FeatureSupport);
572                 extp->BlkStatusRegMask = le16_to_cpu(extp->BlkStatusRegMask);
573                 extp->ProtRegAddr = le16_to_cpu(extp->ProtRegAddr);
574 +
575 +               /* Install our own private info structure */
576 +               cfi->cmdset_priv = extp;        
577 +
578 +               cfi_fixup(mtd, cfi_fixup_table);
579                         
580  #ifdef DEBUG_CFI_FEATURES
581                 /* Tell the user about it in lots of lovely detail */
582 @@ -179,19 +277,15 @@
583  #endif 
584  
585                 if(extp->SuspendCmdSupport & 1) {
586 -//#define CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
587 -#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
588 -/* Some Intel Strata Flash prior to FPO revision C has bugs in this area */ 
589 -                       printk(KERN_WARNING "cfi_cmdset_0001: Suspend "
590 -                              "erase on write disabled.\n");
591 -                       extp->SuspendCmdSupport &= ~1;
592 -#else
593                         printk(KERN_NOTICE "cfi_cmdset_0001: Erase suspend on write enabled\n");
594 -#endif
595                 }
596 -               /* Install our own private info structure */
597 -               cfi->cmdset_priv = extp;        
598         }
599 +       else if (cfi->cfi_mode == CFI_MODE_JEDEC) {
600 +               /* Apply jedec specific fixups */
601 +               cfi_fixup(mtd, jedec_fixup_table);
602 +       }
603 +       /* Apply generic fixups */
604 +       cfi_fixup(mtd, fixup_table);
605  
606         for (i=0; i< cfi->numchips; i++) {
607                 cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;
608 @@ -202,30 +296,19 @@
609  
610         map->fldrv = &cfi_intelext_chipdrv;
611         
612 -       /* Make sure it's in read mode */
613 -       cfi_send_gen_cmd(0xff, 0x55, base, map, cfi, cfi->device_type, NULL);
614 -       return cfi_intelext_setup(map);
615 +       return cfi_intelext_setup(mtd);
616  }
617  
618 -static struct mtd_info *cfi_intelext_setup(struct map_info *map)
619 +static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
620  {
621 +       struct map_info *map = mtd->priv;
622         struct cfi_private *cfi = map->fldrv_priv;
623 -       struct mtd_info *mtd;
624         unsigned long offset = 0;
625         int i,j;
626         unsigned long devsize = (1<<cfi->cfiq->DevSize) * cfi->interleave;
627  
628 -       mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
629         //printk(KERN_DEBUG "number of CFI chips: %d\n", cfi->numchips);
630  
631 -       if (!mtd) {
632 -               printk(KERN_ERR "Failed to allocate memory for MTD device\n");
633 -               goto setup_err;
634 -       }
635 -
636 -       memset(mtd, 0, sizeof(*mtd));
637 -       mtd->priv = map;
638 -       mtd->type = MTD_NORFLASH;
639         mtd->size = devsize * cfi->numchips;
640  
641         mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
642 @@ -265,32 +348,16 @@
643                        mtd->eraseregions[i].numblocks);
644         }
645  
646 -       /* Also select the correct geometry setup too */ 
647 -       mtd->erase = cfi_intelext_erase_varsize;
648 -       mtd->read = cfi_intelext_read;
649 -
650 -       if (map_is_linear(map)) {
651 -               mtd->point = cfi_intelext_point;
652 -               mtd->unpoint = cfi_intelext_unpoint;
653 -       }
654 -
655 -       if ( cfi->cfiq->BufWriteTimeoutTyp && !FORCE_WORD_WRITE) {
656 -               printk(KERN_INFO "Using buffer write method\n" );
657 -               mtd->write = cfi_intelext_write_buffers;
658 -       } else {
659 -               printk(KERN_INFO "Using word write method\n" );
660 -               mtd->write = cfi_intelext_write_words;
661 -       }
662 +#if 0
663         mtd->read_user_prot_reg = cfi_intelext_read_user_prot_reg;
664         mtd->read_fact_prot_reg = cfi_intelext_read_fact_prot_reg;
665 -       mtd->sync = cfi_intelext_sync;
666 -       mtd->lock = cfi_intelext_lock;
667 -       mtd->unlock = cfi_intelext_unlock;
668 -       mtd->suspend = cfi_intelext_suspend;
669 -       mtd->resume = cfi_intelext_resume;
670 -       mtd->flags = MTD_CAP_NORFLASH;
671 -       map->fldrv = &cfi_intelext_chipdrv;
672 -       mtd->name = map->name;
673 +#endif
674 +
675 +       /* This function has the potential to distort the reality
676 +          a bit and therefore should be called last. */
677 +       if (cfi_intelext_partition_fixup(map, &cfi) != 0)
678 +               goto setup_err;
679 +
680         __module_get(THIS_MODULE);
681         return mtd;
682  
683 @@ -301,10 +368,87 @@
684                 kfree(mtd);
685         }
686         kfree(cfi->cmdset_priv);
687 -       kfree(cfi->cfiq);
688         return NULL;
689  }
690  
691 +static int cfi_intelext_partition_fixup(struct map_info *map,
692 +                                       struct cfi_private **pcfi)
693 +{
694 +       struct cfi_private *cfi = *pcfi;
695 +       struct cfi_pri_intelext *extp = cfi->cmdset_priv;
696 +
697 +       /*
698 +        * Probing of multi-partition flash ships.
699 +        *
700 +        * This is extremely crude at the moment and should probably be
701 +        * extracted entirely from the Intel extended query data instead.
702 +        * Right now a L18 flash is assumed if multiple operations is
703 +        * detected.
704 +        *
705 +        * To support multiple partitions when available, we simply arrange
706 +        * for each of them to have their own flchip structure even if they
707 +        * are on the same physical chip.  This means completely recreating
708 +        * a new cfi_private structure right here which is a blatent code
709 +        * layering violation, but this is still the least intrusive
710 +        * arrangement at this point. This can be rearranged in the future
711 +        * if someone feels motivated enough.  --nico
712 +        */
713 +       if (extp && extp->FeatureSupport & (1 << 9)) {
714 +               struct cfi_private *newcfi;
715 +               struct flchip *chip;
716 +               struct flchip_shared *shared;
717 +               int numparts, partshift, numvirtchips, i, j;
718 +
719 +               /*
720 +                * The L18 flash memory array is divided
721 +                * into multiple 8-Mbit partitions.
722 +                */
723 +               numparts = 1 << (cfi->cfiq->DevSize - 20);
724 +               partshift = 20 + __ffs(cfi->interleave);
725 +               numvirtchips = cfi->numchips * numparts;
726 +
727 +               newcfi = kmalloc(sizeof(struct cfi_private) + numvirtchips * sizeof(struct flchip), GFP_KERNEL);
728 +               if (!newcfi)
729 +                       return -ENOMEM;
730 +               shared = kmalloc(sizeof(struct flchip_shared) * cfi->numchips, GFP_KERNEL);
731 +               if (!shared) {
732 +                       kfree(newcfi);
733 +                       return -ENOMEM;
734 +               }
735 +               memcpy(newcfi, cfi, sizeof(struct cfi_private));
736 +               newcfi->numchips = numvirtchips;
737 +               newcfi->chipshift = partshift;
738 +
739 +               chip = &newcfi->chips[0];
740 +               for (i = 0; i < cfi->numchips; i++) {
741 +                       shared[i].writing = shared[i].erasing = NULL;
742 +                       spin_lock_init(&shared[i].lock);
743 +                       for (j = 0; j < numparts; j++) {
744 +                               *chip = cfi->chips[i];
745 +                               chip->start += j << partshift;
746 +                               chip->priv = &shared[i];
747 +                               /* those should be reset too since
748 +                                  they create memory references. */
749 +                               init_waitqueue_head(&chip->wq);
750 +                               spin_lock_init(&chip->_spinlock);
751 +                               chip->mutex = &chip->_spinlock;
752 +                               chip++;
753 +                       }
754 +               }
755 +
756 +               printk(KERN_DEBUG "%s: %d sets of %d interleaved chips "
757 +                                 "--> %d partitions of %#x bytes\n",
758 +                                 map->name, cfi->numchips, cfi->interleave,
759 +                                 newcfi->numchips, 1<<newcfi->chipshift);
760 +
761 +               map->fldrv_priv = newcfi;
762 +               *pcfi = newcfi;
763 +               kfree(cfi);
764 +       }
765 +
766 +       return 0;
767 +}
768 +
769  /*
770   *  *********** CHIP ACCESS FUNCTIONS ***********
771   */
772 @@ -313,25 +457,87 @@
773  {
774         DECLARE_WAITQUEUE(wait, current);
775         struct cfi_private *cfi = map->fldrv_priv;
776 -       cfi_word status, status_OK = CMD(0x80);
777 +       map_word status, status_OK = CMD(0x80), status_PWS = CMD(0x01);
778         unsigned long timeo;
779 -       struct cfi_pri_intelext *cfip = (struct cfi_pri_intelext *)cfi->cmdset_priv;
780 +       struct cfi_pri_intelext *cfip = cfi->cmdset_priv;
781  
782   resettime:
783         timeo = jiffies + HZ;
784   retry:
785 +       if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING)) {
786 +               /*
787 +                * OK. We have possibility for contension on the write/erase
788 +                * operations which are global to the real chip and not per
789 +                * partition.  So let's fight it over in the partition which
790 +                * currently has authority on the operation.
791 +                *
792 +                * The rules are as follows:
793 +                *
794 +                * - any write operation must own shared->writing.
795 +                *
796 +                * - any erase operation must own _both_ shared->writing and
797 +                *   shared->erasing.
798 +                *
799 +                * - contension arbitration is handled in the owner's context.
800 +                *
801 +                * The 'shared' struct can be read when its lock is taken.
802 +                * However any writes to it can only be made when the current
803 +                * owner's lock is also held.
804 +                */
805 +               struct flchip_shared *shared = chip->priv;
806 +               struct flchip *contender;
807 +               spin_lock(&shared->lock);
808 +               contender = shared->writing;
809 +               if (contender && contender != chip) {
810 +                       /*
811 +                        * The engine to perform desired operation on this
812 +                        * partition is already in use by someone else.
813 +                        * Let's fight over it in the context of the chip
814 +                        * currently using it.  If it is possible to suspend,
815 +                        * that other partition will do just that, otherwise
816 +                        * it'll happily send us to sleep.  In any case, when
817 +                        * get_chip returns success we're clear to go ahead.
818 +                        */
819 +                       int ret = spin_trylock(contender->mutex);
820 +                       spin_unlock(&shared->lock);
821 +                       if (!ret)
822 +                               goto retry;
823 +                       spin_unlock(chip->mutex);
824 +                       ret = get_chip(map, contender, contender->start, mode);
825 +                       spin_lock(chip->mutex);
826 +                       if (ret) {
827 +                               spin_unlock(contender->mutex);
828 +                               return ret;
829 +                       }
830 +                       timeo = jiffies + HZ;
831 +                       spin_lock(&shared->lock);
832 +               }
833 +
834 +               /* We now own it */
835 +               shared->writing = chip;
836 +               if (mode == FL_ERASING)
837 +                       shared->erasing = chip;
838 +               if (contender && contender != chip)
839 +                       spin_unlock(contender->mutex);
840 +               spin_unlock(&shared->lock);
841 +       }
842 +
843         switch (chip->state) {
844  
845         case FL_STATUS:
846                 for (;;) {
847 -                       status = cfi_read(map, adr);
848 -                       if ((status & status_OK) == status_OK)
849 +                       status = map_read(map, adr);
850 +                       if (map_word_andequal(map, status, status_OK, status_OK))
851 +                               break;
852 +
853 +                       /* At this point we're fine with write operations
854 +                          in other partitions as they don't conflict. */
855 +                       if (chip->priv && map_word_andequal(map, status, status_PWS, status_PWS))
856                                 break;
857  
858                         if (time_after(jiffies, timeo)) {
859 -                               printk(KERN_ERR "Waiting for chip to be ready timed out. Status %llx\n", 
860 -                                      (long long)status);
861 -                               spin_unlock(chip->mutex);
862 +                               printk(KERN_ERR "Waiting for chip to be ready timed out. Status %lx\n", 
863 +                                      status.x[0]);
864                                 return -EIO;
865                         }
866                         spin_unlock(chip->mutex);
867 @@ -347,38 +553,39 @@
868                 return 0;
869  
870         case FL_ERASING:
871 -               if (!(cfip->FeatureSupport & 2) ||
872 +               if (!cfip ||
873 +                   !(cfip->FeatureSupport & 2) ||
874                     !(mode == FL_READY || mode == FL_POINT ||
875                      (mode == FL_WRITING && (cfip->SuspendCmdSupport & 1))))
876                         goto sleep;
877  
878  
879                 /* Erase suspend */
880 -               cfi_write(map, CMD(0xB0), adr);
881 +               map_write(map, CMD(0xB0), adr);
882  
883                 /* If the flash has finished erasing, then 'erase suspend'
884                  * appears to make some (28F320) flash devices switch to
885                  * 'read' mode.  Make sure that we switch to 'read status'
886                  * mode so we get the right data. --rmk
887                  */
888 -               cfi_write(map, CMD(0x70), adr);
889 +               map_write(map, CMD(0x70), adr);
890                 chip->oldstate = FL_ERASING;
891                 chip->state = FL_ERASE_SUSPENDING;
892                 chip->erase_suspended = 1;
893                 for (;;) {
894 -                       status = cfi_read(map, adr);
895 -                       if ((status & status_OK) == status_OK)
896 +                       status = map_read(map, adr);
897 +                       if (map_word_andequal(map, status, status_OK, status_OK))
898                                 break;
899  
900                         if (time_after(jiffies, timeo)) {
901                                 /* Urgh. Resume and pretend we weren't here.  */
902 -                               cfi_write(map, CMD(0xd0), adr);
903 +                               map_write(map, CMD(0xd0), adr);
904                                 /* Make sure we're in 'read status' mode if it had finished */
905 -                               cfi_write(map, CMD(0x70), adr);
906 +                               map_write(map, CMD(0x70), adr);
907                                 chip->state = FL_ERASING;
908                                 chip->oldstate = FL_READY;
909                                 printk(KERN_ERR "Chip not ready after erase "
910 -                                      "suspended: status = 0x%x\n", status);
911 +                                      "suspended: status = 0x%lx\n", status.x[0]);
912                                 return -EIO;
913                         }
914  
915 @@ -412,6 +619,32 @@
916  {
917         struct cfi_private *cfi = map->fldrv_priv;
918  
919 +       if (chip->priv) {
920 +               struct flchip_shared *shared = chip->priv;
921 +               spin_lock(&shared->lock);
922 +               if (shared->writing == chip) {
923 +                       /* We own the ability to write, but we're done */
924 +                       shared->writing = shared->erasing;
925 +                       if (shared->writing && shared->writing != chip) {
926 +                               /* give back ownership to who we loaned it from */
927 +                               struct flchip *loaner = shared->writing;
928 +                               spin_lock(loaner->mutex);
929 +                               spin_unlock(&shared->lock);
930 +                               spin_unlock(chip->mutex);
931 +                               put_chip(map, loaner, loaner->start);
932 +                               spin_lock(chip->mutex);
933 +                               spin_unlock(loaner->mutex);
934 +                       } else {
935 +                               if (chip->oldstate != FL_ERASING) {
936 +                                       shared->erasing = NULL;
937 +                                       if (chip->oldstate != FL_WRITING)
938 +                                               shared->writing = NULL;
939 +                               }
940 +                               spin_unlock(&shared->lock);
941 +                       }
942 +               }
943 +       }
944 +
945         switch(chip->oldstate) {
946         case FL_ERASING:
947                 chip->state = chip->oldstate;
948 @@ -424,13 +657,15 @@
949                    sending the 0x70 (Read Status) command to an erasing
950                    chip and expecting it to be ignored, that's what we 
951                    do. */
952 -               cfi_write(map, CMD(0xd0), adr);
953 -               cfi_write(map, CMD(0x70), adr);
954 +               map_write(map, CMD(0xd0), adr);
955 +               map_write(map, CMD(0x70), adr);
956                 chip->oldstate = FL_READY;
957                 chip->state = FL_ERASING;
958                 break;
959  
960         case FL_READY:
961 +       case FL_STATUS:
962 +       case FL_JEDEC_QUERY:
963                 /* We should really make set_vpp() count, rather than doing this */
964                 DISABLE_VPP(map);
965                 break;
966 @@ -449,7 +684,7 @@
967         adr += chip->start;
968  
969         /* Ensure cmd read/writes are aligned. */ 
970 -       cmd_addr = adr & ~(CFIDEV_BUSWIDTH-1); 
971 +       cmd_addr = adr & ~(map_bankwidth(map)-1); 
972  
973         spin_lock(chip->mutex);
974  
975 @@ -457,7 +692,7 @@
976  
977         if (!ret) {
978                 if (chip->state != FL_POINT && chip->state != FL_READY)
979 -                       cfi_write(map, CMD(0xff), cmd_addr);
980 +                       map_write(map, CMD(0xff), cmd_addr);
981  
982                 chip->state = FL_POINT;
983                 chip->ref_point_counter++;
984 @@ -475,12 +710,10 @@
985         int chipnum;
986         int ret = 0;
987  
988 -       if (from + len > mtd->size)
989 +       if (!map->virt || (from + len > mtd->size))
990                 return -EINVAL;
991         
992         *mtdbuf = (void *)map->virt + from;
993 -       if(*mtdbuf == NULL)
994 -               return -EINVAL; /* can not point this region */
995         *retlen = 0;
996  
997         /* Now lock the chip(s) to POINT state */
998 @@ -565,7 +798,7 @@
999         adr += chip->start;
1000  
1001         /* Ensure cmd read/writes are aligned. */ 
1002 -       cmd_addr = adr & ~(CFIDEV_BUSWIDTH-1); 
1003 +       cmd_addr = adr & ~(map_bankwidth(map)-1); 
1004  
1005         spin_lock(chip->mutex);
1006         ret = get_chip(map, chip, cmd_addr, FL_READY);
1007 @@ -575,7 +808,7 @@
1008         }
1009  
1010         if (chip->state != FL_POINT && chip->state != FL_READY) {
1011 -               cfi_write(map, CMD(0xff), cmd_addr);
1012 +               map_write(map, CMD(0xff), cmd_addr);
1013  
1014                 chip->state = FL_READY;
1015         }
1016 @@ -626,7 +859,7 @@
1017         }
1018         return ret;
1019  }
1020 -
1021 +#if 0
1022  static int cfi_intelext_read_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, int base_offst, int reg_sz)
1023  {
1024         struct map_info *map = mtd->priv;
1025 @@ -657,7 +890,7 @@
1026                 }
1027  
1028                 if (chip->state != FL_JEDEC_QUERY) {
1029 -                       cfi_write(map, CMD(0x90), chip->start);
1030 +                       map_write(map, CMD(0x90), chip->start);
1031                         chip->state = FL_JEDEC_QUERY;
1032                 }
1033  
1034 @@ -688,7 +921,7 @@
1035         int base_offst,reg_sz;
1036         
1037         /* Check that we actually have some protection registers */
1038 -       if(!(extp->FeatureSupport&64)){
1039 +       if(!extp || !(extp->FeatureSupport&64)){
1040                 printk(KERN_WARNING "%s: This flash device has no protection data to read!\n",map->name);
1041                 return 0;
1042         }
1043 @@ -707,7 +940,7 @@
1044         int base_offst,reg_sz;
1045         
1046         /* Check that we actually have some protection registers */
1047 -       if(!(extp->FeatureSupport&64)){
1048 +       if(!extp || !(extp->FeatureSupport&64)){
1049                 printk(KERN_WARNING "%s: This flash device has no protection data to read!\n",map->name);
1050                 return 0;
1051         }
1052 @@ -717,12 +950,12 @@
1053  
1054         return cfi_intelext_read_prot_reg(mtd, from, len, retlen, buf, base_offst, reg_sz);
1055  }
1056 +#endif
1057  
1058 -
1059 -static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, cfi_word datum)
1060 +static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, map_word datum)
1061  {
1062         struct cfi_private *cfi = map->fldrv_priv;
1063 -       cfi_word status, status_OK;
1064 +       map_word status, status_OK;
1065         unsigned long timeo;
1066         int z, ret=0;
1067  
1068 @@ -739,11 +972,12 @@
1069         }
1070  
1071         ENABLE_VPP(map);
1072 -       cfi_write(map, CMD(0x40), adr);
1073 -       cfi_write(map, datum, adr);
1074 +       map_write(map, CMD(0x40), adr);
1075 +       map_write(map, datum, adr);
1076         chip->state = FL_WRITING;
1077  
1078         spin_unlock(chip->mutex);
1079 +       INVALIDATE_CACHED_RANGE(map, adr, map_bankwidth(map));
1080         cfi_udelay(chip->word_write_time);
1081         spin_lock(chip->mutex);
1082  
1083 @@ -764,8 +998,8 @@
1084                         continue;
1085                 }
1086  
1087 -               status = cfi_read(map, adr);
1088 -               if ((status & status_OK) == status_OK)
1089 +               status = map_read(map, adr);
1090 +               if (map_word_andequal(map, status, status_OK, status_OK))
1091                         break;
1092                 
1093                 /* OK Still waiting */
1094 @@ -793,11 +1027,11 @@
1095         /* Done and happy. */
1096         chip->state = FL_STATUS;
1097         /* check for lock bit */
1098 -       if (status & CMD(0x02)) {
1099 +       if (map_word_bitsset(map, status, CMD(0x02))) {
1100                 /* clear status */
1101 -               cfi_write(map, CMD(0x50), adr);
1102 +               map_write(map, CMD(0x50), adr);
1103                 /* put back into read status register mode */
1104 -               cfi_write(map, CMD(0x70), adr);
1105 +               map_write(map, CMD(0x70), adr);
1106                 ret = -EROFS;
1107         }
1108   out:
1109 @@ -824,35 +1058,22 @@
1110         ofs = to  - (chipnum << cfi->chipshift);
1111  
1112         /* If it's not bus-aligned, do the first byte write */
1113 -       if (ofs & (CFIDEV_BUSWIDTH-1)) {
1114 -               unsigned long bus_ofs = ofs & ~(CFIDEV_BUSWIDTH-1);
1115 +       if (ofs & (map_bankwidth(map)-1)) {
1116 +               unsigned long bus_ofs = ofs & ~(map_bankwidth(map)-1);
1117                 int gap = ofs - bus_ofs;
1118 -               int i = 0, n = 0;
1119 -               u_char tmp_buf[8];
1120 -               cfi_word datum;
1121 -
1122 -               while (gap--)
1123 -                       tmp_buf[i++] = 0xff;
1124 -               while (len && i < CFIDEV_BUSWIDTH)
1125 -                       tmp_buf[i++] = buf[n++], len--;
1126 -               while (i < CFIDEV_BUSWIDTH)
1127 -                       tmp_buf[i++] = 0xff;
1128 -
1129 -               if (cfi_buswidth_is_2()) {
1130 -                       datum = *(__u16*)tmp_buf;
1131 -               } else if (cfi_buswidth_is_4()) {
1132 -                       datum = *(__u32*)tmp_buf;
1133 -               } else if (cfi_buswidth_is_8()) {
1134 -                       datum = *(__u64*)tmp_buf;
1135 -               } else {
1136 -                       return -EINVAL;  /* should never happen, but be safe */
1137 -               }
1138 +               int n;
1139 +               map_word datum;
1140 +
1141 +               n = min_t(int, len, map_bankwidth(map)-gap);
1142 +               datum = map_word_ff(map);
1143 +               datum = map_word_load_partial(map, datum, buf, gap, n);
1144  
1145                 ret = do_write_oneword(map, &cfi->chips[chipnum],
1146                                                bus_ofs, datum);
1147                 if (ret) 
1148                         return ret;
1149 -               
1150 +
1151 +               len -= n;
1152                 ofs += n;
1153                 buf += n;
1154                 (*retlen) += n;
1155 @@ -865,30 +1086,18 @@
1156                 }
1157         }
1158         
1159 -       while(len >= CFIDEV_BUSWIDTH) {
1160 -               cfi_word datum;
1161 -
1162 -               if (cfi_buswidth_is_1()) {
1163 -                       datum = *(__u8*)buf;
1164 -               } else if (cfi_buswidth_is_2()) {
1165 -                       datum = *(__u16*)buf;
1166 -               } else if (cfi_buswidth_is_4()) {
1167 -                       datum = *(__u32*)buf;
1168 -               } else if (cfi_buswidth_is_8()) {
1169 -                       datum = *(__u64*)buf;
1170 -               } else {
1171 -                       return -EINVAL;
1172 -               }
1173 +       while(len >= map_bankwidth(map)) {
1174 +               map_word datum = map_word_load(map, buf);
1175  
1176                 ret = do_write_oneword(map, &cfi->chips[chipnum],
1177                                 ofs, datum);
1178                 if (ret)
1179                         return ret;
1180  
1181 -               ofs += CFIDEV_BUSWIDTH;
1182 -               buf += CFIDEV_BUSWIDTH;
1183 -               (*retlen) += CFIDEV_BUSWIDTH;
1184 -               len -= CFIDEV_BUSWIDTH;
1185 +               ofs += map_bankwidth(map);
1186 +               buf += map_bankwidth(map);
1187 +               (*retlen) += map_bankwidth(map);
1188 +               len -= map_bankwidth(map);
1189  
1190                 if (ofs >> cfi->chipshift) {
1191                         chipnum ++; 
1192 @@ -898,32 +1107,18 @@
1193                 }
1194         }
1195  
1196 -       if (len & (CFIDEV_BUSWIDTH-1)) {
1197 -               int i = 0, n = 0;
1198 -               u_char tmp_buf[8];
1199 -               cfi_word datum;
1200 -
1201 -               while (len--)
1202 -                       tmp_buf[i++] = buf[n++];
1203 -               while (i < CFIDEV_BUSWIDTH)
1204 -                       tmp_buf[i++] = 0xff;
1205 -
1206 -               if (cfi_buswidth_is_2()) {
1207 -                       datum = *(__u16*)tmp_buf;
1208 -               } else if (cfi_buswidth_is_4()) {
1209 -                       datum = *(__u32*)tmp_buf;
1210 -               } else if (cfi_buswidth_is_8()) {
1211 -                       datum = *(__u64*)tmp_buf;
1212 -               } else {
1213 -                       return -EINVAL;  /* should never happen, but be safe */
1214 -               }
1215 +       if (len & (map_bankwidth(map)-1)) {
1216 +               map_word datum;
1217 +
1218 +               datum = map_word_ff(map);
1219 +               datum = map_word_load_partial(map, datum, buf, 0, len);
1220  
1221                 ret = do_write_oneword(map, &cfi->chips[chipnum],
1222                                                ofs, datum);
1223                 if (ret) 
1224                         return ret;
1225                 
1226 -               (*retlen) += n;
1227 +               (*retlen) += len;
1228         }
1229  
1230         return 0;
1231 @@ -934,11 +1129,11 @@
1232                                   unsigned long adr, const u_char *buf, int len)
1233  {
1234         struct cfi_private *cfi = map->fldrv_priv;
1235 -       cfi_word status, status_OK;
1236 +       map_word status, status_OK;
1237         unsigned long cmd_adr, timeo;
1238         int wbufsize, z, ret=0, bytes, words;
1239  
1240 -       wbufsize = CFIDEV_INTERLEAVE << cfi->cfiq->MaxBufWriteSize;
1241 +       wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
1242         adr += chip->start;
1243         cmd_adr = adr & ~(wbufsize-1);
1244         
1245 @@ -952,29 +1147,28 @@
1246                 return ret;
1247         }
1248  
1249 -       if (chip->state != FL_STATUS)
1250 -               cfi_write(map, CMD(0x70), cmd_adr);
1251 -
1252 -       status = cfi_read(map, cmd_adr);
1253 -
1254         /* ยง4.8 of the 28FxxxJ3A datasheet says "Any time SR.4 and/or SR.5 is set
1255            [...], the device will not accept any more Write to Buffer commands". 
1256            So we must check here and reset those bits if they're set. Otherwise
1257            we're just pissing in the wind */
1258 -       if (status & CMD(0x30)) {
1259 -               printk(KERN_WARNING "SR.4 or SR.5 bits set in buffer write (status %x). Clearing.\n", status);
1260 -               cfi_write(map, CMD(0x50), cmd_adr);
1261 -               cfi_write(map, CMD(0x70), cmd_adr);
1262 +       if (chip->state != FL_STATUS)
1263 +               map_write(map, CMD(0x70), cmd_adr);
1264 +       status = map_read(map, cmd_adr);
1265 +       if (map_word_bitsset(map, status, CMD(0x30))) {
1266 +               printk(KERN_WARNING "SR.4 or SR.5 bits set in buffer write (status %lx). Clearing.\n", status.x[0]);
1267 +               map_write(map, CMD(0x50), cmd_adr);
1268 +               map_write(map, CMD(0x70), cmd_adr);
1269         }
1270 +
1271         ENABLE_VPP(map);
1272         chip->state = FL_WRITING_TO_BUFFER;
1273  
1274         z = 0;
1275         for (;;) {
1276 -               cfi_write(map, CMD(0xe8), cmd_adr);
1277 +               map_write(map, CMD(0xe8), cmd_adr);
1278  
1279 -               status = cfi_read(map, cmd_adr);
1280 -               if ((status & status_OK) == status_OK)
1281 +               status = map_read(map, cmd_adr);
1282 +               if (map_word_andequal(map, status, status_OK, status_OK))
1283                         break;
1284  
1285                 spin_unlock(chip->mutex);
1286 @@ -983,84 +1177,47 @@
1287  
1288                 if (++z > 20) {
1289                         /* Argh. Not ready for write to buffer */
1290 -                       cfi_write(map, CMD(0x70), cmd_adr);
1291 +                       map_write(map, CMD(0x70), cmd_adr);
1292                         chip->state = FL_STATUS;
1293 -                       printk(KERN_ERR "Chip not ready for buffer write. Xstatus = %llx, status = %llx\n", (__u64)status, (__u64)cfi_read(map, cmd_adr));
1294 +                       printk(KERN_ERR "Chip not ready for buffer write. Xstatus = %lx, status = %lx\n",
1295 +                              status.x[0], map_read(map, cmd_adr).x[0]);
1296                         /* Odd. Clear status bits */
1297 -                       cfi_write(map, CMD(0x50), cmd_adr);
1298 -                       cfi_write(map, CMD(0x70), cmd_adr);
1299 +                       map_write(map, CMD(0x50), cmd_adr);
1300 +                       map_write(map, CMD(0x70), cmd_adr);
1301                         ret = -EIO;
1302                         goto out;
1303                 }
1304         }
1305  
1306         /* Write length of data to come */
1307 -       bytes = len & (CFIDEV_BUSWIDTH-1);
1308 -       words = len / CFIDEV_BUSWIDTH;
1309 -       cfi_write(map, CMD(words - !bytes), cmd_adr );
1310 +       bytes = len & (map_bankwidth(map)-1);
1311 +       words = len / map_bankwidth(map);
1312 +       map_write(map, CMD(words - !bytes), cmd_adr );
1313  
1314         /* Write data */
1315         z = 0;
1316 -       while(z < words * CFIDEV_BUSWIDTH) {
1317 -               if (cfi_buswidth_is_1()) {
1318 -                       u8 *b = (u8 *)buf;
1319 -
1320 -                       map_write8 (map, *b++, adr+z);
1321 -                       buf = (const u_char *)b;
1322 -               } else if (cfi_buswidth_is_2()) {
1323 -                       u16 *b = (u16 *)buf;
1324 -
1325 -                       map_write16 (map, *b++, adr+z);
1326 -                       buf = (const u_char *)b;
1327 -               } else if (cfi_buswidth_is_4()) {
1328 -                       u32 *b = (u32 *)buf;
1329 -
1330 -                       map_write32 (map, *b++, adr+z);
1331 -                       buf = (const u_char *)b;
1332 -               } else if (cfi_buswidth_is_8()) {
1333 -                       u64 *b = (u64 *)buf;
1334 -
1335 -                       map_write64 (map, *b++, adr+z);
1336 -                       buf = (const u_char *)b;
1337 -               } else {
1338 -                       ret = -EINVAL;
1339 -                       goto out;
1340 -               }
1341 -               z += CFIDEV_BUSWIDTH;
1342 +       while(z < words * map_bankwidth(map)) {
1343 +               map_word datum = map_word_load(map, buf);
1344 +               map_write(map, datum, adr+z);
1345 +
1346 +               z += map_bankwidth(map);
1347 +               buf += map_bankwidth(map);
1348         }
1349 +
1350         if (bytes) {
1351 -               int i = 0, n = 0;
1352 -               u_char tmp_buf[8], *tmp_p = tmp_buf;
1353 +               map_word datum;
1354  
1355 -               while (bytes--)
1356 -                       tmp_buf[i++] = buf[n++];
1357 -               while (i < CFIDEV_BUSWIDTH)
1358 -                       tmp_buf[i++] = 0xff;
1359 -               if (cfi_buswidth_is_2()) {
1360 -                       u16 *b = (u16 *)tmp_p;
1361 -
1362 -                       map_write16 (map, *b++, adr+z);
1363 -                       tmp_p = (u_char *)b;
1364 -               } else if (cfi_buswidth_is_4()) {
1365 -                       u32 *b = (u32 *)tmp_p;
1366 -
1367 -                       map_write32 (map, *b++, adr+z);
1368 -                       tmp_p = (u_char *)b;
1369 -               } else if (cfi_buswidth_is_8()) {
1370 -                       u64 *b = (u64 *)tmp_p;
1371 -
1372 -                       map_write64 (map, *b++, adr+z);
1373 -                       tmp_p = (u_char *)b;
1374 -               } else {
1375 -                       ret = -EINVAL;
1376 -                       goto out;
1377 -               }
1378 +               datum = map_word_ff(map);
1379 +               datum = map_word_load_partial(map, datum, buf, 0, bytes);
1380 +               map_write(map, datum, adr+z);
1381         }
1382 +
1383         /* GO GO GO */
1384 -       cfi_write(map, CMD(0xd0), cmd_adr);
1385 +       map_write(map, CMD(0xd0), cmd_adr);
1386         chip->state = FL_WRITING;
1387  
1388         spin_unlock(chip->mutex);
1389 +       INVALIDATE_CACHED_RANGE(map, adr, len);
1390         cfi_udelay(chip->buffer_write_time);
1391         spin_lock(chip->mutex);
1392  
1393 @@ -1080,8 +1237,8 @@
1394                         continue;
1395                 }
1396  
1397 -               status = cfi_read(map, cmd_adr);
1398 -               if ((status & status_OK) == status_OK)
1399 +               status = map_read(map, cmd_adr);
1400 +               if (map_word_andequal(map, status, status_OK, status_OK))
1401                         break;
1402  
1403                 /* OK Still waiting */
1404 @@ -1110,11 +1267,11 @@
1405         chip->state = FL_STATUS;
1406  
1407         /* check for lock bit */
1408 -       if (status & CMD(0x02)) {
1409 +       if (map_word_bitsset(map, status, CMD(0x02))) {
1410                 /* clear status */
1411 -               cfi_write(map, CMD(0x50), cmd_adr);
1412 +               map_write(map, CMD(0x50), cmd_adr);
1413                 /* put back into read status register mode */
1414 -               cfi_write(map, CMD(0x70), adr);
1415 +               map_write(map, CMD(0x70), adr);
1416                 ret = -EROFS;
1417         }
1418  
1419 @@ -1129,7 +1286,7 @@
1420  {
1421         struct map_info *map = mtd->priv;
1422         struct cfi_private *cfi = map->fldrv_priv;
1423 -       int wbufsize = CFIDEV_INTERLEAVE << cfi->cfiq->MaxBufWriteSize;
1424 +       int wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
1425         int ret = 0;
1426         int chipnum;
1427         unsigned long ofs;
1428 @@ -1142,8 +1299,8 @@
1429         ofs = to  - (chipnum << cfi->chipshift);
1430  
1431         /* If it's not bus-aligned, do the first word write */
1432 -       if (ofs & (CFIDEV_BUSWIDTH-1)) {
1433 -               size_t local_len = (-ofs)&(CFIDEV_BUSWIDTH-1);
1434 +       if (ofs & (map_bankwidth(map)-1)) {
1435 +               size_t local_len = (-ofs)&(map_bankwidth(map)-1);
1436                 if (local_len > len)
1437                         local_len = len;
1438                 ret = cfi_intelext_write_words(mtd, to, local_len,
1439 @@ -1162,7 +1319,6 @@
1440                 }
1441         }
1442  
1443 -       /* Write buffer is worth it only if more than one word to write... */
1444         while(len) {
1445                 /* We must not cross write block boundaries */
1446                 int size = wbufsize - (ofs & (wbufsize-1));
1447 @@ -1189,102 +1345,11 @@
1448         return 0;
1449  }
1450  
1451 -typedef int (*varsize_frob_t)(struct map_info *map, struct flchip *chip,
1452 -                             unsigned long adr, void *thunk);
1453 -
1454 -static int cfi_intelext_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
1455 -                                    loff_t ofs, size_t len, void *thunk)
1456 -{
1457 -       struct map_info *map = mtd->priv;
1458 -       struct cfi_private *cfi = map->fldrv_priv;
1459 -       unsigned long adr;
1460 -       int chipnum, ret = 0;
1461 -       int i, first;
1462 -       struct mtd_erase_region_info *regions = mtd->eraseregions;
1463 -
1464 -       if (ofs > mtd->size)
1465 -               return -EINVAL;
1466 -
1467 -       if ((len + ofs) > mtd->size)
1468 -               return -EINVAL;
1469 -
1470 -       /* Check that both start and end of the requested erase are
1471 -        * aligned with the erasesize at the appropriate addresses.
1472 -        */
1473 -
1474 -       i = 0;
1475 -
1476 -       /* Skip all erase regions which are ended before the start of 
1477 -          the requested erase. Actually, to save on the calculations,
1478 -          we skip to the first erase region which starts after the
1479 -          start of the requested erase, and then go back one.
1480 -       */
1481 -       
1482 -       while (i < mtd->numeraseregions && ofs >= regions[i].offset)
1483 -              i++;
1484 -       i--;
1485 -
1486 -       /* OK, now i is pointing at the erase region in which this 
1487 -          erase request starts. Check the start of the requested
1488 -          erase range is aligned with the erase size which is in
1489 -          effect here.
1490 -       */
1491 -
1492 -       if (ofs & (regions[i].erasesize-1))
1493 -               return -EINVAL;
1494 -
1495 -       /* Remember the erase region we start on */
1496 -       first = i;
1497 -
1498 -       /* Next, check that the end of the requested erase is aligned
1499 -        * with the erase region at that address.
1500 -        */
1501 -
1502 -       while (i<mtd->numeraseregions && (ofs + len) >= regions[i].offset)
1503 -               i++;
1504 -
1505 -       /* As before, drop back one to point at the region in which
1506 -          the address actually falls
1507 -       */
1508 -       i--;
1509 -       
1510 -       if ((ofs + len) & (regions[i].erasesize-1))
1511 -               return -EINVAL;
1512 -
1513 -       chipnum = ofs >> cfi->chipshift;
1514 -       adr = ofs - (chipnum << cfi->chipshift);
1515 -
1516 -       i=first;
1517 -
1518 -       while(len) {
1519 -               ret = (*frob)(map, &cfi->chips[chipnum], adr, thunk);
1520 -               
1521 -               if (ret)
1522 -                       return ret;
1523 -
1524 -               adr += regions[i].erasesize;
1525 -               len -= regions[i].erasesize;
1526 -
1527 -               if (adr % (1<< cfi->chipshift) == ((regions[i].offset + (regions[i].erasesize * regions[i].numblocks)) %( 1<< cfi->chipshift)))
1528 -                       i++;
1529 -
1530 -               if (adr >> cfi->chipshift) {
1531 -                       adr = 0;
1532 -                       chipnum++;
1533 -                       
1534 -                       if (chipnum >= cfi->numchips)
1535 -                       break;
1536 -               }
1537 -       }
1538 -
1539 -       return 0;
1540 -}
1541 -
1542 -
1543 -static int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr, void *thunk)
1544 +static int do_erase_oneblock(struct map_info *map, struct flchip *chip,
1545 +                            unsigned long adr, int len, void *thunk)
1546  {
1547         struct cfi_private *cfi = map->fldrv_priv;
1548 -       cfi_word status, status_OK;
1549 +       map_word status, status_OK;
1550         unsigned long timeo;
1551         int retries = 3;
1552         DECLARE_WAITQUEUE(wait, current);
1553 @@ -1305,17 +1370,17 @@
1554  
1555         ENABLE_VPP(map);
1556         /* Clear the status register first */
1557 -       cfi_write(map, CMD(0x50), adr);
1558 +       map_write(map, CMD(0x50), adr);
1559  
1560         /* Now erase */
1561 -       cfi_write(map, CMD(0x20), adr);
1562 -       cfi_write(map, CMD(0xD0), adr);
1563 +       map_write(map, CMD(0x20), adr);
1564 +       map_write(map, CMD(0xD0), adr);
1565         chip->state = FL_ERASING;
1566         chip->erase_suspended = 0;
1567  
1568         spin_unlock(chip->mutex);
1569 -       set_current_state(TASK_UNINTERRUPTIBLE);
1570 -       schedule_timeout((chip->erase_time*HZ)/(2*1000));
1571 +       INVALIDATE_CACHED_RANGE(map, adr, len);
1572 +       msleep(chip->erase_time / 2);
1573         spin_lock(chip->mutex);
1574  
1575         /* FIXME. Use a timer to check this, and return immediately. */
1576 @@ -1340,19 +1405,19 @@
1577                         chip->erase_suspended = 0;
1578                 }
1579  
1580 -               status = cfi_read(map, adr);
1581 -               if ((status & status_OK) == status_OK)
1582 +               status = map_read(map, adr);
1583 +               if (map_word_andequal(map, status, status_OK, status_OK))
1584                         break;
1585                 
1586                 /* OK Still waiting */
1587                 if (time_after(jiffies, timeo)) {
1588 -                       cfi_write(map, CMD(0x70), adr);
1589 +                       map_write(map, CMD(0x70), adr);
1590                         chip->state = FL_STATUS;
1591 -                       printk(KERN_ERR "waiting for erase at %08lx to complete timed out. Xstatus = %llx, status = %llx.\n",
1592 -                              adr, (__u64)status, (__u64)cfi_read(map, adr));
1593 +                       printk(KERN_ERR "waiting for erase at %08lx to complete timed out. Xstatus = %lx, status = %lx.\n",
1594 +                              adr, status.x[0], map_read(map, adr).x[0]);
1595                         /* Clear status bits */
1596 -                       cfi_write(map, CMD(0x50), adr);
1597 -                       cfi_write(map, CMD(0x70), adr);
1598 +                       map_write(map, CMD(0x50), adr);
1599 +                       map_write(map, CMD(0x70), adr);
1600                         DISABLE_VPP(map);
1601                         spin_unlock(chip->mutex);
1602                         return -EIO;
1603 @@ -1369,43 +1434,46 @@
1604         ret = 0;
1605  
1606         /* We've broken this before. It doesn't hurt to be safe */
1607 -       cfi_write(map, CMD(0x70), adr);
1608 +       map_write(map, CMD(0x70), adr);
1609         chip->state = FL_STATUS;
1610 -       status = cfi_read(map, adr);
1611 +       status = map_read(map, adr);
1612  
1613         /* check for lock bit */
1614 -       if (status & CMD(0x3a)) {
1615 -               unsigned char chipstatus = status;
1616 -               if (status != CMD(status & 0xff)) {
1617 -                       int i;
1618 -                       for (i = 1; i<CFIDEV_INTERLEAVE; i++) {
1619 -                                     chipstatus |= status >> (cfi->device_type * 8);
1620 +       if (map_word_bitsset(map, status, CMD(0x3a))) {
1621 +               unsigned char chipstatus = status.x[0];
1622 +               if (!map_word_equal(map, status, CMD(chipstatus))) {
1623 +                       int i, w;
1624 +                       for (w=0; w<map_words(map); w++) {
1625 +                               for (i = 0; i<cfi_interleave(cfi); i++) {
1626 +                                       chipstatus |= status.x[w] >> (cfi->device_type * 8);
1627 +                               }
1628                         }
1629 -                       printk(KERN_WARNING "Status is not identical for all chips: 0x%llx. Merging to give 0x%02x\n", (__u64)status, chipstatus);
1630 +                       printk(KERN_WARNING "Status is not identical for all chips: 0x%lx. Merging to give 0x%02x\n",
1631 +                              status.x[0], chipstatus);
1632                 }
1633                 /* Reset the error bits */
1634 -               cfi_write(map, CMD(0x50), adr);
1635 -               cfi_write(map, CMD(0x70), adr);
1636 +               map_write(map, CMD(0x50), adr);
1637 +               map_write(map, CMD(0x70), adr);
1638                 
1639                 if ((chipstatus & 0x30) == 0x30) {
1640 -                       printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%llx\n", (__u64)status);
1641 +                       printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%x\n", chipstatus);
1642                         ret = -EIO;
1643                 } else if (chipstatus & 0x02) {
1644                         /* Protection bit set */
1645                         ret = -EROFS;
1646                 } else if (chipstatus & 0x8) {
1647                         /* Voltage */
1648 -                       printk(KERN_WARNING "Chip reports voltage low on erase: status 0x%llx\n", (__u64)status);
1649 +                       printk(KERN_WARNING "Chip reports voltage low on erase: status 0x%x\n", chipstatus);
1650                         ret = -EIO;
1651                 } else if (chipstatus & 0x20) {
1652                         if (retries--) {
1653 -                               printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%llx. Retrying...\n", adr, (__u64)status);
1654 +                               printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%x. Retrying...\n", adr, chipstatus);
1655                                 timeo = jiffies + HZ;
1656                                 chip->state = FL_STATUS;
1657                                 spin_unlock(chip->mutex);
1658                                 goto retry;
1659                         }
1660 -                       printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%llx\n", adr, (__u64)status);
1661 +                       printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%x\n", adr, chipstatus);
1662                         ret = -EIO;
1663                 }
1664         }
1665 @@ -1423,13 +1491,12 @@
1666         ofs = instr->addr;
1667         len = instr->len;
1668  
1669 -       ret = cfi_intelext_varsize_frob(mtd, do_erase_oneblock, ofs, len, 0);
1670 +       ret = cfi_varsize_frob(mtd, do_erase_oneblock, ofs, len, NULL);
1671         if (ret)
1672                 return ret;
1673  
1674         instr->state = MTD_ERASE_DONE;
1675 -       if (instr->callback)
1676 -               instr->callback(instr);
1677 +       mtd_erase_callback(instr);
1678         
1679         return 0;
1680  }
1681 @@ -1475,7 +1542,8 @@
1682  }
1683  
1684  #ifdef DEBUG_LOCK_BITS
1685 -static int do_printlockstatus_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr, void *thunk)
1686 +static int do_printlockstatus_oneblock(struct map_info *map, struct flchip *chip,
1687 +                                      unsigned long adr, int len, void *thunk)
1688  {
1689         struct cfi_private *cfi = map->fldrv_priv;
1690         int ofs_factor = cfi->interleave * cfi->device_type;
1691 @@ -1483,8 +1551,7 @@
1692         cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
1693         printk(KERN_DEBUG "block status register for 0x%08lx is %x\n",
1694                adr, cfi_read_query(map, adr+(2*ofs_factor)));
1695 -       cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
1696 -       
1697 +       chip->state = FL_JEDEC_QUERY;
1698         return 0;
1699  }
1700  #endif
1701 @@ -1492,10 +1559,11 @@
1702  #define DO_XXLOCK_ONEBLOCK_LOCK                ((void *) 1)
1703  #define DO_XXLOCK_ONEBLOCK_UNLOCK      ((void *) 2)
1704  
1705 -static int do_xxlock_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr, void *thunk)
1706 +static int do_xxlock_oneblock(struct map_info *map, struct flchip *chip,
1707 +                             unsigned long adr, int len, void *thunk)
1708  {
1709         struct cfi_private *cfi = map->fldrv_priv;
1710 -       cfi_word status, status_OK;
1711 +       map_word status, status_OK;
1712         unsigned long timeo = jiffies + HZ;
1713         int ret;
1714  
1715 @@ -1512,13 +1580,13 @@
1716         }
1717  
1718         ENABLE_VPP(map);
1719 -       cfi_write(map, CMD(0x60), adr);
1720 +       map_write(map, CMD(0x60), adr);
1721  
1722         if (thunk == DO_XXLOCK_ONEBLOCK_LOCK) {
1723 -               cfi_write(map, CMD(0x01), adr);
1724 +               map_write(map, CMD(0x01), adr);
1725                 chip->state = FL_LOCKING;
1726         } else if (thunk == DO_XXLOCK_ONEBLOCK_UNLOCK) {
1727 -               cfi_write(map, CMD(0xD0), adr);
1728 +               map_write(map, CMD(0xD0), adr);
1729                 chip->state = FL_UNLOCKING;
1730         } else
1731                 BUG();
1732 @@ -1533,15 +1601,16 @@
1733         timeo = jiffies + (HZ*20);
1734         for (;;) {
1735  
1736 -               status = cfi_read(map, adr);
1737 -               if ((status & status_OK) == status_OK)
1738 +               status = map_read(map, adr);
1739 +               if (map_word_andequal(map, status, status_OK, status_OK))
1740                         break;
1741                 
1742                 /* OK Still waiting */
1743                 if (time_after(jiffies, timeo)) {
1744 -                       cfi_write(map, CMD(0x70), adr);
1745 +                       map_write(map, CMD(0x70), adr);
1746                         chip->state = FL_STATUS;
1747 -                       printk(KERN_ERR "waiting for unlock to complete timed out. Xstatus = %llx, status = %llx.\n", (__u64)status, (__u64)cfi_read(map, adr));
1748 +                       printk(KERN_ERR "waiting for unlock to complete timed out. Xstatus = %lx, status = %lx.\n",
1749 +                              status.x[0], map_read(map, adr).x[0]);
1750                         DISABLE_VPP(map);
1751                         spin_unlock(chip->mutex);
1752                         return -EIO;
1753 @@ -1567,18 +1636,18 @@
1754  #ifdef DEBUG_LOCK_BITS
1755         printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n",
1756                __FUNCTION__, ofs, len);
1757 -       cfi_intelext_varsize_frob(mtd, do_printlockstatus_oneblock,
1758 -                                 ofs, len, 0);
1759 +       cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
1760 +               ofs, len, 0);
1761  #endif
1762  
1763 -       ret = cfi_intelext_varsize_frob(mtd, do_xxlock_oneblock, 
1764 -                                       ofs, len, DO_XXLOCK_ONEBLOCK_LOCK);
1765 +       ret = cfi_varsize_frob(mtd, do_xxlock_oneblock, 
1766 +               ofs, len, DO_XXLOCK_ONEBLOCK_LOCK);
1767         
1768  #ifdef DEBUG_LOCK_BITS
1769 -       printk(KERN_DEBUG __FUNCTION__
1770 -              "%s: lock status after, ret=%d\n", __FUNCTION__, ret);
1771 -       cfi_intelext_varsize_frob(mtd, do_printlockstatus_oneblock,
1772 -                                 ofs, len, 0);
1773 +       printk(KERN_DEBUG "%s: lock status after, ret=%d\n",
1774 +              __FUNCTION__, ret);
1775 +       cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
1776 +               ofs, len, 0);
1777  #endif
1778  
1779         return ret;
1780 @@ -1591,17 +1660,18 @@
1781  #ifdef DEBUG_LOCK_BITS
1782         printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n",
1783                __FUNCTION__, ofs, len);
1784 -       cfi_intelext_varsize_frob(mtd, do_printlockstatus_oneblock,
1785 -                                 ofs, len, 0);
1786 +       cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
1787 +               ofs, len, 0);
1788  #endif
1789  
1790 -       ret = cfi_intelext_varsize_frob(mtd, do_xxlock_oneblock,
1791 +       ret = cfi_varsize_frob(mtd, do_xxlock_oneblock,
1792                                         ofs, len, DO_XXLOCK_ONEBLOCK_UNLOCK);
1793         
1794  #ifdef DEBUG_LOCK_BITS
1795 -       printk(KERN_DEBUG "%s: lock status after, ret=%d\n", __FUNCTION__, ret);
1796 -       cfi_intelext_varsize_frob(mtd, do_printlockstatus_oneblock, 
1797 -                                 ofs, len, 0);
1798 +       printk(KERN_DEBUG "%s: lock status after, ret=%d\n",
1799 +              __FUNCTION__, ret);
1800 +       cfi_varsize_frob(mtd, do_printlockstatus_oneblock, 
1801 +               ofs, len, 0);
1802  #endif
1803         
1804         return ret;
1805 @@ -1679,7 +1749,7 @@
1806                 
1807                 /* Go to known state. Chip may have been power cycled */
1808                 if (chip->state == FL_PM_SUSPENDED) {
1809 -                       cfi_write(map, CMD(0xFF), 0);
1810 +                       map_write(map, CMD(0xFF), cfi->chips[i].start);
1811                         chip->state = FL_READY;
1812                         wake_up(&chip->wq);
1813                 }
1814 @@ -1694,6 +1764,7 @@
1815         struct cfi_private *cfi = map->fldrv_priv;
1816         kfree(cfi->cmdset_priv);
1817         kfree(cfi->cfiq);
1818 +       kfree(cfi->chips[0].priv);
1819         kfree(cfi);
1820         kfree(mtd->eraseregions);
1821  }
1822 Index: linux-2.6.5/drivers/mtd/chips/cfi_cmdset_0002.c
1823 ===================================================================
1824 --- linux-2.6.5.orig/drivers/mtd/chips/cfi_cmdset_0002.c        2004-04-03 22:36:57.000000000 -0500
1825 +++ linux-2.6.5/drivers/mtd/chips/cfi_cmdset_0002.c     2005-02-01 17:11:17.000000000 -0500
1826 @@ -3,15 +3,21 @@
1827   *   AMD & Fujitsu Standard Vendor Command Set (ID 0x0002)
1828   *
1829   * Copyright (C) 2000 Crossnet Co. <info@crossnet.co.jp>
1830 + * Copyright (C) 2004 Arcom Control Systems Ltd <linux@arcom.com>
1831   *
1832   * 2_by_8 routines added by Simon Munton
1833   *
1834 + * 4_by_16 work by Carolyn J. Smith
1835 + *
1836 + * Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com
1837 + *
1838   * This code is GPL
1839   *
1840 - * $Id: cfi_cmdset_0002.c,v 1.74 2003/05/28 12:51:48 dwmw2 Exp $
1841 + * $Id: cfi_cmdset_0002.c,v 1.109 2004/09/15 23:48:09 thayne Exp $
1842   *
1843   */
1844  
1845 +#include <linux/config.h>
1846  #include <linux/module.h>
1847  #include <linux/types.h>
1848  #include <linux/kernel.h>
1849 @@ -24,17 +30,24 @@
1850  #include <linux/slab.h>
1851  #include <linux/delay.h>
1852  #include <linux/interrupt.h>
1853 +#include <linux/mtd/compatmac.h>
1854  #include <linux/mtd/map.h>
1855  #include <linux/mtd/mtd.h>
1856  #include <linux/mtd/cfi.h>
1857 -#include <linux/mtd/compatmac.h>
1858  
1859  #define AMD_BOOTLOC_BUG
1860 +#define FORCE_WORD_WRITE 0
1861 +
1862 +#define MAX_WORD_RETRIES 3
1863 +
1864 +#define MANUFACTURER_AMD       0x0001
1865 +#define MANUFACTURER_SST       0x00BF
1866 +#define SST49LF004B            0x0060
1867  
1868  static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
1869 -static int cfi_amdstd_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
1870 +static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
1871 +static int cfi_amdstd_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
1872  static int cfi_amdstd_erase_chip(struct mtd_info *, struct erase_info *);
1873 -static int cfi_amdstd_erase_onesize(struct mtd_info *, struct erase_info *);
1874  static int cfi_amdstd_erase_varsize(struct mtd_info *, struct erase_info *);
1875  static void cfi_amdstd_sync (struct mtd_info *);
1876  static int cfi_amdstd_suspend (struct mtd_info *);
1877 @@ -44,8 +57,11 @@
1878  static void cfi_amdstd_destroy(struct mtd_info *);
1879  
1880  struct mtd_info *cfi_cmdset_0002(struct map_info *, int);
1881 -static struct mtd_info *cfi_amdstd_setup (struct map_info *);
1882 +static struct mtd_info *cfi_amdstd_setup (struct mtd_info *);
1883  
1884 +static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode);
1885 +static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr);
1886 +#include "fwh_lock.h"
1887  
1888  static struct mtd_chip_driver cfi_amdstd_chipdrv = {
1889         .probe          = NULL, /* Not usable directly */
1890 @@ -55,50 +71,199 @@
1891  };
1892  
1893  
1894 +/* #define DEBUG_CFI_FEATURES */
1895 +
1896 +
1897 +#ifdef DEBUG_CFI_FEATURES
1898 +static void cfi_tell_features(struct cfi_pri_amdstd *extp)
1899 +{
1900 +       const char* erase_suspend[3] = {
1901 +               "Not supported", "Read only", "Read/write"
1902 +       };
1903 +       const char* top_bottom[6] = {
1904 +               "No WP", "8x8KiB sectors at top & bottom, no WP",
1905 +               "Bottom boot", "Top boot",
1906 +               "Uniform, Bottom WP", "Uniform, Top WP"
1907 +       };
1908 +
1909 +       printk("  Silicon revision: %d\n", extp->SiliconRevision >> 1);
1910 +       printk("  Address sensitive unlock: %s\n", 
1911 +              (extp->SiliconRevision & 1) ? "Not required" : "Required");
1912 +
1913 +       if (extp->EraseSuspend < ARRAY_SIZE(erase_suspend))
1914 +               printk("  Erase Suspend: %s\n", erase_suspend[extp->EraseSuspend]);
1915 +       else
1916 +               printk("  Erase Suspend: Unknown value %d\n", extp->EraseSuspend);
1917 +
1918 +       if (extp->BlkProt == 0)
1919 +               printk("  Block protection: Not supported\n");
1920 +       else
1921 +               printk("  Block protection: %d sectors per group\n", extp->BlkProt);
1922 +
1923 +
1924 +       printk("  Temporary block unprotect: %s\n",
1925 +              extp->TmpBlkUnprotect ? "Supported" : "Not supported");
1926 +       printk("  Block protect/unprotect scheme: %d\n", extp->BlkProtUnprot);
1927 +       printk("  Number of simultaneous operations: %d\n", extp->SimultaneousOps);
1928 +       printk("  Burst mode: %s\n",
1929 +              extp->BurstMode ? "Supported" : "Not supported");
1930 +       if (extp->PageMode == 0)
1931 +               printk("  Page mode: Not supported\n");
1932 +       else
1933 +               printk("  Page mode: %d word page\n", extp->PageMode << 2);
1934 +
1935 +       printk("  Vpp Supply Minimum Program/Erase Voltage: %d.%d V\n", 
1936 +              extp->VppMin >> 4, extp->VppMin & 0xf);
1937 +       printk("  Vpp Supply Maximum Program/Erase Voltage: %d.%d V\n", 
1938 +              extp->VppMax >> 4, extp->VppMax & 0xf);
1939 +
1940 +       if (extp->TopBottom < ARRAY_SIZE(top_bottom))
1941 +               printk("  Top/Bottom Boot Block: %s\n", top_bottom[extp->TopBottom]);
1942 +       else
1943 +               printk("  Top/Bottom Boot Block: Unknown value %d\n", extp->TopBottom);
1944 +}
1945 +#endif
1946 +
1947 +#ifdef AMD_BOOTLOC_BUG
1948 +/* Wheee. Bring me the head of someone at AMD. */
1949 +static void fixup_amd_bootblock(struct mtd_info *mtd, void* param)
1950 +{
1951 +       struct map_info *map = mtd->priv;
1952 +       struct cfi_private *cfi = map->fldrv_priv;
1953 +       struct cfi_pri_amdstd *extp = cfi->cmdset_priv;
1954 +       __u8 major = extp->MajorVersion;
1955 +       __u8 minor = extp->MinorVersion;
1956 +
1957 +       if (((major << 8) | minor) < 0x3131) {
1958 +               /* CFI version 1.0 => don't trust bootloc */
1959 +               if (cfi->id & 0x80) {
1960 +                       printk(KERN_WARNING "%s: JEDEC Device ID is 0x%02X. Assuming broken CFI table.\n", map->name, cfi->id);
1961 +                       extp->TopBottom = 3;    /* top boot */
1962 +               } else {
1963 +                       extp->TopBottom = 2;    /* bottom boot */
1964 +               }
1965 +       }
1966 +}
1967 +#endif
1968 +
1969 +static void fixup_use_write_buffers(struct mtd_info *mtd, void *param)
1970 +{
1971 +       struct map_info *map = mtd->priv;
1972 +       struct cfi_private *cfi = map->fldrv_priv;
1973 +       if (cfi->cfiq->BufWriteTimeoutTyp) {
1974 +               DEBUG(MTD_DEBUG_LEVEL1, "Using buffer write method\n" );
1975 +               mtd->write = cfi_amdstd_write_buffers;
1976 +       }
1977 +}
1978 +
1979 +static void fixup_use_secsi(struct mtd_info *mtd, void *param)
1980 +{
1981 +       /* Setup for chips with a secsi area */
1982 +       mtd->read_user_prot_reg = cfi_amdstd_secsi_read;
1983 +       mtd->read_fact_prot_reg = cfi_amdstd_secsi_read;
1984 +}
1985 +
1986 +static void fixup_use_erase_chip(struct mtd_info *mtd, void *param)
1987 +{
1988 +       struct map_info *map = mtd->priv;
1989 +       struct cfi_private *cfi = map->fldrv_priv;
1990 +       if ((cfi->cfiq->NumEraseRegions == 1) &&
1991 +               ((cfi->cfiq->EraseRegionInfo[0] & 0xffff) == 0)) {
1992 +               mtd->erase = cfi_amdstd_erase_chip;
1993 +       }
1994 +       
1995 +}
1996 +
1997 +static struct cfi_fixup cfi_fixup_table[] = {
1998 +#ifdef AMD_BOOTLOC_BUG
1999 +       { CFI_MFR_AMD, CFI_ID_ANY, fixup_amd_bootblock, NULL },
2000 +#endif
2001 +       { CFI_MFR_AMD, 0x0050, fixup_use_secsi, NULL, },
2002 +       { CFI_MFR_AMD, 0x0053, fixup_use_secsi, NULL, },
2003 +       { CFI_MFR_AMD, 0x0055, fixup_use_secsi, NULL, },
2004 +       { CFI_MFR_AMD, 0x0056, fixup_use_secsi, NULL, },
2005 +       { CFI_MFR_AMD, 0x005C, fixup_use_secsi, NULL, },
2006 +       { CFI_MFR_AMD, 0x005F, fixup_use_secsi, NULL, },
2007 +#if !FORCE_WORD_WRITE
2008 +       { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, },
2009 +#endif
2010 +       { 0, 0, NULL, NULL }
2011 +};
2012 +static struct cfi_fixup jedec_fixup_table[] = {
2013 +       { MANUFACTURER_SST, SST49LF004B, fixup_use_fwh_lock, NULL, },
2014 +       { 0, 0, NULL, NULL }
2015 +};
2016 +
2017 +static struct cfi_fixup fixup_table[] = {
2018 +       /* The CFI vendor ids and the JEDEC vendor IDs appear
2019 +        * to be common.  It is like the devices id's are as
2020 +        * well.  This table is to pick all cases where
2021 +        * we know that is the case.
2022 +        */
2023 +       { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_erase_chip, NULL },
2024 +       { 0, 0, NULL, NULL }
2025 +};
2026 +
2027 +
2028  struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
2029  {
2030         struct cfi_private *cfi = map->fldrv_priv;
2031 -       unsigned char bootloc;
2032 -       int ofs_factor = cfi->interleave * cfi->device_type;
2033 +       struct mtd_info *mtd;
2034         int i;
2035 -       __u8 major, minor;
2036 -       __u32 base = cfi->chips[0].start;
2037 +
2038 +       mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
2039 +       if (!mtd) {
2040 +               printk(KERN_WARNING "Failed to allocate memory for MTD device\n");
2041 +               return NULL;
2042 +       }
2043 +       memset(mtd, 0, sizeof(*mtd));
2044 +       mtd->priv = map;
2045 +       mtd->type = MTD_NORFLASH;
2046 +
2047 +       /* Fill in the default mtd operations */
2048 +       mtd->erase   = cfi_amdstd_erase_varsize;
2049 +       mtd->write   = cfi_amdstd_write_words;
2050 +       mtd->read    = cfi_amdstd_read;
2051 +       mtd->sync    = cfi_amdstd_sync;
2052 +       mtd->suspend = cfi_amdstd_suspend;
2053 +       mtd->resume  = cfi_amdstd_resume;
2054 +       mtd->flags   = MTD_CAP_NORFLASH;
2055 +       mtd->name    = map->name;
2056  
2057         if (cfi->cfi_mode==CFI_MODE_CFI){
2058 +               unsigned char bootloc;
2059 +               /* 
2060 +                * It's a real CFI chip, not one for which the probe
2061 +                * routine faked a CFI structure. So we read the feature
2062 +                * table from it.
2063 +                */
2064                 __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
2065 +               struct cfi_pri_amdstd *extp;
2066  
2067 -               cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
2068 -               
2069 -               major = cfi_read_query(map, base + (adr+3)*ofs_factor);
2070 -               minor = cfi_read_query(map, base + (adr+4)*ofs_factor);
2071 -               
2072 -               printk(KERN_NOTICE " Amd/Fujitsu Extended Query Table v%c.%c at 0x%4.4X\n",
2073 -                      major, minor, adr);
2074 -                               cfi_send_gen_cmd(0xf0, 0x55, base, map, cfi, cfi->device_type, NULL);
2075 -               
2076 -               cfi_send_gen_cmd(0xaa, 0x555, base, map, cfi, cfi->device_type, NULL);
2077 -               cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL);
2078 -               cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL);
2079 -               /* FIXME - should have a delay before continuing */
2080 -               cfi->mfr = cfi_read_query(map, base);
2081 -               cfi->id = cfi_read_query(map, base + ofs_factor);    
2082 +               extp = (struct cfi_pri_amdstd*)cfi_read_pri(map, adr, sizeof(*extp), "Amd/Fujitsu");
2083 +               if (!extp) {
2084 +                       kfree(mtd);
2085 +                       return NULL;
2086 +               }
2087 +
2088 +               /* Install our own private info structure */
2089 +               cfi->cmdset_priv = extp;        
2090 +
2091 +               /* Apply cfi device specific fixups */
2092 +               cfi_fixup(mtd, cfi_fixup_table);
2093 +
2094 +#ifdef DEBUG_CFI_FEATURES
2095 +               /* Tell the user about it in lots of lovely detail */
2096 +               cfi_tell_features(extp);
2097 +#endif 
2098 +
2099 +               bootloc = extp->TopBottom;
2100 +               if ((bootloc != 2) && (bootloc != 3)) {
2101 +                       printk(KERN_WARNING "%s: CFI does not contain boot "
2102 +                              "bank location. Assuming top.\n", map->name);
2103 +                       bootloc = 2;
2104 +               }
2105  
2106 -               /* Wheee. Bring me the head of someone at AMD. */
2107 -#ifdef AMD_BOOTLOC_BUG
2108 -               if (((major << 8) | minor) < 0x3131) {
2109 -                       /* CFI version 1.0 => don't trust bootloc */
2110 -                       if (cfi->id & 0x80) {
2111 -                               printk(KERN_WARNING "%s: JEDEC Device ID is 0x%02X. Assuming broken CFI table.\n", map->name, cfi->id);
2112 -                               bootloc = 3;    /* top boot */
2113 -                       } else {
2114 -                               bootloc = 2;    /* bottom boot */
2115 -                       }
2116 -               } else
2117 -#endif
2118 -                       {
2119 -                               cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
2120 -                               bootloc = cfi_read_query(map, base + (adr+15)*ofs_factor);
2121 -                       }
2122                 if (bootloc == 3 && cfi->cfiq->NumEraseRegions > 1) {
2123                         printk(KERN_WARNING "%s: Swapping erase regions for broken CFI table.\n", map->name);
2124                         
2125 @@ -112,32 +277,50 @@
2126                         }
2127                 }
2128                 /*
2129 -                * FIXME - These might already be setup (more correctly)
2130 -                * buy jedec_probe.c.
2131 +                * These might already be setup (more correctly) by
2132 +                * jedec_probe.c - still need it for cfi_probe.c path.
2133                  */
2134 -               switch (cfi->device_type) {
2135 -               case CFI_DEVICETYPE_X8:
2136 -                       cfi->addr_unlock1 = 0x555; 
2137 -                       cfi->addr_unlock2 = 0x2aa; 
2138 -                       break;
2139 -               case CFI_DEVICETYPE_X16:
2140 -                       cfi->addr_unlock1 = 0xaaa;
2141 -                       if (map->buswidth == cfi->interleave) {
2142 -                               /* X16 chip(s) in X8 mode */
2143 -                               cfi->addr_unlock2 = 0x555;
2144 -                       } else {
2145 -                               cfi->addr_unlock2 = 0x554;
2146 +               if ( ! (cfi->addr_unlock1 && cfi->addr_unlock2) ) {
2147 +                       switch (cfi->device_type) {
2148 +                       case CFI_DEVICETYPE_X8:
2149 +                               cfi->addr_unlock1 = 0x555; 
2150 +                               cfi->addr_unlock2 = 0x2aa; 
2151 +                               break;
2152 +                       case CFI_DEVICETYPE_X16:
2153 +                               cfi->addr_unlock1 = 0xaaa;
2154 +                               if (map_bankwidth(map) == cfi_interleave(cfi)) {
2155 +                                       /* X16 chip(s) in X8 mode */
2156 +                                       cfi->addr_unlock2 = 0x555;
2157 +                               } else {
2158 +                                       cfi->addr_unlock2 = 0x554;
2159 +                               }
2160 +                               break;
2161 +                       case CFI_DEVICETYPE_X32:
2162 +                               cfi->addr_unlock1 = 0x1554;
2163 +                               if (map_bankwidth(map) == cfi_interleave(cfi)*2) {
2164 +                                       /* X32 chip(s) in X16 mode */
2165 +                                       cfi->addr_unlock1 = 0xaaa;
2166 +                               } else {
2167 +                                       cfi->addr_unlock2 = 0xaa8; 
2168 +                               }
2169 +                               break;
2170 +                       default:
2171 +                               printk(KERN_WARNING
2172 +                                      "MTD %s(): Unsupported device type %d\n",
2173 +                                      __func__, cfi->device_type);
2174 +                               kfree(mtd);
2175 +                               kfree(extp);
2176 +                               return NULL;
2177                         }
2178 -                       break;
2179 -               case CFI_DEVICETYPE_X32:
2180 -                       cfi->addr_unlock1 = 0x1555; 
2181 -                       cfi->addr_unlock2 = 0xaaa; 
2182 -                       break;
2183 -               default:
2184 -                       printk(KERN_NOTICE "Eep. Unknown cfi_cmdset_0002 device type %d\n", cfi->device_type);
2185 -                       return NULL;
2186                 }
2187 +
2188         } /* CFI mode */
2189 +       else if (cfi->cfi_mode == CFI_MODE_JEDEC) {
2190 +               /* Apply jedec specific fixups */
2191 +               cfi_fixup(mtd, jedec_fixup_table);
2192 +       }
2193 +       /* Apply generic fixups */
2194 +       cfi_fixup(mtd, fixup_table);
2195  
2196         for (i=0; i< cfi->numchips; i++) {
2197                 cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;
2198 @@ -146,135 +329,66 @@
2199         }               
2200         
2201         map->fldrv = &cfi_amdstd_chipdrv;
2202 -
2203 -       cfi_send_gen_cmd(0xf0, 0x55, base, map, cfi, cfi->device_type, NULL);
2204 -       return cfi_amdstd_setup(map);
2205 +       
2206 +       return cfi_amdstd_setup(mtd);
2207  }
2208  
2209 -static struct mtd_info *cfi_amdstd_setup(struct map_info *map)
2210 +
2211 +static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
2212  {
2213 +       struct map_info *map = mtd->priv;
2214         struct cfi_private *cfi = map->fldrv_priv;
2215 -       struct mtd_info *mtd;
2216         unsigned long devsize = (1<<cfi->cfiq->DevSize) * cfi->interleave;
2217 +       unsigned long offset = 0;
2218 +       int i,j;
2219  
2220 -       mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
2221         printk(KERN_NOTICE "number of %s chips: %d\n", 
2222 -               (cfi->cfi_mode == CFI_MODE_CFI)?"CFI":"JEDEC",cfi->numchips);
2223 +              (cfi->cfi_mode == CFI_MODE_CFI)?"CFI":"JEDEC",cfi->numchips);
2224 +       /* Select the correct geometry setup */ 
2225 +       mtd->size = devsize * cfi->numchips;
2226  
2227 -       if (!mtd) {
2228 -         printk(KERN_WARNING "Failed to allocate memory for MTD device\n");
2229 -         goto setup_err;
2230 +       mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
2231 +       mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
2232 +                                   * mtd->numeraseregions, GFP_KERNEL);
2233 +       if (!mtd->eraseregions) { 
2234 +               printk(KERN_WARNING "Failed to allocate memory for MTD erase region info\n");
2235 +               goto setup_err;
2236         }
2237 -
2238 -       memset(mtd, 0, sizeof(*mtd));
2239 -       mtd->priv = map;
2240 -       mtd->type = MTD_NORFLASH;
2241 -       /* Also select the correct geometry setup too */ 
2242 -       mtd->size = devsize * cfi->numchips;
2243 -       
2244 -       if (cfi->cfiq->NumEraseRegions == 1) {
2245 -               /* No need to muck about with multiple erase sizes */
2246 -               mtd->erasesize = ((cfi->cfiq->EraseRegionInfo[0] >> 8) & ~0xff) * cfi->interleave;
2247 -       } else {
2248 -               unsigned long offset = 0;
2249 -               int i,j;
2250 -
2251 -               mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
2252 -               mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) * mtd->numeraseregions, GFP_KERNEL);
2253 -               if (!mtd->eraseregions) { 
2254 -                       printk(KERN_WARNING "Failed to allocate memory for MTD erase region info\n");
2255 -                       goto setup_err;
2256 -               }
2257                         
2258 -               for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
2259 -                       unsigned long ernum, ersize;
2260 -                       ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
2261 -                       ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1;
2262 +       for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
2263 +               unsigned long ernum, ersize;
2264 +               ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
2265 +               ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1;
2266                         
2267 -                       if (mtd->erasesize < ersize) {
2268 -                               mtd->erasesize = ersize;
2269 -                       }
2270 -                       for (j=0; j<cfi->numchips; j++) {
2271 -                               mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].offset = (j*devsize)+offset;
2272 -                               mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].erasesize = ersize;
2273 -                               mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].numblocks = ernum;
2274 -                       }
2275 -                       offset += (ersize * ernum);
2276 -               }
2277 -               if (offset != devsize) {
2278 -                       /* Argh */
2279 -                       printk(KERN_WARNING "Sum of regions (%lx) != total size of set of interleaved chips (%lx)\n", offset, devsize);
2280 -                       goto setup_err;
2281 +               if (mtd->erasesize < ersize) {
2282 +                       mtd->erasesize = ersize;
2283                 }
2284 -#if 0
2285 -               // debug
2286 -               for (i=0; i<mtd->numeraseregions;i++){
2287 -                       printk("%d: offset=0x%x,size=0x%x,blocks=%d\n",
2288 -                              i,mtd->eraseregions[i].offset,
2289 -                              mtd->eraseregions[i].erasesize,
2290 -                              mtd->eraseregions[i].numblocks);
2291 -               }
2292 -#endif
2293 -       }
2294 -
2295 -       switch (CFIDEV_BUSWIDTH)
2296 -       {
2297 -       case 1:
2298 -       case 2:
2299 -       case 4:
2300 -#if 1
2301 -               if (mtd->numeraseregions > 1)
2302 -                       mtd->erase = cfi_amdstd_erase_varsize;
2303 -               else
2304 -#endif
2305 -               if (((cfi->cfiq->EraseRegionInfo[0] & 0xffff) + 1) == 1)
2306 -                       mtd->erase = cfi_amdstd_erase_chip;
2307 -               else
2308 -                       mtd->erase = cfi_amdstd_erase_onesize;
2309 -               mtd->read = cfi_amdstd_read;
2310 -               mtd->write = cfi_amdstd_write;
2311 -               break;
2312 -
2313 -       default:
2314 -               printk(KERN_WARNING "Unsupported buswidth\n");
2315 +               for (j=0; j<cfi->numchips; j++) {
2316 +                       mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].offset = (j*devsize)+offset;
2317 +                       mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].erasesize = ersize;
2318 +                       mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].numblocks = ernum;
2319 +               }
2320 +               offset += (ersize * ernum);
2321 +       }
2322 +       if (offset != devsize) {
2323 +               /* Argh */
2324 +               printk(KERN_WARNING "Sum of regions (%lx) != total size of set of interleaved chips (%lx)\n", offset, devsize);
2325                 goto setup_err;
2326 -               break;
2327         }
2328 -       if (cfi->fast_prog) {
2329 -               /* In cfi_amdstd_write() we frob the protection stuff
2330 -                  without paying any attention to the state machine.
2331 -                  This upsets in-progress erases. So we turn this flag
2332 -                  off for now till the code gets fixed. */
2333 -               printk(KERN_NOTICE "cfi_cmdset_0002: Disabling fast programming due to code brokenness.\n");
2334 -               cfi->fast_prog = 0;
2335 +#if 0
2336 +       // debug
2337 +       for (i=0; i<mtd->numeraseregions;i++){
2338 +               printk("%d: offset=0x%x,size=0x%x,blocks=%d\n",
2339 +                      i,mtd->eraseregions[i].offset,
2340 +                      mtd->eraseregions[i].erasesize,
2341 +                      mtd->eraseregions[i].numblocks);
2342         }
2343 +#endif
2344  
2345 +       /* FIXME: erase-suspend-program is broken.  See
2346 +          http://lists.infradead.org/pipermail/linux-mtd/2003-December/009001.html */
2347 +       printk(KERN_NOTICE "cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.\n");
2348  
2349 -        /* does this chip have a secsi area? */
2350 -       if(cfi->mfr==1){
2351 -               
2352 -               switch(cfi->id){
2353 -               case 0x50:
2354 -               case 0x53:
2355 -               case 0x55:
2356 -               case 0x56:
2357 -               case 0x5C:
2358 -               case 0x5F:
2359 -                       /* Yes */
2360 -                       mtd->read_user_prot_reg = cfi_amdstd_secsi_read;
2361 -                       mtd->read_fact_prot_reg = cfi_amdstd_secsi_read;
2362 -               default:                       
2363 -                       ;
2364 -               }
2365 -       }
2366 -       
2367 -               
2368 -       mtd->sync = cfi_amdstd_sync;
2369 -       mtd->suspend = cfi_amdstd_suspend;
2370 -       mtd->resume = cfi_amdstd_resume;
2371 -       mtd->flags = MTD_CAP_NORFLASH;
2372 -       map->fldrv = &cfi_amdstd_chipdrv;
2373 -       mtd->name = map->name;
2374         __module_get(THIS_MODULE);
2375         return mtd;
2376  
2377 @@ -289,46 +403,182 @@
2378         return NULL;
2379  }
2380  
2381 -static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
2382 +/*
2383 + * Return true if the chip is ready.
2384 + *
2385 + * Ready is one of: read mode, query mode, erase-suspend-read mode (in any
2386 + * non-suspended sector) and is indicated by no toggle bits toggling.
2387 + *
2388 + * Note that anything more complicated than checking if no bits are toggling
2389 + * (including checking DQ5 for an error status) is tricky to get working
2390 + * correctly and is therefore not done (particulary with interleaved chips
2391 + * as each chip must be checked independantly of the others).
2392 + */
2393 +static int chip_ready(struct map_info *map, unsigned long addr)
2394 +{
2395 +       map_word d, t;
2396 +
2397 +       d = map_read(map, addr);
2398 +       t = map_read(map, addr);
2399 +
2400 +       return map_word_equal(map, d, t);
2401 +}
2402 +
2403 +static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
2404  {
2405         DECLARE_WAITQUEUE(wait, current);
2406 -       unsigned long timeo = jiffies + HZ;
2407 +       struct cfi_private *cfi = map->fldrv_priv;
2408 +       unsigned long timeo;
2409 +       struct cfi_pri_amdstd *cfip = (struct cfi_pri_amdstd *)cfi->cmdset_priv;
2410  
2411 + resettime:
2412 +       timeo = jiffies + HZ;
2413   retry:
2414 -       cfi_spin_lock(chip->mutex);
2415 +       switch (chip->state) {
2416  
2417 -       if (chip->state != FL_READY){
2418 -#if 0
2419 -               printk(KERN_DEBUG "Waiting for chip to read, status = %d\n", chip->state);
2420 -#endif
2421 +       case FL_STATUS:
2422 +               for (;;) {
2423 +                       if (chip_ready(map, adr))
2424 +                               break;
2425 +
2426 +                       if (time_after(jiffies, timeo)) {
2427 +                               printk(KERN_ERR "Waiting for chip to be ready timed out.\n");
2428 +                               cfi_spin_unlock(chip->mutex);
2429 +                               return -EIO;
2430 +                       }
2431 +                       cfi_spin_unlock(chip->mutex);
2432 +                       cfi_udelay(1);
2433 +                       cfi_spin_lock(chip->mutex);
2434 +                       /* Someone else might have been playing with it. */
2435 +                       goto retry;
2436 +               }
2437 +                               
2438 +       case FL_READY:
2439 +       case FL_CFI_QUERY:
2440 +       case FL_JEDEC_QUERY:
2441 +               return 0;
2442 +
2443 +       case FL_ERASING:
2444 +               if (mode == FL_WRITING) /* FIXME: Erase-suspend-program appears broken. */
2445 +                       goto sleep;
2446 +
2447 +               if (!(mode == FL_READY || mode == FL_POINT
2448 +                     || !cfip
2449 +                     || (mode == FL_WRITING && (cfip->EraseSuspend & 0x2))
2450 +                     || (mode == FL_WRITING && (cfip->EraseSuspend & 0x1))))
2451 +                       goto sleep;
2452 +
2453 +               /* We could check to see if we're trying to access the sector
2454 +                * that is currently being erased. However, no user will try
2455 +                * anything like that so we just wait for the timeout. */
2456 +
2457 +               /* Erase suspend */
2458 +               /* It's harmless to issue the Erase-Suspend and Erase-Resume
2459 +                * commands when the erase algorithm isn't in progress. */
2460 +               map_write(map, CMD(0xB0), chip->in_progress_block_addr);
2461 +               chip->oldstate = FL_ERASING;
2462 +               chip->state = FL_ERASE_SUSPENDING;
2463 +               chip->erase_suspended = 1;
2464 +               for (;;) {
2465 +                       if (chip_ready(map, adr))
2466 +                               break;
2467 +
2468 +                       if (time_after(jiffies, timeo)) {
2469 +                               /* Should have suspended the erase by now.
2470 +                                * Send an Erase-Resume command as either
2471 +                                * there was an error (so leave the erase
2472 +                                * routine to recover from it) or we trying to
2473 +                                * use the erase-in-progress sector. */
2474 +                               map_write(map, CMD(0x30), chip->in_progress_block_addr);
2475 +                               chip->state = FL_ERASING;
2476 +                               chip->oldstate = FL_READY;
2477 +                               printk(KERN_ERR "MTD %s(): chip not ready after erase suspend\n", __func__);
2478 +                               return -EIO;
2479 +                       }
2480 +                       
2481 +                       cfi_spin_unlock(chip->mutex);
2482 +                       cfi_udelay(1);
2483 +                       cfi_spin_lock(chip->mutex);
2484 +                       /* Nobody will touch it while it's in state FL_ERASE_SUSPENDING.
2485 +                          So we can just loop here. */
2486 +               }
2487 +               chip->state = FL_READY;
2488 +               return 0;
2489 +
2490 +       case FL_POINT:
2491 +               /* Only if there's no operation suspended... */
2492 +               if (mode == FL_READY && chip->oldstate == FL_READY)
2493 +                       return 0;
2494 +
2495 +       default:
2496 +       sleep:
2497                 set_current_state(TASK_UNINTERRUPTIBLE);
2498                 add_wait_queue(&chip->wq, &wait);
2499 -                
2500                 cfi_spin_unlock(chip->mutex);
2501 -
2502                 schedule();
2503                 remove_wait_queue(&chip->wq, &wait);
2504 -#if 0
2505 -               if(signal_pending(current))
2506 -                       return -EINTR;
2507 -#endif
2508 -               timeo = jiffies + HZ;
2509 +               cfi_spin_lock(chip->mutex);
2510 +               goto resettime;
2511 +       }
2512 +}
2513  
2514 -               goto retry;
2515 -       }       
2516 +
2517 +static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr)
2518 +{
2519 +       struct cfi_private *cfi = map->fldrv_priv;
2520 +
2521 +       switch(chip->oldstate) {
2522 +       case FL_ERASING:
2523 +               chip->state = chip->oldstate;
2524 +               map_write(map, CMD(0x30), chip->in_progress_block_addr);
2525 +               chip->oldstate = FL_READY;
2526 +               chip->state = FL_ERASING;
2527 +               break;
2528 +
2529 +       case FL_READY:
2530 +       case FL_STATUS:
2531 +               /* We should really make set_vpp() count, rather than doing this */
2532 +               DISABLE_VPP(map);
2533 +               break;
2534 +       default:
2535 +               printk(KERN_ERR "MTD: put_chip() called with oldstate %d!!\n", chip->oldstate);
2536 +       }
2537 +       wake_up(&chip->wq);
2538 +}
2539 +
2540 +
2541 +static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
2542 +{
2543 +       unsigned long cmd_addr;
2544 +       struct cfi_private *cfi = map->fldrv_priv;
2545 +       int ret;
2546  
2547         adr += chip->start;
2548  
2549 -       chip->state = FL_READY;
2550 +       /* Ensure cmd read/writes are aligned. */ 
2551 +       cmd_addr = adr & ~(map_bankwidth(map)-1); 
2552 +
2553 +       cfi_spin_lock(chip->mutex);
2554 +       ret = get_chip(map, chip, cmd_addr, FL_READY);
2555 +       if (ret) {
2556 +               cfi_spin_unlock(chip->mutex);
2557 +               return ret;
2558 +       }
2559 +
2560 +       if (chip->state != FL_POINT && chip->state != FL_READY) {
2561 +               map_write(map, CMD(0xf0), cmd_addr);
2562 +               chip->state = FL_READY;
2563 +       }
2564  
2565         map_copy_from(map, buf, adr, len);
2566  
2567 -       wake_up(&chip->wq);
2568 -       cfi_spin_unlock(chip->mutex);
2569 +       put_chip(map, chip, cmd_addr);
2570  
2571 +       cfi_spin_unlock(chip->mutex);
2572         return 0;
2573  }
2574  
2575 +
2576  static int cfi_amdstd_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
2577  {
2578         struct map_info *map = mtd->priv;
2579 @@ -370,6 +620,7 @@
2580         return ret;
2581  }
2582  
2583 +
2584  static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
2585  {
2586         DECLARE_WAITQUEUE(wait, current);
2587 @@ -381,11 +632,11 @@
2588  
2589         if (chip->state != FL_READY){
2590  #if 0
2591 -               printk(KERN_DEBUG "Waiting for chip to read, status = %d\n", chip->state);
2592 +               printk(KERN_DEBUG "Waiting for chip to read, status = %d\n", chip->state);
2593  #endif
2594                 set_current_state(TASK_UNINTERRUPTIBLE);
2595                 add_wait_queue(&chip->wq, &wait);
2596 -                
2597 +               
2598                 cfi_spin_unlock(chip->mutex);
2599  
2600                 schedule();
2601 @@ -402,13 +653,15 @@
2602         adr += chip->start;
2603  
2604         chip->state = FL_READY;
2605 -       
2606 +
2607 +       /* should these be CFI_DEVICETYPE_X8 instead of cfi->device_type? */
2608         cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
2609         cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
2610         cfi_send_gen_cmd(0x88, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
2611         
2612         map_copy_from(map, buf, adr, len);
2613  
2614 +       /* should these be CFI_DEVICETYPE_X8 instead of cfi->device_type? */
2615         cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
2616         cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
2617         cfi_send_gen_cmd(0x90, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
2618 @@ -463,215 +716,388 @@
2619         return ret;
2620  }
2621  
2622 -static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, cfi_word datum, int fast)
2623 +
2624 +static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, map_word datum)
2625  {
2626 -       unsigned long timeo = jiffies + HZ;
2627 -       unsigned int oldstatus, status, prev_oldstatus, prev_status;
2628 -       unsigned int dq6;
2629         struct cfi_private *cfi = map->fldrv_priv;
2630 -    /* We use a 1ms + 1 jiffies generic timeout for writes (most devices have
2631 -       a max write time of a few hundreds usec). However, we should use the
2632 -       maximum timeout value given by the chip at probe time instead. 
2633 -       Unfortunately, struct flchip does have a field for maximum timeout, 
2634 -       only for typical which can be far too short depending of the conditions.
2635 -       The ' + 1' is to avoid having a timeout of 0 jiffies if HZ is smaller
2636 -       than 1000. Using a static variable allows makes us save the costly
2637 -       divide operation at each word write.*/ 
2638 -    static unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
2639 -       DECLARE_WAITQUEUE(wait, current);
2640 +       unsigned long timeo = jiffies + HZ;
2641 +       /*
2642 +        * We use a 1ms + 1 jiffies generic timeout for writes (most devices
2643 +        * have a max write time of a few hundreds usec). However, we should
2644 +        * use the maximum timeout value given by the chip at probe time
2645 +        * instead.  Unfortunately, struct flchip does have a field for
2646 +        * maximum timeout, only for typical which can be far too short
2647 +        * depending of the conditions.  The ' + 1' is to avoid having a
2648 +        * timeout of 0 jiffies if HZ is smaller than 1000.
2649 +        */
2650 +       unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
2651         int ret = 0;
2652 -       int ta = 0;
2653 +       map_word oldd, curd;
2654 +       int retry_cnt = 0;
2655  
2656 +       adr += chip->start;
2657 +
2658 +       cfi_spin_lock(chip->mutex);
2659 +       ret = get_chip(map, chip, adr, FL_WRITING);
2660 +       if (ret) {
2661 +               cfi_spin_unlock(chip->mutex);
2662 +               return ret;
2663 +       }
2664 +
2665 +       DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8lx)\n",
2666 +              __func__, adr, datum.x[0] );
2667 +
2668 +       /*
2669 +        * Check for a NOP for the case when the datum to write is already
2670 +        * present - it saves time and works around buggy chips that corrupt
2671 +        * data at other locations when 0xff is written to a location that
2672 +        * already contains 0xff.
2673 +        */
2674 +       oldd = map_read(map, adr);
2675 +       if (map_word_equal(map, oldd, datum)) {
2676 +               DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): NOP\n",
2677 +                      __func__);
2678 +               goto op_done;
2679 +       }
2680 +
2681 +       ENABLE_VPP(map);
2682   retry:
2683 +       /*
2684 +        * The CFI_DEVICETYPE_X8 argument is needed even when
2685 +        * cfi->device_type != CFI_DEVICETYPE_X8.  The addresses for
2686 +        * command sequences don't scale even when the device is
2687 +        * wider.  This is the case for many of the cfi_send_gen_cmd()
2688 +        * below.  I'm not sure, however, why some use
2689 +        * cfi->device_type.
2690 +        */
2691 +       cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
2692 +       cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
2693 +       cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
2694 +       map_write(map, datum, adr);
2695 +       chip->state = FL_WRITING;
2696 +
2697 +       cfi_spin_unlock(chip->mutex);
2698 +       cfi_udelay(chip->word_write_time);
2699         cfi_spin_lock(chip->mutex);
2700  
2701 -       if (chip->state != FL_READY) {
2702 +       /* See comment above for timeout value. */
2703 +       timeo = jiffies + uWriteTimeout; 
2704 +       for (;;) {
2705 +               if (chip->state != FL_WRITING) {
2706 +                       /* Someone's suspended the write. Sleep */
2707 +                       DECLARE_WAITQUEUE(wait, current);
2708 +
2709 +                       set_current_state(TASK_UNINTERRUPTIBLE);
2710 +                       add_wait_queue(&chip->wq, &wait);
2711 +                       cfi_spin_unlock(chip->mutex);
2712 +                       schedule();
2713 +                       remove_wait_queue(&chip->wq, &wait);
2714 +                       timeo = jiffies + (HZ / 2); /* FIXME */
2715 +                       cfi_spin_lock(chip->mutex);
2716 +                       continue;
2717 +               }
2718 +
2719 +               /* Test to see if toggling has stopped. */
2720 +               oldd = map_read(map, adr);
2721 +               curd = map_read(map, adr);
2722 +               if (map_word_equal(map, curd, oldd)) {
2723 +                       /* Do we have the correct value? */
2724 +                       if (map_word_equal(map, curd, datum)) {
2725 +                               goto op_done;
2726 +                       }
2727 +                       /* Nope something has gone wrong. */
2728 +                       break;
2729 +               }
2730 +
2731 +               if (time_after(jiffies, timeo)) {
2732 +                       printk(KERN_WARNING "MTD %s(): software timeout\n",
2733 +                               __func__ );
2734 +                       break;
2735 +               }
2736 +
2737 +               /* Latency issues. Drop the lock, wait a while and retry */
2738 +               cfi_spin_unlock(chip->mutex);
2739 +               cfi_udelay(1);
2740 +               cfi_spin_lock(chip->mutex);
2741 +       }
2742 +
2743 +       /* reset on all failures. */
2744 +       map_write( map, CMD(0xF0), chip->start );
2745 +       /* FIXME - should have reset delay before continuing */
2746 +       if (++retry_cnt <= MAX_WORD_RETRIES) 
2747 +               goto retry;
2748 +
2749 +       ret = -EIO;
2750 + op_done:
2751 +       chip->state = FL_READY;
2752 +       put_chip(map, chip, adr);
2753 +       cfi_spin_unlock(chip->mutex);
2754 +
2755 +       return ret;
2756 +}
2757 +
2758 +
2759 +static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
2760 +                                 size_t *retlen, const u_char *buf)
2761 +{
2762 +       struct map_info *map = mtd->priv;
2763 +       struct cfi_private *cfi = map->fldrv_priv;
2764 +       int ret = 0;
2765 +       int chipnum;
2766 +       unsigned long ofs, chipstart;
2767 +       DECLARE_WAITQUEUE(wait, current);
2768 +
2769 +       *retlen = 0;
2770 +       if (!len)
2771 +               return 0;
2772 +
2773 +       chipnum = to >> cfi->chipshift;
2774 +       ofs = to  - (chipnum << cfi->chipshift);
2775 +       chipstart = cfi->chips[chipnum].start;
2776 +
2777 +       /* If it's not bus-aligned, do the first byte write */
2778 +       if (ofs & (map_bankwidth(map)-1)) {
2779 +               unsigned long bus_ofs = ofs & ~(map_bankwidth(map)-1);
2780 +               int i = ofs - bus_ofs;
2781 +               int n = 0;
2782 +               map_word tmp_buf;
2783 +
2784 + retry:
2785 +               cfi_spin_lock(cfi->chips[chipnum].mutex);
2786 +
2787 +               if (cfi->chips[chipnum].state != FL_READY) {
2788  #if 0
2789 -               printk(KERN_DEBUG "Waiting for chip to write, status = %d\n", chip->state);
2790 +                       printk(KERN_DEBUG "Waiting for chip to write, status = %d\n", cfi->chips[chipnum].state);
2791  #endif
2792 -               set_current_state(TASK_UNINTERRUPTIBLE);
2793 -               add_wait_queue(&chip->wq, &wait);
2794 -                
2795 -               cfi_spin_unlock(chip->mutex);
2796 +                       set_current_state(TASK_UNINTERRUPTIBLE);
2797 +                       add_wait_queue(&cfi->chips[chipnum].wq, &wait);
2798  
2799 -               schedule();
2800 -               remove_wait_queue(&chip->wq, &wait);
2801 +                       cfi_spin_unlock(cfi->chips[chipnum].mutex);
2802 +
2803 +                       schedule();
2804 +                       remove_wait_queue(&cfi->chips[chipnum].wq, &wait);
2805  #if 0
2806 -               printk(KERN_DEBUG "Wake up to write:\n");
2807 -               if(signal_pending(current))
2808 -                       return -EINTR;
2809 +                       if(signal_pending(current))
2810 +                               return -EINTR;
2811  #endif
2812 -               timeo = jiffies + HZ;
2813 +                       goto retry;
2814 +               }
2815  
2816 -               goto retry;
2817 -       }       
2818 +               /* Load 'tmp_buf' with old contents of flash */
2819 +               tmp_buf = map_read(map, bus_ofs+chipstart);
2820  
2821 -       chip->state = FL_WRITING;
2822 +               cfi_spin_unlock(cfi->chips[chipnum].mutex);
2823 +
2824 +               /* Number of bytes to copy from buffer */
2825 +               n = min_t(int, len, map_bankwidth(map)-i);
2826 +               
2827 +               tmp_buf = map_word_load_partial(map, tmp_buf, buf, i, n);
2828 +
2829 +               ret = do_write_oneword(map, &cfi->chips[chipnum], 
2830 +                                      bus_ofs, tmp_buf);
2831 +               if (ret) 
2832 +                       return ret;
2833 +               
2834 +               ofs += n;
2835 +               buf += n;
2836 +               (*retlen) += n;
2837 +               len -= n;
2838 +
2839 +               if (ofs >> cfi->chipshift) {
2840 +                       chipnum ++; 
2841 +                       ofs = 0;
2842 +                       if (chipnum == cfi->numchips)
2843 +                               return 0;
2844 +               }
2845 +       }
2846 +       
2847 +       /* We are now aligned, write as much as possible */
2848 +       while(len >= map_bankwidth(map)) {
2849 +               map_word datum;
2850 +
2851 +               datum = map_word_load(map, buf);
2852 +
2853 +               ret = do_write_oneword(map, &cfi->chips[chipnum],
2854 +                                      ofs, datum);
2855 +               if (ret)
2856 +                       return ret;
2857 +
2858 +               ofs += map_bankwidth(map);
2859 +               buf += map_bankwidth(map);
2860 +               (*retlen) += map_bankwidth(map);
2861 +               len -= map_bankwidth(map);
2862 +
2863 +               if (ofs >> cfi->chipshift) {
2864 +                       chipnum ++; 
2865 +                       ofs = 0;
2866 +                       if (chipnum == cfi->numchips)
2867 +                               return 0;
2868 +                       chipstart = cfi->chips[chipnum].start;
2869 +               }
2870 +       }
2871 +
2872 +       /* Write the trailing bytes if any */
2873 +       if (len & (map_bankwidth(map)-1)) {
2874 +               map_word tmp_buf;
2875 +
2876 + retry1:
2877 +               cfi_spin_lock(cfi->chips[chipnum].mutex);
2878 +
2879 +               if (cfi->chips[chipnum].state != FL_READY) {
2880 +#if 0
2881 +                       printk(KERN_DEBUG "Waiting for chip to write, status = %d\n", cfi->chips[chipnum].state);
2882 +#endif
2883 +                       set_current_state(TASK_UNINTERRUPTIBLE);
2884 +                       add_wait_queue(&cfi->chips[chipnum].wq, &wait);
2885 +
2886 +                       cfi_spin_unlock(cfi->chips[chipnum].mutex);
2887 +
2888 +                       schedule();
2889 +                       remove_wait_queue(&cfi->chips[chipnum].wq, &wait);
2890 +#if 0
2891 +                       if(signal_pending(current))
2892 +                               return -EINTR;
2893 +#endif
2894 +                       goto retry1;
2895 +               }
2896 +
2897 +               tmp_buf = map_read(map, ofs + chipstart);
2898 +
2899 +               cfi_spin_unlock(cfi->chips[chipnum].mutex);
2900 +
2901 +               tmp_buf = map_word_load_partial(map, tmp_buf, buf, 0, len);
2902 +       
2903 +               ret = do_write_oneword(map, &cfi->chips[chipnum], 
2904 +                               ofs, tmp_buf);
2905 +               if (ret) 
2906 +                       return ret;
2907 +               
2908 +               (*retlen) += len;
2909 +       }
2910 +
2911 +       return 0;
2912 +}
2913 +
2914 +
2915 +/*