コード例 #1
0
u16 GLOB_LLD_Write_Page_Main_Spare(u8 *write_data, u32 block,
				      u16 Page, u16 PageCount)
{
	return emu_Write_Page_Main_Spare(write_data, block, Page, PageCount);
}
コード例 #2
0
ファイル: lld_emu.c プロジェクト: matianfu/barcelona_kernel
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
* 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;
}