]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/staging/spectra/lld_emu.c
staging: lirc: remove duplicated include
[net-next-2.6.git] / drivers / staging / spectra / lld_emu.c
CommitLineData
494a43bb
AO
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 "flash.h"
23#include "ffsdefs.h"
24#include "lld_emu.h"
25#include "lld.h"
26#if CMD_DMA
27#include "lld_cdma.h"
28#endif
29
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
34
35#if (CMD_DMA && FLASH_EMU)
36#include "lld_cdma.h"
37u32 totalUsedBanks;
38u32 valid_banks[MAX_CHANS];
39#endif
40
41#if FLASH_EMU /* This is for entire module */
42
43static u8 *flash_memory[GLOB_LLD_BLOCKS * GLOB_LLD_PAGES];
44
45/* Read nand emu file and then fill it's content to flash_memory */
46int emu_load_file_to_mem(void)
47{
48 mm_segment_t fs;
49 struct file *nef_filp = NULL;
50 struct inode *inode = NULL;
51 loff_t nef_size = 0;
52 loff_t tmp_file_offset, file_offset;
53 ssize_t nread;
54 int i, rc = -EINVAL;
55
56 nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
57 __FILE__, __LINE__, __func__);
58
59 fs = get_fs();
60 set_fs(get_ds());
61
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);
67 }
68
69 if (nef_filp->f_path.dentry) {
70 inode = nef_filp->f_path.dentry->d_inode;
71 } else {
72 printk(KERN_ERR "Can not get valid inode!\n");
73 goto out;
74 }
75
76 nef_size = i_size_read(inode->i_mapping->host);
77 if (nef_size <= 0) {
78 printk(KERN_ERR "Invalid nand emu file size: "
79 "0x%llx\n", nef_size);
80 goto out;
81 } else {
82 nand_dbg_print(NAND_DBG_DEBUG, "nand emu file size: %lld\n",
83 nef_size);
84 }
85
86 file_offset = 0;
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);
96 goto out;
97 }
98 file_offset += GLOB_LLD_PAGE_SIZE;
99 }
100 rc = 0;
101
102out:
103 filp_close(nef_filp, current->files);
104 set_fs(fs);
105 return rc;
106}
107
108/* Write contents of flash_memory to nand emu file */
109int emu_write_mem_to_file(void)
110{
111 mm_segment_t fs;
112 struct file *nef_filp = NULL;
113 struct inode *inode = NULL;
114 loff_t nef_size = 0;
115 loff_t tmp_file_offset, file_offset;
116 ssize_t nwritten;
117 int i, rc = -EINVAL;
118
119 nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
120 __FILE__, __LINE__, __func__);
121
122 fs = get_fs();
123 set_fs(get_ds());
124
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);
130 }
131
132 if (nef_filp->f_path.dentry) {
133 inode = nef_filp->f_path.dentry->d_inode;
134 } else {
135 printk(KERN_ERR "Invalid " "nef_filp->f_path.dentry value!\n");
136 goto out;
137 }
138
139 nef_size = i_size_read(inode->i_mapping->host);
140 if (nef_size <= 0) {
141 printk(KERN_ERR "Invalid "
142 "nand emu file size: 0x%llx\n", nef_size);
143 goto out;
144 } else {
145 nand_dbg_print(NAND_DBG_DEBUG, "nand emu file size: "
146 "%lld\n", nef_size);
147 }
148
149 file_offset = 0;
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);
159 goto out;
160 }
161 file_offset += GLOB_LLD_PAGE_SIZE;
162 }
163 rc = 0;
164
165out:
166 filp_close(nef_filp, current->files);
167 set_fs(fs);
168 return rc;
169}
170
171/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
172* Function: emu_Flash_Init
173* Inputs: none
174* Outputs: PASS=0 (notice 0=ok here)
175* Description: Creates & initializes the flash RAM array.
176*
177*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
178u16 emu_Flash_Init(void)
179{
180 int i;
181
182 nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
183 __FILE__, __LINE__, __func__);
184
185 flash_memory[0] = (u8 *)vmalloc(GLOB_LLD_PAGE_SIZE *
186 GLOB_LLD_BLOCKS *
187 GLOB_LLD_PAGES *
188 sizeof(u8));
189 if (!flash_memory[0]) {
190 printk(KERN_ERR "Fail to allocate memory "
191 "for nand emulator!\n");
192 return ERR;
193 }
194
195 memset((char *)(flash_memory[0]), 0xFF,
196 GLOB_LLD_PAGE_SIZE * GLOB_LLD_BLOCKS * GLOB_LLD_PAGES *
197 sizeof(u8));
198
199 for (i = 1; i < GLOB_LLD_BLOCKS * GLOB_LLD_PAGES; i++)
200 flash_memory[i] = flash_memory[i - 1] + GLOB_LLD_PAGE_SIZE;
201
202 emu_load_file_to_mem(); /* Load nand emu file to mem */
203
204 return PASS;
205}
206
207/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
208* Function: emu_Flash_Release
209* Inputs: none
210* Outputs: PASS=0 (notice 0=ok here)
211* Description: Releases the flash.
212*
213*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
214int emu_Flash_Release(void)
215{
216 nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
217 __FILE__, __LINE__, __func__);
218
219 emu_write_mem_to_file(); /* Write back mem to nand emu file */
220
221 vfree(flash_memory[0]);
222 return PASS;
223}
224
225/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
226* Function: emu_Read_Device_ID
227* Inputs: none
228* Outputs: PASS=1 FAIL=0
229* Description: Reads the info from the controller registers.
230* Sets up DeviceInfo structure with device parameters
231*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
232
233u16 emu_Read_Device_ID(void)
234{
235 nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
236 __FILE__, __LINE__, __func__);
237
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
252 + 1);
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);
260
261#if CMD_DMA
262 totalUsedBanks = 4;
263 valid_banks[0] = 1;
264 valid_banks[1] = 1;
265 valid_banks[2] = 1;
266 valid_banks[3] = 1;
267#endif
268
269 return PASS;
270}
271
272/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
273* Function: emu_Flash_Reset
274* Inputs: none
275* Outputs: PASS=0 (notice 0=ok here)
276* Description: Reset the flash
277*
278*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
279u16 emu_Flash_Reset(void)
280{
281 nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
282 __FILE__, __LINE__, __func__);
283
284 return PASS;
285}
286
287/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
288* Function: emu_Erase_Block
289* Inputs: Address
290* Outputs: PASS=0 (notice 0=ok here)
291* Description: Erase a block
292*
293*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
294u16 emu_Erase_Block(u32 block_add)
295{
296 int i;
297
298 nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
299 __FILE__, __LINE__, __func__);
300
301 if (block_add >= DeviceInfo.wTotalBlocks) {
302 printk(KERN_ERR "emu_Erase_Block error! "
303 "Too big block address: %d\n", block_add);
304 return FAIL;
305 }
306
307 nand_dbg_print(NAND_DBG_DEBUG, "Erasing block %d\n",
308 (int)block_add);
309
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));
315 }
316 }
317
318 return PASS;
319}
320
321/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
322* Function: emu_Write_Page_Main
323* Inputs: Write buffer address pointer
324* Block number
325* Page number
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
329*
330*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
331u16 emu_Write_Page_Main(u8 *write_data, u32 Block,
332 u16 Page, u16 PageCount)
333{
334 int i;
335
336 nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
337 __FILE__, __LINE__, __func__);
338
339 if (Block >= DeviceInfo.wTotalBlocks)
340 return FAIL;
341
342 if (Page + PageCount > DeviceInfo.wPagesPerBlock)
343 return FAIL;
344
345 nand_dbg_print(NAND_DBG_DEBUG, "emu_Write_Page_Main: "
346 "lba %u Page %u PageCount %u\n",
347 (unsigned int)Block,
348 (unsigned int)Page, (unsigned int)PageCount);
349
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");
353 return FAIL;
354 }
355 memcpy((u8 *) (flash_memory[Block * GLOB_LLD_PAGES + Page]),
356 write_data, DeviceInfo.wPageDataSize);
357 write_data += DeviceInfo.wPageDataSize;
358 Page++;
359 }
360
361 return PASS;
362}
363
364/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
365* Function: emu_Read_Page_Main
366* Inputs: Read buffer address pointer
367* Block number
368* Page number
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
372*
373*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
374u16 emu_Read_Page_Main(u8 *read_data, u32 Block,
375 u16 Page, u16 PageCount)
376{
377 int i;
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 return FAIL;
384
385 if (Page + PageCount > DeviceInfo.wPagesPerBlock)
386 return FAIL;
387
388 nand_dbg_print(NAND_DBG_DEBUG, "emu_Read_Page_Main: "
389 "lba %u Page %u PageCount %u\n",
390 (unsigned int)Block,
391 (unsigned int)Page, (unsigned int)PageCount);
392
393 for (i = 0; i < PageCount; i++) {
394 if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
395 memset(read_data, 0xFF, DeviceInfo.wPageDataSize);
396 } else {
397 memcpy(read_data,
398 (u8 *) (flash_memory[Block * GLOB_LLD_PAGES
399 + Page]),
400 DeviceInfo.wPageDataSize);
401 }
402 read_data += DeviceInfo.wPageDataSize;
403 Page++;
404 }
405
406 return PASS;
407}
408
409#ifndef ELDORA
410/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
411* Function: emu_Read_Page_Main_Spare
412* Inputs: Write Buffer
413* Address
414* Buffer size
415* Outputs: PASS=0 (notice 0=ok here)
416* Description: Read from flash main+spare area
417*
418*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
419u16 emu_Read_Page_Main_Spare(u8 *read_data, u32 Block,
420 u16 Page, u16 PageCount)
421{
422 int i;
423
424 nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
425 __FILE__, __LINE__, __func__);
426
427 if (Block >= DeviceInfo.wTotalBlocks) {
428 printk(KERN_ERR "Read Page Main+Spare "
429 "Error: Block Address too big\n");
430 return FAIL;
431 }
432
433 if (Page + PageCount > DeviceInfo.wPagesPerBlock) {
434 printk(KERN_ERR "Read Page Main+Spare "
435 "Error: Page number too big\n");
436 return FAIL;
437 }
438
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);
443
444 for (i = 0; i < PageCount; i++) {
445 if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
446 memset(read_data, 0xFF, DeviceInfo.wPageSize);
447 } else {
448 memcpy(read_data, (u8 *) (flash_memory[Block *
449 GLOB_LLD_PAGES
450 + Page]),
451 DeviceInfo.wPageSize);
452 }
453
454 read_data += DeviceInfo.wPageSize;
455 Page++;
456 }
457
458 return PASS;
459}
460
461/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
462* Function: emu_Write_Page_Main_Spare
463* Inputs: Write buffer
464* address
465* buffer length
466* Outputs: PASS=0 (notice 0=ok here)
467* Description: Write the buffer to main+spare area of flash
468*
469*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
470u16 emu_Write_Page_Main_Spare(u8 *write_data, u32 Block,
471 u16 Page, u16 page_count)
472{
473 u16 i;
474
475 nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
476 __FILE__, __LINE__, __func__);
477
478 if (Block >= DeviceInfo.wTotalBlocks) {
479 printk(KERN_ERR "Write Page Main + Spare "
480 "Error: Block Address too big\n");
481 return FAIL;
482 }
483
484 if (Page + page_count > DeviceInfo.wPagesPerBlock) {
485 printk(KERN_ERR "Write Page Main + Spare "
486 "Error: Page number too big\n");
487 return FAIL;
488 }
489
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);
494
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");
498 return FAIL;
499 }
500 memcpy((u8 *) (flash_memory[Block * GLOB_LLD_PAGES + Page]),
501 write_data, DeviceInfo.wPageSize);
502 write_data += DeviceInfo.wPageSize;
503 Page++;
504 }
505
506 return PASS;
507}
508
509/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
510* Function: emu_Write_Page_Spare
511* Inputs: Write buffer
512* Address
513* buffer size
514* Outputs: PASS=0 (notice 0=ok here)
515* Description: Write the buffer in the spare area
516*
517*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
518u16 emu_Write_Page_Spare(u8 *write_data, u32 Block,
519 u16 Page, u16 PageCount)
520{
521 nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
522 __FILE__, __LINE__, __func__);
523
524 if (Block >= DeviceInfo.wTotalBlocks) {
525 printk(KERN_ERR "Read Page Spare Error: "
526 "Block Address too big\n");
527 return FAIL;
528 }
529
530 if (Page + PageCount > DeviceInfo.wPagesPerBlock) {
531 printk(KERN_ERR "Read Page Spare Error: "
532 "Page number too big\n");
533 return FAIL;
534 }
535
536 nand_dbg_print(NAND_DBG_DEBUG, "Write Page Spare- "
537 "block %u page %u\n",
538 (unsigned int)Block, (unsigned int)Page);
539
540 if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
541 printk(KERN_ERR "Run out of memory!\n");
542 return FAIL;
543 }
544
545 memcpy((u8 *) (flash_memory[Block * GLOB_LLD_PAGES + Page] +
546 DeviceInfo.wPageDataSize), write_data,
547 (DeviceInfo.wPageSize - DeviceInfo.wPageDataSize));
548
549 return PASS;
550}
551
552/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
553* Function: emu_Read_Page_Spare
554* Inputs: Write Buffer
555* Address
556* Buffer size
557* Outputs: PASS=0 (notice 0=ok here)
558* Description: Read data from the spare area
559*
560*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
561u16 emu_Read_Page_Spare(u8 *write_data, u32 Block,
562 u16 Page, u16 PageCount)
563{
564 nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
565 __FILE__, __LINE__, __func__);
566
567 if (Block >= DeviceInfo.wTotalBlocks) {
568 printk(KERN_ERR "Read Page Spare "
569 "Error: Block Address too big\n");
570 return FAIL;
571 }
572
573 if (Page + PageCount > DeviceInfo.wPagesPerBlock) {
574 printk(KERN_ERR "Read Page Spare "
575 "Error: Page number too big\n");
576 return FAIL;
577 }
578
579 nand_dbg_print(NAND_DBG_DEBUG, "Read Page Spare- "
580 "block %u page %u\n",
581 (unsigned int)Block, (unsigned int)Page);
582
583 if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
584 memset(write_data, 0xFF,
585 (DeviceInfo.wPageSize - DeviceInfo.wPageDataSize));
586 } else {
587 memcpy(write_data,
588 (u8 *) (flash_memory[Block * GLOB_LLD_PAGES + Page]
589 + DeviceInfo.wPageDataSize),
590 (DeviceInfo.wPageSize - DeviceInfo.wPageDataSize));
591 }
592
593 return PASS;
594}
595
596/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
597* Function: emu_Enable_Disable_Interrupts
598* Inputs: enable or disable
599* Outputs: none
600* Description: NOP
601*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
602void emu_Enable_Disable_Interrupts(u16 INT_ENABLE)
603{
604 nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
605 __FILE__, __LINE__, __func__);
606}
607
608u16 emu_Get_Bad_Block(u32 block)
609{
610 return 0;
611}
612
613#if CMD_DMA
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*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
623u16 emu_CDMA_Flash_Init(void)
624{
625 u16 i;
626
627 nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
628 __FILE__, __LINE__, __func__);
629
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;
646 }
647
648 return PASS;
649}
650
651static void emu_isr(int irq, void *dev_id)
652{
653 /* TODO: ... */
654}
655
656/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
657* Function: CDMA_Execute_CMDs
658* Inputs: tag_count: the number of pending cmds to do
659* Outputs: PASS/FAIL
660* Description: execute each command in the pending CMD array
661*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
662u16 emu_CDMA_Execute_CMDs(u16 tag_count)
663{
664 u16 i, j;
665 u8 CMD; /* cmd parameter */
666 u8 *data;
667 u32 block;
668 u16 page;
669 u16 count;
670 u16 status = PASS;
671
672 nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
673 __FILE__, __LINE__, __func__);
674
675 nand_dbg_print(NAND_DBG_TRACE, "At start of Execute CMDs: "
676 "Tag Count %u\n", tag_count);
677
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;
683
684 for (j = 0; j <= MAX_CHANS; j++)
685 PendingCMD[i].ChanSync[j] = 0;
686 }
687
688 CDMA_Execute_CMDs(tag_count);
689
690 print_pending_cmds(tag_count);
691
692#if DEBUG_SYNC
693 }
694 debug_sync_cnt++;
695#endif
696
697 for (i = MAX_CHANS;
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;
704
705 switch (CMD) {
706 case ERASE_CMD:
707 emu_Erase_Block(block);
708 PendingCMD[i].Status = PASS;
709 break;
710 case WRITE_MAIN_CMD:
711 emu_Write_Page_Main(data, block, page, count);
712 PendingCMD[i].Status = PASS;
713 break;
714 case WRITE_MAIN_SPARE_CMD:
715 emu_Write_Page_Main_Spare(data, block, page, count);
716 PendingCMD[i].Status = PASS;
717 break;
718 case READ_MAIN_CMD:
719 emu_Read_Page_Main(data, block, page, count);
720 PendingCMD[i].Status = PASS;
721 break;
722 case MEMCOPY_CMD:
723 memcpy(PendingCMD[i].DataDestAddr,
724 PendingCMD[i].DataSrcAddr,
725 PendingCMD[i].MemCopyByteCnt);
726 case DUMMY_CMD:
727 PendingCMD[i].Status = PASS;
728 break;
729 default:
730 PendingCMD[i].Status = FAIL;
731 break;
732 }
733 }
734
735 /*
736 * Temperory adding code to reset PendingCMD array for basic testing.
737 * It should be done at the end of event status function.
738 */
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;
755 }
756
757 nand_dbg_print(NAND_DBG_TRACE, "At end of Execute CMDs.\n");
758
759 emu_isr(0, 0); /* This is a null isr now. Need fill it in future */
760
761 return status;
762}
763
764/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
765* Function: emu_Event_Status
766* Inputs: none
767* Outputs: Event_Status code
768* Description: This function can also be used to force errors
769*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
770u16 emu_CDMA_Event_Status(void)
771{
772 nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
773 __FILE__, __LINE__, __func__);
774
775 return EVENT_PASS;
776}
777
778#endif /* CMD_DMA */
779#endif /* !ELDORA */
780#endif /* FLASH_EMU */