📄 nand_util.c
字号:
{
trace1(0, util, 0, "block %d: not in use - marked bad", g_addr_rd_phy_blk) ;
util_trace_page() ;
return;
}
// call media to retrieve lb of current pb, or return a reason why it can't be done
if(k_success != _media_phy2log())
{
trace1(0, util, 0, "block %d: not in use - invalid log binding", g_addr_rd_phy_blk) ;
util_trace_page() ;
return;
}
trace2(0, util, 0, "block:%d ==> lb: %d", g_addr_rd_phy_blk, g_addr_log_blk) ;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void util_trace_map_zone() reentrant
{
trace1(0, util, 0, "--- Zone %d Map -----------", g_addr_zone) ;
for(g_addr_rd_phy_blk=0; g_addr_rd_phy_blk<_media_data(physical_blocks_per_zone);g_addr_rd_phy_blk++)
{
util_trace_map_block() ;
}
trace1(0, util, 0, "--- Zone %d Map End -------", g_addr_zone) ;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void util_trace_map_media() reentrant
{
for(g_addr_zone=0;g_addr_zone<_media_data(num_zones);g_addr_zone++)
{
if(g_active_media != k_ix_media_sm)
{
nand_select_card() ;
}
util_trace_map_zone() ;
}
}
#endif
xdata uint16 _erase_blocks ;
xdata uint16 _erase_blocks_rsvd ;
xdata uint16 _erase_blocks_bad ;
xdata uint16 _erase_blocks_restored ;
xdata uint16 _total_blocks ;
xdata uint16 _total_blocks_rsvd ;
xdata uint16 _total_blocks_bad ;
xdata uint16 _total_blocks_restored ;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result util_wr_verify_page_aa() reentrant
{
return k_false ;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result util_wr_verify_page_55() reentrant
{
return k_true ;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result util_recover_bad_block() reentrant
{
uint16 i ;
t_result result ;
if(g_active_media == k_ix_media_ms)
{
return _media_erase_block() ;
}
#if (k_lun_sm < k_max_log_lun)
result = k_error ;
// smart media/nand recovery only
// test for factor-marked bad... redt data of all 0's is the best test
for(i=0; i<16;i++)
{
if(x_sm_redt_data[i] != 0x00)
result = k_success ;
}
#endif
// an error indicates a factory-marked-bad candidate
if(k_success != result)
{
// check to see if the block is all 00's too... if so, don't touch it
nand_rd_va2pa() ;
_media_data(sector_buffer) = g_sector_buffer ;
result = _media_read_sector() ;
if(k_success != result)
return result ;
result = k_error ;
for(i=0;i<512;i++)
{
if(g_sector_buffer[i] != 0x00)
{
result = k_success ;
}
}
if(k_success != result)
{
// factory-marked-bad block... bail
return result ;
}
}
// do the block erase here
result = _media_erase_block() ;
#if 0
if(k_success != result)
return result ;
// write first pattern
for(g_addr_page;g_addr_page < _media_data(pages_per_block);g_addr_page++)
{
result=util_wr_verify_page_55() ;
if(result != k_success)
return result ;
}
g_addr_page=0 ;
result = _media_erase_block() ;
for(g_addr_page;g_addr_page < _media_data(pages_per_block);g_addr_page++)
{
result=util_wr_verify_page_aa() ;
if(result != k_success)
return result ;
}
g_addr_page=0;
result = _media_erase_block() ;
#endif
// technically, should write the pattern here for save erase
return result ;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void util_safe_erase_block() reentrant
{
if ((!g_addr_zone) && (g_addr_rd_phy_blk <= _media_data(boot_block)))
{
trace2(0, util, 0, "zone %d block %d - reserved. not erased", g_addr_zone, g_addr_rd_phy_blk) ;
_erase_blocks_rsvd++ ;
return;
}
g_addr_page=0 ;
_media_read_extra_data() ;
if( _media_is_phyblock_ok() )
{
if (_media_is_phyblock_blank() )
{
// not bad... not written... don't erase
return;
}
if (k_success == _media_erase_block())
{
_erase_blocks++ ;
return;
}
}
_erase_blocks_bad++ ;
// attempt to recover blocks not marked bad by the factory
if( k_success == util_recover_bad_block() )
{
trace2(0, util, 0, "zone %d block %d - restored", g_addr_zone, g_addr_wr_phy_blk) ;
_erase_blocks_bad-- ;
_erase_blocks_restored++ ;
return;
}
trace2(0, util, 0, "zone %d block %d - block is bad",g_addr_zone, g_addr_wr_phy_blk) ;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void util_safe_erase_zone() reentrant
{
trace1(0, util, 0, "Erasing Zone %d ------", g_addr_zone) ;
for(g_addr_rd_phy_blk=0; g_addr_rd_phy_blk<_media_data(physical_blocks_per_zone);g_addr_rd_phy_blk++)
{
g_addr_wr_phy_blk=g_addr_rd_phy_blk ;
util_safe_erase_block() ;
}
/*
trace1(0, util, 0, "Zone %d Erase Stats:", g_addr_zone) ;
trace1(0, util, 0, " blocks erased: %d", _erase_blocks) ;
trace1(0, util, 0, " blocks_rsvd: %d", _erase_blocks_rsvd) ;
trace1(0, util, 0, " blocks_bad: %d", _erase_blocks_bad) ;
trace1(0, util, 0, " blocks_restored:%d", _erase_blocks_restored) ;
*/
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void util_safe_erase_media() reentrant
{
trace0(0, util, 0, "util_safe_erase_media() - erase all blocks not explicitly marked 'bad' by the factory") ;
_total_blocks=0;
_total_blocks_rsvd=0;
_total_blocks_bad=0;
_total_blocks_restored=0;
for(g_addr_zone=0;g_addr_zone<_media_data(num_zones);g_addr_zone++)
{
if( !((g_active_media==k_ix_media_sm)||(g_active_media==k_ix_media_ms)))
{
nand_select_card() ;
}
_erase_blocks=0;
_erase_blocks_rsvd=0;
_erase_blocks_bad=0;
_erase_blocks_restored=0;
util_safe_erase_zone() ;
_total_blocks += _erase_blocks ;
_total_blocks_rsvd += _erase_blocks_rsvd ;
_total_blocks_bad += _erase_blocks_bad ;
_total_blocks_restored += _erase_blocks_restored ;
}
/*
trace0(0, util, 0, "Safe Erase Results:") ;
trace1(0, util, 0, " total blocks erased: %d", _total_blocks) ;
trace1(0, util, 0, " total blocks_rsvd: %d", _total_blocks_rsvd) ;
trace1(0, util, 0, " total blocks_bad: %d", _total_blocks_bad) ;
trace1(0, util, 0, " total blocks_restored:%d", _total_blocks_restored) ;
*/
}
#if 0
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void fmc_dbg_dump_sector(uint8* sector) reentrant;
void sm_dbg_dump_redt_data() reentrant;
void n2k_test_read_sequential() reentrant
{
uint16 i ;
// useful routine for dumping the contents of a block
g_addr_zone=0;
map_build_sector_map() ;
map_lba2addr_rd(0) ;
nand_select_card() ;
nand_rd_va2pa() ;
// read page into page buffer
nand_page_read_for_datay() ;
// read next page into cache
n2k_read_cache_next() ;
for(g_addr_page=0;g_addr_page<_media_data(pages_per_block);g_addr_page++)
{
trace1(0, nand, 0, "Read Page %d", g_addr_page) ;
for(i=0;i<512;i++)
{
g_sector_buffer[i] = _sm_data_rd() ;
}
fmc_dbg_dump_sector(g_sector_buffer) ;
for(i=0;i<16;i++)
{
x_sm_redt_data[i] = _sm_data_rd() ;
}
sm_dbg_dump_redt_data() ;
if( (g_addr_page&0x03)==3)
{
trace0(0, nand, 0, "read cache decision...") ;
if(g_addr_page==255)
{
trace0(0, nand, 0, "last page... don't issue any command") ;
continue ;
}
else if(g_addr_page==251)
{
trace0(0, nand, 0, "2nd to last page. issue read-final-cache command") ;
n2k_read_cache_final() ;
}
else
{
trace0(0, nand, 0, "read in next cached page") ;
n2k_read_cache_next() ;
}
}
}
}
#endif
#if 0
void util_clear_boot_block() reentrant
{
uint16 i;
for(i=0;i<256;i++)
{
nand_boot_write(i, 0xff) ;
}
nand_boot_write_flush() ;
}
#endif
//+-----------------------------------------------------------------------------
// Name:
// util_verify_sector_map()
//
// Declaration:
// t_result util_verify_sector_map(void) reentrant
//
// Purpose:
//
// Arguments:
//
// Return:
//
// Notes:
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
#if 0
void util_verify_sector_map(void) reentrant
{
uint8 zone ;
uint16 max_lb ;
uint16 lb;
uint8 check_for_l2p_entry ;
trace0(0, map, 0, "map_verify_sector_map()") ;
zone = g_addr_zone?1:0;
g_addr_page=0;
trace2(0, map, 0, "verifying sector map of media zone %d to map index %d", g_addr_zone, zone) ;
_l2p_map = _l2p_map(zone) ;
_a_map = _assign_map(zone) ;
max_lb = zone?_media_data(logical_blocks_per_zone):_media_data(logical_blocks_per_boot_zone);
// populate the assignment map
for (g_addr_rd_phy_blk=0;
g_addr_rd_phy_blk < _media_data(physical_blocks_per_zone);
g_addr_rd_phy_blk++ )
{
g_addr_page = 0 ;
if ((!g_addr_zone) && (g_addr_rd_phy_blk <= _media_data(boot_block)))
{
// first zone, before CIS struct... in sm terms, nothing comes there
_map_phy_blk_used( _a_map, g_addr_rd_phy_blk ) ;
continue;
}
if(k_error == _media_read_extra_data() )
{
trace0(0, map, 0, "phy_block %d: cannot read extra data. mark block used, but not mapped.") ;
if( !_map_is_phy_blk_used( _a_map, g_addr_rd_phy_blk ) )
{
trace0(0, map, 0, "*** error! phy_block %d mapping corrupted!") ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -