u16 GLOB_LLD_Read_Page_Main_Spare(u8 *read_data, u32 block, u16 Page, u16 PageCount) { return emu_Read_Page_Main_Spare(read_data, block, Page, PageCount); }
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& * Function: CDMA_Execute_CMDs * Inputs: tag_count: the number of pending cmds to do * Outputs: PASS/FAIL * Description: execute each command in the pending CMD array *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ uint16 emu_CDMA_Execute_CMDs (uint16 tag_count) { uint16 i, j; byte CMD ; // cmd parameter byte* data ; BLOCKNODE block; PAGENUMTYPE page ; PAGENUMTYPE count; // Page Count uint16 status = PASS; #if EMU_BAD_BLOCK uint16 channel; uint32 hit_bad_block = 0; uint32 hit_sync_point = 0; int channels_with_bad_blocks[LLD_NUM_FLASH_CHANNELS]; #endif #if TEST_FTL && LONG_RUN_FOR_UGLY_CASE_2 uint16 uncorrectable_error_occured =0; int k; #endif GLOB_cmd_tag_count = tag_count; #if EMU_BAD_BLOCK for (i =0; i < LLD_NUM_FLASH_CHANNELS; i++) { channels_with_bad_blocks[i] = -1; discarded_blocks[i] = -1; } #endif print("\n \n At start of Execute CMDs : Tag Count %u\n",GLOB_cmd_tag_count); for (i =0; i < GLOB_totalUsedBanks; i++) { GLOB_PendingCMD[i].CMD = DUMMY_CMD; GLOB_PendingCMD[i].Tag = 0xFF; GLOB_PendingCMD[i].SBDCmdIndex = 0xFF; GLOB_PendingCMD[i].Block = i * (GLOB_DeviceInfo.wTotalBlocks / GLOB_totalUsedBanks); for (j = 0; j<=LLD_NUM_FLASH_CHANNELS; j++) GLOB_PendingCMD[i].ChanSync[j] = 0; GLOB_PendingCMD[i].Status = CMD_PASS; } #if TEST_FTL GLOB_PendingCMD[LLD_NUM_FLASH_CHANNELS+GLOB_cmd_tag_count].CMD = 0; //needed to print only valid entry #endif CDMA_Execute_CMDs(GLOB_cmd_tag_count); #if DEBUG_SYNC if (!(debug_sync_cnt % DBG_SNC_PRINTEVERY)) { print("_%lu_",debug_sync_cnt); #endif #if VERBOSE PrintGLOB_PendingCMDs(GLOB_cmd_tag_count); #endif #if DEBUG_SYNC #if VERBOSE PrintGLOB_PendingCMDsPerChannel(GLOB_cmd_tag_count); #endif } debug_sync_cnt++; #endif for (i=LLD_NUM_FLASH_CHANNELS; i<GLOB_cmd_tag_count+LLD_NUM_FLASH_CHANNELS; i++) { CMD = GLOB_PendingCMD[i].CMD; data = GLOB_PendingCMD[i].DataAddr; block = GLOB_PendingCMD[i].Block; page = GLOB_PendingCMD[i].Page; count = GLOB_PendingCMD[i].PageCount; #if TEST_FTL #if LONG_RUN_FOR_UGLY_CASE_2 for(k=0;k<32;k++) if(block == uncorrectable_error[k].block_num) { PAGENUMTYPE page_num; if(uncorrectable_error_occured) { for(;i<GLOB_cmd_tag_count+LLD_NUM_FLASH_CHANNELS;i++) GLOB_PendingCMD[i].Status = CMD_NOT_DONE; return status; } else uncorrectable_error_occured =1; for(page_num =0;page_num < GLOB_LLD_PAGES;page_num++) { if(GLOB_flash_memory[block*GLOB_LLD_PAGES+ page_num] == NULL) GLOB_flash_memory[block*GLOB_LLD_PAGES+ page_num] = (unsigned char *)GLOB_MALLOC(GLOB_DeviceInfo.wPageSize*sizeof(unsigned char)); } GLOB_PendingCMD[i].Status = FAIL; i++; k=32; forced_error =1; CMD = GLOB_PendingCMD[i].CMD; data = GLOB_PendingCMD[i].DataAddr; block = GLOB_PendingCMD[i].Block; page = GLOB_PendingCMD[i].Page; count = GLOB_PendingCMD[i].PageCount; } #else if(forced_error && (i == (tag_for_forced_error_command+LLD_NUM_FLASH_CHANNELS))) { int page_num; print("uncorrectable error in CMD %u Block %u Page %u\n",CMD,block,page); for(page_num =0;page_num < GLOB_LLD_PAGES;page_num++) { if(GLOB_flash_memory[block*GLOB_LLD_PAGES+ page_num] == NULL) GLOB_flash_memory[block*GLOB_LLD_PAGES+ page_num] = (unsigned char *)GLOB_MALLOC(GLOB_DeviceInfo.wPageSize*sizeof(unsigned char)); } GLOB_PendingCMD[i].Status = CMD_FAIL; continue; } #endif #endif #if EMU_BAD_BLOCK channel = (GLOB_PendingCMD[i].Block) / ((GLOB_DeviceInfo.wTotalBlocks) / GLOB_totalUsedBanks); if (channels_with_bad_blocks[channel] == 1) { GLOB_PendingCMD[i].Status = CMD_NOT_DONE; continue; } if ( ( FAIL == emu_bad_block_check(GLOB_PendingCMD[i].Block)) && (GLOB_PendingCMD[i].CMD != MEMCOPY_CMD)) { channel = (GLOB_PendingCMD[i].Block) / ((GLOB_DeviceInfo.wTotalBlocks) / GLOB_totalUsedBanks); channels_with_bad_blocks[channel] = 1; #if NO_CMDS_DONE_AFTER_ERROR if( hit_bad_block == 1) { GLOB_PendingCMD[i].Status = CMD_NOT_DONE; } else { GLOB_PendingCMD[i].Status = CMD_FAIL; } #else GLOB_PendingCMD[i].Status = CMD_FAIL; #endif hit_bad_block = 1; continue; } #if NO_CMDS_DONE_AFTER_ERROR if(hit_sync_point) { GLOB_PendingCMD[i].Status = CMD_NOT_DONE; continue; } if( (hit_bad_block == 1) ) { hit_sync_point = 1; GLOB_PendingCMD[i].Status = CMD_NOT_DONE; continue; } #else if( (hit_bad_block == 1) && ( (GLOB_PendingCMD[i].CMD == ERASE_CMD) || (GLOB_PendingCMD[i].CMD == WRITE_MAIN_SPARE_CMD) || (GLOB_PendingCMD[i].CMD == WRITE_MAIN_CMD) ) ) { channels_with_bad_blocks[channel] = 1; discarded_blocks[channel] = GLOB_PendingCMD[i].Block; } #endif #endif switch (CMD) { case ERASE_CMD: emu_Erase_Block(block); GLOB_PendingCMD[i].Status = CMD_PASS; break; case WRITE_MAIN_CMD: emu_Write_Page_Main(data, block, page, count); GLOB_PendingCMD[i].Status = CMD_PASS; break; case WRITE_MAIN_SPARE_CMD: emu_Write_Page_Main_Spare(data, block, page, count); GLOB_PendingCMD[i].Status = CMD_PASS; break; case READ_MAIN_SPARE_CMD: emu_Read_Page_Main_Spare(data, block, page, count); GLOB_PendingCMD[i].Status = CMD_PASS; break; case READ_MAIN_CMD: emu_Read_Page_Main(data, block, page, count); GLOB_PendingCMD[i].Status = CMD_PASS; break; case MEMCOPY_CMD: memcpy(GLOB_PendingCMD[i].DataDestAddr, GLOB_PendingCMD[i].DataSrcAddr, GLOB_PendingCMD[i].MemCopyByteCnt); GLOB_PendingCMD[i].Status = CMD_PASS; break; case DUMMY_CMD: GLOB_PendingCMD[i].Status = CMD_PASS; break; default: GLOB_PendingCMD[i].Status = CMD_FAIL; break; } } /*&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ // clear the rest of the pending CMD array /*&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ for (i=GLOB_cmd_tag_count+LLD_NUM_FLASH_CHANNELS; i<MAX_DESCRIPTORS; i++) { GLOB_PendingCMD[i].CMD = 0; GLOB_PendingCMD[i].Tag = 0; GLOB_PendingCMD[i].DataAddr = 0; GLOB_PendingCMD[i].Block = 0; GLOB_PendingCMD[i].Page = 0; GLOB_PendingCMD[i].PageCount = 0; GLOB_PendingCMD[i].DataDestAddr = 0; GLOB_PendingCMD[i].DataSrcAddr = 0; GLOB_PendingCMD[i].MemCopyByteCnt= 0; GLOB_PendingCMD[i].SBDCmdIndex = 0; GLOB_PendingCMD[i].ChanSync[0] = 0; GLOB_PendingCMD[i].ChanSync[1] = 0; GLOB_PendingCMD[i].ChanSync[2] = 0; GLOB_PendingCMD[i].ChanSync[3] = 0; GLOB_PendingCMD[i].ChanSync[4] = 0; GLOB_PendingCMD[i].Status = CMD_NOT_DONE; } print(" At end of Execute CMDs \n\n"); GLOB_SCHEDULE_FUNCTION(&GLOB_ISR); return status; }