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