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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [mtd/] [devices/] [doc2000.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
 
2
/*
3
 * Linux driver for Disk-On-Chip 2000 and Millennium
4
 * (c) 1999 Machine Vision Holdings, Inc.
5
 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
6
 *
7
 * $Id: doc2000.c,v 1.67 2005/11/07 11:14:24 gleixner Exp $
8
 */
9
 
10
#include <linux/kernel.h>
11
#include <linux/module.h>
12
#include <asm/errno.h>
13
#include <asm/io.h>
14
#include <asm/uaccess.h>
15
#include <linux/miscdevice.h>
16
#include <linux/delay.h>
17
#include <linux/slab.h>
18
#include <linux/sched.h>
19
#include <linux/init.h>
20
#include <linux/types.h>
21
#include <linux/bitops.h>
22
#include <linux/mutex.h>
23
 
24
#include <linux/mtd/mtd.h>
25
#include <linux/mtd/nand.h>
26
#include <linux/mtd/doc2000.h>
27
 
28
#define DOC_SUPPORT_2000
29
#define DOC_SUPPORT_2000TSOP
30
#define DOC_SUPPORT_MILLENNIUM
31
 
32
#ifdef DOC_SUPPORT_2000
33
#define DoC_is_2000(doc) (doc->ChipID == DOC_ChipID_Doc2k)
34
#else
35
#define DoC_is_2000(doc) (0)
36
#endif
37
 
38
#if defined(DOC_SUPPORT_2000TSOP) || defined(DOC_SUPPORT_MILLENNIUM)
39
#define DoC_is_Millennium(doc) (doc->ChipID == DOC_ChipID_DocMil)
40
#else
41
#define DoC_is_Millennium(doc) (0)
42
#endif
43
 
44
/* #define ECC_DEBUG */
45
 
46
/* I have no idea why some DoC chips can not use memcpy_from|to_io().
47
 * This may be due to the different revisions of the ASIC controller built-in or
48
 * simplily a QA/Bug issue. Who knows ?? If you have trouble, please uncomment
49
 * this:
50
 #undef USE_MEMCPY
51
*/
52
 
53
static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
54
                    size_t *retlen, u_char *buf);
55
static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
56
                     size_t *retlen, const u_char *buf);
57
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
58
                        struct mtd_oob_ops *ops);
59
static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
60
                         struct mtd_oob_ops *ops);
61
static int doc_write_oob_nolock(struct mtd_info *mtd, loff_t ofs, size_t len,
62
                         size_t *retlen, const u_char *buf);
63
static int doc_erase (struct mtd_info *mtd, struct erase_info *instr);
64
 
65
static struct mtd_info *doc2klist = NULL;
66
 
67
/* Perform the required delay cycles by reading from the appropriate register */
68
static void DoC_Delay(struct DiskOnChip *doc, unsigned short cycles)
69
{
70
        volatile char dummy;
71
        int i;
72
 
73
        for (i = 0; i < cycles; i++) {
74
                if (DoC_is_Millennium(doc))
75
                        dummy = ReadDOC(doc->virtadr, NOP);
76
                else
77
                        dummy = ReadDOC(doc->virtadr, DOCStatus);
78
        }
79
 
80
}
81
 
82
/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
83
static int _DoC_WaitReady(struct DiskOnChip *doc)
84
{
85
        void __iomem *docptr = doc->virtadr;
86
        unsigned long timeo = jiffies + (HZ * 10);
87
 
88
        DEBUG(MTD_DEBUG_LEVEL3,
89
              "_DoC_WaitReady called for out-of-line wait\n");
90
 
91
        /* Out-of-line routine to wait for chip response */
92
        while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
93
                /* issue 2 read from NOP register after reading from CDSNControl register
94
                see Software Requirement 11.4 item 2. */
95
                DoC_Delay(doc, 2);
96
 
97
                if (time_after(jiffies, timeo)) {
98
                        DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");
99
                        return -EIO;
100
                }
101
                udelay(1);
102
                cond_resched();
103
        }
104
 
105
        return 0;
106
}
107
 
108
static inline int DoC_WaitReady(struct DiskOnChip *doc)
109
{
110
        void __iomem *docptr = doc->virtadr;
111
 
112
        /* This is inline, to optimise the common case, where it's ready instantly */
113
        int ret = 0;
114
 
115
        /* 4 read form NOP register should be issued in prior to the read from CDSNControl
116
           see Software Requirement 11.4 item 2. */
117
        DoC_Delay(doc, 4);
118
 
119
        if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B))
120
                /* Call the out-of-line routine to wait */
121
                ret = _DoC_WaitReady(doc);
122
 
123
        /* issue 2 read from NOP register after reading from CDSNControl register
124
           see Software Requirement 11.4 item 2. */
125
        DoC_Delay(doc, 2);
126
 
127
        return ret;
128
}
129
 
130
/* DoC_Command: Send a flash command to the flash chip through the CDSN Slow IO register to
131
   bypass the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
132
   required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
133
 
134
static int DoC_Command(struct DiskOnChip *doc, unsigned char command,
135
                              unsigned char xtraflags)
136
{
137
        void __iomem *docptr = doc->virtadr;
138
 
139
        if (DoC_is_2000(doc))
140
                xtraflags |= CDSN_CTRL_FLASH_IO;
141
 
142
        /* Assert the CLE (Command Latch Enable) line to the flash chip */
143
        WriteDOC(xtraflags | CDSN_CTRL_CLE | CDSN_CTRL_CE, docptr, CDSNControl);
144
        DoC_Delay(doc, 4);      /* Software requirement 11.4.3 for Millennium */
145
 
146
        if (DoC_is_Millennium(doc))
147
                WriteDOC(command, docptr, CDSNSlowIO);
148
 
149
        /* Send the command */
150
        WriteDOC_(command, docptr, doc->ioreg);
151
        if (DoC_is_Millennium(doc))
152
                WriteDOC(command, docptr, WritePipeTerm);
153
 
