📄 ms_media.c
字号:
if (_factor & kbm_ms_reg_int_err)
{
trace0(0, ms, 10, "error: ced&err unrecoverable flash write error");
ms_media_set_phyblock_failed();
return k_error;
}
// write complete
return k_success;
}
#endif
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//t_result ms_media_write_sector() reentrant
//{
// trace0(0, ms_media, 0, "ms_media_write_sector()");
// set_wr_phyblk();
// return ms_pio_write_page(k_max_pnr);
//}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result ms_media_phy2log() reentrant
{
uint16 absolute;
uint16 relative;
trace0(0, ms_media, 10, "ms_media_phy2log()");
absolute = g_ms_extra[k_log_addr_msb_flg_offset] * 256 + g_ms_extra[k_log_addr_lsb_flg_offset];
switch (g_addr_zone)
{
case 0:
relative = absolute;
break;
case 1:
relative = absolute - _media_data(logical_blocks_per_boot_zone);
break;
default:
relative = absolute - _media_data(logical_blocks_per_boot_zone);
relative %= _media_data(logical_blocks_per_zone);
break;
}
g_addr_log_blk = relative;
trace3(0, ms, 110, "...zone:%02d absolute:0x%04X relative:0x%04X", g_addr_zone, absolute, g_addr_log_blk);
return k_success;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result ms_media_bind_log2phy() reentrant
{
uint16 absolute;
trace1(0, ms_media, 10, "ms_media_bind_log2phy() log:%04X", g_addr_log_blk);
switch (g_addr_zone)
{
case 0:
absolute = g_addr_log_blk;
break;
case 1:
absolute = g_addr_log_blk + _media_data(logical_blocks_per_boot_zone);
break;
default:
absolute = g_addr_log_blk + _media_data(logical_blocks_per_boot_zone);
absolute += (g_addr_zone - 1) * _media_data(logical_blocks_per_zone);
break;
}
trace3(0, ms, 10, "...zone:%02d absolute:0x%04X relative:0x%04X", g_addr_zone, absolute, g_addr_log_blk);
g_ms_extra[k_log_addr_msb_flg_offset] = _h(absolute);
g_ms_extra[k_log_addr_lsb_flg_offset] = _l(absolute);
return k_success;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result ms_media_set_phyblock_failed() reentrant
{
trace0(0, ms_media, 0, "ms_media_set_phyblock_failed()");
g_ms_extra[k_ovwr_flg_offset] &= ~ kbm_ms_ext_ovwr_bkst;
return k_error;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#define k_reference_bad_block_table
t_bool ms_media_is_phyblock_ok() reentrant
{
t_bool rslt;
trace0(0, ms_media, 110, "ms_media_is_phyblock_ok()");
// start out hopeful
rslt = k_yes;
// is this a user area block?
if(!g_addr_zone && g_addr_rd_phy_blk < g_ms_user_area_start_blk)
{
trace0(0, ms_media, 110, "alert: ms_media_is_phyblock_ok() - block is not in user area");
rslt = k_no;
}
// block status of 0 is bad
if (!(g_ms_extra[k_ovwr_flg_offset] & kbm_ms_ext_ovwr_bkst))
{
trace0(0, ms_media, 110, "alert: ms_media_is_phyblock_ok() - bad page by bkst");
rslt = k_no;
}
// page status of 1 is bad
if (g_ms_extra[k_ovwr_flg_offset] & (kbm_ms_ext_ovwr_pgst0 | kbm_ms_ext_ovwr_pgst1) == 1)
{
trace0(0, ms_media, 110, "alert: ms_media_is_phyblock_ok() - bad page by pgst01");
rslt = k_no;
}
// is it the log2phy map table block? if yes it should get whacked.
if (!g_ms_extra[k_mgmt_flg_offset] & kbm_ms_ext_mgmt_atflg)
{
trace0(0, ms_media, 110, "alert: ms_media_is_phyblock_ok() - table block found");
trace1(0, ms, 80, "atflg:%02X", g_ms_extra[k_mgmt_flg_offset] & kbm_ms_ext_mgmt_atflg);
}
#ifdef k_reference_bad_block_table
// read the bad block list
if (rslt == k_yes)
{
t_uw16 blk_to_check;
trace0(0, ms_media, 110, "reference the bad block table");
// look to see if this phy block is in it
trace2(0, ms_media, 110, "g_addr_zone:%d g_addr_rd_phy_blk:%d", g_addr_zone, g_addr_rd_phy_blk);
blk_to_check.u16 = g_addr_zone * _media_data(physical_blocks_per_zone) + g_addr_rd_phy_blk;
trace1(0, ms_media, 110, "blk_to_check:%d", blk_to_check.u16);
if (ms_is_this_blk_in_bad_blk_tbl(blk_to_check.u16))
{
// this physical block appears in the bad block list
rslt = k_no;
trace1(0, ms_media, 110, "alert: block:%d is in the bad block table!", blk_to_check.u16);
}
}
//exit:
#endif //k_reference_bad_block_table
trace1(0, ms_media, 110, "ms_media_is_phyblock_ok(): %c", rslt ? 'Y' : 'N');
return rslt;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result ms_media_is_phyblock_blank() reentrant
{
t_bool is_blank;
is_blank = (0xFF == g_ms_extra[k_log_addr_msb_flg_offset]) && (0xFF == g_ms_extra[k_log_addr_lsb_flg_offset]);
trace1(0, ms_media, 0, "ms_media_is_phyblock_blank(): %c", is_blank ? 'Y' : 'N');
return is_blank;
}
#if 0
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result ms_media_is_phyblock_wp() reentrant
{
t_bool is_wp;
uint16 blk_to_check;
blk_to_check = g_addr_zone * _media_data(physical_blocks_per_zone) + g_addr_rd_phy_blk;
trace1(0, ms_media, 110, "blk_to_check:%d", blk_to_check);
is_wp = ms_is_this_blk_the_information_block(blk_to_check);
trace1(0, ms_media, 0, "ms_media_is_phyblock_wp(): %c", is_wp ? 'Y' : 'N');
return is_wp;
}
#endif
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result ms_media_read_extra_data() reentrant
{
trace0(0, ms_media, 0, "ms_media_read_extra_data()------------------------------------");
set_rd_phyblk();
return ms_read_extra_data();
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result ms_media_write_extra_data() reentrant
{
trace0(0, ms_media, 0, "ms_media_write_extra_data()");
set_wr_phyblk();
return ms_write_extra_data();
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result ms_media_clear_extra_data(void) reentrant
{
trace0(0, ms_media, 0, "ms_media_clear_extra_data()");
memset(g_ms_extra, 0xFF, 4);
return k_success;
}
//+-----------------------------------------------------------------------------
// Name:
// ms_media_resolve_conflict()
//
// Declaration:
// t_result ms_media_resolve_conflict(void) reentrant
//
// Purpose:
// resolve a log2phy binding in a media-specific algorithm
//
// Arguments:
// - see Notes
//
// Return:
// k_success always
//
// Notes:
// when called,
// g_addr_rd_phy_blk contains one of the bindings,
// g_addr_wr_phy_blk contains the original mapping
//
// before returning, ensure:
// g_addr_rd_phy_blk should contain the correct mapping
// g_addr_wr_phy_blk should contain the block to be erased (or not used)
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
t_result ms_media_resolve_conflict() reentrant
{
uint16 tmp;
uint8 udst0;
uint8 udst1;
trace0(0, ms_media, 110, "ms_media_resolve_conflict()");
trace2(0, ms_media, 110, "->g_addr_rd_phy_blk:0x%04X, g_addr_wr_phy_blk:0x%04X", g_addr_rd_phy_blk, g_addr_wr_phy_blk);
// determine the update status of the block at g_addr_rd_phy_blk
set_rd_phyblk();
ms_read_extra_data();
udst0 = g_ms_extra[k_ovwr_flg_offset] & kbm_ms_ext_ovwr_udst;
// determine the update status of the block at g_addr_wr_phy_blk
set_wr_phyblk();
ms_read_extra_data();
udst1 = g_ms_extra[k_ovwr_flg_offset] & kbm_ms_ext_ovwr_udst;
// udst0 udst1 choose
// ----- ----- ------
// 0 0 largest phy addr
// 0 1 g_addr_rd_phy_blk
// 1 0 g_addr_wr_phy_blk
// 1 1 largest phy addr
if (udst0 == udst1)
{
// cannot tell by update status; choose the larger physical block number
tmp = _max(g_addr_rd_phy_blk, g_addr_wr_phy_blk);
g_addr_wr_phy_blk = _min(g_addr_rd_phy_blk, g_addr_wr_phy_blk);
g_addr_rd_phy_blk = tmp;
trace1(0, ms_media, 110, "-->chose larger:0x%04X", g_addr_rd_phy_blk);
}
else
if (!udst1)
{
// ye olde triangle swap
tmp = g_addr_wr_phy_blk;
g_addr_wr_phy_blk = g_addr_rd_phy_blk;
g_addr_rd_phy_blk = tmp;
trace1(0, ms_media, 110, "-->chose: wr by update status 0x%04X", g_addr_rd_phy_blk);
}
else
{
trace1(0, ms_media, 110, "-->chose: rd by update status 0x%04X", g_addr_rd_phy_blk);
}
// and reverse the order because this works, and doing it the way the spec says doesnt.
//tmp = g_addr_wr_phy_blk;
//g_addr_wr_phy_blk = g_addr_rd_phy_blk;
//g_addr_rd_phy_blk = tmp;
// otherwise udst0 must be zero, so no variable swapping needs to occur
return k_success;
}
//+-----------------------------------------------------------------------------
// Name:
// media_erase_card()
//
// Declaration:
// t_result media_erase_card() reentrant
//
// Purpose:
// TBD
//
// Arguments:
// TBD
//
// Return:
// k_success always
//
// Notes:
// TBD
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
#if 0
t_result ms_media_erase_card() reentrant
{
uint16 max_lb ;
trace0(0, sm, 0, "ms_media_erase_card() - Erasing Memory Stick Card.") ;
for(g_addr_zone=0 ; g_addr_zone < _media_data(num_zones) ; g_addr_zone++)
{
max_lb = g_addr_zone? (_media_data(logical_blocks_per_zone)) : (_media_data(logical_blocks_per_boot_zone)) ;
g_addr_log_blk = 0 ;
for(g_addr_wr_phy_blk = g_addr_zone?0:_media_data(cis_phy_block)+1;
g_addr_wr_phy_blk < _media_data(physical_blocks_per_zone) ;
g_addr_wr_phy_blk++)
{
_media_erase_block() ;
if( g_addr_log_blk < max_lb )
{
// bind the log2phy addrs... memory stick gets upset if all blocks are bound to log_blk 0xffff
_media_clear_extra_data() ;
_media_bind_log2phy() ;
_media_write_extra_data() ;
g_addr_log_blk++ ;
}
}
}
return k_success ;
}
#endif
//+-----------------------------------------------------------------------------
// Name:
// ms_media_is_phyblock_reserved()
//
// Declaration:
// t_result ms_media_is_phyblock_reserved() reentrant
//
// Purpose:
// tells mapper whether or not a block is reserved (i.e. boot area) or
// usable by mapper & user.
//
// Arguments:
//
// Return:
// k_true if physical zone/block can be a user-accessible block
// k_false if physical block should be ignored by the mapper for everything
//
// Notes:
// a reserved block is NOT a factory or user-marked bad block. it is a block reserved
// for storing private data or boot information. (i.e. boot blocks, boot area, etc.)
// blocks marked bad by the factory will be detected in a subsequent call
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
t_result ms_media_is_phyblock_reserved(void) reentrant
{
trace0(0, ms_media, 110, "ms_media_is_phyblock_reserved()");
if ((!g_addr_zone) && (g_addr_rd_phy_blk < g_ms_user_area_start_blk))
{
trace2(0, sm_media, 0, "block %d:%d is part of the boot area. tell mapper it is reserved", g_addr_zone, g_addr_rd_phy_blk);
return k_true;
}
return k_false;
}
//---eof------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -