]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/staging/spectra/lld_mtd.c
mtd: introduce mtd_read interface
[mv-sheeva.git] / drivers / staging / spectra / lld_mtd.c
1 /*
2  * NAND Flash Controller Device Driver
3  * Copyright (c) 2009, Intel Corporation and its suppliers.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  */
19
20 #include <linux/fs.h>
21 #include <linux/slab.h>
22 #include <linux/mtd/mtd.h>
23 #include "flash.h"
24 #include "ffsdefs.h"
25 #include "lld_emu.h"
26 #include "lld.h"
27 #if CMD_DMA
28 #include "lld_cdma.h"
29 u32 totalUsedBanks;
30 u32 valid_banks[MAX_CHANS];
31 #endif
32
33 #define GLOB_LLD_PAGES           64
34 #define GLOB_LLD_PAGE_SIZE       (512+16)
35 #define GLOB_LLD_PAGE_DATA_SIZE  512
36 #define GLOB_LLD_BLOCKS          2048
37
38 static struct mtd_info *spectra_mtd;
39 static int mtddev = -1;
40 module_param(mtddev, int, 0);
41
42 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
43 * Function:     mtd_Flash_Init
44 * Inputs:       none
45 * Outputs:      PASS=0 (notice 0=ok here)
46 * Description:  Creates & initializes the flash RAM array.
47 *
48 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
49 u16 mtd_Flash_Init(void)
50 {
51         if (mtddev == -1) {
52                 printk(KERN_ERR "No MTD device specified. Give mtddev parameter\n");
53                 return FAIL;
54         }
55
56         spectra_mtd = get_mtd_device(NULL, mtddev);
57         if (!spectra_mtd) {
58                 printk(KERN_ERR "Failed to obtain MTD device #%d\n", mtddev);
59                 return FAIL;
60         }
61
62         nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
63                        __FILE__, __LINE__, __func__);
64
65         return PASS;
66 }
67
68 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
69 * Function:     mtd_Flash_Release
70 * Inputs:       none
71 * Outputs:      PASS=0 (notice 0=ok here)
72 * Description:          Releases the flash.
73 *
74 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
75 int mtd_Flash_Release(void)
76 {
77         nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
78                        __FILE__, __LINE__, __func__);
79         if (!spectra_mtd)
80                 return PASS;
81
82         put_mtd_device(spectra_mtd);
83         spectra_mtd = NULL;
84
85         return PASS;
86 }
87
88 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
89 * Function:     mtd_Read_Device_ID
90 * Inputs:       none
91 * Outputs:      PASS=1 FAIL=0
92 * Description:  Reads the info from the controller registers.
93 *               Sets up DeviceInfo structure with device parameters
94 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
95
96 u16 mtd_Read_Device_ID(void)
97 {
98         uint64_t tmp;
99         nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
100                        __FILE__, __LINE__, __func__);
101
102         if (!spectra_mtd)
103                 return FAIL;
104
105         DeviceInfo.wDeviceMaker = 0;
106         DeviceInfo.wDeviceType = 8;
107         DeviceInfo.wSpectraStartBlock = SPECTRA_START_BLOCK;
108         tmp = spectra_mtd->size;
109         do_div(tmp, spectra_mtd->erasesize);
110         DeviceInfo.wTotalBlocks = tmp;
111         DeviceInfo.wSpectraEndBlock = DeviceInfo.wTotalBlocks - 1;
112         DeviceInfo.wPagesPerBlock = spectra_mtd->erasesize / spectra_mtd->writesize;
113         DeviceInfo.wPageSize = spectra_mtd->writesize + spectra_mtd->oobsize;
114         DeviceInfo.wPageDataSize = spectra_mtd->writesize;
115         DeviceInfo.wPageSpareSize = spectra_mtd->oobsize;
116         DeviceInfo.wBlockSize = DeviceInfo.wPageSize * DeviceInfo.wPagesPerBlock;
117         DeviceInfo.wBlockDataSize = DeviceInfo.wPageDataSize * DeviceInfo.wPagesPerBlock;
118         DeviceInfo.wDataBlockNum = (u32) (DeviceInfo.wSpectraEndBlock -
119                                                 DeviceInfo.wSpectraStartBlock
120                                                 + 1);
121         DeviceInfo.MLCDevice = 0;//spectra_mtd->celltype & NAND_CI_CELLTYPE_MSK;
122         DeviceInfo.nBitsInPageNumber =
123                 (u8)GLOB_Calc_Used_Bits(DeviceInfo.wPagesPerBlock);
124         DeviceInfo.nBitsInPageDataSize =
125                 (u8)GLOB_Calc_Used_Bits(DeviceInfo.wPageDataSize);
126         DeviceInfo.nBitsInBlockDataSize =
127                 (u8)GLOB_Calc_Used_Bits(DeviceInfo.wBlockDataSize);
128
129 #if CMD_DMA
130         totalUsedBanks = 4;
131         valid_banks[0] = 1;
132         valid_banks[1] = 1;
133         valid_banks[2] = 1;
134         valid_banks[3] = 1;
135 #endif
136
137         return PASS;
138 }
139
140 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
141 * Function:     mtd_Flash_Reset
142 * Inputs:       none
143 * Outputs:      PASS=0 (notice 0=ok here)
144 * Description:          Reset the flash
145 *
146 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
147 u16 mtd_Flash_Reset(void)
148 {
149         nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
150                        __FILE__, __LINE__, __func__);
151
152         return PASS;
153 }
154
155 void erase_callback(struct erase_info *e)
156 {
157         complete((void *)e->priv);
158 }
159
160 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
161 * Function:     mtd_Erase_Block
162 * Inputs:       Address
163 * Outputs:      PASS=0 (notice 0=ok here)
164 * Description:          Erase a block
165 *
166 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
167 u16 mtd_Erase_Block(u32 block_add)
168 {
169         struct erase_info erase;
170         DECLARE_COMPLETION_ONSTACK(comp);
171         int ret;
172
173         nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
174                        __FILE__, __LINE__, __func__);
175
176         if (block_add >= DeviceInfo.wTotalBlocks) {
177                 printk(KERN_ERR "mtd_Erase_Block error! "
178                        "Too big block address: %d\n", block_add);
179                 return FAIL;
180         }
181
182         nand_dbg_print(NAND_DBG_DEBUG, "Erasing block %d\n",
183                 (int)block_add);
184
185         erase.mtd = spectra_mtd;
186         erase.callback = erase_callback;
187         erase.addr = block_add * spectra_mtd->erasesize;
188         erase.len = spectra_mtd->erasesize;
189         erase.priv = (unsigned long)&comp;
190
191         ret = mtd_erase(spectra_mtd, &erase);
192         if (!ret) {
193                 wait_for_completion(&comp);
194                 if (erase.state != MTD_ERASE_DONE)
195                         ret = -EIO;
196         }
197         if (ret) {
198                 printk(KERN_WARNING "mtd_Erase_Block error! "
199                        "erase of region [0x%llx, 0x%llx] failed\n",
200                        erase.addr, erase.len);
201                 return FAIL;
202         }
203
204         return PASS;
205 }
206
207 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
208 * Function:     mtd_Write_Page_Main
209 * Inputs:       Write buffer address pointer
210 *               Block number
211 *               Page  number
212 *               Number of pages to process
213 * Outputs:      PASS=0 (notice 0=ok here)
214 * Description:  Write the data in the buffer to main area of flash
215 *
216 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
217 u16 mtd_Write_Page_Main(u8 *write_data, u32 Block,
218                            u16 Page, u16 PageCount)
219 {
220         size_t retlen;
221         int ret = 0;
222
223         if (Block >= DeviceInfo.wTotalBlocks)
224                 return FAIL;
225
226         if (Page + PageCount > DeviceInfo.wPagesPerBlock)
227                 return FAIL;
228
229         nand_dbg_print(NAND_DBG_DEBUG, "mtd_Write_Page_Main: "
230                        "lba %u Page %u PageCount %u\n",
231                        (unsigned int)Block,
232                        (unsigned int)Page, (unsigned int)PageCount);
233
234
235         while (PageCount) {
236                 ret = spectra_mtd->write(spectra_mtd,
237                                          (Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
238                                          DeviceInfo.wPageDataSize, &retlen, write_data);
239                 if (ret) {
240                         printk(KERN_ERR "%s failed %d\n", __func__, ret);
241                         return FAIL;
242                 }
243                 write_data += DeviceInfo.wPageDataSize;
244                 Page++;
245                 PageCount--;
246         }
247
248         nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
249                        __FILE__, __LINE__, __func__);
250
251         return PASS;
252 }
253
254 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
255 * Function:     mtd_Read_Page_Main
256 * Inputs:       Read buffer address pointer
257 *               Block number
258 *               Page  number
259 *               Number of pages to process
260 * Outputs:      PASS=0 (notice 0=ok here)
261 * Description:  Read the data from the flash main area to the buffer
262 *
263 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
264 u16 mtd_Read_Page_Main(u8 *read_data, u32 Block,
265                           u16 Page, u16 PageCount)
266 {
267         size_t retlen;
268         int ret = 0;
269
270         nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
271                        __FILE__, __LINE__, __func__);
272
273         if (Block >= DeviceInfo.wTotalBlocks)
274                 return FAIL;
275
276         if (Page + PageCount > DeviceInfo.wPagesPerBlock)
277                 return FAIL;
278
279         nand_dbg_print(NAND_DBG_DEBUG, "mtd_Read_Page_Main: "
280                        "lba %u Page %u PageCount %u\n",
281                        (unsigned int)Block,
282                        (unsigned int)Page, (unsigned int)PageCount);
283
284
285         while (PageCount) {
286                 ret = mtd_read(spectra_mtd,
287                                (Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
288                                DeviceInfo.wPageDataSize,
289                                &retlen,
290                                read_data);
291                 if (ret) {
292                         printk(KERN_ERR "%s failed %d\n", __func__, ret);
293                         return FAIL;
294                 }
295                 read_data += DeviceInfo.wPageDataSize;
296                 Page++;
297                 PageCount--;
298         }
299
300         nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
301                        __FILE__, __LINE__, __func__);
302
303         return PASS;
304 }
305
306 #ifndef ELDORA
307 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
308 * Function:     mtd_Read_Page_Main_Spare
309 * Inputs:       Write Buffer
310 *                       Address
311 *                       Buffer size
312 * Outputs:      PASS=0 (notice 0=ok here)
313 * Description:          Read from flash main+spare area
314 *
315 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
316 u16 mtd_Read_Page_Main_Spare(u8 *read_data, u32 Block,
317                                 u16 Page, u16 PageCount)
318 {
319         nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
320                        __FILE__, __LINE__, __func__);
321
322         if (Block >= DeviceInfo.wTotalBlocks) {
323                 printk(KERN_ERR "Read Page Main+Spare "
324                        "Error: Block Address too big\n");
325                 return FAIL;
326         }
327
328         if (Page + PageCount > DeviceInfo.wPagesPerBlock) {
329                 printk(KERN_ERR "Read Page Main+Spare "
330                        "Error: Page number %d+%d too big in block %d\n",
331                        Page, PageCount, Block);
332                 return FAIL;
333         }
334
335         nand_dbg_print(NAND_DBG_DEBUG, "Read Page Main + Spare - "
336                        "No. of pages %u block %u start page %u\n",
337                        (unsigned int)PageCount,
338                        (unsigned int)Block, (unsigned int)Page);
339
340
341         while (PageCount) {
342                 struct mtd_oob_ops ops;
343                 int ret;
344
345                 ops.mode = MTD_OPS_AUTO_OOB;
346                 ops.datbuf = read_data;
347                 ops.len = DeviceInfo.wPageDataSize;
348                 ops.oobbuf = read_data + DeviceInfo.wPageDataSize + BTSIG_OFFSET;
349                 ops.ooblen = BTSIG_BYTES;
350                 ops.ooboffs = 0;
351
352                 ret = spectra_mtd->read_oob(spectra_mtd,
353                                             (Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
354                                             &ops);
355                 if (ret) {
356                         printk(KERN_ERR "%s failed %d\n", __func__, ret);
357                         return FAIL;
358                 }
359                 read_data += DeviceInfo.wPageSize;
360                 Page++;
361                 PageCount--;
362         }
363
364         return PASS;
365 }
366
367 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
368 * Function:     mtd_Write_Page_Main_Spare
369 * Inputs:       Write buffer
370 *                       address
371 *                       buffer length
372 * Outputs:      PASS=0 (notice 0=ok here)
373 * Description:          Write the buffer to main+spare area of flash
374 *
375 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
376 u16 mtd_Write_Page_Main_Spare(u8 *write_data, u32 Block,
377                                  u16 Page, u16 page_count)
378 {
379         nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
380                        __FILE__, __LINE__, __func__);
381
382         if (Block >= DeviceInfo.wTotalBlocks) {
383                 printk(KERN_ERR "Write Page Main + Spare "
384                        "Error: Block Address too big\n");
385                 return FAIL;
386         }
387
388         if (Page + page_count > DeviceInfo.wPagesPerBlock) {
389                 printk(KERN_ERR "Write Page Main + Spare "
390                        "Error: Page number %d+%d too big in block %d\n",
391                        Page, page_count, Block);
392                 WARN_ON(1);
393                 return FAIL;
394         }
395
396         nand_dbg_print(NAND_DBG_DEBUG, "Write Page Main+Spare - "
397                        "No. of pages %u block %u start page %u\n",
398                        (unsigned int)page_count,
399                        (unsigned int)Block, (unsigned int)Page);
400
401         while (page_count) {
402                 struct mtd_oob_ops ops;
403                 int ret;
404
405                 ops.mode = MTD_OPS_AUTO_OOB;
406                 ops.datbuf = write_data;
407                 ops.len = DeviceInfo.wPageDataSize;
408                 ops.oobbuf = write_data + DeviceInfo.wPageDataSize + BTSIG_OFFSET;
409                 ops.ooblen = BTSIG_BYTES;
410                 ops.ooboffs = 0;
411
412                 ret = spectra_mtd->write_oob(spectra_mtd,
413                                              (Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
414                                              &ops);
415                 if (ret) {
416                         printk(KERN_ERR "%s failed %d\n", __func__, ret);
417                         return FAIL;
418                 }
419                 write_data += DeviceInfo.wPageSize;
420                 Page++;
421                 page_count--;
422         }
423
424         return PASS;
425 }
426
427 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
428 * Function:     mtd_Write_Page_Spare
429 * Inputs:       Write buffer
430 *                       Address
431 *                       buffer size
432 * Outputs:      PASS=0 (notice 0=ok here)
433 * Description:          Write the buffer in the spare area
434 *
435 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
436 u16 mtd_Write_Page_Spare(u8 *write_data, u32 Block,
437                             u16 Page, u16 PageCount)
438 {
439         WARN_ON(1);
440         return FAIL;
441 }
442
443 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
444 * Function:     mtd_Read_Page_Spare
445 * Inputs:       Write Buffer
446 *                       Address
447 *                       Buffer size
448 * Outputs:      PASS=0 (notice 0=ok here)
449 * Description:          Read data from the spare area
450 *
451 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
452 u16 mtd_Read_Page_Spare(u8 *read_data, u32 Block,
453                            u16 Page, u16 PageCount)
454 {
455         nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
456                        __FILE__, __LINE__, __func__);
457
458         if (Block >= DeviceInfo.wTotalBlocks) {
459                 printk(KERN_ERR "Read Page Spare "
460                        "Error: Block Address too big\n");
461                 return FAIL;
462         }
463
464         if (Page + PageCount > DeviceInfo.wPagesPerBlock) {
465                 printk(KERN_ERR "Read Page Spare "
466                        "Error: Page number too big\n");
467                 return FAIL;
468         }
469
470         nand_dbg_print(NAND_DBG_DEBUG, "Read Page Spare- "
471                        "block %u page %u (%u pages)\n",
472                        (unsigned int)Block, (unsigned int)Page, PageCount);
473
474         while (PageCount) {
475                 struct mtd_oob_ops ops;
476                 int ret;
477
478                 ops.mode = MTD_OPS_AUTO_OOB;
479                 ops.datbuf = NULL;
480                 ops.len = 0;
481                 ops.oobbuf = read_data;
482                 ops.ooblen = BTSIG_BYTES;
483                 ops.ooboffs = 0;
484
485                 ret = spectra_mtd->read_oob(spectra_mtd,
486                                             (Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
487                                             &ops);
488                 if (ret) {
489                         printk(KERN_ERR "%s failed %d\n", __func__, ret);
490                         return FAIL;
491                 }
492
493                 read_data += DeviceInfo.wPageSize;
494                 Page++;
495                 PageCount--;
496         }
497
498         return PASS;
499 }
500
501 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
502 * Function:     mtd_Enable_Disable_Interrupts
503 * Inputs:       enable or disable
504 * Outputs:      none
505 * Description:  NOP
506 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
507 void mtd_Enable_Disable_Interrupts(u16 INT_ENABLE)
508 {
509         nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
510                        __FILE__, __LINE__, __func__);
511 }
512
513 u16 mtd_Get_Bad_Block(u32 block)
514 {
515         return 0;
516 }
517
518 #if CMD_DMA
519 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
520 * Support for CDMA functions
521 ************************************
522 *       mtd_CDMA_Flash_Init
523 *           CDMA_process_data command   (use LLD_CDMA)
524 *           CDMA_MemCopy_CMD            (use LLD_CDMA)
525 *       mtd_CDMA_execute all commands
526 *       mtd_CDMA_Event_Status
527 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
528 u16 mtd_CDMA_Flash_Init(void)
529 {
530         u16 i;
531
532         nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
533                        __FILE__, __LINE__, __func__);
534
535         for (i = 0; i < MAX_DESCS + MAX_CHANS; i++) {
536                 PendingCMD[i].CMD = 0;
537                 PendingCMD[i].Tag = 0;
538                 PendingCMD[i].DataAddr = 0;
539                 PendingCMD[i].Block = 0;
540                 PendingCMD[i].Page = 0;
541                 PendingCMD[i].PageCount = 0;
542                 PendingCMD[i].DataDestAddr = 0;
543                 PendingCMD[i].DataSrcAddr = 0;
544                 PendingCMD[i].MemCopyByteCnt = 0;
545                 PendingCMD[i].ChanSync[0] = 0;
546                 PendingCMD[i].ChanSync[1] = 0;
547                 PendingCMD[i].ChanSync[2] = 0;
548                 PendingCMD[i].ChanSync[3] = 0;
549                 PendingCMD[i].ChanSync[4] = 0;
550                 PendingCMD[i].Status = 3;
551         }
552
553         return PASS;
554 }
555
556 static void mtd_isr(int irq, void *dev_id)
557 {
558         /* TODO:  ... */
559 }
560
561 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
562 * Function:     CDMA_Execute_CMDs
563 * Inputs:       tag_count:  the number of pending cmds to do
564 * Outputs:      PASS/FAIL
565 * Description:  execute each command in the pending CMD array
566 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
567 u16 mtd_CDMA_Execute_CMDs(u16 tag_count)
568 {
569         u16 i, j;
570         u8 CMD;         /* cmd parameter */
571         u8 *data;
572         u32 block;
573         u16 page;
574         u16 count;
575         u16 status = PASS;
576
577         nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
578                        __FILE__, __LINE__, __func__);
579
580         nand_dbg_print(NAND_DBG_TRACE, "At start of Execute CMDs: "
581                        "Tag Count %u\n", tag_count);
582
583         for (i = 0; i < totalUsedBanks; i++) {
584                 PendingCMD[i].CMD = DUMMY_CMD;
585                 PendingCMD[i].Tag = 0xFF;
586                 PendingCMD[i].Block =
587                     (DeviceInfo.wTotalBlocks / totalUsedBanks) * i;
588
589                 for (j = 0; j <= MAX_CHANS; j++)
590                         PendingCMD[i].ChanSync[j] = 0;
591         }
592
593         CDMA_Execute_CMDs(tag_count);
594
595 #ifdef VERBOSE
596                 print_pending_cmds(tag_count);
597 #endif
598 #if DEBUG_SYNC
599         }
600         debug_sync_cnt++;
601 #endif
602
603         for (i = MAX_CHANS;
604              i < tag_count + MAX_CHANS; i++) {
605                 CMD = PendingCMD[i].CMD;
606                 data = PendingCMD[i].DataAddr;
607                 block = PendingCMD[i].Block;
608                 page = PendingCMD[i].Page;
609                 count = PendingCMD[i].PageCount;
610
611                 switch (CMD) {
612                 case ERASE_CMD:
613                         mtd_Erase_Block(block);
614                         PendingCMD[i].Status = PASS;
615                         break;
616                 case WRITE_MAIN_CMD:
617                         mtd_Write_Page_Main(data, block, page, count);
618                         PendingCMD[i].Status = PASS;
619                         break;
620                 case WRITE_MAIN_SPARE_CMD:
621                         mtd_Write_Page_Main_Spare(data, block, page, count);
622                         PendingCMD[i].Status = PASS;
623                         break;
624                 case READ_MAIN_CMD:
625                         mtd_Read_Page_Main(data, block, page, count);
626                         PendingCMD[i].Status = PASS;
627                         break;
628                 case MEMCOPY_CMD:
629                         memcpy(PendingCMD[i].DataDestAddr,
630                                PendingCMD[i].DataSrcAddr,
631                                PendingCMD[i].MemCopyByteCnt);
632                 case DUMMY_CMD:
633                         PendingCMD[i].Status = PASS;
634                         break;
635                 default:
636                         PendingCMD[i].Status = FAIL;
637                         break;
638                 }
639         }
640
641         /*
642          * Temperory adding code to reset PendingCMD array for basic testing.
643          * It should be done at the end of  event status function.
644          */
645         for (i = tag_count + MAX_CHANS; i < MAX_DESCS; i++) {
646                 PendingCMD[i].CMD = 0;
647                 PendingCMD[i].Tag = 0;
648                 PendingCMD[i].DataAddr = 0;
649                 PendingCMD[i].Block = 0;
650                 PendingCMD[i].Page = 0;
651                 PendingCMD[i].PageCount = 0;
652                 PendingCMD[i].DataDestAddr = 0;
653                 PendingCMD[i].DataSrcAddr = 0;
654                 PendingCMD[i].MemCopyByteCnt = 0;
655                 PendingCMD[i].ChanSync[0] = 0;
656                 PendingCMD[i].ChanSync[1] = 0;
657                 PendingCMD[i].ChanSync[2] = 0;
658                 PendingCMD[i].ChanSync[3] = 0;
659                 PendingCMD[i].ChanSync[4] = 0;
660                 PendingCMD[i].Status = CMD_NOT_DONE;
661         }
662
663         nand_dbg_print(NAND_DBG_TRACE, "At end of Execute CMDs.\n");
664
665         mtd_isr(0, 0); /* This is a null isr now. Need fill it in future */
666
667         return status;
668 }
669
670 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
671 * Function:     mtd_Event_Status
672 * Inputs:       none
673 * Outputs:      Event_Status code
674 * Description:  This function can also be used to force errors
675 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
676 u16 mtd_CDMA_Event_Status(void)
677 {
678         nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
679                        __FILE__, __LINE__, __func__);
680
681         return EVENT_PASS;
682 }
683
684 #endif /* CMD_DMA */
685 #endif /* !ELDORA */