154
        /* Lower the CLE line */
155
        WriteDOC(xtraflags | CDSN_CTRL_CE, docptr, CDSNControl);
156
        DoC_Delay(doc, 4);      /* Software requirement 11.4.3 for Millennium */
157
 
158
        /* Wait for the chip to respond - Software requirement 11.4.1 (extended for any command) */
159
        return DoC_WaitReady(doc);
160
}
161
 
162
/* DoC_Address: Set the current address for the flash chip through the CDSN Slow IO register to
163
   bypass the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
164
   required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
165
 
166
static int DoC_Address(struct DiskOnChip *doc, int numbytes, unsigned long ofs,
167
                       unsigned char xtraflags1, unsigned char xtraflags2)
168
{
169
        int i;
170
        void __iomem *docptr = doc->virtadr;
171
 
172
        if (DoC_is_2000(doc))
173
                xtraflags1 |= CDSN_CTRL_FLASH_IO;
174
 
175
        /* Assert the ALE (Address Latch Enable) line to the flash chip */
176
        WriteDOC(xtraflags1 | CDSN_CTRL_ALE | CDSN_CTRL_CE, docptr, CDSNControl);
177
 
178
        DoC_Delay(doc, 4);      /* Software requirement 11.4.3 for Millennium */
179
 
180
        /* Send the address */
181
        /* Devices with 256-byte page are addressed as:
182
           Column (bits 0-7), Page (bits 8-15, 16-23, 24-31)
183
           * there is no device on the market with page256
184
           and more than 24 bits.
185
           Devices with 512-byte page are addressed as:
186
           Column (bits 0-7), Page (bits 9-16, 17-24, 25-31)
187
           * 25-31 is sent only if the chip support it.
188
           * bit 8 changes the read command to be sent
189
           (NAND_CMD_READ0 or NAND_CMD_READ1).
190
         */
191
 
192
        if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE) {
193
                if (DoC_is_Millennium(doc))
194
                        WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
195
                WriteDOC_(ofs & 0xff, docptr, doc->ioreg);
196
        }
197
 
198
        if (doc->page256) {
199
                ofs = ofs >> 8;
200
        } else {
201
                ofs = ofs >> 9;
202
        }
203
 
204
        if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE) {
205
                for (i = 0; i < doc->pageadrlen; i++, ofs = ofs >> 8) {
206
                        if (DoC_is_Millennium(doc))
207
                                WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
208
                        WriteDOC_(ofs & 0xff, docptr, doc->ioreg);
209
                }
210
        }
211
 
212
        if (DoC_is_Millennium(doc))
213
                WriteDOC(ofs & 0xff, docptr, WritePipeTerm);
214
 
215
        DoC_Delay(doc, 2);      /* Needed for some slow flash chips. mf. */
216
 
217
        /* FIXME: The SlowIO's for millennium could be replaced by
218
           a single WritePipeTerm here. mf. */
219
 
220
        /* Lower the ALE line */
221
        WriteDOC(xtraflags1 | xtraflags2 | CDSN_CTRL_CE, docptr,
222
                 CDSNControl);
223
 
224
        DoC_Delay(doc, 4);      /* Software requirement 11.4.3 for Millennium */
225
 
226
        /* Wait for the chip to respond - Software requirement 11.4.1 */
227
        return DoC_WaitReady(doc);
228
}
229
 
230
/* Read a buffer from DoC, taking care of Millennium odditys */
231
static void DoC_ReadBuf(struct DiskOnChip *doc, u_char * buf, int len)
232
{
233
        volatile int dummy;
234
        int modulus = 0xffff;
235
        void __iomem *docptr = doc->virtadr;
236
        int i;
237
 
238
        if (len <= 0)
239
                return;
240
 
241
        if (DoC_is_Millennium(doc)) {
242
                /* Read the data via the internal pipeline through CDSN IO register,
243
                   see Pipelined Read Operations 11.3 */
244
                dummy = ReadDOC(docptr, ReadPipeInit);
245
 
246
                /* Millennium should use the LastDataRead register - Pipeline Reads */
247
                len--;
248
 
249
                /* This is needed for correctly ECC calculation */
250
                modulus = 0xff;
251
        }
252
 
253
        for (i = 0; i < len; i++)
254
                buf[i] = ReadDOC_(docptr, doc->ioreg + (i & modulus));
255
 
256
        if (DoC_is_Millennium(doc)) {
257
                buf[i] = ReadDOC(docptr, LastDataRead);
258
        }
259
}
260
 
261
/* Write a buffer to DoC, taking care of Millennium odditys */
262
static void DoC_WriteBuf(struct DiskOnChip *doc, const u_char * buf, int len)
263
{
264
        void __iomem *docptr = doc->virtadr;
265
        int i;
266
 
267
        if (len <= 0)
268
                return;
269
 
270
        for (i = 0; i < len; i++)
271
                WriteDOC_(buf[i], docptr, doc->ioreg + i);
272
 
273
        if (DoC_is_Millennium(doc)) {
274
                WriteDOC(0x00, docptr, WritePipeTerm);
275
        }
276
}
277
 
278
 
279
/* DoC_SelectChip: Select a given flash chip within the current floor */
280
 
281
static inline int DoC_SelectChip(struct DiskOnChip *doc, int chip)
282
{
283
        void __iomem *docptr = doc->virtadr;
284
 
285
        /* Software requirement 11.4.4 before writing DeviceSelect */
286
        /* Deassert the CE line to eliminate glitches on the FCE# outputs */
287
        WriteDOC(CDSN_CTRL_WP, docptr, CDSNControl);
288
        DoC_Delay(doc, 4);      /* Software requirement 11.4.3 for Millennium */
289
 
290
        /* Select the individual flash chip requested */
291
        WriteDOC(chip, docptr, CDSNDeviceSelect);
292
        DoC_Delay(doc, 4);
293
 
294
        /* Reassert the CE line */
295
        WriteDOC(CDSN_CTRL_CE | CDSN_CTRL_FLASH_IO | CDSN_CTRL_WP, docptr,
296
                 CDSNControl);
297
        DoC_Delay(doc, 4);      /* Software requirement 11.4.3 for Millennium */
298
 
299
        /* Wait for it to be ready */
300
        return DoC_WaitReady(doc);
301
}
302
 
