OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [mtd/] [chips/] [cfi_cmdset_0020.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.