2 * NAND Flash Controller Device Driver
3 * Copyright (c) 2009, Intel Corporation and its suppliers.
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.
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
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.
21 #include <linux/slab.h>
30 #define GLOB_LLD_PAGES 64
31 #define GLOB_LLD_PAGE_SIZE (512+16)
32 #define GLOB_LLD_PAGE_DATA_SIZE 512
33 #define GLOB_LLD_BLOCKS 2048
35 #if (CMD_DMA && FLASH_EMU)
38 u32 valid_banks
[MAX_CHANS
];
41 #if FLASH_EMU /* This is for entire module */
43 static u8
*flash_memory
[GLOB_LLD_BLOCKS
* GLOB_LLD_PAGES
];
45 /* Read nand emu file and then fill it's content to flash_memory */
46 int emu_load_file_to_mem(void)
49 struct file
*nef_filp
= NULL
;
50 struct inode
*inode
= NULL
;
52 loff_t tmp_file_offset
, file_offset
;
56 nand_dbg_print(NAND_DBG_TRACE
, "%s, Line %d, Function: %s\n",
57 __FILE__
, __LINE__
, __func__
);
62 nef_filp
= filp_open("/root/nand_emu_file", O_RDWR
| O_LARGEFILE
, 0);
63 if (IS_ERR(nef_filp
)) {
64 printk(KERN_ERR
"filp_open error: "
65 "Unable to open nand emu file!\n");
66 return PTR_ERR(nef_filp
);
69 if (nef_filp
->f_path
.dentry
) {
70 inode
= nef_filp
->f_path
.dentry
->d_inode
;
72 printk(KERN_ERR
"Can not get valid inode!\n");
76 nef_size
= i_size_read(inode
->i_mapping
->host
);
78 printk(KERN_ERR
"Invalid nand emu file size: "
79 "0x%llx\n", nef_size
);
82 nand_dbg_print(NAND_DBG_DEBUG
, "nand emu file size: %lld\n",
87 for (i
= 0; i
< GLOB_LLD_BLOCKS
* GLOB_LLD_PAGES
; i
++) {
88 tmp_file_offset
= file_offset
;
89 nread
= vfs_read(nef_filp
,
90 (char __user
*)flash_memory
[i
],
91 GLOB_LLD_PAGE_SIZE
, &tmp_file_offset
);
92 if (nread
< GLOB_LLD_PAGE_SIZE
) {
93 printk(KERN_ERR
"%s, Line %d - "
94 "nand emu file partial read: "
95 "%d bytes\n", __FILE__
, __LINE__
, (int)nread
);
98 file_offset
+= GLOB_LLD_PAGE_SIZE
;
103 filp_close(nef_filp
, current
->files
);
108 /* Write contents of flash_memory to nand emu file */
109 int emu_write_mem_to_file(void)
112 struct file
*nef_filp
= NULL
;
113 struct inode
*inode
= NULL
;
115 loff_t tmp_file_offset
, file_offset
;
119 nand_dbg_print(NAND_DBG_TRACE
, "%s, Line %d, Function: %s\n",
120 __FILE__
, __LINE__
, __func__
);
125 nef_filp
= filp_open("/root/nand_emu_file", O_RDWR
| O_LARGEFILE
, 0);
126 if (IS_ERR(nef_filp
)) {
127 printk(KERN_ERR
"filp_open error: "
128 "Unable to open nand emu file!\n");
129 return PTR_ERR(nef_filp
);
132 if (nef_filp
->f_path
.dentry
) {
133 inode
= nef_filp
->f_path
.dentry
->d_inode
;
135 printk(KERN_ERR
"Invalid " "nef_filp->f_path.dentry value!\n");
139 nef_size
= i_size_read(inode
->i_mapping
->host
);
141 printk(KERN_ERR
"Invalid "
142 "nand emu file size: 0x%llx\n", nef_size
);
145 nand_dbg_print(NAND_DBG_DEBUG
, "nand emu file size: "
150 for (i
= 0; i
< GLOB_LLD_BLOCKS
* GLOB_LLD_PAGES
; i
++) {
151 tmp_file_offset
= file_offset
;
152 nwritten
= vfs_write(nef_filp
,
153 (char __user
*)flash_memory
[i
],
154 GLOB_LLD_PAGE_SIZE
, &tmp_file_offset
);
155 if (nwritten
< GLOB_LLD_PAGE_SIZE
) {
156 printk(KERN_ERR
"%s, Line %d - "
157 "nand emu file partial write: "
158 "%d bytes\n", __FILE__
, __LINE__
, (int)nwritten
);
161 file_offset
+= GLOB_LLD_PAGE_SIZE
;
166 filp_close(nef_filp
, current
->files
);
171 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
172 * Function: emu_Flash_Init
174 * Outputs: PASS=0 (notice 0=ok here)
175 * Description: Creates & initializes the flash RAM array.
177 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
178 u16
emu_Flash_Init(void)
182 nand_dbg_print(NAND_DBG_TRACE
, "%s, Line %d, Function: %s\n",
183 __FILE__
, __LINE__
, __func__
);
185 flash_memory
[0] = (u8
*)vmalloc(GLOB_LLD_PAGE_SIZE
*
189 if (!flash_memory
[0]) {
190 printk(KERN_ERR
"Fail to allocate memory "
191 "for nand emulator!\n");
195 memset((char *)(flash_memory
[0]), 0xFF,
196 GLOB_LLD_PAGE_SIZE
* GLOB_LLD_BLOCKS
* GLOB_LLD_PAGES
*
199 for (i
= 1; i
< GLOB_LLD_BLOCKS
* GLOB_LLD_PAGES
; i
++)
200 flash_memory
[i
] = flash_memory
[i
- 1] + GLOB_LLD_PAGE_SIZE
;
202 emu_load_file_to_mem(); /* Load nand emu file to mem */
207 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
208 * Function: emu_Flash_Release
210 * Outputs: PASS=0 (notice 0=ok here)
211 * Description: Releases the flash.
213 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
214 int emu_Flash_Release(void)
216 nand_dbg_print(NAND_DBG_TRACE
, "%s, Line %d, Function: %s\n",
217 __FILE__
, __LINE__
, __func__
);
219 emu_write_mem_to_file(); /* Write back mem to nand emu file */
221 vfree(flash_memory
[0]);
225 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
226 * Function: emu_Read_Device_ID
228 * Outputs: PASS=1 FAIL=0
229 * Description: Reads the info from the controller registers.
230 * Sets up DeviceInfo structure with device parameters
231 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
233 u16
emu_Read_Device_ID(void)
235 nand_dbg_print(NAND_DBG_TRACE
, "%s, Line %d, Function: %s\n",
236 __FILE__
, __LINE__
, __func__
);
238 DeviceInfo
.wDeviceMaker
= 0;
239 DeviceInfo
.wDeviceType
= 8;
240 DeviceInfo
.wSpectraStartBlock
= 36;
241 DeviceInfo
.wSpectraEndBlock
= GLOB_LLD_BLOCKS
- 1;
242 DeviceInfo
.wTotalBlocks
= GLOB_LLD_BLOCKS
;
243 DeviceInfo
.wPagesPerBlock
= GLOB_LLD_PAGES
;
244 DeviceInfo
.wPageSize
= GLOB_LLD_PAGE_SIZE
;
245 DeviceInfo
.wPageDataSize
= GLOB_LLD_PAGE_DATA_SIZE
;
246 DeviceInfo
.wPageSpareSize
= GLOB_LLD_PAGE_SIZE
-
247 GLOB_LLD_PAGE_DATA_SIZE
;
248 DeviceInfo
.wBlockSize
= DeviceInfo
.wPageSize
* GLOB_LLD_PAGES
;
249 DeviceInfo
.wBlockDataSize
= DeviceInfo
.wPageDataSize
* GLOB_LLD_PAGES
;
250 DeviceInfo
.wDataBlockNum
= (u32
) (DeviceInfo
.wSpectraEndBlock
-
251 DeviceInfo
.wSpectraStartBlock
253 DeviceInfo
.MLCDevice
= 1; /* Emulate MLC device */
254 DeviceInfo
.nBitsInPageNumber
=
255 (u8
)GLOB_Calc_Used_Bits(DeviceInfo
.wPagesPerBlock
);
256 DeviceInfo
.nBitsInPageDataSize
=
257 (u8
)GLOB_Calc_Used_Bits(DeviceInfo
.wPageDataSize
);
258 DeviceInfo
.nBitsInBlockDataSize
=
259 (u8
)GLOB_Calc_Used_Bits(DeviceInfo
.wBlockDataSize
);
272 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
273 * Function: emu_Flash_Reset
275 * Outputs: PASS=0 (notice 0=ok here)
276 * Description: Reset the flash
278 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
279 u16
emu_Flash_Reset(void)
281 nand_dbg_print(NAND_DBG_TRACE
, "%s, Line %d, Function: %s\n",
282 __FILE__
, __LINE__
, __func__
);
287 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
288 * Function: emu_Erase_Block
290 * Outputs: PASS=0 (notice 0=ok here)
291 * Description: Erase a block
293 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
294 u16
emu_Erase_Block(u32 block_add
)
298 nand_dbg_print(NAND_DBG_TRACE
, "%s, Line %d, Function: %s\n",
299 __FILE__
, __LINE__
, __func__
);
301 if (block_add
>= DeviceInfo
.wTotalBlocks
) {
302 printk(KERN_ERR
"emu_Erase_Block error! "
303 "Too big block address: %d\n", block_add
);
307 nand_dbg_print(NAND_DBG_DEBUG
, "Erasing block %d\n",
310 for (i
= block_add
* GLOB_LLD_PAGES
;
311 i
< ((block_add
+ 1) * GLOB_LLD_PAGES
); i
++) {
312 if (flash_memory
[i
]) {
313 memset((u8
*)(flash_memory
[i
]), 0xFF,
314 DeviceInfo
.wPageSize
* sizeof(u8
));
321 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
322 * Function: emu_Write_Page_Main
323 * Inputs: Write buffer address pointer
326 * Number of pages to process
327 * Outputs: PASS=0 (notice 0=ok here)
328 * Description: Write the data in the buffer to main area of flash
330 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
331 u16
emu_Write_Page_Main(u8
*write_data
, u32 Block
,
332 u16 Page
, u16 PageCount
)
336 nand_dbg_print(NAND_DBG_TRACE
, "%s, Line %d, Function: %s\n",
337 __FILE__
, __LINE__
, __func__
);
339 if (Block
>= DeviceInfo
.wTotalBlocks
)
342 if (Page
+ PageCount
> DeviceInfo
.wPagesPerBlock
)
345 nand_dbg_print(NAND_DBG_DEBUG
, "emu_Write_Page_Main: "
346 "lba %u Page %u PageCount %u\n",
348 (unsigned int)Page
, (unsigned int)PageCount
);
350 for (i
= 0; i
< PageCount
; i
++) {
351 if (NULL
== flash_memory
[Block
* GLOB_LLD_PAGES
+ Page
]) {
352 printk(KERN_ERR
"Run out of memory\n");
355 memcpy((u8
*) (flash_memory
[Block
* GLOB_LLD_PAGES
+ Page
]),
356 write_data
, DeviceInfo
.wPageDataSize
);
357 write_data
+= DeviceInfo
.wPageDataSize
;
364 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
365 * Function: emu_Read_Page_Main
366 * Inputs: Read buffer address pointer
369 * Number of pages to process
370 * Outputs: PASS=0 (notice 0=ok here)
371 * Description: Read the data from the flash main area to the buffer
373 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
374 u16
emu_Read_Page_Main(u8
*read_data
, u32 Block
,
375 u16 Page
, u16 PageCount
)
379 nand_dbg_print(NAND_DBG_TRACE
, "%s, Line %d, Function: %s\n",
380 __FILE__
, __LINE__
, __func__
);
382 if (Block
>= DeviceInfo
.wTotalBlocks
)
385 if (Page
+ PageCount
> DeviceInfo
.wPagesPerBlock
)
388 nand_dbg_print(NAND_DBG_DEBUG
, "emu_Read_Page_Main: "
389 "lba %u Page %u PageCount %u\n",
391 (unsigned int)Page
, (unsigned int)PageCount
);
393 for (i
= 0; i
< PageCount
; i
++) {
394 if (NULL
== flash_memory
[Block
* GLOB_LLD_PAGES
+ Page
]) {
395 memset(read_data
, 0xFF, DeviceInfo
.wPageDataSize
);
398 (u8
*) (flash_memory
[Block
* GLOB_LLD_PAGES
400 DeviceInfo
.wPageDataSize
);
402 read_data
+= DeviceInfo
.wPageDataSize
;
410 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
411 * Function: emu_Read_Page_Main_Spare
412 * Inputs: Write Buffer
415 * Outputs: PASS=0 (notice 0=ok here)
416 * Description: Read from flash main+spare area
418 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
419 u16
emu_Read_Page_Main_Spare(u8
*read_data
, u32 Block
,
420 u16 Page
, u16 PageCount
)
424 nand_dbg_print(NAND_DBG_TRACE
, "%s, Line %d, Function: %s\n",
425 __FILE__
, __LINE__
, __func__
);
427 if (Block
>= DeviceInfo
.wTotalBlocks
) {
428 printk(KERN_ERR
"Read Page Main+Spare "
429 "Error: Block Address too big\n");
433 if (Page
+ PageCount
> DeviceInfo
.wPagesPerBlock
) {
434 printk(KERN_ERR
"Read Page Main+Spare "
435 "Error: Page number too big\n");
439 nand_dbg_print(NAND_DBG_DEBUG
, "Read Page Main + Spare - "
440 "No. of pages %u block %u start page %u\n",
441 (unsigned int)PageCount
,
442 (unsigned int)Block
, (unsigned int)Page
);
444 for (i
= 0; i
< PageCount
; i
++) {
445 if (NULL
== flash_memory
[Block
* GLOB_LLD_PAGES
+ Page
]) {
446 memset(read_data
, 0xFF, DeviceInfo
.wPageSize
);
448 memcpy(read_data
, (u8
*) (flash_memory
[Block
*
451 DeviceInfo
.wPageSize
);
454 read_data
+= DeviceInfo
.wPageSize
;
461 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
462 * Function: emu_Write_Page_Main_Spare
463 * Inputs: Write buffer
466 * Outputs: PASS=0 (notice 0=ok here)
467 * Description: Write the buffer to main+spare area of flash
469 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
470 u16
emu_Write_Page_Main_Spare(u8
*write_data
, u32 Block
,
471 u16 Page
, u16 page_count
)
475 nand_dbg_print(NAND_DBG_TRACE
, "%s, Line %d, Function: %s\n",
476 __FILE__
, __LINE__
, __func__
);
478 if (Block
>= DeviceInfo
.wTotalBlocks
) {
479 printk(KERN_ERR
"Write Page Main + Spare "
480 "Error: Block Address too big\n");
484 if (Page
+ page_count
> DeviceInfo
.wPagesPerBlock
) {
485 printk(KERN_ERR
"Write Page Main + Spare "
486 "Error: Page number too big\n");
490 nand_dbg_print(NAND_DBG_DEBUG
, "Write Page Main+Spare - "
491 "No. of pages %u block %u start page %u\n",
492 (unsigned int)page_count
,
493 (unsigned int)Block
, (unsigned int)Page
);
495 for (i
= 0; i
< page_count
; i
++) {
496 if (NULL
== flash_memory
[Block
* GLOB_LLD_PAGES
+ Page
]) {
497 printk(KERN_ERR
"Run out of memory!\n");
500 memcpy((u8
*) (flash_memory
[Block
* GLOB_LLD_PAGES
+ Page
]),
501 write_data
, DeviceInfo
.wPageSize
);
502 write_data
+= DeviceInfo
.wPageSize
;
509 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
510 * Function: emu_Write_Page_Spare
511 * Inputs: Write buffer
514 * Outputs: PASS=0 (notice 0=ok here)
515 * Description: Write the buffer in the spare area
517 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
518 u16
emu_Write_Page_Spare(u8
*write_data
, u32 Block
,
519 u16 Page
, u16 PageCount
)
521 nand_dbg_print(NAND_DBG_TRACE
, "%s, Line %d, Function: %s\n",
522 __FILE__
, __LINE__
, __func__
);
524 if (Block
>= DeviceInfo
.wTotalBlocks
) {
525 printk(KERN_ERR
"Read Page Spare Error: "
526 "Block Address too big\n");
530 if (Page
+ PageCount
> DeviceInfo
.wPagesPerBlock
) {
531 printk(KERN_ERR
"Read Page Spare Error: "
532 "Page number too big\n");
536 nand_dbg_print(NAND_DBG_DEBUG
, "Write Page Spare- "
537 "block %u page %u\n",
538 (unsigned int)Block
, (unsigned int)Page
);
540 if (NULL
== flash_memory
[Block
* GLOB_LLD_PAGES
+ Page
]) {
541 printk(KERN_ERR
"Run out of memory!\n");
545 memcpy((u8
*) (flash_memory
[Block
* GLOB_LLD_PAGES
+ Page
] +
546 DeviceInfo
.wPageDataSize
), write_data
,
547 (DeviceInfo
.wPageSize
- DeviceInfo
.wPageDataSize
));
552 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
553 * Function: emu_Read_Page_Spare
554 * Inputs: Write Buffer
557 * Outputs: PASS=0 (notice 0=ok here)
558 * Description: Read data from the spare area
560 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
561 u16
emu_Read_Page_Spare(u8
*write_data
, u32 Block
,
562 u16 Page
, u16 PageCount
)
564 nand_dbg_print(NAND_DBG_TRACE
, "%s, Line %d, Function: %s\n",
565 __FILE__
, __LINE__
, __func__
);
567 if (Block
>= DeviceInfo
.wTotalBlocks
) {
568 printk(KERN_ERR
"Read Page Spare "
569 "Error: Block Address too big\n");
573 if (Page
+ PageCount
> DeviceInfo
.wPagesPerBlock
) {
574 printk(KERN_ERR
"Read Page Spare "
575 "Error: Page number too big\n");
579 nand_dbg_print(NAND_DBG_DEBUG
, "Read Page Spare- "
580 "block %u page %u\n",
581 (unsigned int)Block
, (unsigned int)Page
);
583 if (NULL
== flash_memory
[Block
* GLOB_LLD_PAGES
+ Page
]) {
584 memset(write_data
, 0xFF,
585 (DeviceInfo
.wPageSize
- DeviceInfo
.wPageDataSize
));
588 (u8
*) (flash_memory
[Block
* GLOB_LLD_PAGES
+ Page
]
589 + DeviceInfo
.wPageDataSize
),
590 (DeviceInfo
.wPageSize
- DeviceInfo
.wPageDataSize
));
596 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
597 * Function: emu_Enable_Disable_Interrupts
598 * Inputs: enable or disable
601 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
602 void emu_Enable_Disable_Interrupts(u16 INT_ENABLE
)
604 nand_dbg_print(NAND_DBG_TRACE
, "%s, Line %d, Function: %s\n",
605 __FILE__
, __LINE__
, __func__
);
608 u16
emu_Get_Bad_Block(u32 block
)
614 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
615 * Support for CDMA functions
616 ************************************
617 * emu_CDMA_Flash_Init
618 * CDMA_process_data command (use LLD_CDMA)
619 * CDMA_MemCopy_CMD (use LLD_CDMA)
620 * emu_CDMA_execute all commands
621 * emu_CDMA_Event_Status
622 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
623 u16
emu_CDMA_Flash_Init(void)
627 nand_dbg_print(NAND_DBG_TRACE
, "%s, Line %d, Function: %s\n",
628 __FILE__
, __LINE__
, __func__
);
630 for (i
= 0; i
< MAX_DESCS
+ MAX_CHANS
; i
++) {
631 PendingCMD
[i
].CMD
= 0;
632 PendingCMD
[i
].Tag
= 0;
633 PendingCMD
[i
].DataAddr
= 0;
634 PendingCMD
[i
].Block
= 0;
635 PendingCMD
[i
].Page
= 0;
636 PendingCMD
[i
].PageCount
= 0;
637 PendingCMD
[i
].DataDestAddr
= 0;
638 PendingCMD
[i
].DataSrcAddr
= 0;
639 PendingCMD
[i
].MemCopyByteCnt
= 0;
640 PendingCMD
[i
].ChanSync
[0] = 0;
641 PendingCMD
[i
].ChanSync
[1] = 0;
642 PendingCMD
[i
].ChanSync
[2] = 0;
643 PendingCMD
[i
].ChanSync
[3] = 0;
644 PendingCMD
[i
].ChanSync
[4] = 0;
645 PendingCMD
[i
].Status
= 3;
651 static void emu_isr(int irq
, void *dev_id
)
656 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
657 * Function: CDMA_Execute_CMDs
658 * Inputs: tag_count: the number of pending cmds to do
660 * Description: execute each command in the pending CMD array
661 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
662 u16
emu_CDMA_Execute_CMDs(u16 tag_count
)
665 u8 CMD
; /* cmd parameter */
672 nand_dbg_print(NAND_DBG_TRACE
, "%s, Line %d, Function: %s\n",
673 __FILE__
, __LINE__
, __func__
);
675 nand_dbg_print(NAND_DBG_TRACE
, "At start of Execute CMDs: "
676 "Tag Count %u\n", tag_count
);
678 for (i
= 0; i
< totalUsedBanks
; i
++) {
679 PendingCMD
[i
].CMD
= DUMMY_CMD
;
680 PendingCMD
[i
].Tag
= 0xFF;
681 PendingCMD
[i
].Block
=
682 (DeviceInfo
.wTotalBlocks
/ totalUsedBanks
) * i
;
684 for (j
= 0; j
<= MAX_CHANS
; j
++)
685 PendingCMD
[i
].ChanSync
[j
] = 0;
688 CDMA_Execute_CMDs(tag_count
);
690 print_pending_cmds(tag_count
);
698 i
< tag_count
+ MAX_CHANS
; i
++) {
699 CMD
= PendingCMD
[i
].CMD
;
700 data
= PendingCMD
[i
].DataAddr
;
701 block
= PendingCMD
[i
].Block
;
702 page
= PendingCMD
[i
].Page
;
703 count
= PendingCMD
[i
].PageCount
;
707 emu_Erase_Block(block
);
708 PendingCMD
[i
].Status
= PASS
;
711 emu_Write_Page_Main(data
, block
, page
, count
);
712 PendingCMD
[i
].Status
= PASS
;
714 case WRITE_MAIN_SPARE_CMD
:
715 emu_Write_Page_Main_Spare(data
, block
, page
, count
);
716 PendingCMD
[i
].Status
= PASS
;
719 emu_Read_Page_Main(data
, block
, page
, count
);
720 PendingCMD
[i
].Status
= PASS
;
723 memcpy(PendingCMD
[i
].DataDestAddr
,
724 PendingCMD
[i
].DataSrcAddr
,
725 PendingCMD
[i
].MemCopyByteCnt
);
727 PendingCMD
[i
].Status
= PASS
;
730 PendingCMD
[i
].Status
= FAIL
;
736 * Temperory adding code to reset PendingCMD array for basic testing.
737 * It should be done at the end of event status function.
739 for (i
= tag_count
+ MAX_CHANS
; i
< MAX_DESCS
; i
++) {
740 PendingCMD
[i
].CMD
= 0;
741 PendingCMD
[i
].Tag
= 0;
742 PendingCMD
[i
].DataAddr
= 0;
743 PendingCMD
[i
].Block
= 0;
744 PendingCMD
[i
].Page
= 0;
745 PendingCMD
[i
].PageCount
= 0;
746 PendingCMD
[i
].DataDestAddr
= 0;
747 PendingCMD
[i
].DataSrcAddr
= 0;
748 PendingCMD
[i
].MemCopyByteCnt
= 0;
749 PendingCMD
[i
].ChanSync
[0] = 0;
750 PendingCMD
[i
].ChanSync
[1] = 0;
751 PendingCMD
[i
].ChanSync
[2] = 0;
752 PendingCMD
[i
].ChanSync
[3] = 0;
753 PendingCMD
[i
].ChanSync
[4] = 0;
754 PendingCMD
[i
].Status
= CMD_NOT_DONE
;
757 nand_dbg_print(NAND_DBG_TRACE
, "At end of Execute CMDs.\n");
759 emu_isr(0, 0); /* This is a null isr now. Need fill it in future */
764 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
765 * Function: emu_Event_Status
767 * Outputs: Event_Status code
768 * Description: This function can also be used to force errors
769 *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
770 u16
emu_CDMA_Event_Status(void)
772 nand_dbg_print(NAND_DBG_TRACE
, "%s, Line %d, Function: %s\n",
773 __FILE__
, __LINE__
, __func__
);
780 #endif /* FLASH_EMU */