303
/* DoC_SelectFloor: Select a given floor (bank of flash chips) */
304
 
305
static inline int DoC_SelectFloor(struct DiskOnChip *doc, int floor)
306
{
307
        void __iomem *docptr = doc->virtadr;
308
 
309
        /* Select the floor (bank) of chips required */
310
        WriteDOC(floor, docptr, FloorSelect);
311
 
312
        /* Wait for the chip to be ready */
313
        return DoC_WaitReady(doc);
314
}
315
 
316
/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */
317
 
318
static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
319
{
320
        int mfr, id, i, j;
321
        volatile char dummy;
322
 
323
        /* Page in the required floor/chip */
324
        DoC_SelectFloor(doc, floor);
325
        DoC_SelectChip(doc, chip);
326
 
327
        /* Reset the chip */
328
        if (DoC_Command(doc, NAND_CMD_RESET, CDSN_CTRL_WP)) {
329
                DEBUG(MTD_DEBUG_LEVEL2,
330
                      "DoC_Command (reset) for %d,%d returned true\n",
331
                      floor, chip);
332
                return 0;
333
        }
334
 
335
 
336
        /* Read the NAND chip ID: 1. Send ReadID command */
337
        if (DoC_Command(doc, NAND_CMD_READID, CDSN_CTRL_WP)) {
338
                DEBUG(MTD_DEBUG_LEVEL2,
339
                      "DoC_Command (ReadID) for %d,%d returned true\n",
340
                      floor, chip);
341
                return 0;
342
        }
343
 
344
        /* Read the NAND chip ID: 2. Send address byte zero */
345
        DoC_Address(doc, ADDR_COLUMN, 0, CDSN_CTRL_WP, 0);
346
 
347
        /* Read the manufacturer and device id codes from the device */
348
 
349
        if (DoC_is_Millennium(doc)) {
350
                DoC_Delay(doc, 2);
351
                dummy = ReadDOC(doc->virtadr, ReadPipeInit);
352
                mfr = ReadDOC(doc->virtadr, LastDataRead);
353
 
354
                DoC_Delay(doc, 2);
355
                dummy = ReadDOC(doc->virtadr, ReadPipeInit);
356
                id = ReadDOC(doc->virtadr, LastDataRead);
357
        } else {
358
                /* CDSN Slow IO register see Software Req 11.4 item 5. */
359
                dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
360
                DoC_Delay(doc, 2);
361
                mfr = ReadDOC_(doc->virtadr, doc->ioreg);
362
 
363
                /* CDSN Slow IO register see Software Req 11.4 item 5. */
364
                dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
365
                DoC_Delay(doc, 2);
366
                id = ReadDOC_(doc->virtadr, doc->ioreg);
367
        }
368
 
369
        /* No response - return failure */
370
        if (mfr == 0xff || mfr == 0)
371
                return 0;
372
 
373
        /* Check it's the same as the first chip we identified.
374
         * M-Systems say that any given DiskOnChip device should only
375
         * contain _one_ type of flash part, although that's not a
376
         * hardware restriction. */
377
        if (doc->mfr) {
378
                if (doc->mfr == mfr && doc->id == id)
379
                        return 1;       /* This is another the same the first */
380
                else
381
                        printk(KERN_WARNING
382
                               "Flash chip at floor %d, chip %d is different:\n",
383
                               floor, chip);
384
        }
385
 
386
        /* Print and store the manufacturer and ID codes. */
387
        for (i = 0; nand_flash_ids[i].name != NULL; i++) {
388
                if (id == nand_flash_ids[i].id) {
389
                        /* Try to identify manufacturer */
390
                        for (j = 0; nand_manuf_ids[j].id != 0x0; j++) {
391
                                if (nand_manuf_ids[j].id == mfr)
392
                                        break;
393
                        }
394
                        printk(KERN_INFO
395
                               "Flash chip found: Manufacturer ID: %2.2X, "
396
                               "Chip ID: %2.2X (%s:%s)\n", mfr, id,
397
                               nand_manuf_ids[j].name, nand_flash_ids[i].name);
398
                        if (!doc->mfr) {
399
                                doc->mfr = mfr;
400
                                doc->id = id;
401
                                doc->chipshift =
402
                                        ffs((nand_flash_ids[i].chipsize << 20)) - 1;
403
                                doc->page256 = (nand_flash_ids[i].pagesize == 256) ? 1 : 0;
404
                                doc->pageadrlen = doc->chipshift > 25 ? 3 : 2;
405
                                doc->erasesize =
406
                                    nand_flash_ids[i].erasesize;
407
                                return 1;
408
                        }
409
                        return 0;
410
                }
411
        }
412
 
413
 
414
        /* We haven't fully identified the chip. Print as much as we know. */
415
        printk(KERN_WARNING "Unknown flash chip found: %2.2X %2.2X\n",
416
               id, mfr);
417
 
418
        printk(KERN_WARNING "Please report to dwmw2@infradead.org\n");
419
        return 0;
420
}
421
 
422
/* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */
423
 
