PageRenderTime 39ms CodeModel.GetById 12ms app.highlight 22ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/staging/spectra/lld_mtd.c

https://bitbucket.org/slukk/jb-tsm-kernel-4.2
C | 683 lines | 449 code | 93 blank | 141 comment | 36 complexity | 909d62f6a5357191a8695d111c722e55 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  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"
 29u32 totalUsedBanks;
 30u32 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
 38static struct mtd_info *spectra_mtd;
 39static int mtddev = -1;
 40module_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*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
 49u16 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*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
 75int 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
 96u16 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*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
147u16 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
155void 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*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
167u16 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 = spectra_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*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
217u16 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*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
264u16 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 = spectra_mtd->read(spectra_mtd,
287					(Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
288					DeviceInfo.wPageDataSize, &retlen, read_data);
289		if (ret) {
290			printk(KERN_ERR "%s failed %d\n", __func__, ret);
291			return FAIL;
292		}
293		read_data += DeviceInfo.wPageDataSize;
294		Page++;
295		PageCount--;
296	}
297
298	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
299		       __FILE__, __LINE__, __func__);
300
301	return PASS;
302}
303
304#ifndef ELDORA
305/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
306* Function:     mtd_Read_Page_Main_Spare
307* Inputs:       Write Buffer
308*                       Address
309*                       Buffer size
310* Outputs:      PASS=0 (notice 0=ok here)
311* Description:          Read from flash main+spare area
312*
313*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
314u16 mtd_Read_Page_Main_Spare(u8 *read_data, u32 Block,
315				u16 Page, u16 PageCount)
316{
317	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
318		       __FILE__, __LINE__, __func__);
319
320	if (Block >= DeviceInfo.wTotalBlocks) {
321		printk(KERN_ERR "Read Page Main+Spare "
322		       "Error: Block Address too big\n");
323		return FAIL;
324	}
325
326	if (Page + PageCount > DeviceInfo.wPagesPerBlock) {
327		printk(KERN_ERR "Read Page Main+Spare "
328		       "Error: Page number %d+%d too big in block %d\n",
329		       Page, PageCount, Block);
330		return FAIL;
331	}
332
333	nand_dbg_print(NAND_DBG_DEBUG, "Read Page Main + Spare - "
334		       "No. of pages %u block %u start page %u\n",
335		       (unsigned int)PageCount,
336		       (unsigned int)Block, (unsigned int)Page);
337
338
339	while (PageCount) {
340		struct mtd_oob_ops ops;
341		int ret;
342
343		ops.mode = MTD_OOB_AUTO;
344		ops.datbuf = read_data;
345		ops.len = DeviceInfo.wPageDataSize;
346		ops.oobbuf = read_data + DeviceInfo.wPageDataSize + BTSIG_OFFSET;
347		ops.ooblen = BTSIG_BYTES;
348		ops.ooboffs = 0;
349
350		ret = spectra_mtd->read_oob(spectra_mtd,
351					    (Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
352					    &ops);
353		if (ret) {
354			printk(KERN_ERR "%s failed %d\n", __func__, ret);
355			return FAIL;
356		}
357		read_data += DeviceInfo.wPageSize;
358		Page++;
359		PageCount--;
360	}
361
362	return PASS;
363}
364
365/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
366* Function:     mtd_Write_Page_Main_Spare
367* Inputs:       Write buffer
368*                       address
369*                       buffer length
370* Outputs:      PASS=0 (notice 0=ok here)
371* Description:          Write the buffer to main+spare area of flash
372*
373*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
374u16 mtd_Write_Page_Main_Spare(u8 *write_data, u32 Block,
375				 u16 Page, u16 page_count)
376{
377	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
378		       __FILE__, __LINE__, __func__);
379
380	if (Block >= DeviceInfo.wTotalBlocks) {
381		printk(KERN_ERR "Write Page Main + Spare "
382		       "Error: Block Address too big\n");
383		return FAIL;
384	}
385
386	if (Page + page_count > DeviceInfo.wPagesPerBlock) {
387		printk(KERN_ERR "Write Page Main + Spare "
388		       "Error: Page number %d+%d too big in block %d\n",
389		       Page, page_count, Block);
390		WARN_ON(1);
391		return FAIL;
392	}
393
394	nand_dbg_print(NAND_DBG_DEBUG, "Write Page Main+Spare - "
395		       "No. of pages %u block %u start page %u\n",
396		       (unsigned int)page_count,
397		       (unsigned int)Block, (unsigned int)Page);
398
399	while (page_count) {
400		struct mtd_oob_ops ops;
401		int ret;
402
403		ops.mode = MTD_OOB_AUTO;
404		ops.datbuf = write_data;
405		ops.len = DeviceInfo.wPageDataSize;
406		ops.oobbuf = write_data + DeviceInfo.wPageDataSize + BTSIG_OFFSET;
407		ops.ooblen = BTSIG_BYTES;
408		ops.ooboffs = 0;
409
410		ret = spectra_mtd->write_oob(spectra_mtd,
411					     (Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
412					     &ops);
413		if (ret) {
414			printk(KERN_ERR "%s failed %d\n", __func__, ret);
415			return FAIL;
416		}
417		write_data += DeviceInfo.wPageSize;
418		Page++;
419		page_count--;
420	}
421
422	return PASS;
423}
424
425/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
426* Function:     mtd_Write_Page_Spare
427* Inputs:       Write buffer
428*                       Address
429*                       buffer size
430* Outputs:      PASS=0 (notice 0=ok here)
431* Description:          Write the buffer in the spare area
432*
433*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
434u16 mtd_Write_Page_Spare(u8 *write_data, u32 Block,
435			    u16 Page, u16 PageCount)
436{
437	WARN_ON(1);
438	return FAIL;
439}
440
441/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
442* Function:     mtd_Read_Page_Spare
443* Inputs:       Write Buffer
444*                       Address
445*                       Buffer size
446* Outputs:      PASS=0 (notice 0=ok here)
447* Description:          Read data from the spare area
448*
449*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
450u16 mtd_Read_Page_Spare(u8 *read_data, u32 Block,
451			   u16 Page, u16 PageCount)
452{
453	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
454		       __FILE__, __LINE__, __func__);
455
456	if (Block >= DeviceInfo.wTotalBlocks) {
457		printk(KERN_ERR "Read Page Spare "
458		       "Error: Block Address too big\n");
459		return FAIL;
460	}
461
462	if (Page + PageCount > DeviceInfo.wPagesPerBlock) {
463		printk(KERN_ERR "Read Page Spare "
464		       "Error: Page number too big\n");
465		return FAIL;
466	}
467
468	nand_dbg_print(NAND_DBG_DEBUG, "Read Page Spare- "
469		       "block %u page %u (%u pages)\n",
470		       (unsigned int)Block, (unsigned int)Page, PageCount);
471
472	while (PageCount) {
473		struct mtd_oob_ops ops;
474		int ret;
475
476		ops.mode = MTD_OOB_AUTO;
477		ops.datbuf = NULL;
478		ops.len = 0;
479		ops.oobbuf = read_data;
480		ops.ooblen = BTSIG_BYTES;
481		ops.ooboffs = 0;
482
483		ret = spectra_mtd->read_oob(spectra_mtd,
484					    (Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
485					    &ops);
486		if (ret) {
487			printk(KERN_ERR "%s failed %d\n", __func__, ret);
488			return FAIL;
489		}
490
491		read_data += DeviceInfo.wPageSize;
492		Page++;
493		PageCount--;
494	}
495
496	return PASS;
497}
498
499/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
500* Function:     mtd_Enable_Disable_Interrupts
501* Inputs:       enable or disable
502* Outputs:      none
503* Description:  NOP
504*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
505void mtd_Enable_Disable_Interrupts(u16 INT_ENABLE)
506{
507	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
508		       __FILE__, __LINE__, __func__);
509}
510
511u16 mtd_Get_Bad_Block(u32 block)
512{
513	return 0;
514}
515
516#if CMD_DMA
517/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
518* Support for CDMA functions
519************************************
520*       mtd_CDMA_Flash_Init
521*           CDMA_process_data command   (use LLD_CDMA)
522*           CDMA_MemCopy_CMD            (use LLD_CDMA)
523*       mtd_CDMA_execute all commands
524*       mtd_CDMA_Event_Status
525*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
526u16 mtd_CDMA_Flash_Init(void)
527{
528	u16 i;
529
530	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
531		       __FILE__, __LINE__, __func__);
532
533	for (i = 0; i < MAX_DESCS + MAX_CHANS; i++) {
534		PendingCMD[i].CMD = 0;
535		PendingCMD[i].Tag = 0;
536		PendingCMD[i].DataAddr = 0;
537		PendingCMD[i].Block = 0;
538		PendingCMD[i].Page = 0;
539		PendingCMD[i].PageCount = 0;
540		PendingCMD[i].DataDestAddr = 0;
541		PendingCMD[i].DataSrcAddr = 0;
542		PendingCMD[i].MemCopyByteCnt = 0;
543		PendingCMD[i].ChanSync[0] = 0;
544		PendingCMD[i].ChanSync[1] = 0;
545		PendingCMD[i].ChanSync[2] = 0;
546		PendingCMD[i].ChanSync[3] = 0;
547		PendingCMD[i].ChanSync[4] = 0;
548		PendingCMD[i].Status = 3;
549	}
550
551	return PASS;
552}
553
554static void mtd_isr(int irq, void *dev_id)
555{
556	/* TODO:  ... */
557}
558
559/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
560* Function:     CDMA_Execute_CMDs
561* Inputs:       tag_count:  the number of pending cmds to do
562* Outputs:      PASS/FAIL
563* Description:  execute each command in the pending CMD array
564*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
565u16 mtd_CDMA_Execute_CMDs(u16 tag_count)
566{
567	u16 i, j;
568	u8 CMD;		/* cmd parameter */
569	u8 *data;
570	u32 block;
571	u16 page;
572	u16 count;
573	u16 status = PASS;
574
575	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
576		       __FILE__, __LINE__, __func__);
577
578	nand_dbg_print(NAND_DBG_TRACE, "At start of Execute CMDs: "
579		       "Tag Count %u\n", tag_count);
580
581	for (i = 0; i < totalUsedBanks; i++) {
582		PendingCMD[i].CMD = DUMMY_CMD;
583		PendingCMD[i].Tag = 0xFF;
584		PendingCMD[i].Block =
585		    (DeviceInfo.wTotalBlocks / totalUsedBanks) * i;
586
587		for (j = 0; j <= MAX_CHANS; j++)
588			PendingCMD[i].ChanSync[j] = 0;
589	}
590
591	CDMA_Execute_CMDs(tag_count);
592
593#ifdef VERBOSE
594		print_pending_cmds(tag_count);
595#endif
596#if DEBUG_SYNC
597	}
598	debug_sync_cnt++;
599#endif
600
601	for (i = MAX_CHANS;
602	     i < tag_count + MAX_CHANS; i++) {
603		CMD = PendingCMD[i].CMD;
604		data = PendingCMD[i].DataAddr;
605		block = PendingCMD[i].Block;
606		page = PendingCMD[i].Page;
607		count = PendingCMD[i].PageCount;
608
609		switch (CMD) {
610		case ERASE_CMD:
611			mtd_Erase_Block(block);
612			PendingCMD[i].Status = PASS;
613			break;
614		case WRITE_MAIN_CMD:
615			mtd_Write_Page_Main(data, block, page, count);
616			PendingCMD[i].Status = PASS;
617			break;
618		case WRITE_MAIN_SPARE_CMD:
619			mtd_Write_Page_Main_Spare(data, block, page, count);
620			PendingCMD[i].Status = PASS;
621			break;
622		case READ_MAIN_CMD:
623			mtd_Read_Page_Main(data, block, page, count);
624			PendingCMD[i].Status = PASS;
625			break;
626		case MEMCOPY_CMD:
627			memcpy(PendingCMD[i].DataDestAddr,
628			       PendingCMD[i].DataSrcAddr,
629			       PendingCMD[i].MemCopyByteCnt);
630		case DUMMY_CMD:
631			PendingCMD[i].Status = PASS;
632			break;
633		default:
634			PendingCMD[i].Status = FAIL;
635			break;
636		}
637	}
638
639	/*
640	 * Temperory adding code to reset PendingCMD array for basic testing.
641	 * It should be done at the end of  event status function.
642	 */
643	for (i = tag_count + MAX_CHANS; i < MAX_DESCS; i++) {
644		PendingCMD[i].CMD = 0;
645		PendingCMD[i].Tag = 0;
646		PendingCMD[i].DataAddr = 0;
647		PendingCMD[i].Block = 0;
648		PendingCMD[i].Page = 0;
649		PendingCMD[i].PageCount = 0;
650		PendingCMD[i].DataDestAddr = 0;
651		PendingCMD[i].DataSrcAddr = 0;
652		PendingCMD[i].MemCopyByteCnt = 0;
653		PendingCMD[i].ChanSync[0] = 0;
654		PendingCMD[i].ChanSync[1] = 0;
655		PendingCMD[i].ChanSync[2] = 0;
656		PendingCMD[i].ChanSync[3] = 0;
657		PendingCMD[i].ChanSync[4] = 0;
658		PendingCMD[i].Status = CMD_NOT_DONE;
659	}
660
661	nand_dbg_print(NAND_DBG_TRACE, "At end of Execute CMDs.\n");
662
663	mtd_isr(0, 0); /* This is a null isr now. Need fill it in future */
664
665	return status;
666}
667
668/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
669* Function:     mtd_Event_Status
670* Inputs:       none
671* Outputs:      Event_Status code
672* Description:  This function can also be used to force errors
673*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
674u16 mtd_CDMA_Event_Status(void)
675{
676	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
677		       __FILE__, __LINE__, __func__);
678
679	return EVENT_PASS;
680}
681
682#endif /* CMD_DMA */
683#endif /* !ELDORA */