Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/drivers/mtd/chips/cfi_cmdset_0020.c (Version 2.6.31.13) and /linux/drivers/mtd/chips/cfi_cmdset_0020.c (Version 2.6.25.8)


  1 /*                                                  1 /*
  2  * Common Flash Interface support:                  2  * Common Flash Interface support:
  3  *   ST Advanced Architecture Command Set (ID       3  *   ST Advanced Architecture Command Set (ID 0x0020)
  4  *                                                  4  *
  5  * (C) 2000 Red Hat. GPL'd                          5  * (C) 2000 Red Hat. GPL'd
  6  *                                                  6  *
                                                   >>   7  * $Id: cfi_cmdset_0020.c,v 1.22 2005/11/07 11:14:22 gleixner Exp $
                                                   >>   8  *
  7  * 10/10/2000   Nicolas Pitre <nico@cam.org>        9  * 10/10/2000   Nicolas Pitre <nico@cam.org>
  8  *      - completely revamped method functions     10  *      - completely revamped method functions so they are aware and
  9  *        independent of the flash geometry (b     11  *        independent of the flash geometry (buswidth, interleave, etc.)
 10  *      - scalability vs code size is complete     12  *      - scalability vs code size is completely set at compile-time
 11  *        (see include/linux/mtd/cfi.h for sel     13  *        (see include/linux/mtd/cfi.h for selection)
 12  *      - optimized write buffer method            14  *      - optimized write buffer method
 13  * 06/21/2002   Joern Engel <joern@wh.fh-wedel     15  * 06/21/2002   Joern Engel <joern@wh.fh-wedel.de> and others
 14  *      - modified Intel Command Set 0x0001 to     16  *      - modified Intel Command Set 0x0001 to support ST Advanced Architecture
 15  *        (command set 0x0020)                     17  *        (command set 0x0020)
 16  *      - added a writev function                  18  *      - added a writev function
 17  * 07/13/2005   Joern Engel <joern@wh.fh-wedel     19  * 07/13/2005   Joern Engel <joern@wh.fh-wedel.de>
 18  *      - Plugged memory leak in cfi_staa_writ     20  *      - Plugged memory leak in cfi_staa_writev().
 19  */                                                21  */
 20                                                    22 
 21 #include <linux/module.h>                          23 #include <linux/module.h>
 22 #include <linux/types.h>                           24 #include <linux/types.h>
 23 #include <linux/kernel.h>                          25 #include <linux/kernel.h>
 24 #include <linux/sched.h>                           26 #include <linux/sched.h>
 25 #include <linux/init.h>                            27 #include <linux/init.h>
 26 #include <asm/io.h>                                28 #include <asm/io.h>
 27 #include <asm/byteorder.h>                         29 #include <asm/byteorder.h>
 28                                                    30 
 29 #include <linux/errno.h>                           31 #include <linux/errno.h>
 30 #include <linux/slab.h>                            32 #include <linux/slab.h>
 31 #include <linux/delay.h>                           33 #include <linux/delay.h>
 32 #include <linux/interrupt.h>                       34 #include <linux/interrupt.h>
 33 #include <linux/mtd/map.h>                         35 #include <linux/mtd/map.h>
 34 #include <linux/mtd/cfi.h>                         36 #include <linux/mtd/cfi.h>
 35 #include <linux/mtd/mtd.h>                         37 #include <linux/mtd/mtd.h>
 36 #include <linux/mtd/compatmac.h>                   38 #include <linux/mtd/compatmac.h>
 37                                                    39 
 38                                                    40 
 39 static int cfi_staa_read(struct mtd_info *, lo     41 static int cfi_staa_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *);
 40 static int cfi_staa_write_buffers(struct mtd_i     42 static int cfi_staa_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
 41 static int cfi_staa_writev(struct mtd_info *mt     43 static int cfi_staa_writev(struct mtd_info *mtd, const struct kvec *vecs,
 42                 unsigned long count, loff_t to     44                 unsigned long count, loff_t to, size_t *retlen);
 43 static int cfi_staa_erase_varsize(struct mtd_i     45 static int cfi_staa_erase_varsize(struct mtd_info *, struct erase_info *);
 44 static void cfi_staa_sync (struct mtd_info *);     46 static void cfi_staa_sync (struct mtd_info *);
 45 static int cfi_staa_lock(struct mtd_info *mtd, !!  47 static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, size_t len);
 46 static int cfi_staa_unlock(struct mtd_info *mt !!  48 static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, size_t len);
 47 static int cfi_staa_suspend (struct mtd_info *     49 static int cfi_staa_suspend (struct mtd_info *);
 48 static void cfi_staa_resume (struct mtd_info *     50 static void cfi_staa_resume (struct mtd_info *);
 49                                                    51 
 50 static void cfi_staa_destroy(struct mtd_info *     52 static void cfi_staa_destroy(struct mtd_info *);
 51                                                    53 
 52 struct mtd_info *cfi_cmdset_0020(struct map_in     54 struct mtd_info *cfi_cmdset_0020(struct map_info *, int);
 53                                                    55 
 54 static struct mtd_info *cfi_staa_setup (struct     56 static struct mtd_info *cfi_staa_setup (struct map_info *);
 55                                                    57 
 56 static struct mtd_chip_driver cfi_staa_chipdrv     58 static struct mtd_chip_driver cfi_staa_chipdrv = {
 57         .probe          = NULL, /* Not usable      59         .probe          = NULL, /* Not usable directly */
 58         .destroy        = cfi_staa_destroy,        60         .destroy        = cfi_staa_destroy,
 59         .name           = "cfi_cmdset_0020",       61         .name           = "cfi_cmdset_0020",
 60         .module         = THIS_MODULE              62         .module         = THIS_MODULE
 61 };                                                 63 };
 62                                                    64 
 63 /* #define DEBUG_LOCK_BITS */                      65 /* #define DEBUG_LOCK_BITS */
 64 //#define DEBUG_CFI_FEATURES                       66 //#define DEBUG_CFI_FEATURES
 65                                                    67 
 66 #ifdef DEBUG_CFI_FEATURES                          68 #ifdef DEBUG_CFI_FEATURES
 67 static void cfi_tell_features(struct cfi_pri_i     69 static void cfi_tell_features(struct cfi_pri_intelext *extp)
 68 {                                                  70 {
 69         int i;                                     71         int i;
 70         printk("  Feature/Command Support: %4.     72         printk("  Feature/Command Support: %4.4X\n", extp->FeatureSupport);
 71         printk("     - Chip Erase:         %s\     73         printk("     - Chip Erase:         %s\n", extp->FeatureSupport&1?"supported":"unsupported");
 72         printk("     - Suspend Erase:      %s\     74         printk("     - Suspend Erase:      %s\n", extp->FeatureSupport&2?"supported":"unsupported");
 73         printk("     - Suspend Program:    %s\     75         printk("     - Suspend Program:    %s\n", extp->FeatureSupport&4?"supported":"unsupported");
 74         printk("     - Legacy Lock/Unlock: %s\     76         printk("     - Legacy Lock/Unlock: %s\n", extp->FeatureSupport&8?"supported":"unsupported");
 75         printk("     - Queued Erase:       %s\     77         printk("     - Queued Erase:       %s\n", extp->FeatureSupport&16?"supported":"unsupported");
 76         printk("     - Instant block lock: %s\     78         printk("     - Instant block lock: %s\n", extp->FeatureSupport&32?"supported":"unsupported");
 77         printk("     - Protection Bits:    %s\     79         printk("     - Protection Bits:    %s\n", extp->FeatureSupport&64?"supported":"unsupported");
 78         printk("     - Page-mode read:     %s\     80         printk("     - Page-mode read:     %s\n", extp->FeatureSupport&128?"supported":"unsupported");
 79         printk("     - Synchronous read:   %s\     81         printk("     - Synchronous read:   %s\n", extp->FeatureSupport&256?"supported":"unsupported");
 80         for (i=9; i<32; i++) {                     82         for (i=9; i<32; i++) {
 81                 if (extp->FeatureSupport & (1<     83                 if (extp->FeatureSupport & (1<<i))
 82                         printk("     - Unknown     84                         printk("     - Unknown Bit %X:      supported\n", i);
 83         }                                          85         }
 84                                                    86 
 85         printk("  Supported functions after Su     87         printk("  Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport);
 86         printk("     - Program after Erase Sus     88         printk("     - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported");
 87         for (i=1; i<8; i++) {                      89         for (i=1; i<8; i++) {
 88                 if (extp->SuspendCmdSupport &      90                 if (extp->SuspendCmdSupport & (1<<i))
 89                         printk("     - Unknown     91                         printk("     - Unknown Bit %X:               supported\n", i);
 90         }                                          92         }
 91                                                    93 
 92         printk("  Block Status Register Mask:      94         printk("  Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask);
 93         printk("     - Lock Bit Active:      %     95         printk("     - Lock Bit Active:      %s\n", extp->BlkStatusRegMask&1?"yes":"no");
 94         printk("     - Valid Bit Active:     %     96         printk("     - Valid Bit Active:     %s\n", extp->BlkStatusRegMask&2?"yes":"no");
 95         for (i=2; i<16; i++) {                     97         for (i=2; i<16; i++) {
 96                 if (extp->BlkStatusRegMask & (     98                 if (extp->BlkStatusRegMask & (1<<i))
 97                         printk("     - Unknown     99                         printk("     - Unknown Bit %X Active: yes\n",i);
 98         }                                         100         }
 99                                                   101 
100         printk("  Vcc Logic Supply Optimum Pro    102         printk("  Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n",
101                extp->VccOptimal >> 8, extp->Vc    103                extp->VccOptimal >> 8, extp->VccOptimal & 0xf);
102         if (extp->VppOptimal)                     104         if (extp->VppOptimal)
103                 printk("  Vpp Programming Supp    105                 printk("  Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n",
104                        extp->VppOptimal >> 8,     106                        extp->VppOptimal >> 8, extp->VppOptimal & 0xf);
105 }                                                 107 }
106 #endif                                            108 #endif
107                                                   109 
108 /* This routine is made available to other mtd    110 /* This routine is made available to other mtd code via
109  * inter_module_register.  It must only be acc    111  * inter_module_register.  It must only be accessed through
110  * inter_module_get which will bump the use co    112  * inter_module_get which will bump the use count of this module.  The
111  * addresses passed back in cfi are valid as l    113  * addresses passed back in cfi are valid as long as the use count of
112  * this module is non-zero, i.e. between inter    114  * this module is non-zero, i.e. between inter_module_get and
113  * inter_module_put.  Keith Owens <kaos@ocs.co    115  * inter_module_put.  Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
114  */                                               116  */
115 struct mtd_info *cfi_cmdset_0020(struct map_in    117 struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary)
116 {                                                 118 {
117         struct cfi_private *cfi = map->fldrv_p    119         struct cfi_private *cfi = map->fldrv_priv;
118         int i;                                    120         int i;
119                                                   121 
120         if (cfi->cfi_mode) {                      122         if (cfi->cfi_mode) {
121                 /*                                123                 /*
122                  * It's a real CFI chip, not o    124                  * It's a real CFI chip, not one for which the probe
123                  * routine faked a CFI structu    125                  * routine faked a CFI structure. So we read the feature
124                  * table from it.                 126                  * table from it.
125                  */                               127                  */
126                 __u16 adr = primary?cfi->cfiq-    128                 __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
127                 struct cfi_pri_intelext *extp;    129                 struct cfi_pri_intelext *extp;
128                                                   130 
129                 extp = (struct cfi_pri_intelex    131                 extp = (struct cfi_pri_intelext*)cfi_read_pri(map, adr, sizeof(*extp), "ST Microelectronics");
130                 if (!extp)                        132                 if (!extp)
131                         return NULL;              133                         return NULL;
132                                                   134 
133                 if (extp->MajorVersion != '1'     135                 if (extp->MajorVersion != '1' ||
134                     (extp->MinorVersion < '' |    136                     (extp->MinorVersion < '' || extp->MinorVersion > '3')) {
135                         printk(KERN_ERR "  Unk    137                         printk(KERN_ERR "  Unknown ST Microelectronics"
136                                " Extended Quer    138                                " Extended Query version %c.%c.\n",
137                                extp->MajorVers    139                                extp->MajorVersion, extp->MinorVersion);
138                         kfree(extp);              140                         kfree(extp);
139                         return NULL;              141                         return NULL;
140                 }                                 142                 }
141                                                   143 
142                 /* Do some byteswapping if nec    144                 /* Do some byteswapping if necessary */
143                 extp->FeatureSupport = cfi32_t    145                 extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport);
144                 extp->BlkStatusRegMask = cfi32    146                 extp->BlkStatusRegMask = cfi32_to_cpu(extp->BlkStatusRegMask);
145                                                   147 
146 #ifdef DEBUG_CFI_FEATURES                         148 #ifdef DEBUG_CFI_FEATURES
147                 /* Tell the user about it in l    149                 /* Tell the user about it in lots of lovely detail */
148                 cfi_tell_features(extp);          150                 cfi_tell_features(extp);
149 #endif                                            151 #endif
150                                                   152 
151                 /* Install our own private inf    153                 /* Install our own private info structure */
152                 cfi->cmdset_priv = extp;          154                 cfi->cmdset_priv = extp;
153         }                                         155         }
154                                                   156 
155         for (i=0; i< cfi->numchips; i++) {        157         for (i=0; i< cfi->numchips; i++) {
156                 cfi->chips[i].word_write_time     158                 cfi->chips[i].word_write_time = 128;
157                 cfi->chips[i].buffer_write_tim    159                 cfi->chips[i].buffer_write_time = 128;
158                 cfi->chips[i].erase_time = 102    160                 cfi->chips[i].erase_time = 1024;
159                 cfi->chips[i].ref_point_counte    161                 cfi->chips[i].ref_point_counter = 0;
160                 init_waitqueue_head(&(cfi->chi    162                 init_waitqueue_head(&(cfi->chips[i].wq));
161         }                                         163         }
162                                                   164 
163         return cfi_staa_setup(map);               165         return cfi_staa_setup(map);
164 }                                                 166 }
165 EXPORT_SYMBOL_GPL(cfi_cmdset_0020);               167 EXPORT_SYMBOL_GPL(cfi_cmdset_0020);
166                                                   168 
167 static struct mtd_info *cfi_staa_setup(struct     169 static struct mtd_info *cfi_staa_setup(struct map_info *map)
168 {                                                 170 {
169         struct cfi_private *cfi = map->fldrv_p    171         struct cfi_private *cfi = map->fldrv_priv;
170         struct mtd_info *mtd;                     172         struct mtd_info *mtd;
171         unsigned long offset = 0;                 173         unsigned long offset = 0;
172         int i,j;                                  174         int i,j;
173         unsigned long devsize = (1<<cfi->cfiq-    175         unsigned long devsize = (1<<cfi->cfiq->DevSize) * cfi->interleave;
174                                                   176 
175         mtd = kzalloc(sizeof(*mtd), GFP_KERNEL    177         mtd = kzalloc(sizeof(*mtd), GFP_KERNEL);
176         //printk(KERN_DEBUG "number of CFI chi    178         //printk(KERN_DEBUG "number of CFI chips: %d\n", cfi->numchips);
177                                                   179 
178         if (!mtd) {                               180         if (!mtd) {
179                 printk(KERN_ERR "Failed to all    181                 printk(KERN_ERR "Failed to allocate memory for MTD device\n");
180                 kfree(cfi->cmdset_priv);          182                 kfree(cfi->cmdset_priv);
181                 return NULL;                      183                 return NULL;
182         }                                         184         }
183                                                   185 
184         mtd->priv = map;                          186         mtd->priv = map;
185         mtd->type = MTD_NORFLASH;                 187         mtd->type = MTD_NORFLASH;
186         mtd->size = devsize * cfi->numchips;      188         mtd->size = devsize * cfi->numchips;
187                                                   189 
188         mtd->numeraseregions = cfi->cfiq->NumE    190         mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
189         mtd->eraseregions = kmalloc(sizeof(str    191         mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
190                         * mtd->numeraseregions    192                         * mtd->numeraseregions, GFP_KERNEL);
191         if (!mtd->eraseregions) {                 193         if (!mtd->eraseregions) {
192                 printk(KERN_ERR "Failed to all    194                 printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n");
193                 kfree(cfi->cmdset_priv);          195                 kfree(cfi->cmdset_priv);
194                 kfree(mtd);                       196                 kfree(mtd);
195                 return NULL;                      197                 return NULL;
196         }                                         198         }
197                                                   199 
198         for (i=0; i<cfi->cfiq->NumEraseRegions    200         for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
199                 unsigned long ernum, ersize;      201                 unsigned long ernum, ersize;
200                 ersize = ((cfi->cfiq->EraseReg    202                 ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
201                 ernum = (cfi->cfiq->EraseRegio    203                 ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1;
202                                                   204 
203                 if (mtd->erasesize < ersize) {    205                 if (mtd->erasesize < ersize) {
204                         mtd->erasesize = ersiz    206                         mtd->erasesize = ersize;
205                 }                                 207                 }
206                 for (j=0; j<cfi->numchips; j++    208                 for (j=0; j<cfi->numchips; j++) {
207                         mtd->eraseregions[(j*c    209                         mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].offset = (j*devsize)+offset;
208                         mtd->eraseregions[(j*c    210                         mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].erasesize = ersize;
209                         mtd->eraseregions[(j*c    211                         mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].numblocks = ernum;
210                 }                                 212                 }
211                 offset += (ersize * ernum);       213                 offset += (ersize * ernum);
212                 }                                 214                 }
213                                                   215 
214                 if (offset != devsize) {          216                 if (offset != devsize) {
215                         /* Argh */                217                         /* Argh */
216                         printk(KERN_WARNING "S    218                         printk(KERN_WARNING "Sum of regions (%lx) != total size of set of interleaved chips (%lx)\n", offset, devsize);
217                         kfree(mtd->eraseregion    219                         kfree(mtd->eraseregions);
218                         kfree(cfi->cmdset_priv    220                         kfree(cfi->cmdset_priv);
219                         kfree(mtd);               221                         kfree(mtd);
220                         return NULL;              222                         return NULL;
221                 }                                 223                 }
222                                                   224 
223                 for (i=0; i<mtd->numeraseregio    225                 for (i=0; i<mtd->numeraseregions;i++){
224                         printk(KERN_DEBUG "%d: !! 226                         printk(KERN_DEBUG "%d: offset=0x%x,size=0x%x,blocks=%d\n",
225                                i, (unsigned lo !! 227                                i,mtd->eraseregions[i].offset,
226                                mtd->eraseregio    228                                mtd->eraseregions[i].erasesize,
227                                mtd->eraseregio    229                                mtd->eraseregions[i].numblocks);
228                 }                                 230                 }
229                                                   231 
230         /* Also select the correct geometry se    232         /* Also select the correct geometry setup too */
231         mtd->erase = cfi_staa_erase_varsize;      233         mtd->erase = cfi_staa_erase_varsize;
232         mtd->read = cfi_staa_read;                234         mtd->read = cfi_staa_read;
233         mtd->write = cfi_staa_write_buffers;      235         mtd->write = cfi_staa_write_buffers;
234         mtd->writev = cfi_staa_writev;            236         mtd->writev = cfi_staa_writev;
235         mtd->sync = cfi_staa_sync;                237         mtd->sync = cfi_staa_sync;
236         mtd->lock = cfi_staa_lock;                238         mtd->lock = cfi_staa_lock;
237         mtd->unlock = cfi_staa_unlock;            239         mtd->unlock = cfi_staa_unlock;
238         mtd->suspend = cfi_staa_suspend;          240         mtd->suspend = cfi_staa_suspend;
239         mtd->resume = cfi_staa_resume;            241         mtd->resume = cfi_staa_resume;
240         mtd->flags = MTD_CAP_NORFLASH & ~MTD_B    242         mtd->flags = MTD_CAP_NORFLASH & ~MTD_BIT_WRITEABLE;
241         mtd->writesize = 8; /* FIXME: Should b    243         mtd->writesize = 8; /* FIXME: Should be 0 for STMicro flashes w/out ECC */
242         map->fldrv = &cfi_staa_chipdrv;           244         map->fldrv = &cfi_staa_chipdrv;
243         __module_get(THIS_MODULE);                245         __module_get(THIS_MODULE);
244         mtd->name = map->name;                    246         mtd->name = map->name;
245         return mtd;                               247         return mtd;
246 }                                                 248 }
247                                                   249 
248                                                   250 
249 static inline int do_read_onechip(struct map_i    251 static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
250 {                                                 252 {
251         map_word status, status_OK;               253         map_word status, status_OK;
252         unsigned long timeo;                      254         unsigned long timeo;
253         DECLARE_WAITQUEUE(wait, current);         255         DECLARE_WAITQUEUE(wait, current);
254         int suspended = 0;                        256         int suspended = 0;
255         unsigned long cmd_addr;                   257         unsigned long cmd_addr;
256         struct cfi_private *cfi = map->fldrv_p    258         struct cfi_private *cfi = map->fldrv_priv;
257                                                   259 
258         adr += chip->start;                       260         adr += chip->start;
259                                                   261 
260         /* Ensure cmd read/writes are aligned.    262         /* Ensure cmd read/writes are aligned. */
261         cmd_addr = adr & ~(map_bankwidth(map)-    263         cmd_addr = adr & ~(map_bankwidth(map)-1);
262                                                   264 
263         /* Let's determine this according to t    265         /* Let's determine this according to the interleave only once */
264         status_OK = CMD(0x80);                    266         status_OK = CMD(0x80);
265                                                   267 
266         timeo = jiffies + HZ;                     268         timeo = jiffies + HZ;
267  retry:                                           269  retry:
268         spin_lock_bh(chip->mutex);                270         spin_lock_bh(chip->mutex);
269                                                   271 
270         /* Check that the chip's ready to talk    272         /* Check that the chip's ready to talk to us.
271          * If it's in FL_ERASING state, suspen    273          * If it's in FL_ERASING state, suspend it and make it talk now.
272          */                                       274          */
273         switch (chip->state) {                    275         switch (chip->state) {
274         case FL_ERASING:                          276         case FL_ERASING:
275                 if (!(((struct cfi_pri_intelex    277                 if (!(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2))
276                         goto sleep; /* We don'    278                         goto sleep; /* We don't support erase suspend */
277                                                   279 
278                 map_write (map, CMD(0xb0), cmd    280                 map_write (map, CMD(0xb0), cmd_addr);
279                 /* If the flash has finished e    281                 /* If the flash has finished erasing, then 'erase suspend'
280                  * appears to make some (28F32    282                  * appears to make some (28F320) flash devices switch to
281                  * 'read' mode.  Make sure tha    283                  * 'read' mode.  Make sure that we switch to 'read status'
282                  * mode so we get the right da    284                  * mode so we get the right data. --rmk
283                  */                               285                  */
284                 map_write(map, CMD(0x70), cmd_    286                 map_write(map, CMD(0x70), cmd_addr);
285                 chip->oldstate = FL_ERASING;      287                 chip->oldstate = FL_ERASING;
286                 chip->state = FL_ERASE_SUSPEND    288                 chip->state = FL_ERASE_SUSPENDING;
287                 //              printk("Erase     289                 //              printk("Erase suspending at 0x%lx\n", cmd_addr);
288                 for (;;) {                        290                 for (;;) {
289                         status = map_read(map,    291                         status = map_read(map, cmd_addr);
290                         if (map_word_andequal(    292                         if (map_word_andequal(map, status, status_OK, status_OK))
291                                 break;            293                                 break;
292                                                   294 
293                         if (time_after(jiffies    295                         if (time_after(jiffies, timeo)) {
294                                 /* Urgh */        296                                 /* Urgh */
295                                 map_write(map,    297                                 map_write(map, CMD(0xd0), cmd_addr);
296                                 /* make sure w    298                                 /* make sure we're in 'read status' mode */
297                                 map_write(map,    299                                 map_write(map, CMD(0x70), cmd_addr);
298                                 chip->state =     300                                 chip->state = FL_ERASING;
299                                 spin_unlock_bh    301                                 spin_unlock_bh(chip->mutex);
300                                 printk(KERN_ER    302                                 printk(KERN_ERR "Chip not ready after erase "
301                                        "suspen    303                                        "suspended: status = 0x%lx\n", status.x[0]);
302                                 return -EIO;      304                                 return -EIO;
303                         }                         305                         }
304                                                   306 
305                         spin_unlock_bh(chip->m    307                         spin_unlock_bh(chip->mutex);
306                         cfi_udelay(1);            308                         cfi_udelay(1);
307                         spin_lock_bh(chip->mut    309                         spin_lock_bh(chip->mutex);
308                 }                                 310                 }
309                                                   311 
310                 suspended = 1;                    312                 suspended = 1;
311                 map_write(map, CMD(0xff), cmd_    313                 map_write(map, CMD(0xff), cmd_addr);
312                 chip->state = FL_READY;           314                 chip->state = FL_READY;
313                 break;                            315                 break;
314                                                   316 
315 #if 0                                             317 #if 0
316         case FL_WRITING:                          318         case FL_WRITING:
317                 /* Not quite yet */               319                 /* Not quite yet */
318 #endif                                            320 #endif
319                                                   321 
320         case FL_READY:                            322         case FL_READY:
321                 break;                            323                 break;
322                                                   324 
323         case FL_CFI_QUERY:                        325         case FL_CFI_QUERY:
324         case FL_JEDEC_QUERY:                      326         case FL_JEDEC_QUERY:
325                 map_write(map, CMD(0x70), cmd_    327                 map_write(map, CMD(0x70), cmd_addr);
326                 chip->state = FL_STATUS;          328                 chip->state = FL_STATUS;
327                                                   329 
328         case FL_STATUS:                           330         case FL_STATUS:
329                 status = map_read(map, cmd_add    331                 status = map_read(map, cmd_addr);
330                 if (map_word_andequal(map, sta    332                 if (map_word_andequal(map, status, status_OK, status_OK)) {
331                         map_write(map, CMD(0xf    333                         map_write(map, CMD(0xff), cmd_addr);
332                         chip->state = FL_READY    334                         chip->state = FL_READY;
333                         break;                    335                         break;
334                 }                                 336                 }
335                                                   337 
336                 /* Urgh. Chip not yet ready to    338                 /* Urgh. Chip not yet ready to talk to us. */
337                 if (time_after(jiffies, timeo)    339                 if (time_after(jiffies, timeo)) {
338                         spin_unlock_bh(chip->m    340                         spin_unlock_bh(chip->mutex);
339                         printk(KERN_ERR "waiti    341                         printk(KERN_ERR "waiting for chip to be ready timed out in read. WSM status = %lx\n", status.x[0]);
340                         return -EIO;              342                         return -EIO;
341                 }                                 343                 }
342                                                   344 
343                 /* Latency issues. Drop the lo    345                 /* Latency issues. Drop the lock, wait a while and retry */
344                 spin_unlock_bh(chip->mutex);      346                 spin_unlock_bh(chip->mutex);
345                 cfi_udelay(1);                    347                 cfi_udelay(1);
346                 goto retry;                       348                 goto retry;
347                                                   349 
348         default:                                  350         default:
349         sleep:                                    351         sleep:
350                 /* Stick ourselves on a wait q    352                 /* Stick ourselves on a wait queue to be woken when
351                    someone changes the status     353                    someone changes the status */
352                 set_current_state(TASK_UNINTER    354                 set_current_state(TASK_UNINTERRUPTIBLE);
353                 add_wait_queue(&chip->wq, &wai    355                 add_wait_queue(&chip->wq, &wait);
354                 spin_unlock_bh(chip->mutex);      356                 spin_unlock_bh(chip->mutex);
355                 schedule();                       357                 schedule();
356                 remove_wait_queue(&chip->wq, &    358                 remove_wait_queue(&chip->wq, &wait);
357                 timeo = jiffies + HZ;             359                 timeo = jiffies + HZ;
358                 goto retry;                       360                 goto retry;
359         }                                         361         }
360                                                   362 
361         map_copy_from(map, buf, adr, len);        363         map_copy_from(map, buf, adr, len);
362                                                   364 
363         if (suspended) {                          365         if (suspended) {
364                 chip->state = chip->oldstate;     366                 chip->state = chip->oldstate;
365                 /* What if one interleaved chi    367                 /* What if one interleaved chip has finished and the
366                    other hasn't? The old code     368                    other hasn't? The old code would leave the finished
367                    one in READY mode. That's b    369                    one in READY mode. That's bad, and caused -EROFS
368                    errors to be returned from     370                    errors to be returned from do_erase_oneblock because
369                    that's the only bit it chec    371                    that's the only bit it checked for at the time.
370                    As the state machine appear    372                    As the state machine appears to explicitly allow
371                    sending the 0x70 (Read Stat    373                    sending the 0x70 (Read Status) command to an erasing
372                    chip and expecting it to be    374                    chip and expecting it to be ignored, that's what we
373                    do. */                         375                    do. */
374                 map_write(map, CMD(0xd0), cmd_    376                 map_write(map, CMD(0xd0), cmd_addr);
375                 map_write(map, CMD(0x70), cmd_    377                 map_write(map, CMD(0x70), cmd_addr);
376         }                                         378         }
377                                                   379 
378         wake_up(&chip->wq);                       380         wake_up(&chip->wq);
379         spin_unlock_bh(chip->mutex);              381         spin_unlock_bh(chip->mutex);
380         return 0;                                 382         return 0;
381 }                                                 383 }
382                                                   384 
383 static int cfi_staa_read (struct mtd_info *mtd    385 static int cfi_staa_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
384 {                                                 386 {
385         struct map_info *map = mtd->priv;         387         struct map_info *map = mtd->priv;
386         struct cfi_private *cfi = map->fldrv_p    388         struct cfi_private *cfi = map->fldrv_priv;
387         unsigned long ofs;                        389         unsigned long ofs;
388         int chipnum;                              390         int chipnum;
389         int ret = 0;                              391         int ret = 0;
390                                                   392 
391         /* ofs: offset within the first chip t    393         /* ofs: offset within the first chip that the first read should start */
392         chipnum = (from >> cfi->chipshift);       394         chipnum = (from >> cfi->chipshift);
393         ofs = from - (chipnum <<  cfi->chipshi    395         ofs = from - (chipnum <<  cfi->chipshift);
394                                                   396 
395         *retlen = 0;                              397         *retlen = 0;
396                                                   398 
397         while (len) {                             399         while (len) {
398                 unsigned long thislen;            400                 unsigned long thislen;
399                                                   401 
400                 if (chipnum >= cfi->numchips)     402                 if (chipnum >= cfi->numchips)
401                         break;                    403                         break;
402                                                   404 
403                 if ((len + ofs -1) >> cfi->chi    405                 if ((len + ofs -1) >> cfi->chipshift)
404                         thislen = (1<<cfi->chi    406                         thislen = (1<<cfi->chipshift) - ofs;
405                 else                              407                 else
406                         thislen = len;            408                         thislen = len;
407                                                   409 
408                 ret = do_read_onechip(map, &cf    410                 ret = do_read_onechip(map, &cfi->chips[chipnum], ofs, thislen, buf);
409                 if (ret)                          411                 if (ret)
410                         break;                    412                         break;
411                                                   413 
412                 *retlen += thislen;               414                 *retlen += thislen;
413                 len -= thislen;                   415                 len -= thislen;
414                 buf += thislen;                   416                 buf += thislen;
415                                                   417 
416                 ofs = 0;                          418                 ofs = 0;
417                 chipnum++;                        419                 chipnum++;
418         }                                         420         }
419         return ret;                               421         return ret;
420 }                                                 422 }
421                                                   423 
422 static inline int do_write_buffer(struct map_i    424 static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
423                                   unsigned lon    425                                   unsigned long adr, const u_char *buf, int len)
424 {                                                 426 {
425         struct cfi_private *cfi = map->fldrv_p    427         struct cfi_private *cfi = map->fldrv_priv;
426         map_word status, status_OK;               428         map_word status, status_OK;
427         unsigned long cmd_adr, timeo;             429         unsigned long cmd_adr, timeo;
428         DECLARE_WAITQUEUE(wait, current);         430         DECLARE_WAITQUEUE(wait, current);
429         int wbufsize, z;                          431         int wbufsize, z;
430                                                   432 
431         /* M58LW064A requires bus alignment fo    433         /* M58LW064A requires bus alignment for buffer wriets -- saw */
432         if (adr & (map_bankwidth(map)-1))         434         if (adr & (map_bankwidth(map)-1))
433             return -EINVAL;                       435             return -EINVAL;
434                                                   436 
435         wbufsize = cfi_interleave(cfi) << cfi-    437         wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
436         adr += chip->start;                       438         adr += chip->start;
437         cmd_adr = adr & ~(wbufsize-1);            439         cmd_adr = adr & ~(wbufsize-1);
438                                                   440 
439         /* Let's determine this according to t    441         /* Let's determine this according to the interleave only once */
440         status_OK = CMD(0x80);                    442         status_OK = CMD(0x80);
441                                                   443 
442         timeo = jiffies + HZ;                     444         timeo = jiffies + HZ;
443  retry:                                           445  retry:
444                                                   446 
445 #ifdef DEBUG_CFI_FEATURES                         447 #ifdef DEBUG_CFI_FEATURES
446        printk("%s: chip->state[%d]\n", __func_ !! 448        printk("%s: chip->state[%d]\n", __FUNCTION__, chip->state);
447 #endif                                            449 #endif
448         spin_lock_bh(chip->mutex);                450         spin_lock_bh(chip->mutex);
449                                                   451 
450         /* Check that the chip's ready to talk    452         /* Check that the chip's ready to talk to us.
451          * Later, we can actually think about     453          * Later, we can actually think about interrupting it
452          * if it's in FL_ERASING state.           454          * if it's in FL_ERASING state.
453          * Not just yet, though.                  455          * Not just yet, though.
454          */                                       456          */
455         switch (chip->state) {                    457         switch (chip->state) {
456         case FL_READY:                            458         case FL_READY:
457                 break;                            459                 break;
458                                                   460 
459         case FL_CFI_QUERY:                        461         case FL_CFI_QUERY:
460         case FL_JEDEC_QUERY:                      462         case FL_JEDEC_QUERY:
461                 map_write(map, CMD(0x70), cmd_    463                 map_write(map, CMD(0x70), cmd_adr);
462                 chip->state = FL_STATUS;          464                 chip->state = FL_STATUS;
463 #ifdef DEBUG_CFI_FEATURES                         465 #ifdef DEBUG_CFI_FEATURES
464         printk("%s: 1 status[%x]\n", __func__, !! 466         printk("%s: 1 status[%x]\n", __FUNCTION__, map_read(map, cmd_adr));
465 #endif                                            467 #endif
466                                                   468 
467         case FL_STATUS:                           469         case FL_STATUS:
468                 status = map_read(map, cmd_adr    470                 status = map_read(map, cmd_adr);
469                 if (map_word_andequal(map, sta    471                 if (map_word_andequal(map, status, status_OK, status_OK))
470                         break;                    472                         break;
471                 /* Urgh. Chip not yet ready to    473                 /* Urgh. Chip not yet ready to talk to us. */
472                 if (time_after(jiffies, timeo)    474                 if (time_after(jiffies, timeo)) {
473                         spin_unlock_bh(chip->m    475                         spin_unlock_bh(chip->mutex);
474                         printk(KERN_ERR "waiti    476                         printk(KERN_ERR "waiting for chip to be ready timed out in buffer write Xstatus = %lx, status = %lx\n",
475                                status.x[0], ma    477                                status.x[0], map_read(map, cmd_adr).x[0]);
476                         return -EIO;              478                         return -EIO;
477                 }                                 479                 }
478                                                   480 
479                 /* Latency issues. Drop the lo    481                 /* Latency issues. Drop the lock, wait a while and retry */
480                 spin_unlock_bh(chip->mutex);      482                 spin_unlock_bh(chip->mutex);
481                 cfi_udelay(1);                    483                 cfi_udelay(1);
482                 goto retry;                       484                 goto retry;
483                                                   485 
484         default:                                  486         default:
485                 /* Stick ourselves on a wait q    487                 /* Stick ourselves on a wait queue to be woken when
486                    someone changes the status     488                    someone changes the status */
487                 set_current_state(TASK_UNINTER    489                 set_current_state(TASK_UNINTERRUPTIBLE);
488                 add_wait_queue(&chip->wq, &wai    490                 add_wait_queue(&chip->wq, &wait);
489                 spin_unlock_bh(chip->mutex);      491                 spin_unlock_bh(chip->mutex);
490                 schedule();                       492                 schedule();
491                 remove_wait_queue(&chip->wq, &    493                 remove_wait_queue(&chip->wq, &wait);
492                 timeo = jiffies + HZ;             494                 timeo = jiffies + HZ;
493                 goto retry;                       495                 goto retry;
494         }                                         496         }
495                                                   497 
496         ENABLE_VPP(map);                          498         ENABLE_VPP(map);
497         map_write(map, CMD(0xe8), cmd_adr);       499         map_write(map, CMD(0xe8), cmd_adr);
498         chip->state = FL_WRITING_TO_BUFFER;       500         chip->state = FL_WRITING_TO_BUFFER;
499                                                   501 
500         z = 0;                                    502         z = 0;
501         for (;;) {                                503         for (;;) {
502                 status = map_read(map, cmd_adr    504                 status = map_read(map, cmd_adr);
503                 if (map_word_andequal(map, sta    505                 if (map_word_andequal(map, status, status_OK, status_OK))
504                         break;                    506                         break;
505                                                   507 
506                 spin_unlock_bh(chip->mutex);      508                 spin_unlock_bh(chip->mutex);
507                 cfi_udelay(1);                    509                 cfi_udelay(1);
508                 spin_lock_bh(chip->mutex);        510                 spin_lock_bh(chip->mutex);
509                                                   511 
510                 if (++z > 100) {                  512                 if (++z > 100) {
511                         /* Argh. Not ready for    513                         /* Argh. Not ready for write to buffer */
512                         DISABLE_VPP(map);         514                         DISABLE_VPP(map);
513                         map_write(map, CMD(0x7    515                         map_write(map, CMD(0x70), cmd_adr);
514                         chip->state = FL_STATU    516                         chip->state = FL_STATUS;
515                         spin_unlock_bh(chip->m    517                         spin_unlock_bh(chip->mutex);
516                         printk(KERN_ERR "Chip     518                         printk(KERN_ERR "Chip not ready for buffer write. Xstatus = %lx\n", status.x[0]);
517                         return -EIO;              519                         return -EIO;
518                 }                                 520                 }
519         }                                         521         }
520                                                   522 
521         /* Write length of data to come */        523         /* Write length of data to come */
522         map_write(map, CMD(len/map_bankwidth(m    524         map_write(map, CMD(len/map_bankwidth(map)-1), cmd_adr );
523                                                   525 
524         /* Write data */                          526         /* Write data */
525         for (z = 0; z < len;                      527         for (z = 0; z < len;
526              z += map_bankwidth(map), buf += m    528              z += map_bankwidth(map), buf += map_bankwidth(map)) {
527                 map_word d;                       529                 map_word d;
528                 d = map_word_load(map, buf);      530                 d = map_word_load(map, buf);
529                 map_write(map, d, adr+z);         531                 map_write(map, d, adr+z);
530         }                                         532         }
531         /* GO GO GO */                            533         /* GO GO GO */
532         map_write(map, CMD(0xd0), cmd_adr);       534         map_write(map, CMD(0xd0), cmd_adr);
533         chip->state = FL_WRITING;                 535         chip->state = FL_WRITING;
534                                                   536 
535         spin_unlock_bh(chip->mutex);              537         spin_unlock_bh(chip->mutex);
536         cfi_udelay(chip->buffer_write_time);      538         cfi_udelay(chip->buffer_write_time);
537         spin_lock_bh(chip->mutex);                539         spin_lock_bh(chip->mutex);
538                                                   540 
539         timeo = jiffies + (HZ/2);                 541         timeo = jiffies + (HZ/2);
540         z = 0;                                    542         z = 0;
541         for (;;) {                                543         for (;;) {
542                 if (chip->state != FL_WRITING)    544                 if (chip->state != FL_WRITING) {
543                         /* Someone's suspended    545                         /* Someone's suspended the write. Sleep */
544                         set_current_state(TASK    546                         set_current_state(TASK_UNINTERRUPTIBLE);
545                         add_wait_queue(&chip->    547                         add_wait_queue(&chip->wq, &wait);
546                         spin_unlock_bh(chip->m    548                         spin_unlock_bh(chip->mutex);
547                         schedule();               549                         schedule();
548                         remove_wait_queue(&chi    550                         remove_wait_queue(&chip->wq, &wait);
549                         timeo = jiffies + (HZ     551                         timeo = jiffies + (HZ / 2); /* FIXME */
550                         spin_lock_bh(chip->mut    552                         spin_lock_bh(chip->mutex);
551                         continue;                 553                         continue;
552                 }                                 554                 }
553                                                   555 
554                 status = map_read(map, cmd_adr    556                 status = map_read(map, cmd_adr);
555                 if (map_word_andequal(map, sta    557                 if (map_word_andequal(map, status, status_OK, status_OK))
556                         break;                    558                         break;
557                                                   559 
558                 /* OK Still waiting */            560                 /* OK Still waiting */
559                 if (time_after(jiffies, timeo)    561                 if (time_after(jiffies, timeo)) {
560                         /* clear status */        562                         /* clear status */
561                         map_write(map, CMD(0x5    563                         map_write(map, CMD(0x50), cmd_adr);
562                         /* put back into read     564                         /* put back into read status register mode */
563                         map_write(map, CMD(0x7    565                         map_write(map, CMD(0x70), adr);
564                         chip->state = FL_STATU    566                         chip->state = FL_STATUS;
565                         DISABLE_VPP(map);         567                         DISABLE_VPP(map);
566                         spin_unlock_bh(chip->m    568                         spin_unlock_bh(chip->mutex);
567                         printk(KERN_ERR "waiti    569                         printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n");
568                         return -EIO;              570                         return -EIO;
569                 }                                 571                 }
570                                                   572 
571                 /* Latency issues. Drop the lo    573                 /* Latency issues. Drop the lock, wait a while and retry */
572                 spin_unlock_bh(chip->mutex);      574                 spin_unlock_bh(chip->mutex);
573                 cfi_udelay(1);                    575                 cfi_udelay(1);
574                 z++;                              576                 z++;
575                 spin_lock_bh(chip->mutex);        577                 spin_lock_bh(chip->mutex);
576         }                                         578         }
577         if (!z) {                                 579         if (!z) {
578                 chip->buffer_write_time--;        580                 chip->buffer_write_time--;
579                 if (!chip->buffer_write_time)     581                 if (!chip->buffer_write_time)
580                         chip->buffer_write_tim    582                         chip->buffer_write_time++;
581         }                                         583         }
582         if (z > 1)                                584         if (z > 1)
583                 chip->buffer_write_time++;        585                 chip->buffer_write_time++;
584                                                   586 
585         /* Done and happy. */                     587         /* Done and happy. */
586         DISABLE_VPP(map);                         588         DISABLE_VPP(map);
587         chip->state = FL_STATUS;                  589         chip->state = FL_STATUS;
588                                                   590 
589         /* check for errors: 'lock bit', 'VPP'    591         /* check for errors: 'lock bit', 'VPP', 'dead cell'/'unerased cell' or 'incorrect cmd' -- saw */
590         if (map_word_bitsset(map, status, CMD(    592         if (map_word_bitsset(map, status, CMD(0x3a))) {
591 #ifdef DEBUG_CFI_FEATURES                         593 #ifdef DEBUG_CFI_FEATURES
592                 printk("%s: 2 status[%lx]\n",  !! 594                 printk("%s: 2 status[%lx]\n", __FUNCTION__, status.x[0]);
593 #endif                                            595 #endif
594                 /* clear status */                596                 /* clear status */
595                 map_write(map, CMD(0x50), cmd_    597                 map_write(map, CMD(0x50), cmd_adr);
596                 /* put back into read status r    598                 /* put back into read status register mode */
597                 map_write(map, CMD(0x70), adr)    599                 map_write(map, CMD(0x70), adr);
598                 wake_up(&chip->wq);               600                 wake_up(&chip->wq);
599                 spin_unlock_bh(chip->mutex);      601                 spin_unlock_bh(chip->mutex);
600                 return map_word_bitsset(map, s    602                 return map_word_bitsset(map, status, CMD(0x02)) ? -EROFS : -EIO;
601         }                                         603         }
602         wake_up(&chip->wq);                       604         wake_up(&chip->wq);
603         spin_unlock_bh(chip->mutex);              605         spin_unlock_bh(chip->mutex);
604                                                   606 
605         return 0;                                 607         return 0;
606 }                                                 608 }
607                                                   609 
608 static int cfi_staa_write_buffers (struct mtd_    610 static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
609                                        size_t     611                                        size_t len, size_t *retlen, const u_char *buf)
610 {                                                 612 {
611         struct map_info *map = mtd->priv;         613         struct map_info *map = mtd->priv;
612         struct cfi_private *cfi = map->fldrv_p    614         struct cfi_private *cfi = map->fldrv_priv;
613         int wbufsize = cfi_interleave(cfi) <<     615         int wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
614         int ret = 0;                              616         int ret = 0;
615         int chipnum;                              617         int chipnum;
616         unsigned long ofs;                        618         unsigned long ofs;
617                                                   619 
618         *retlen = 0;                              620         *retlen = 0;
619         if (!len)                                 621         if (!len)
620                 return 0;                         622                 return 0;
621                                                   623 
622         chipnum = to >> cfi->chipshift;           624         chipnum = to >> cfi->chipshift;
623         ofs = to  - (chipnum << cfi->chipshift    625         ofs = to  - (chipnum << cfi->chipshift);
624                                                   626 
625 #ifdef DEBUG_CFI_FEATURES                         627 #ifdef DEBUG_CFI_FEATURES
626         printk("%s: map_bankwidth(map)[%x]\n", !! 628         printk("%s: map_bankwidth(map)[%x]\n", __FUNCTION__, map_bankwidth(map));
627         printk("%s: chipnum[%x] wbufsize[%x]\n !! 629         printk("%s: chipnum[%x] wbufsize[%x]\n", __FUNCTION__, chipnum, wbufsize);
628         printk("%s: ofs[%x] len[%x]\n", __func !! 630         printk("%s: ofs[%x] len[%x]\n", __FUNCTION__, ofs, len);
629 #endif                                            631 #endif
630                                                   632 
631         /* Write buffer is worth it only if mo    633         /* Write buffer is worth it only if more than one word to write... */
632         while (len > 0) {                         634         while (len > 0) {
633                 /* We must not cross write blo    635                 /* We must not cross write block boundaries */
634                 int size = wbufsize - (ofs & (    636                 int size = wbufsize - (ofs & (wbufsize-1));
635                                                   637 
636                 if (size > len)                   638                 if (size > len)
637                     size = len;                   639                     size = len;
638                                                   640 
639                 ret = do_write_buffer(map, &cf    641                 ret = do_write_buffer(map, &cfi->chips[chipnum],
640                                       ofs, buf    642                                       ofs, buf, size);
641                 if (ret)                          643                 if (ret)
642                         return ret;               644                         return ret;
643                                                   645 
644                 ofs += size;                      646                 ofs += size;
645                 buf += size;                      647                 buf += size;
646                 (*retlen) += size;                648                 (*retlen) += size;
647                 len -= size;                      649                 len -= size;
648                                                   650 
649                 if (ofs >> cfi->chipshift) {      651                 if (ofs >> cfi->chipshift) {
650                         chipnum ++;               652                         chipnum ++;
651                         ofs = 0;                  653                         ofs = 0;
652                         if (chipnum == cfi->nu    654                         if (chipnum == cfi->numchips)
653                                 return 0;         655                                 return 0;
654                 }                                 656                 }
655         }                                         657         }
656                                                   658 
657         return 0;                                 659         return 0;
658 }                                                 660 }
659                                                   661 
660 /*                                                662 /*
661  * Writev for ECC-Flashes is a little more com    663  * Writev for ECC-Flashes is a little more complicated. We need to maintain
662  * a small buffer for this.                       664  * a small buffer for this.
663  * XXX: If the buffer size is not a multiple o    665  * XXX: If the buffer size is not a multiple of 2, this will break
664  */                                               666  */
665 #define ECCBUF_SIZE (mtd->writesize)              667 #define ECCBUF_SIZE (mtd->writesize)
666 #define ECCBUF_DIV(x) ((x) & ~(ECCBUF_SIZE - 1    668 #define ECCBUF_DIV(x) ((x) & ~(ECCBUF_SIZE - 1))
667 #define ECCBUF_MOD(x) ((x) &  (ECCBUF_SIZE - 1    669 #define ECCBUF_MOD(x) ((x) &  (ECCBUF_SIZE - 1))
668 static int                                        670 static int
669 cfi_staa_writev(struct mtd_info *mtd, const st    671 cfi_staa_writev(struct mtd_info *mtd, const struct kvec *vecs,
670                 unsigned long count, loff_t to    672                 unsigned long count, loff_t to, size_t *retlen)
671 {                                                 673 {
672         unsigned long i;                          674         unsigned long i;
673         size_t   totlen = 0, thislen;             675         size_t   totlen = 0, thislen;
674         int      ret = 0;                         676         int      ret = 0;
675         size_t   buflen = 0;                      677         size_t   buflen = 0;
676         static char *buffer;                      678         static char *buffer;
677                                                   679 
678         if (!ECCBUF_SIZE) {                       680         if (!ECCBUF_SIZE) {
679                 /* We should fall back to a ge    681                 /* We should fall back to a general writev implementation.
680                  * Until that is written, just    682                  * Until that is written, just break.
681                  */                               683                  */
682                 return -EIO;                      684                 return -EIO;
683         }                                         685         }
684         buffer = kmalloc(ECCBUF_SIZE, GFP_KERN    686         buffer = kmalloc(ECCBUF_SIZE, GFP_KERNEL);
685         if (!buffer)                              687         if (!buffer)
686                 return -ENOMEM;                   688                 return -ENOMEM;
687                                                   689 
688         for (i=0; i<count; i++) {                 690         for (i=0; i<count; i++) {
689                 size_t elem_len = vecs[i].iov_    691                 size_t elem_len = vecs[i].iov_len;
690                 void *elem_base = vecs[i].iov_    692                 void *elem_base = vecs[i].iov_base;
691                 if (!elem_len) /* FIXME: Might    693                 if (!elem_len) /* FIXME: Might be unnecessary. Check that */
692                         continue;                 694                         continue;
693                 if (buflen) { /* cut off head     695                 if (buflen) { /* cut off head */
694                         if (buflen + elem_len     696                         if (buflen + elem_len < ECCBUF_SIZE) { /* just accumulate */
695                                 memcpy(buffer+    697                                 memcpy(buffer+buflen, elem_base, elem_len);
696                                 buflen += elem    698                                 buflen += elem_len;
697                                 continue;         699                                 continue;
698                         }                         700                         }
699                         memcpy(buffer+buflen,     701                         memcpy(buffer+buflen, elem_base, ECCBUF_SIZE-buflen);
700                         ret = mtd->write(mtd,     702                         ret = mtd->write(mtd, to, ECCBUF_SIZE, &thislen, buffer);
701                         totlen += thislen;        703                         totlen += thislen;
702                         if (ret || thislen !=     704                         if (ret || thislen != ECCBUF_SIZE)
703                                 goto write_err    705                                 goto write_error;
704                         elem_len -= thislen-bu    706                         elem_len -= thislen-buflen;
705                         elem_base += thislen-b    707                         elem_base += thislen-buflen;
706                         to += ECCBUF_SIZE;        708                         to += ECCBUF_SIZE;
707                 }                                 709                 }
708                 if (ECCBUF_DIV(elem_len)) { /*    710                 if (ECCBUF_DIV(elem_len)) { /* write clean aligned data */
709                         ret = mtd->write(mtd,     711                         ret = mtd->write(mtd, to, ECCBUF_DIV(elem_len), &thislen, elem_base);
710                         totlen += thislen;        712                         totlen += thislen;
711                         if (ret || thislen !=     713                         if (ret || thislen != ECCBUF_DIV(elem_len))
712                                 goto write_err    714                                 goto write_error;
713                         to += thislen;            715                         to += thislen;
714                 }                                 716                 }
715                 buflen = ECCBUF_MOD(elem_len);    717                 buflen = ECCBUF_MOD(elem_len); /* cut off tail */
716                 if (buflen) {                     718                 if (buflen) {
717                         memset(buffer, 0xff, E    719                         memset(buffer, 0xff, ECCBUF_SIZE);
718                         memcpy(buffer, elem_ba    720                         memcpy(buffer, elem_base + thislen, buflen);
719                 }                                 721                 }
720         }                                         722         }
721         if (buflen) { /* flush last page, even    723         if (buflen) { /* flush last page, even if not full */
722                 /* This is sometimes intended     724                 /* This is sometimes intended behaviour, really */
723                 ret = mtd->write(mtd, to, bufl    725                 ret = mtd->write(mtd, to, buflen, &thislen, buffer);
724                 totlen += thislen;                726                 totlen += thislen;
725                 if (ret || thislen != ECCBUF_S    727                 if (ret || thislen != ECCBUF_SIZE)
726                         goto write_error;         728                         goto write_error;
727         }                                         729         }
728 write_error:                                      730 write_error:
729         if (retlen)                               731         if (retlen)
730                 *retlen = totlen;                 732                 *retlen = totlen;
731         kfree(buffer);                            733         kfree(buffer);
732         return ret;                               734         return ret;
733 }                                                 735 }
734                                                   736 
735                                                   737 
736 static inline int do_erase_oneblock(struct map    738 static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
737 {                                                 739 {
738         struct cfi_private *cfi = map->fldrv_p    740         struct cfi_private *cfi = map->fldrv_priv;
739         map_word status, status_OK;               741         map_word status, status_OK;
740         unsigned long timeo;                      742         unsigned long timeo;
741         int retries = 3;                          743         int retries = 3;
742         DECLARE_WAITQUEUE(wait, current);         744         DECLARE_WAITQUEUE(wait, current);
743         int ret = 0;                              745         int ret = 0;
744                                                   746 
745         adr += chip->start;                       747         adr += chip->start;
746                                                   748 
747         /* Let's determine this according to t    749         /* Let's determine this according to the interleave only once */
748         status_OK = CMD(0x80);                    750         status_OK = CMD(0x80);
749                                                   751 
750         timeo = jiffies + HZ;                     752         timeo = jiffies + HZ;
751 retry:                                            753 retry:
752         spin_lock_bh(chip->mutex);                754         spin_lock_bh(chip->mutex);
753                                                   755 
754         /* Check that the chip's ready to talk    756         /* Check that the chip's ready to talk to us. */
755         switch (chip->state) {                    757         switch (chip->state) {
756         case FL_CFI_QUERY:                        758         case FL_CFI_QUERY:
757         case FL_JEDEC_QUERY:                      759         case FL_JEDEC_QUERY:
758         case FL_READY:                            760         case FL_READY:
759                 map_write(map, CMD(0x70), adr)    761                 map_write(map, CMD(0x70), adr);
760                 chip->state = FL_STATUS;          762                 chip->state = FL_STATUS;
761                                                   763 
762         case FL_STATUS:                           764         case FL_STATUS:
763                 status = map_read(map, adr);      765                 status = map_read(map, adr);
764                 if (map_word_andequal(map, sta    766                 if (map_word_andequal(map, status, status_OK, status_OK))
765                         break;                    767                         break;
766                                                   768 
767                 /* Urgh. Chip not yet ready to    769                 /* Urgh. Chip not yet ready to talk to us. */
768                 if (time_after(jiffies, timeo)    770                 if (time_after(jiffies, timeo)) {
769                         spin_unlock_bh(chip->m    771                         spin_unlock_bh(chip->mutex);
770                         printk(KERN_ERR "waiti    772                         printk(KERN_ERR "waiting for chip to be ready timed out in erase\n");
771                         return -EIO;              773                         return -EIO;
772                 }                                 774                 }
773                                                   775 
774                 /* Latency issues. Drop the lo    776                 /* Latency issues. Drop the lock, wait a while and retry */
775                 spin_unlock_bh(chip->mutex);      777                 spin_unlock_bh(chip->mutex);
776                 cfi_udelay(1);                    778                 cfi_udelay(1);
777                 goto retry;                       779                 goto retry;
778                                                   780 
779         default:                                  781         default:
780                 /* Stick ourselves on a wait q    782                 /* Stick ourselves on a wait queue to be woken when
781                    someone changes the status     783                    someone changes the status */
782                 set_current_state(TASK_UNINTER    784                 set_current_state(TASK_UNINTERRUPTIBLE);
783                 add_wait_queue(&chip->wq, &wai    785                 add_wait_queue(&chip->wq, &wait);
784                 spin_unlock_bh(chip->mutex);      786                 spin_unlock_bh(chip->mutex);
785                 schedule();                       787                 schedule();
786                 remove_wait_queue(&chip->wq, &    788                 remove_wait_queue(&chip->wq, &wait);
787                 timeo = jiffies + HZ;             789                 timeo = jiffies + HZ;
788                 goto retry;                       790                 goto retry;
789         }                                         791         }
790                                                   792 
791         ENABLE_VPP(map);                          793         ENABLE_VPP(map);
792         /* Clear the status register first */     794         /* Clear the status register first */
793         map_write(map, CMD(0x50), adr);           795         map_write(map, CMD(0x50), adr);
794                                                   796 
795         /* Now erase */                           797         /* Now erase */
796         map_write(map, CMD(0x20), adr);           798         map_write(map, CMD(0x20), adr);
797         map_write(map, CMD(0xD0), adr);           799         map_write(map, CMD(0xD0), adr);
798         chip->state = FL_ERASING;                 800         chip->state = FL_ERASING;
799                                                   801 
800         spin_unlock_bh(chip->mutex);              802         spin_unlock_bh(chip->mutex);
801         msleep(1000);                             803         msleep(1000);
802         spin_lock_bh(chip->mutex);                804         spin_lock_bh(chip->mutex);
803                                                   805 
804         /* FIXME. Use a timer to check this, a    806         /* FIXME. Use a timer to check this, and return immediately. */
805         /* Once the state machine's known to b    807         /* Once the state machine's known to be working I'll do that */
806                                                   808 
807         timeo = jiffies + (HZ*20);                809         timeo = jiffies + (HZ*20);
808         for (;;) {                                810         for (;;) {
809                 if (chip->state != FL_ERASING)    811                 if (chip->state != FL_ERASING) {
810                         /* Someone's suspended    812                         /* Someone's suspended the erase. Sleep */
811                         set_current_state(TASK    813                         set_current_state(TASK_UNINTERRUPTIBLE);
812                         add_wait_queue(&chip->    814                         add_wait_queue(&chip->wq, &wait);
813                         spin_unlock_bh(chip->m    815                         spin_unlock_bh(chip->mutex);
814                         schedule();               816                         schedule();
815                         remove_wait_queue(&chi    817                         remove_wait_queue(&chip->wq, &wait);
816                         timeo = jiffies + (HZ*    818                         timeo = jiffies + (HZ*20); /* FIXME */
817                         spin_lock_bh(chip->mut    819                         spin_lock_bh(chip->mutex);
818                         continue;                 820                         continue;
819                 }                                 821                 }
820                                                   822 
821                 status = map_read(map, adr);      823                 status = map_read(map, adr);
822                 if (map_word_andequal(map, sta    824                 if (map_word_andequal(map, status, status_OK, status_OK))
823                         break;                    825                         break;
824                                                   826 
825                 /* OK Still waiting */            827                 /* OK Still waiting */
826                 if (time_after(jiffies, timeo)    828                 if (time_after(jiffies, timeo)) {
827                         map_write(map, CMD(0x7    829                         map_write(map, CMD(0x70), adr);
828                         chip->state = FL_STATU    830                         chip->state = FL_STATUS;
829                         printk(KERN_ERR "waiti    831                         printk(KERN_ERR "waiting for erase to complete timed out. Xstatus = %lx, status = %lx.\n", status.x[0], map_read(map, adr).x[0]);
830                         DISABLE_VPP(map);         832                         DISABLE_VPP(map);
831                         spin_unlock_bh(chip->m    833                         spin_unlock_bh(chip->mutex);
832                         return -EIO;              834                         return -EIO;
833                 }                                 835                 }
834                                                   836 
835                 /* Latency issues. Drop the lo    837                 /* Latency issues. Drop the lock, wait a while and retry */
836                 spin_unlock_bh(chip->mutex);      838                 spin_unlock_bh(chip->mutex);
837                 cfi_udelay(1);                    839                 cfi_udelay(1);
838                 spin_lock_bh(chip->mutex);        840                 spin_lock_bh(chip->mutex);
839         }                                         841         }
840                                                   842 
841         DISABLE_VPP(map);                         843         DISABLE_VPP(map);
842         ret = 0;                                  844         ret = 0;
843                                                   845 
844         /* We've broken this before. It doesn'    846         /* We've broken this before. It doesn't hurt to be safe */
845         map_write(map, CMD(0x70), adr);           847         map_write(map, CMD(0x70), adr);
846         chip->state = FL_STATUS;                  848         chip->state = FL_STATUS;
847         status = map_read(map, adr);              849         status = map_read(map, adr);
848                                                   850 
849         /* check for lock bit */                  851         /* check for lock bit */
850         if (map_word_bitsset(map, status, CMD(    852         if (map_word_bitsset(map, status, CMD(0x3a))) {
851                 unsigned char chipstatus = sta    853                 unsigned char chipstatus = status.x[0];
852                 if (!map_word_equal(map, statu    854                 if (!map_word_equal(map, status, CMD(chipstatus))) {
853                         int i, w;                 855                         int i, w;
854                         for (w=0; w<map_words(    856                         for (w=0; w<map_words(map); w++) {
855                                 for (i = 0; i<    857                                 for (i = 0; i<cfi_interleave(cfi); i++) {
856                                         chipst    858                                         chipstatus |= status.x[w] >> (cfi->device_type * 8);
857                                 }                 859                                 }
858                         }                         860                         }
859                         printk(KERN_WARNING "S    861                         printk(KERN_WARNING "Status is not identical for all chips: 0x%lx. Merging to give 0x%02x\n",
860                                status.x[0], ch    862                                status.x[0], chipstatus);
861                 }                                 863                 }
862                 /* Reset the error bits */        864                 /* Reset the error bits */
863                 map_write(map, CMD(0x50), adr)    865                 map_write(map, CMD(0x50), adr);
864                 map_write(map, CMD(0x70), adr)    866                 map_write(map, CMD(0x70), adr);
865                                                   867 
866                 if ((chipstatus & 0x30) == 0x3    868                 if ((chipstatus & 0x30) == 0x30) {
867                         printk(KERN_NOTICE "Ch    869                         printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%x\n", chipstatus);
868                         ret = -EIO;               870                         ret = -EIO;
869                 } else if (chipstatus & 0x02)     871                 } else if (chipstatus & 0x02) {
870                         /* Protection bit set     872                         /* Protection bit set */
871                         ret = -EROFS;             873                         ret = -EROFS;
872                 } else if (chipstatus & 0x8) {    874                 } else if (chipstatus & 0x8) {
873                         /* Voltage */             875                         /* Voltage */
874                         printk(KERN_WARNING "C    876                         printk(KERN_WARNING "Chip reports voltage low on erase: status 0x%x\n", chipstatus);
875                         ret = -EIO;               877                         ret = -EIO;
876                 } else if (chipstatus & 0x20)     878                 } else if (chipstatus & 0x20) {
877                         if (retries--) {          879                         if (retries--) {
878                                 printk(KERN_DE    880                                 printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%x. Retrying...\n", adr, chipstatus);
879                                 timeo = jiffie    881                                 timeo = jiffies + HZ;
880                                 chip->state =     882                                 chip->state = FL_STATUS;
881                                 spin_unlock_bh    883                                 spin_unlock_bh(chip->mutex);
882                                 goto retry;       884                                 goto retry;
883                         }                         885                         }
884                         printk(KERN_DEBUG "Chi    886                         printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%x\n", adr, chipstatus);
885                         ret = -EIO;               887                         ret = -EIO;
886                 }                                 888                 }
887         }                                         889         }
888                                                   890 
889         wake_up(&chip->wq);                       891         wake_up(&chip->wq);
890         spin_unlock_bh(chip->mutex);              892         spin_unlock_bh(chip->mutex);
891         return ret;                               893         return ret;
892 }                                                 894 }
893                                                   895 
894 static int cfi_staa_erase_varsize(struct mtd_i !! 896 int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
895                                   struct erase << 
896 {       struct map_info *map = mtd->priv;         897 {       struct map_info *map = mtd->priv;
897         struct cfi_private *cfi = map->fldrv_p    898         struct cfi_private *cfi = map->fldrv_priv;
898         unsigned long adr, len;                   899         unsigned long adr, len;
899         int chipnum, ret = 0;                     900         int chipnum, ret = 0;
900         int i, first;                             901         int i, first;
901         struct mtd_erase_region_info *regions     902         struct mtd_erase_region_info *regions = mtd->eraseregions;
902                                                   903 
903         if (instr->addr > mtd->size)              904         if (instr->addr > mtd->size)
904                 return -EINVAL;                   905                 return -EINVAL;
905                                                   906 
906         if ((instr->len + instr->addr) > mtd->    907         if ((instr->len + instr->addr) > mtd->size)
907                 return -EINVAL;                   908                 return -EINVAL;
908                                                   909 
909         /* Check that both start and end of th    910         /* Check that both start and end of the requested erase are
910          * aligned with the erasesize at the a    911          * aligned with the erasesize at the appropriate addresses.
911          */                                       912          */
912                                                   913 
913         i = 0;                                    914         i = 0;
914                                                   915 
915         /* Skip all erase regions which are en    916         /* Skip all erase regions which are ended before the start of
916            the requested erase. Actually, to s    917            the requested erase. Actually, to save on the calculations,
917            we skip to the first erase region w    918            we skip to the first erase region which starts after the
918            start of the requested erase, and t    919            start of the requested erase, and then go back one.
919         */                                        920         */
920                                                   921 
921         while (i < mtd->numeraseregions && ins    922         while (i < mtd->numeraseregions && instr->addr >= regions[i].offset)
922                i++;                               923                i++;
923         i--;                                      924         i--;
924                                                   925 
925         /* OK, now i is pointing at the erase     926         /* OK, now i is pointing at the erase region in which this
926            erase request starts. Check the sta    927            erase request starts. Check the start of the requested
927            erase range is aligned with the era    928            erase range is aligned with the erase size which is in
928            effect here.                           929            effect here.
929         */                                        930         */
930                                                   931 
931         if (instr->addr & (regions[i].erasesiz    932         if (instr->addr & (regions[i].erasesize-1))
932                 return -EINVAL;                   933                 return -EINVAL;
933                                                   934 
934         /* Remember the erase region we start     935         /* Remember the erase region we start on */
935         first = i;                                936         first = i;
936                                                   937 
937         /* Next, check that the end of the req    938         /* Next, check that the end of the requested erase is aligned
938          * with the erase region at that addre    939          * with the erase region at that address.
939          */                                       940          */
940                                                   941 
941         while (i<mtd->numeraseregions && (inst    942         while (i<mtd->numeraseregions && (instr->addr + instr->len) >= regions[i].offset)
942                 i++;                              943                 i++;
943                                                   944 
944         /* As before, drop back one to point a    945         /* As before, drop back one to point at the region in which
945            the address actually falls             946            the address actually falls
946         */                                        947         */
947         i--;                                      948         i--;
948                                                   949 
949         if ((instr->addr + instr->len) & (regi    950         if ((instr->addr + instr->len) & (regions[i].erasesize-1))
950                 return -EINVAL;                   951                 return -EINVAL;
951                                                   952 
952         chipnum = instr->addr >> cfi->chipshif    953         chipnum = instr->addr >> cfi->chipshift;
953         adr = instr->addr - (chipnum << cfi->c    954         adr = instr->addr - (chipnum << cfi->chipshift);
954         len = instr->len;                         955         len = instr->len;
955                                                   956 
956         i=first;                                  957         i=first;
957                                                   958 
958         while(len) {                              959         while(len) {
959                 ret = do_erase_oneblock(map, &    960                 ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr);
960                                                   961 
961                 if (ret)                          962                 if (ret)
962                         return ret;               963                         return ret;
963                                                   964 
964                 adr += regions[i].erasesize;      965                 adr += regions[i].erasesize;
965                 len -= regions[i].erasesize;      966                 len -= regions[i].erasesize;
966                                                   967 
967                 if (adr % (1<< cfi->chipshift) !! 968                 if (adr % (1<< cfi->chipshift) == ((regions[i].offset + (regions[i].erasesize * regions[i].numblocks)) %( 1<< cfi->chipshift)))
968                         i++;                      969                         i++;
969                                                   970 
970                 if (adr >> cfi->chipshift) {      971                 if (adr >> cfi->chipshift) {
971                         adr = 0;                  972                         adr = 0;
972                         chipnum++;                973                         chipnum++;
973                                                   974 
974                         if (chipnum >= cfi->nu    975                         if (chipnum >= cfi->numchips)
975                         break;                    976                         break;
976                 }                                 977                 }
977         }                                         978         }
978                                                   979 
979         instr->state = MTD_ERASE_DONE;            980         instr->state = MTD_ERASE_DONE;
980         mtd_erase_callback(instr);                981         mtd_erase_callback(instr);
981                                                   982 
982         return 0;                                 983         return 0;
983 }                                                 984 }
984                                                   985 
985 static void cfi_staa_sync (struct mtd_info *mt    986 static void cfi_staa_sync (struct mtd_info *mtd)
986 {                                                 987 {
987         struct map_info *map = mtd->priv;         988         struct map_info *map = mtd->priv;
988         struct cfi_private *cfi = map->fldrv_p    989         struct cfi_private *cfi = map->fldrv_priv;
989         int i;                                    990         int i;
990         struct flchip *chip;                      991         struct flchip *chip;
991         int ret = 0;                              992         int ret = 0;
992         DECLARE_WAITQUEUE(wait, current);         993         DECLARE_WAITQUEUE(wait, current);
993                                                   994 
994         for (i=0; !ret && i<cfi->numchips; i++    995         for (i=0; !ret && i<cfi->numchips; i++) {
995                 chip = &cfi->chips[i];            996                 chip = &cfi->chips[i];
996                                                   997 
997         retry:                                    998         retry:
998                 spin_lock_bh(chip->mutex);        999                 spin_lock_bh(chip->mutex);
999                                                   1000 
1000                 switch(chip->state) {            1001                 switch(chip->state) {
1001                 case FL_READY:                   1002                 case FL_READY:
1002                 case FL_STATUS:                  1003                 case FL_STATUS:
1003                 case FL_CFI_QUERY:               1004                 case FL_CFI_QUERY:
1004                 case FL_JEDEC_QUERY:             1005                 case FL_JEDEC_QUERY:
1005                         chip->oldstate = chip    1006                         chip->oldstate = chip->state;
1006                         chip->state = FL_SYNC    1007                         chip->state = FL_SYNCING;
1007                         /* No need to wake_up    1008                         /* No need to wake_up() on this state change -
1008                          * as the whole point    1009                          * as the whole point is that nobody can do anything
1009                          * with the chip now     1010                          * with the chip now anyway.
1010                          */                      1011                          */
1011                 case FL_SYNCING:                 1012                 case FL_SYNCING:
1012                         spin_unlock_bh(chip->    1013                         spin_unlock_bh(chip->mutex);
1013                         break;                   1014                         break;
1014                                                  1015 
1015                 default:                         1016                 default:
1016                         /* Not an idle state     1017                         /* Not an idle state */
1017                         set_current_state(TAS    1018                         set_current_state(TASK_UNINTERRUPTIBLE);
1018                         add_wait_queue(&chip-    1019                         add_wait_queue(&chip->wq, &wait);
1019                                                  1020 
1020                         spin_unlock_bh(chip->    1021                         spin_unlock_bh(chip->mutex);
1021                         schedule();              1022                         schedule();
1022                         remove_wait_queue(&ch    1023                         remove_wait_queue(&chip->wq, &wait);
1023                                                  1024 
1024                         goto retry;              1025                         goto retry;
1025                 }                                1026                 }
1026         }                                        1027         }
1027                                                  1028 
1028         /* Unlock the chips again */             1029         /* Unlock the chips again */
1029                                                  1030 
1030         for (i--; i >=0; i--) {                  1031         for (i--; i >=0; i--) {
1031                 chip = &cfi->chips[i];           1032                 chip = &cfi->chips[i];
1032                                                  1033 
1033                 spin_lock_bh(chip->mutex);       1034                 spin_lock_bh(chip->mutex);
1034                                                  1035 
1035                 if (chip->state == FL_SYNCING    1036                 if (chip->state == FL_SYNCING) {
1036                         chip->state = chip->o    1037                         chip->state = chip->oldstate;
1037                         wake_up(&chip->wq);      1038                         wake_up(&chip->wq);
1038                 }                                1039                 }
1039                 spin_unlock_bh(chip->mutex);     1040                 spin_unlock_bh(chip->mutex);
1040         }                                        1041         }
1041 }                                                1042 }
1042                                                  1043 
1043 static inline int do_lock_oneblock(struct map    1044 static inline int do_lock_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
1044 {                                                1045 {
1045         struct cfi_private *cfi = map->fldrv_    1046         struct cfi_private *cfi = map->fldrv_priv;
1046         map_word status, status_OK;              1047         map_word status, status_OK;
1047         unsigned long timeo = jiffies + HZ;      1048         unsigned long timeo = jiffies + HZ;
1048         DECLARE_WAITQUEUE(wait, current);        1049         DECLARE_WAITQUEUE(wait, current);
1049                                                  1050 
1050         adr += chip->start;                      1051         adr += chip->start;
1051                                                  1052 
1052         /* Let's determine this according to     1053         /* Let's determine this according to the interleave only once */
1053         status_OK = CMD(0x80);                   1054         status_OK = CMD(0x80);
1054                                                  1055 
1055         timeo = jiffies + HZ;                    1056         timeo = jiffies + HZ;
1056 retry:                                           1057 retry:
1057         spin_lock_bh(chip->mutex);               1058         spin_lock_bh(chip->mutex);
1058                                                  1059 
1059         /* Check that the chip's ready to tal    1060         /* Check that the chip's ready to talk to us. */
1060         switch (chip->state) {                   1061         switch (chip->state) {
1061         case FL_CFI_QUERY:                       1062         case FL_CFI_QUERY:
1062         case FL_JEDEC_QUERY:                     1063         case FL_JEDEC_QUERY:
1063         case FL_READY:                           1064         case FL_READY:
1064                 map_write(map, CMD(0x70), adr    1065                 map_write(map, CMD(0x70), adr);
1065                 chip->state = FL_STATUS;         1066                 chip->state = FL_STATUS;
1066                                                  1067 
1067         case FL_STATUS:                          1068         case FL_STATUS:
1068                 status = map_read(map, adr);     1069                 status = map_read(map, adr);
1069                 if (map_word_andequal(map, st    1070                 if (map_word_andequal(map, status, status_OK, status_OK))
1070                         break;                   1071                         break;
1071                                                  1072 
1072                 /* Urgh. Chip not yet ready t    1073                 /* Urgh. Chip not yet ready to talk to us. */
1073                 if (time_after(jiffies, timeo    1074                 if (time_after(jiffies, timeo)) {
1074                         spin_unlock_bh(chip->    1075                         spin_unlock_bh(chip->mutex);
1075                         printk(KERN_ERR "wait    1076                         printk(KERN_ERR "waiting for chip to be ready timed out in lock\n");
1076                         return -EIO;             1077                         return -EIO;
1077                 }                                1078                 }
1078                                                  1079 
1079                 /* Latency issues. Drop the l    1080                 /* Latency issues. Drop the lock, wait a while and retry */
1080                 spin_unlock_bh(chip->mutex);     1081                 spin_unlock_bh(chip->mutex);
1081                 cfi_udelay(1);                   1082                 cfi_udelay(1);
1082                 goto retry;                      1083                 goto retry;
1083                                                  1084 
1084         default:                                 1085         default:
1085                 /* Stick ourselves on a wait     1086                 /* Stick ourselves on a wait queue to be woken when
1086                    someone changes the status    1087                    someone changes the status */
1087                 set_current_state(TASK_UNINTE    1088                 set_current_state(TASK_UNINTERRUPTIBLE);
1088                 add_wait_queue(&chip->wq, &wa    1089                 add_wait_queue(&chip->wq, &wait);
1089                 spin_unlock_bh(chip->mutex);     1090                 spin_unlock_bh(chip->mutex);
1090                 schedule();                      1091                 schedule();
1091                 remove_wait_queue(&chip->wq,     1092                 remove_wait_queue(&chip->wq, &wait);
1092                 timeo = jiffies + HZ;            1093                 timeo = jiffies + HZ;
1093                 goto retry;                      1094                 goto retry;
1094         }                                        1095         }
1095                                                  1096 
1096         ENABLE_VPP(map);                         1097         ENABLE_VPP(map);
1097         map_write(map, CMD(0x60), adr);          1098         map_write(map, CMD(0x60), adr);
1098         map_write(map, CMD(0x01), adr);          1099         map_write(map, CMD(0x01), adr);
1099         chip->state = FL_LOCKING;                1100         chip->state = FL_LOCKING;
1100                                                  1101 
1101         spin_unlock_bh(chip->mutex);             1102         spin_unlock_bh(chip->mutex);
1102         msleep(1000);                            1103         msleep(1000);
1103         spin_lock_bh(chip->mutex);               1104         spin_lock_bh(chip->mutex);
1104                                                  1105 
1105         /* FIXME. Use a timer to check this,     1106         /* FIXME. Use a timer to check this, and return immediately. */
1106         /* Once the state machine's known to     1107         /* Once the state machine's known to be working I'll do that */
1107                                                  1108 
1108         timeo = jiffies + (HZ*2);                1109         timeo = jiffies + (HZ*2);
1109         for (;;) {                               1110         for (;;) {
1110                                                  1111 
1111                 status = map_read(map, adr);     1112                 status = map_read(map, adr);
1112                 if (map_word_andequal(map, st    1113                 if (map_word_andequal(map, status, status_OK, status_OK))
1113                         break;                   1114                         break;
1114                                                  1115 
1115                 /* OK Still waiting */           1116                 /* OK Still waiting */
1116                 if (time_after(jiffies, timeo    1117                 if (time_after(jiffies, timeo)) {
1117                         map_write(map, CMD(0x    1118                         map_write(map, CMD(0x70), adr);
1118                         chip->state = FL_STAT    1119                         chip->state = FL_STATUS;
1119                         printk(KERN_ERR "wait    1120                         printk(KERN_ERR "waiting for lock to complete timed out. Xstatus = %lx, status = %lx.\n", status.x[0], map_read(map, adr).x[0]);
1120                         DISABLE_VPP(map);        1121                         DISABLE_VPP(map);
1121                         spin_unlock_bh(chip->    1122                         spin_unlock_bh(chip->mutex);
1122                         return -EIO;             1123                         return -EIO;
1123                 }                                1124                 }
1124                                                  1125 
1125                 /* Latency issues. Drop the l    1126                 /* Latency issues. Drop the lock, wait a while and retry */
1126                 spin_unlock_bh(chip->mutex);     1127                 spin_unlock_bh(chip->mutex);
1127                 cfi_udelay(1);                   1128                 cfi_udelay(1);
1128                 spin_lock_bh(chip->mutex);       1129                 spin_lock_bh(chip->mutex);
1129         }                                        1130         }
1130                                                  1131 
1131         /* Done and happy. */                    1132         /* Done and happy. */
1132         chip->state = FL_STATUS;                 1133         chip->state = FL_STATUS;
1133         DISABLE_VPP(map);                        1134         DISABLE_VPP(map);
1134         wake_up(&chip->wq);                      1135         wake_up(&chip->wq);
1135         spin_unlock_bh(chip->mutex);             1136         spin_unlock_bh(chip->mutex);
1136         return 0;                                1137         return 0;
1137 }                                                1138 }
1138 static int cfi_staa_lock(struct mtd_info *mtd !! 1139 static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
1139 {                                                1140 {
1140         struct map_info *map = mtd->priv;        1141         struct map_info *map = mtd->priv;
1141         struct cfi_private *cfi = map->fldrv_    1142         struct cfi_private *cfi = map->fldrv_priv;
1142         unsigned long adr;                       1143         unsigned long adr;
1143         int chipnum, ret = 0;                    1144         int chipnum, ret = 0;
1144 #ifdef DEBUG_LOCK_BITS                           1145 #ifdef DEBUG_LOCK_BITS
1145         int ofs_factor = cfi->interleave * cf    1146         int ofs_factor = cfi->interleave * cfi->device_type;
1146 #endif                                           1147 #endif
1147                                                  1148 
1148         if (ofs & (mtd->erasesize - 1))          1149         if (ofs & (mtd->erasesize - 1))
1149                 return -EINVAL;                  1150                 return -EINVAL;
1150                                                  1151 
1151         if (len & (mtd->erasesize -1))           1152         if (len & (mtd->erasesize -1))
1152                 return -EINVAL;                  1153                 return -EINVAL;
1153                                                  1154 
1154         if ((len + ofs) > mtd->size)             1155         if ((len + ofs) > mtd->size)
1155                 return -EINVAL;                  1156                 return -EINVAL;
1156                                                  1157 
1157         chipnum = ofs >> cfi->chipshift;         1158         chipnum = ofs >> cfi->chipshift;
1158         adr = ofs - (chipnum << cfi->chipshif    1159         adr = ofs - (chipnum << cfi->chipshift);
1159                                                  1160 
1160         while(len) {                             1161         while(len) {
1161                                                  1162 
1162 #ifdef DEBUG_LOCK_BITS                           1163 #ifdef DEBUG_LOCK_BITS
1163                 cfi_send_gen_cmd(0x90, 0x55,     1164                 cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
1164                 printk("before lock: block st    1165                 printk("before lock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor)));
1165                 cfi_send_gen_cmd(0xff, 0x55,     1166                 cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
1166 #endif                                           1167 #endif
1167                                                  1168 
1168                 ret = do_lock_oneblock(map, &    1169                 ret = do_lock_oneblock(map, &cfi->chips[chipnum], adr);
1169                                                  1170 
1170 #ifdef DEBUG_LOCK_BITS                           1171 #ifdef DEBUG_LOCK_BITS
1171                 cfi_send_gen_cmd(0x90, 0x55,     1172                 cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
1172                 printk("after lock: block sta    1173                 printk("after lock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor)));
1173                 cfi_send_gen_cmd(0xff, 0x55,     1174                 cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
1174 #endif                                           1175 #endif
1175                                                  1176 
1176                 if (ret)                         1177                 if (ret)
1177                         return ret;              1178                         return ret;
1178                                                  1179 
1179                 adr += mtd->erasesize;           1180                 adr += mtd->erasesize;
1180                 len -= mtd->erasesize;           1181                 len -= mtd->erasesize;
1181                                                  1182 
1182                 if (adr >> cfi->chipshift) {     1183                 if (adr >> cfi->chipshift) {
1183                         adr = 0;                 1184                         adr = 0;
1184                         chipnum++;               1185                         chipnum++;
1185                                                  1186 
1186                         if (chipnum >= cfi->n    1187                         if (chipnum >= cfi->numchips)
1187                         break;                   1188                         break;
1188                 }                                1189                 }
1189         }                                        1190         }
1190         return 0;                                1191         return 0;
1191 }                                                1192 }
1192 static inline int do_unlock_oneblock(struct m    1193 static inline int do_unlock_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
1193 {                                                1194 {
1194         struct cfi_private *cfi = map->fldrv_    1195         struct cfi_private *cfi = map->fldrv_priv;
1195         map_word status, status_OK;              1196         map_word status, status_OK;
1196         unsigned long timeo = jiffies + HZ;      1197         unsigned long timeo = jiffies + HZ;
1197         DECLARE_WAITQUEUE(wait, current);        1198         DECLARE_WAITQUEUE(wait, current);
1198                                                  1199 
1199         adr += chip->start;                      1200         adr += chip->start;
1200                                                  1201 
1201         /* Let's determine this according to     1202         /* Let's determine this according to the interleave only once */
1202         status_OK = CMD(0x80);                   1203         status_OK = CMD(0x80);
1203                                                  1204 
1204         timeo = jiffies + HZ;                    1205         timeo = jiffies + HZ;
1205 retry:                                           1206 retry:
1206         spin_lock_bh(chip->mutex);               1207         spin_lock_bh(chip->mutex);
1207                                                  1208 
1208         /* Check that the chip's ready to tal    1209         /* Check that the chip's ready to talk to us. */
1209         switch (chip->state) {                   1210         switch (chip->state) {
1210         case FL_CFI_QUERY:                       1211         case FL_CFI_QUERY:
1211         case FL_JEDEC_QUERY:                     1212         case FL_JEDEC_QUERY:
1212         case FL_READY:                           1213         case FL_READY:
1213                 map_write(map, CMD(0x70), adr    1214                 map_write(map, CMD(0x70), adr);
1214                 chip->state = FL_STATUS;         1215                 chip->state = FL_STATUS;
1215                                                  1216 
1216         case FL_STATUS:                          1217         case FL_STATUS:
1217                 status = map_read(map, adr);     1218                 status = map_read(map, adr);
1218                 if (map_word_andequal(map, st    1219                 if (map_word_andequal(map, status, status_OK, status_OK))
1219                         break;                   1220                         break;
1220                                                  1221 
1221                 /* Urgh. Chip not yet ready t    1222                 /* Urgh. Chip not yet ready to talk to us. */
1222                 if (time_after(jiffies, timeo    1223                 if (time_after(jiffies, timeo)) {
1223                         spin_unlock_bh(chip->    1224                         spin_unlock_bh(chip->mutex);
1224                         printk(KERN_ERR "wait    1225                         printk(KERN_ERR "waiting for chip to be ready timed out in unlock\n");
1225                         return -EIO;             1226                         return -EIO;
1226                 }                                1227                 }
1227                                                  1228 
1228                 /* Latency issues. Drop the l    1229                 /* Latency issues. Drop the lock, wait a while and retry */
1229                 spin_unlock_bh(chip->mutex);     1230                 spin_unlock_bh(chip->mutex);
1230                 cfi_udelay(1);                   1231                 cfi_udelay(1);
1231                 goto retry;                      1232                 goto retry;
1232                                                  1233 
1233         default:                                 1234         default:
1234                 /* Stick ourselves on a wait     1235                 /* Stick ourselves on a wait queue to be woken when
1235                    someone changes the status    1236                    someone changes the status */
1236                 set_current_state(TASK_UNINTE    1237                 set_current_state(TASK_UNINTERRUPTIBLE);
1237                 add_wait_queue(&chip->wq, &wa    1238                 add_wait_queue(&chip->wq, &wait);
1238                 spin_unlock_bh(chip->mutex);     1239                 spin_unlock_bh(chip->mutex);
1239                 schedule();                      1240                 schedule();
1240                 remove_wait_queue(&chip->wq,     1241                 remove_wait_queue(&chip->wq, &wait);
1241                 timeo = jiffies + HZ;            1242                 timeo = jiffies + HZ;
1242                 goto retry;                      1243                 goto retry;
1243         }                                        1244         }
1244                                                  1245 
1245         ENABLE_VPP(map);                         1246         ENABLE_VPP(map);
1246         map_write(map, CMD(0x60), adr);          1247         map_write(map, CMD(0x60), adr);
1247         map_write(map, CMD(0xD0), adr);          1248         map_write(map, CMD(0xD0), adr);
1248         chip->state = FL_UNLOCKING;              1249         chip->state = FL_UNLOCKING;
1249                                                  1250 
1250         spin_unlock_bh(chip->mutex);             1251         spin_unlock_bh(chip->mutex);
1251         msleep(1000);                            1252         msleep(1000);
1252         spin_lock_bh(chip->mutex);               1253         spin_lock_bh(chip->mutex);
1253                                                  1254 
1254         /* FIXME. Use a timer to check this,     1255         /* FIXME. Use a timer to check this, and return immediately. */
1255         /* Once the state machine's known to     1256         /* Once the state machine's known to be working I'll do that */
1256                                                  1257 
1257         timeo = jiffies + (HZ*2);                1258         timeo = jiffies + (HZ*2);
1258         for (;;) {                               1259         for (;;) {
1259                                                  1260 
1260                 status = map_read(map, adr);     1261                 status = map_read(map, adr);
1261                 if (map_word_andequal(map, st    1262                 if (map_word_andequal(map, status, status_OK, status_OK))
1262                         break;                   1263                         break;
1263                                                  1264 
1264                 /* OK Still waiting */           1265                 /* OK Still waiting */
1265                 if (time_after(jiffies, timeo    1266                 if (time_after(jiffies, timeo)) {
1266                         map_write(map, CMD(0x    1267                         map_write(map, CMD(0x70), adr);
1267                         chip->state = FL_STAT    1268                         chip->state = FL_STATUS;
1268                         printk(KERN_ERR "wait    1269                         printk(KERN_ERR "waiting for unlock to complete timed out. Xstatus = %lx, status = %lx.\n", status.x[0], map_read(map, adr).x[0]);
1269                         DISABLE_VPP(map);        1270                         DISABLE_VPP(map);
1270                         spin_unlock_bh(chip->    1271                         spin_unlock_bh(chip->mutex);
1271                         return -EIO;             1272                         return -EIO;
1272                 }                                1273                 }
1273                                                  1274 
1274                 /* Latency issues. Drop the u    1275                 /* Latency issues. Drop the unlock, wait a while and retry */
1275                 spin_unlock_bh(chip->mutex);     1276                 spin_unlock_bh(chip->mutex);
1276                 cfi_udelay(1);                   1277                 cfi_udelay(1);
1277                 spin_lock_bh(chip->mutex);       1278                 spin_lock_bh(chip->mutex);
1278         }                                        1279         }
1279                                                  1280 
1280         /* Done and happy. */                    1281         /* Done and happy. */
1281         chip->state = FL_STATUS;                 1282         chip->state = FL_STATUS;
1282         DISABLE_VPP(map);                        1283         DISABLE_VPP(map);
1283         wake_up(&chip->wq);                      1284         wake_up(&chip->wq);
1284         spin_unlock_bh(chip->mutex);             1285         spin_unlock_bh(chip->mutex);
1285         return 0;                                1286         return 0;
1286 }                                                1287 }
1287 static int cfi_staa_unlock(struct mtd_info *m !! 1288 static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1288 {                                                1289 {
1289         struct map_info *map = mtd->priv;        1290         struct map_info *map = mtd->priv;
1290         struct cfi_private *cfi = map->fldrv_    1291         struct cfi_private *cfi = map->fldrv_priv;
1291         unsigned long adr;                       1292         unsigned long adr;
1292         int chipnum, ret = 0;                    1293         int chipnum, ret = 0;
1293 #ifdef DEBUG_LOCK_BITS                           1294 #ifdef DEBUG_LOCK_BITS
1294         int ofs_factor = cfi->interleave * cf    1295         int ofs_factor = cfi->interleave * cfi->device_type;
1295 #endif                                           1296 #endif
1296                                                  1297 
1297         chipnum = ofs >> cfi->chipshift;         1298         chipnum = ofs >> cfi->chipshift;
1298         adr = ofs - (chipnum << cfi->chipshif    1299         adr = ofs - (chipnum << cfi->chipshift);
1299                                                  1300 
1300 #ifdef DEBUG_LOCK_BITS                           1301 #ifdef DEBUG_LOCK_BITS
1301         {                                        1302         {
1302                 unsigned long temp_adr = adr;    1303                 unsigned long temp_adr = adr;
1303                 unsigned long temp_len = len;    1304                 unsigned long temp_len = len;
1304                                                  1305 
1305                 cfi_send_gen_cmd(0x90, 0x55,     1306                 cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
1306                 while (temp_len) {               1307                 while (temp_len) {
1307                         printk("before unlock    1308                         printk("before unlock %x: block status register is %x\n",temp_adr,cfi_read_query(map, temp_adr+(2*ofs_factor)));
1308                         temp_adr += mtd->eras    1309                         temp_adr += mtd->erasesize;
1309                         temp_len -= mtd->eras    1310                         temp_len -= mtd->erasesize;
1310                 }                                1311                 }
1311                 cfi_send_gen_cmd(0xff, 0x55,     1312                 cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
1312         }                                        1313         }
1313 #endif                                           1314 #endif
1314                                                  1315 
1315         ret = do_unlock_oneblock(map, &cfi->c    1316         ret = do_unlock_oneblock(map, &cfi->chips[chipnum], adr);
1316                                                  1317 
1317 #ifdef DEBUG_LOCK_BITS                           1318 #ifdef DEBUG_LOCK_BITS
1318         cfi_send_gen_cmd(0x90, 0x55, 0, map,     1319         cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
1319         printk("after unlock: block status re    1320         printk("after unlock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor)));
1320         cfi_send_gen_cmd(0xff, 0x55, 0, map,     1321         cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
1321 #endif                                           1322 #endif
1322                                                  1323 
1323         return ret;                              1324         return ret;
1324 }                                                1325 }
1325                                                  1326 
1326 static int cfi_staa_suspend(struct mtd_info *    1327 static int cfi_staa_suspend(struct mtd_info *mtd)
1327 {                                                1328 {
1328         struct map_info *map = mtd->priv;        1329         struct map_info *map = mtd->priv;
1329         struct cfi_private *cfi = map->fldrv_    1330         struct cfi_private *cfi = map->fldrv_priv;
1330         int i;                                   1331         int i;
1331         struct flchip *chip;                     1332         struct flchip *chip;
1332         int ret = 0;                             1333         int ret = 0;
1333                                                  1334 
1334         for (i=0; !ret && i<cfi->numchips; i+    1335         for (i=0; !ret && i<cfi->numchips; i++) {
1335                 chip = &cfi->chips[i];           1336                 chip = &cfi->chips[i];
1336                                                  1337 
1337                 spin_lock_bh(chip->mutex);       1338                 spin_lock_bh(chip->mutex);
1338                                                  1339 
1339                 switch(chip->state) {            1340                 switch(chip->state) {
1340                 case FL_READY:                   1341                 case FL_READY:
1341                 case FL_STATUS:                  1342                 case FL_STATUS:
1342                 case FL_CFI_QUERY:               1343                 case FL_CFI_QUERY:
1343                 case FL_JEDEC_QUERY:             1344                 case FL_JEDEC_QUERY:
1344                         chip->oldstate = chip    1345                         chip->oldstate = chip->state;
1345                         chip->state = FL_PM_S    1346                         chip->state = FL_PM_SUSPENDED;
1346                         /* No need to wake_up    1347                         /* No need to wake_up() on this state change -
1347                          * as the whole point    1348                          * as the whole point is that nobody can do anything
1348                          * with the chip now     1349                          * with the chip now anyway.
1349                          */                      1350                          */
1350                 case FL_PM_SUSPENDED:            1351                 case FL_PM_SUSPENDED:
1351                         break;                   1352                         break;
1352                                                  1353 
1353                 default:                         1354                 default:
1354                         ret = -EAGAIN;           1355                         ret = -EAGAIN;
1355                         break;                   1356                         break;
1356                 }                                1357                 }
1357                 spin_unlock_bh(chip->mutex);     1358                 spin_unlock_bh(chip->mutex);
1358         }                                        1359         }
1359                                                  1360 
1360         /* Unlock the chips again */             1361         /* Unlock the chips again */
1361                                                  1362 
1362         if (ret) {                               1363         if (ret) {
1363                 for (i--; i >=0; i--) {          1364                 for (i--; i >=0; i--) {
1364                         chip = &cfi->chips[i]    1365                         chip = &cfi->chips[i];
1365                                                  1366 
1366                         spin_lock_bh(chip->mu    1367                         spin_lock_bh(chip->mutex);
1367                                                  1368 
1368                         if (chip->state == FL    1369                         if (chip->state == FL_PM_SUSPENDED) {
1369                                 /* No need to    1370                                 /* No need to force it into a known state here,
1370                                    because we    1371                                    because we're returning failure, and it didn't
1371                                    get power     1372                                    get power cycled */
1372                                 chip->state =    1373                                 chip->state = chip->oldstate;
1373                                 wake_up(&chip    1374                                 wake_up(&chip->wq);
1374                         }                        1375                         }
1375                         spin_unlock_bh(chip->    1376                         spin_unlock_bh(chip->mutex);
1376                 }                                1377                 }
1377         }                                        1378         }
1378                                                  1379 
1379         return ret;                              1380         return ret;
1380 }                                                1381 }
1381                                                  1382 
1382 static void cfi_staa_resume(struct mtd_info *    1383 static void cfi_staa_resume(struct mtd_info *mtd)
1383 {                                                1384 {
1384         struct map_info *map = mtd->priv;        1385         struct map_info *map = mtd->priv;
1385         struct cfi_private *cfi = map->fldrv_    1386         struct cfi_private *cfi = map->fldrv_priv;
1386         int i;                                   1387         int i;
1387         struct flchip *chip;                     1388         struct flchip *chip;
1388                                                  1389 
1389         for (i=0; i<cfi->numchips; i++) {        1390         for (i=0; i<cfi->numchips; i++) {
1390                                                  1391 
1391                 chip = &cfi->chips[i];           1392                 chip = &cfi->chips[i];
1392                                                  1393 
1393                 spin_lock_bh(chip->mutex);       1394                 spin_lock_bh(chip->mutex);
1394                                                  1395 
1395                 /* Go to known state. Chip ma    1396                 /* Go to known state. Chip may have been power cycled */
1396                 if (chip->state == FL_PM_SUSP    1397                 if (chip->state == FL_PM_SUSPENDED) {
1397                         map_write(map, CMD(0x    1398                         map_write(map, CMD(0xFF), 0);
1398                         chip->state = FL_READ    1399                         chip->state = FL_READY;
1399                         wake_up(&chip->wq);      1400                         wake_up(&chip->wq);
1400                 }                                1401                 }
1401                                                  1402 
1402                 spin_unlock_bh(chip->mutex);     1403                 spin_unlock_bh(chip->mutex);
1403         }                                        1404         }
1404 }                                                1405 }
1405                                                  1406 
1406 static void cfi_staa_destroy(struct mtd_info     1407 static void cfi_staa_destroy(struct mtd_info *mtd)
1407 {                                                1408 {
1408         struct map_info *map = mtd->priv;        1409         struct map_info *map = mtd->priv;
1409         struct cfi_private *cfi = map->fldrv_    1410         struct cfi_private *cfi = map->fldrv_priv;
1410         kfree(cfi->cmdset_priv);                 1411         kfree(cfi->cmdset_priv);
1411         kfree(cfi);                              1412         kfree(cfi);
1412 }                                                1413 }
1413                                                  1414 
1414 MODULE_LICENSE("GPL");                           1415 MODULE_LICENSE("GPL");
1415                                                  1416 
  This page was automatically generated by the LXR engine.