424
static void DoC_ScanChips(struct DiskOnChip *this, int maxchips)
425
{
426
        int floor, chip;
427
        int numchips[MAX_FLOORS];
428
        int ret = 1;
429
 
430
        this->numchips = 0;
431
        this->mfr = 0;
432
        this->id = 0;
433
 
434
        /* For each floor, find the number of valid chips it contains */
435
        for (floor = 0; floor < MAX_FLOORS; floor++) {
436
                ret = 1;
437
                numchips[floor] = 0;
438
                for (chip = 0; chip < maxchips && ret != 0; chip++) {
439
 
440
                        ret = DoC_IdentChip(this, floor, chip);
441
                        if (ret) {
442
                                numchips[floor]++;
443
                                this->numchips++;
444
                        }
445
                }
446
        }
447
 
448
        /* If there are none at all that we recognise, bail */
449
        if (!this->numchips) {
450
                printk(KERN_NOTICE "No flash chips recognised.\n");
451
                return;
452
        }
453
 
454
        /* Allocate an array to hold the information for each chip */
455
        this->chips = kmalloc(sizeof(struct Nand) * this->numchips, GFP_KERNEL);
456
        if (!this->chips) {
457
                printk(KERN_NOTICE "No memory for allocating chip info structures\n");
458
                return;
459
        }
460
 
461
        ret = 0;
462
 
463
        /* Fill out the chip array with {floor, chipno} for each
464
         * detected chip in the device. */
465
        for (floor = 0; floor < MAX_FLOORS; floor++) {
466
                for (chip = 0; chip < numchips[floor]; chip++) {
467
                        this->chips[ret].floor = floor;
468
                        this->chips[ret].chip = chip;
469
                        this->chips[ret].curadr = 0;
470
                        this->chips[ret].curmode = 0x50;
471
                        ret++;
472
                }
473
        }
474
 
475
        /* Calculate and print the total size of the device */
476
        this->totlen = this->numchips * (1 << this->chipshift);
477
 
478
        printk(KERN_INFO "%d flash chips found. Total DiskOnChip size: %ld MiB\n",
479
               this->numchips, this->totlen >> 20);
480
}
481
 
482
static int DoC2k_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
483
{
484
        int tmp1, tmp2, retval;
485
        if (doc1->physadr == doc2->physadr)
486
                return 1;
487
 
488
        /* Use the alias resolution register which was set aside for this
489
         * purpose. If it's value is the same on both chips, they might
490
         * be the same chip, and we write to one and check for a change in
491
         * the other. It's unclear if this register is usuable in the
492
         * DoC 2000 (it's in the Millennium docs), but it seems to work. */
493
        tmp1 = ReadDOC(doc1->virtadr, AliasResolution);
494
        tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
495
        if (tmp1 != tmp2)
496
                return 0;
497
 
498
        WriteDOC((tmp1 + 1) % 0xff, doc1->virtadr, AliasResolution);
499
        tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
500
        if (tmp2 == (tmp1 + 1) % 0xff)
501
                retval = 1;
502
        else
503
                retval = 0;
504
 
505
        /* Restore register contents.  May not be necessary, but do it just to
506
         * be safe. */
507
        WriteDOC(tmp1, doc1->virtadr, AliasResolution);
508
 
509
        return retval;
510
}
511
 
512
/* This routine is found from the docprobe code by symbol_get(),
513
 * which will bump the use count of this module. */
514
void DoC2k_init(struct mtd_info *mtd)
515
{
516
        struct DiskOnChip *this = mtd->priv;
517
        struct DiskOnChip *old = NULL;
518
        int maxchips;
519
 
520
        /* We must avoid being called twice for the same device. */
521
 
522
        if (doc2klist)
523
                old = doc2klist->priv;
524
 
525
        while (old) {
526
                if (DoC2k_is_alias(old, this)) {
527
                        printk(KERN_NOTICE
528
                               "Ignoring DiskOnChip 2000 at 0x%lX - already configured\n",
529
                               this->physadr);
530
                        iounmap(this->virtadr);
531
                        kfree(mtd);
532
                        return;
533
                }
534
                if (old->nextdoc)
535
                        old = old->nextdoc->priv;
536
                else
537
                        old = NULL;
538
        }
539
 
540
 
541
        switch (this->ChipID) {
542
        case DOC_ChipID_Doc2kTSOP:
543
                mtd->name = "DiskOnChip 2000 TSOP";
544
                this->ioreg = DoC_Mil_CDSN_IO;
545
                /* Pretend it's a Millennium */
546
                this->ChipID = DOC_ChipID_DocMil;
547
                maxchips = MAX_CHIPS;
548
                break;
549
        case DOC_ChipID_Doc2k:
550
                mtd->name = "DiskOnChip 2000";
551
                this->ioreg = DoC_2k_CDSN_IO;
552
                maxchips = MAX_CHIPS;
553
                break;
554
        case DOC_ChipID_DocMil:
555
                mtd->name = "DiskOnChip Millennium";
556
                this->ioreg = DoC_Mil_CDSN_IO;
557
                maxchips = MAX_CHIPS_MIL;
558
                break;
559
        default:
560
                printk("Unknown ChipID 0x%02x\n", this->ChipID);
561
                kfree(mtd);
562
                iounmap(this->virtadr);
563
                return;
564
        }
565
 
566
        printk(KERN_NOTICE "%s found at address 0x%lX\n", mtd->name,
567
               this->physadr);
568
 
569
        mtd->type = MTD_NANDFLASH;
570
        mtd->flags = MTD_CAP_NANDFLASH;
571
        mtd->size = 0;
572
        mtd->erasesize = 0;
573
        mtd->writesize = 512;
574
        mtd->oobsize = 16;
575
        mtd->owner = THIS_MODULE;
576
        mtd->erase = doc_erase;
577
        mtd->point = NULL;
578
        mtd->unpoint = NULL;
579
        mtd->read = doc_read;
580
        mtd->write = doc_write;
581
        mtd->read_oob = doc_read_oob;
582
        mtd->write_oob = doc_write_oob;
583
        mtd->sync = NULL;
584
 
585
        this->totlen = 0;
586
        this->numchips = 0;
587
 
588
        this->curfloor = -1;
589
        this->curchip = -1;
590
        mutex_init(&this->lock);
591
 
592
        /* Ident all the chips present. */
593
        DoC_ScanChips(this, maxchips);
594
 
595
        if (!this->totlen) {
596
                kfree(mtd);
597
                iounmap(this->virtadr);
598
        } else {
599
                this->nextdoc = doc2klist;
600
                doc2klist = mtd;
601
                mtd->size = this->totlen;
602
                mtd->erasesize = this->erasesize;
603
                add_mtd_device(mtd);
604
                return;
605
        }
606
}
607
EXPORT_SYMBOL_GPL(DoC2k_init);
608
 
609
static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
610
                    size_t * retlen, u_char * buf)
611
{
612
        struct DiskOnChip *this = mtd->priv;
613
        void __iomem *docptr = this->virtadr;
614
        struct Nand *mychip;
615
        unsigned char syndrome[6], eccbuf[6];
616
        volatile char dummy;
617
        int i, len256 = 0, ret=0;
618
        size_t left = len;
619
 
620
        /* Don't allow read past end of device */
621
        if (from >= this->totlen)
622
                return -EINVAL;
623
 
624
        mutex_lock(&this->lock);
625
 
626
        *retlen = 0;
627
        while (left) {
628
                len = left;
629
 
630
                /* Don't allow a single read to cross a 512-byte block boundary */
631
                if (from + len > ((from | 0x1ff) + 1))
632
                        len = ((from | 0x1ff) + 1) - from;
633
 
634
                /* The ECC will not be calculated correctly if less than 512 is read */
635
                if (len != 0x200 && eccbuf)
636
                        printk(KERN_WARNING
637
                               "ECC needs a full sector read (adr: %lx size %lx)\n",
638
                               (long) from, (long) len);
639
 
640
                /* printk("DoC_Read (adr: %lx size %lx)\n", (long) from, (long) len); */
641
 
642
 
643
                /* Find the chip which is to be used and select it */
644
                mychip = &this->chips[from >> (this->chipshift)];
645
 
646
                if (this->curfloor != mychip->floor) {
647
                        DoC_SelectFloor(this, mychip->floor);
648
                        DoC_SelectChip(this, mychip->chip);
649
                } else if (this->curchip != mychip->chip) {
650
                        DoC_SelectChip(this, mychip->chip);
651
                }
652
 
653
                this->curfloor = mychip->floor;
654
                this->curchip = mychip->chip;
655
 
656
                DoC_Command(this,
657
                            (!this->page256
658
                             && (from & 0x100)) ? NAND_CMD_READ1 : NAND_CMD_READ0,
659
                            CDSN_CTRL_WP);
660
                DoC_Address(this, ADDR_COLUMN_PAGE, from, CDSN_CTRL_WP,
661
                            CDSN_CTRL_ECC_IO);
662
 
663
                /* Prime the ECC engine */
664
                WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
665
                WriteDOC(DOC_ECC_EN, docptr, ECCConf);
666
 
667
                /* treat crossing 256-byte sector for 2M x 8bits devices */
668
                if (this->page256 && from + len > (from | 0xff) + 1) {
669
                        len256 = (from | 0xff) + 1 - from;
670
                        DoC_ReadBuf(this, buf, len256);
671
 
672
                        DoC_Command(this, NAND_CMD_READ0, CDSN_CTRL_WP);
673
                        DoC_Address(this, ADDR_COLUMN_PAGE, from + len256,
674
                                    CDSN_CTRL_WP, CDSN_CTRL_ECC_IO);
675
                }
676
 
677
                DoC_ReadBuf(this, &buf[len256], len - len256);
678
 
679
                /* Let the caller know we completed it */
680
                *retlen += len;
681
 
682
                /* Read the ECC data through the DiskOnChip ECC logic */
683
                /* Note: this will work even with 2M x 8bit devices as   */
684
                /*       they have 8 bytes of OOB per 256 page. mf.      */
685
                DoC_ReadBuf(this, eccbuf, 6);
686
 
687
                /* Flush the pipeline */
688
                if (DoC_is_Millennium(this)) {
689
                        dummy = ReadDOC(docptr, ECCConf);
690
                        dummy = ReadDOC(docptr, ECCConf);
691
                        i = ReadDOC(docptr, ECCConf);
692
                } else {
693
                        dummy = ReadDOC(docptr, 2k_ECCStatus);
694
                        dummy = ReadDOC(docptr, 2k_ECCStatus);
695
                        i = ReadDOC(docptr, 2k_ECCStatus);
696
                }
697
 
698
                /* Check the ECC Status */
699
                if (i & 0x80) {
700
                        int nb_errors;
701
                        /* There was an ECC error */
702
#ifdef ECC_DEBUG
703
                        printk(KERN_ERR "DiskOnChip ECC Error: Read at %lx\n", (long)from);
704
#endif
705
                        /* Read the ECC syndrom through the DiskOnChip ECC
706
                           logic.  These syndrome will be all ZERO when there
707
                           is no error */
708
                        for (i = 0; i < 6; i++) {
709
                                syndrome[i] =
710
                                        ReadDOC(docptr, ECCSyndrome0 + i);
711
                        }
712
                        nb_errors = doc_decode_ecc(buf, syndrome);
713
 
714
#ifdef ECC_DEBUG
715
                        printk(KERN_ERR "Errors corrected: %x\n", nb_errors);
716
#endif
717
                        if (nb_errors < 0) {
718
                                /* We return error, but have actually done the
719
                                   read. Not that this can be told to
720
                                   user-space, via sys_read(), but at least
721
                                   MTD-aware stuff can know about it by
722
                                   checking *retlen */
723
                                ret = -EIO;
724
                        }
725
                }
726
 
727
#ifdef PSYCHO_DEBUG
728
                printk(KERN_DEBUG "ECC DATA at %lxB: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
729
                       (long)from, eccbuf[0], eccbuf[1], eccbuf[2],
730
                       eccbuf[3], eccbuf[4], eccbuf[5]);
731
#endif
732
 
733
                /* disable the ECC engine */
734
                WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
735
 
736
                /* according to 11.4.1, we need to wait for the busy line
737
                 * drop if we read to the end of the page.  */
738
                if(0 == ((from + len) & 0x1ff))
739
                {
740
                    DoC_WaitReady(this);
741
                }
742
 
743
                from += len;
744
                left -= len;
745
                buf += len;
746
        }
747
 
748
        mutex_unlock(&this->lock);
749
 
750
        return ret;
751
}
752
 
753
static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
754
                     size_t * retlen, const u_char * buf)
755
{
756
        struct DiskOnChip *this = mtd->priv;
757
        int di; /* Yes, DI is a hangover from when I was disassembling the binary driver */
758
        void __iomem *docptr = this->virtadr;
759
        unsigned char eccbuf[6];
760
        volatile char dummy;
761
        int len256 = 0;
762
        struct Nand *mychip;
763
        size_t left = len;
764
        int status;
765
 
766
        /* Don't allow write past end of device */
767
        if (to >= this->totlen)
768
                return -EINVAL;
769
 
770
        mutex_lock(&this->lock);
771
 
772
        *retlen = 0;
773
        while (left) {
774
                len = left;
775
 
776
                /* Don't allow a single write to cross a 512-byte block boundary */
777
                if (to + len > ((to | 0x1ff) + 1))
778
                        len = ((to | 0x1ff) + 1) - to;
779
 
780
                /* The ECC will not be calculated correctly if less than 512 is written */
781
/* DBB-
782
                if (len != 0x200 && eccbuf)
783
                        printk(KERN_WARNING
784
                               "ECC needs a full sector write (adr: %lx size %lx)\n",
785
                               (long) to, (long) len);
786
   -DBB */
787
 
788
                /* printk("DoC_Write (adr: %lx size %lx)\n", (long) to, (long) len); */
789
 
790
                /* Find the chip which is to be used and select it */
791
                mychip = &this->chips[to >> (this->chipshift)];
792
 
793
                if (this->curfloor != mychip->floor) {
794
                        DoC_SelectFloor(this, mychip->floor);
795
                        DoC_SelectChip(this, mychip->chip);
796
                } else if (this->curchip != mychip->chip) {
797
                        DoC_SelectChip(this, mychip->chip);
798
                }
799
 
800
                this->curfloor = mychip->floor;
801
                this->curchip = mychip->chip;
802
 
803
                /* Set device to main plane of flash */
804
                DoC_Command(this, NAND_CMD_RESET, CDSN_CTRL_WP);
805
                DoC_Command(this,
806
                            (!this->page256
807
                             && (to & 0x100)) ? NAND_CMD_READ1 : NAND_CMD_READ0,
808
                            CDSN_CTRL_WP);
809
 
810
                DoC_Command(this, NAND_CMD_SEQIN, 0);
811
                DoC_Address(this, ADDR_COLUMN_PAGE, to, 0, CDSN_CTRL_ECC_IO);
812
 
813
                /* Prime the ECC engine */
814
                WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
815
                WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
816
 
817
                /* treat crossing 256-byte sector for 2M x 8bits devices */
818
                if (this->page256 && to + len > (to | 0xff) + 1) {
819
                        len256 = (to | 0xff) + 1 - to;
820
                        DoC_WriteBuf(this, buf, len256);
821
 
822
                        DoC_Command(this, NAND_CMD_PAGEPROG, 0);
823
 
824
                        DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
825
                        /* There's an implicit DoC_WaitReady() in DoC_Command */
826
 
827
                        dummy = ReadDOC(docptr, CDSNSlowIO);
828
                        DoC_Delay(this, 2);
829
 
830
                        if (ReadDOC_(docptr, this->ioreg) & 1) {
831
                                printk(KERN_ERR "Error programming flash\n");
832
                                /* Error in programming */
833
                                *retlen = 0;
834
                                mutex_unlock(&this->lock);
835
                                return -EIO;
836
                        }
837
 
838
                        DoC_Command(this, NAND_CMD_SEQIN, 0);
839
                        DoC_Address(this, ADDR_COLUMN_PAGE, to + len256, 0,
840
                                    CDSN_CTRL_ECC_IO);
841
                }
842
 
843
                DoC_WriteBuf(this, &buf[len256], len - len256);
844
 
845
                WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_CE, docptr, CDSNControl);
846
 
847
                if (DoC_is_Millennium(this)) {
848
                        WriteDOC(0, docptr, NOP);
849
                        WriteDOC(0, docptr, NOP);
850
                        WriteDOC(0, docptr, NOP);
851
                } else {
852
                        WriteDOC_(0, docptr, this->ioreg);
853
                        WriteDOC_(0, docptr, this->ioreg);
854
                        WriteDOC_(0, docptr, this->ioreg);
855
                }
856
 
857
                WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_FLASH_IO | CDSN_CTRL_CE, docptr,
858
                         CDSNControl);
859
 
860
                /* Read the ECC data through the DiskOnChip ECC logic */
861
                for (di = 0; di < 6; di++) {
862
                        eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di);
863
                }
864
 
865
                /* Reset the ECC engine */
866
                WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
867
 
868
#ifdef PSYCHO_DEBUG
869
                printk
870
                        ("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
871
                         (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
872
                         eccbuf[4], eccbuf[5]);
873
#endif
874
                DoC_Command(this, NAND_CMD_PAGEPROG, 0);
875
 
876
                DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
877
                /* There's an implicit DoC_WaitReady() in DoC_Command */
878
 
879
                if (DoC_is_Millennium(this)) {
880
                        ReadDOC(docptr, ReadPipeInit);
881
                        status = ReadDOC(docptr, LastDataRead);
882
                } else {
883
                        dummy = ReadDOC(docptr, CDSNSlowIO);
884
                        DoC_Delay(this, 2);
885
                        status = ReadDOC_(docptr, this->ioreg);
886
                }
887
 
888
                if (status & 1) {
889
                        printk(KERN_ERR "Error programming flash\n");
890
                        /* Error in programming */
891
                        *retlen = 0;
892
                        mutex_unlock(&this->lock);
893
                        return -EIO;
894
                }
895
 
896
                /* Let the caller know we completed it */
897
                *retlen += len;
898
 
899
                if (eccbuf) {
900
                        unsigned char x[8];
901
                        size_t dummy;
902
                        int ret;
903
 
904
                        /* Write the ECC data to flash */
905
                        for (di=0; di<6; di++)
906
                                x[di] = eccbuf[di];
907
 
908
                        x[6]=0x55;
909
                        x[7]=0x55;
910
 
911
                        ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x);
912
                        if (ret) {
913
                                mutex_unlock(&this->lock);
914
                                return ret;
915
                        }
916
                }
917
 
918
                to += len;
919
                left -= len;
920
                buf += len;
921
        }
922
 
923
        mutex_unlock(&this->lock);
924
        return 0;
925
}
926
 
927
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
928
                        struct mtd_oob_ops *ops)
929
{
930
        struct DiskOnChip *this = mtd->priv;
931
        int len256 = 0, ret;
932
        struct Nand *mychip;
933
        uint8_t *buf = ops->oobbuf;
934
        size_t len = ops->len;
935
 
936
        BUG_ON(ops->mode != MTD_OOB_PLACE);
937
 
938
        ofs += ops->ooboffs;
939
 
940
        mutex_lock(&this->lock);
941
 
942
        mychip = &this->chips[ofs >> this->chipshift];
943
 
944
        if (this->curfloor != mychip->floor) {
945
                DoC_SelectFloor(this, mychip->floor);
946
                DoC_SelectChip(this, mychip->chip);
947
        } else if (this->curchip != mychip->chip) {
948
                DoC_SelectChip(this, mychip->chip);
949
        }
950
        this->curfloor = mychip->floor;
951
        this->curchip = mychip->chip;
952
 
953
        /* update address for 2M x 8bit devices. OOB starts on the second */
954
        /* page to maintain compatibility with doc_read_ecc. */
955
        if (this->page256) {
956
                if (!(ofs & 0x8))
957
                        ofs += 0x100;
958
                else
959
                        ofs -= 0x8;
960
        }
961
 
962
        DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
963
        DoC_Address(this, ADDR_COLUMN_PAGE, ofs, CDSN_CTRL_WP, 0);
964
 
965
        /* treat crossing 8-byte OOB data for 2M x 8bit devices */
966
        /* Note: datasheet says it should automaticaly wrap to the */
967
        /*       next OOB block, but it didn't work here. mf.      */
968
        if (this->page256 && ofs + len > (ofs | 0x7) + 1) {
969
                len256 = (ofs | 0x7) + 1 - ofs;
970
                DoC_ReadBuf(this, buf, len256);
971
 
972
                DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
973
                DoC_Address(this, ADDR_COLUMN_PAGE, ofs & (~0x1ff),
974
                            CDSN_CTRL_WP, 0);
975
        }
976
 
977
        DoC_ReadBuf(this, &buf[len256], len - len256);
978
 
979
        ops->retlen = len;
980
        /* Reading the full OOB data drops us off of the end of the page,
981
         * causing the flash device to go into busy mode, so we need
982
         * to wait until ready 11.4.1 and Toshiba TC58256FT docs */
983
 
984
        ret = DoC_WaitReady(this);
985
 
986
        mutex_unlock(&this->lock);
987
        return ret;
988
 
989
}
990
 
991
static int doc_write_oob_nolock(struct mtd_info *mtd, loff_t ofs, size_t len,
992
                                size_t * retlen, const u_char * buf)
993
{
994
        struct DiskOnChip *this = mtd->priv;
995
        int len256 = 0;
996
        void __iomem *docptr = this->virtadr;
997
        struct Nand *mychip = &this->chips[ofs >> this->chipshift];
998
        volatile int dummy;
999
        int status;
1000
 
1001
        //      printk("doc_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",(long)ofs, len,
1002
        //   buf[0], buf[1], buf[2], buf[3], buf[8], buf[9], buf[14],buf[15]);
1003
 
1004
        /* Find the chip which is to be used and select it */
1005
        if (this->curfloor != mychip->floor) {
1006
                DoC_SelectFloor(this, mychip->floor);
1007
                DoC_SelectChip(this, mychip->chip);
1008
        } else if (this->curchip != mychip->chip) {
1009
                DoC_SelectChip(this, mychip->chip);
1010
        }
1011
        this->curfloor = mychip->floor;
1012
        this->curchip = mychip->chip;
1013
 
1014
        /* disable the ECC engine */
1015
        WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
1016
        WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
1017
 
1018
        /* Reset the chip, see Software Requirement 11.4 item 1. */
1019
        DoC_Command(this, NAND_CMD_RESET, CDSN_CTRL_WP);
1020
 
1021
        /* issue the Read2 command to set the pointer to the Spare Data Area. */
1022
        DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
1023
 
1024
        /* update address for 2M x 8bit devices. OOB starts on the second */
1025
        /* page to maintain compatibility with doc_read_ecc. */
1026
        if (this->page256) {
1027
                if (!(ofs & 0x8))
1028
                        ofs += 0x100;
1029
                else
1030
                        ofs -= 0x8;
1031
        }
1032
 
1033
        /* issue the Serial Data In command to initial the Page Program process */
1034
        DoC_Command(this, NAND_CMD_SEQIN, 0);
1035
        DoC_Address(this, ADDR_COLUMN_PAGE, ofs, 0, 0);
1036
 
1037
        /* treat crossing 8-byte OOB data for 2M x 8bit devices */
1038
        /* Note: datasheet says it should automaticaly wrap to the */
1039
        /*       next OOB block, but it didn't work here. mf.      */
1040
        if (this->page256 && ofs + len > (ofs | 0x7) + 1) {
1041
                len256 = (ofs | 0x7) + 1 - ofs;
1042
                DoC_WriteBuf(this, buf, len256);
1043
 
1044
                DoC_Command(this, NAND_CMD_PAGEPROG, 0);
1045
                DoC_Command(this, NAND_CMD_STATUS, 0);
1046
                /* DoC_WaitReady() is implicit in DoC_Command */
1047
 
1048
                if (DoC_is_Millennium(this)) {
1049
                        ReadDOC(docptr, ReadPipeInit);
1050
                        status = ReadDOC(docptr, LastDataRead);
1051
                } else {
1052
                        dummy = ReadDOC(docptr, CDSNSlowIO);
1053
                        DoC_Delay(this, 2);
1054
                        status = ReadDOC_(docptr, this->ioreg);
1055
                }
1056
 
1057
                if (status & 1) {
1058
                        printk(KERN_ERR "Error programming oob data\n");
1059
                        /* There was an error */
1060
                        *retlen = 0;
1061
                        return -EIO;
1062
                }
1063
                DoC_Command(this, NAND_CMD_SEQIN, 0);
1064
                DoC_Address(this, ADDR_COLUMN_PAGE, ofs & (~0x1ff), 0, 0);
1065
        }
1066
 
1067
        DoC_WriteBuf(this, &buf[len256], len - len256);
1068
 
1069
        DoC_Command(this, NAND_CMD_PAGEPROG, 0);
1070
        DoC_Command(this, NAND_CMD_STATUS, 0);
1071
        /* DoC_WaitReady() is implicit in DoC_Command */
1072
 
1073
        if (DoC_is_Millennium(this)) {
1074
                ReadDOC(docptr, ReadPipeInit);
1075
                status = ReadDOC(docptr, LastDataRead);
1076
        } else {
1077
                dummy = ReadDOC(docptr, CDSNSlowIO);
1078
                DoC_Delay(this, 2);
1079
                status = ReadDOC_(docptr, this->ioreg);
1080
        }
1081
 
1082
        if (status & 1) {
1083
                printk(KERN_ERR "Error programming oob data\n");
1084
                /* There was an error */
1085
                *retlen = 0;
1086
                return -EIO;
1087
        }
1088
 
1089
        *retlen = len;
1090
        return 0;
1091
 
1092
}
1093
 
1094
static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
1095
                         struct mtd_oob_ops *ops)
1096
{
1097
        struct DiskOnChip *this = mtd->priv;
1098
        int ret;
1099
 
1100
        BUG_ON(ops->mode != MTD_OOB_PLACE);
1101
 
1102
        mutex_lock(&this->lock);
1103
        ret = doc_write_oob_nolock(mtd, ofs + ops->ooboffs, ops->len,
1104
                                   &ops->retlen, ops->oobbuf);
1105
 
1106
        mutex_unlock(&this->lock);
1107
        return ret;
1108
}
1109
 
1110
static int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
1111
{
1112
        struct DiskOnChip *this = mtd->priv;
1113
        __u32 ofs = instr->addr;
1114
        __u32 len = instr->len;
1115
        volatile int dummy;
1116
        void __iomem *docptr = this->virtadr;
1117
        struct Nand *mychip;
1118
        int status;
1119
 
1120
        mutex_lock(&this->lock);
1121
 
1122
        if (ofs & (mtd->erasesize-1) || len & (mtd->erasesize-1)) {
1123
                mutex_unlock(&this->lock);
1124
                return -EINVAL;
1125
        }
1126
 
1127
        instr->state = MTD_ERASING;
1128
 
1129
        /* FIXME: Do this in the background. Use timers or schedule_task() */
1130
        while(len) {
1131
                mychip = &this->chips[ofs >> this->chipshift];
1132
 
1133
                if (this->curfloor != mychip->floor) {
1134
                        DoC_SelectFloor(this, mychip->floor);
1135
                        DoC_SelectChip(this, mychip->chip);
1136
                } else if (this->curchip != mychip->chip) {
1137
                        DoC_SelectChip(this, mychip->chip);
1138
                }
1139
                this->curfloor = mychip->floor;
1140
                this->curchip = mychip->chip;
1141
 
1142
                DoC_Command(this, NAND_CMD_ERASE1, 0);
1143
                DoC_Address(this, ADDR_PAGE, ofs, 0, 0);
1144
                DoC_Command(this, NAND_CMD_ERASE2, 0);
1145
 
1146
                DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
1147
 
1148
                if (DoC_is_Millennium(this)) {
1149
                        ReadDOC(docptr, ReadPipeInit);
1150
                        status = ReadDOC(docptr, LastDataRead);
1151
                } else {
1152
                        dummy = ReadDOC(docptr, CDSNSlowIO);
1153
                        DoC_Delay(this, 2);
1154
                        status = ReadDOC_(docptr, this->ioreg);
1155
                }
1156
 
1157
                if (status & 1) {
1158
                        printk(KERN_ERR "Error erasing at 0x%x\n", ofs);
1159
                        /* There was an error */
1160
                        instr->state = MTD_ERASE_FAILED;
1161
                        goto callback;
1162
                }
1163
                ofs += mtd->erasesize;
1164
                len -= mtd->erasesize;
1165
        }
1166
        instr->state = MTD_ERASE_DONE;
1167
 
1168
 callback:
1169
        mtd_erase_callback(instr);
1170
 
1171
        mutex_unlock(&this->lock);
1172
        return 0;
1173
}
1174
 
1175
 
1176
/****************************************************************************
1177
 *
1178
 * Module stuff
1179
 *
1180
 ****************************************************************************/
1181
 
1182
static void __exit cleanup_doc2000(void)
1183
{
1184
        struct mtd_info *mtd;
1185
        struct DiskOnChip *this;
1186
 
1187
        while ((mtd = doc2klist)) {
1188
                this = mtd->priv;
1189
                doc2klist = this->nextdoc;
1190
 
1191
                del_mtd_device(mtd);
1192
 
1193
                iounmap(this->virtadr);
1194
                kfree(this->chips);
1195
                kfree(mtd);
1196
        }
1197
}
1198
 
1199
module_exit(cleanup_doc2000);
1200
 
1201
MODULE_LICENSE("GPL");
1202
MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org> et al.");
1203
MODULE_DESCRIPTION("MTD driver for DiskOnChip 2000 and Millennium");
1204
 

powered by: WebSVN 2.1.0

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