📄 nand.c
字号:
//+-----------------------------------------------------------------------------
// Name:
// sm_power_up()
//
// Declaration:
// t_result sm_power_up(void) reentrant
//
// Purpose:
//
// Arguments:
//
// Return:
//
// Notes:
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
t_result nand_power_up(void) reentrant
{
trace0(0, nand, 0, "nand_power_up()");
return k_success ;
}
//+-----------------------------------------------------------------------------
// Name:
// sm_reset_controller()
//
// Declaration:
// void sm_reset_controller(void) reentrant
//
// Purpose:
// erase all physical blocks on media card, then
// rebuild sector mapping table
//
// Arguments:
// none
//
// Return:
//
// Notes:
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
void nand_reset_controller(void) reentrant
{
trace0(0, nand, 0, "nand_reset_controller()");
}
//+-----------------------------------------------------------------------------
// Name:
// dfa_sm_identify_media
//
// Declaration:
// void dfa_sm_identify_media(void);
//
// Purpose:
// determine if smart media is present the device and if so,
// determine max lba and lb size
//
// Arguments:
// none
//
// Return:
// none
//
// Notes:
// This is a DFA
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
void nand_dfa_identify_media(void) reentrant
{
trace0(0, nand, 0, "nand_dfa_identify_media()");
_lun_data(media) |= kbm_lun_media_unknown ;
if (k_success != nand_check_format())
{
trace0(0, nand, 0, "nand_check_format() returned an error!") ;
_thread_return_dfa(k_error) ;
}
_lun_data(capacity.lba_max.u32) = _media_data(num_zones) * (uint32) _media_data(logical_blocks_per_zone) * (uint32) _media_data(pages_per_block) ;
_lun_data(capacity.lba_sz.u32) = 512 ;
if( x_media_sts & kbm_media_sts_sm_256_page )
_lun_data(capacity.lba_max.u32) /= 2 ;
if( k_ix_media_nand_2k == g_active_media)
_lun_data(capacity.lba_max.u32) *= 4 ;
_lun_data(capacity.lba_max.u32) -= (uint32) 1 ;
// media is now known
_lun_data(media) &= ~kbm_lun_media_unknown;
_lun_data(sensep) = &sense_media_change;
if(x_media_sts & kbm_media_sts_sm_wp )
_lun_data(media) |= kbm_lun_media_wrprot ;
else
_lun_data(media) &= ~kbm_lun_media_wrprot ;
#if 1
// check attributes
if(g_dev_attr_lo&kbm_attr_lo_sm_timing)
{
trace0(0, nand, 0, "Forcing Smart Media-Compatible Cycle Timing on NAND flash") ;
g_nand_rw_speed=0;
}
else
{
trace0(0, nand, 0, "Enabling fast cycle time on NAND flash") ;
g_nand_rw_speed=kbm_sm_mode_fast_cycle_time;
}
#else
g_nand_rw_speed=0;
#endif
trace2(0, nand, 0, "nand capacity: lba_max:%04x%04x lba_sz:00000200", _hw(_lun_data(capacity.lba_max.u32)), _lw(_lun_data(capacity.lba_max.u32))) ;
thread_return_dfa(k_success) ;
}
//+-----------------------------------------------------------------------------
// Name:
// TBD
//
// Declaration:
// TBD
//
// Purpose:
// TBD
//
// Arguments:
// TBD
//
// Return:
// TBD
//
// Notes:
// This is a DFA, not a FUNCTION.
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
void nand_dfa_initialize_media() reentrant
{
trace0(0, nand, 0, "nand_dfa_initialize_media()");
_lun_data(media) &= ~kbm_lun_media_changed;
trace2(0, lun, 0, "_lun_data(%d, media)=%02x", g_active_media, _lun_data(media));
_thread_return_dfa(k_success);
}
//+-----------------------------------------------------------------------------
// Name:
// TBD
//
// Declaration:
// TBD
//
// Purpose:
// TBD
//
// Arguments:
// TBD
//
// Return:
// TBD
//
// Notes:
// This is a DFA, not a FUNCTION.
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
void nand_dfa_reset_media() reentrant
{
trace0(0, nand, 0, "nand_dfa_reset_media()");
_thread_return_dfa(k_success);
}
//+-----------------------------------------------------------------------------
// Name:
// sm_initialize_controller()
//
// Declaration:
// void sm_initialize_controller(void) reentrant
//
// Purpose:
// TBD
//
// Arguments:
// TBD
//
// Return:
// TBD
//
// Notes:
// TBD
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
void nand_initialize_controller(void) reentrant
{
uint16 i;
trace0(0, nand, 0, "nand_initialize_controller()") ;
// initialize _lun_data
memcpy(_lun_data(device_id), "HD", k_lun_max_devid_sz) ;
_lun_data(media) &=~ kbm_lun_media_unknown ;
g_nand_rw_speed=0 ;
#ifdef k_opt_password
_lun_data(media) |= kbm_lun_media_lockable;
#endif
// by default, it is thus. However, we must check at run-time
// whether or not to keep it such. The removable bit is first used
// checked on Inquiry processing
_lun_data(media) &=~ kbm_lun_media_removable;
_lun_data(device_type) = k_device_type_nand ;
// we have to make sure we wait at least 1 ms before accessing the device,
// but we don't have a timer running yet
i=1000 ;
while(i--) ;
// try to identify the media configuration
fmc_select_nand() ;
if ( k_success != nand_identify_media_format() )
{
trace0(0, nand, 0, "failed to identify media format") ;
return;
}
// $$$ intercepting
// util_trace_media() ;
// util_trace_map_media() ;
// read the boot block to see if out custom boot structure exists.
nand_boot_seek() ;
#ifdef k_enable_write_caching
// initialize the write head/tail cache
map_write_cache_init() ;
#endif
// safe erase the media here... for utilitarian purposes
// util_safe_erase_media() ;
// util_trace_map_media();
/*
for(g_addr_rd_phy_blk=0;g_addr_rd_phy_blk<8;g_addr_rd_phy_blk++)
{
util_trace_phy_block();
}
*/
// util_trace_log_media();
/*
g_addr_rd_phy_blk=0;
g_addr_page=0;
_media_data(boot_block)=0;
_media_data(boot_page)=0;
_media_data(assign_zone)=0;
g_addr_zone=0;
map_build_sector_map();
util_test_copy_double_bit_ecc(33) ;
*/
// store initial state of the wp bit.
_nand_media_status = _mcu_register_rd(x_media_sts) ;
}
//------------------------------------------------------------------------------
void nand_dfa_inquiry(void) reentrant
{
trace0(0, nand, 0, "nand_dfa_inquiry()") ;
// check attribute bit... will be valid by this point
if(g_dev_attr_lo&kbm_attr_lo_hd_as_rm)
{
trace0(0, nand, 0, "kbm_attr_lo_hd_as_rm bit set. Reporting lun as Removable") ;
_lun_data(media)|=kbm_lun_media_removable ;
}
else if(x_media_sts&kbm_media_sts_sm_wp )
{
trace0(0, nand, 0, "nand write protected. Reporting lun as Removable") ;
_lun_data(media)|=kbm_lun_media_removable ;
}
else if(!g_password_validated)
{
trace0(0, nand, 0, "Password exists, and is not validated. Make removable") ;
_lun_data(media)|=kbm_lun_media_removable;
}
else
{
trace0(0, nand, 0, "reporting lun as Fixed Media") ;
_lun_data(media)&=~kbm_lun_media_removable ;
}
// call base class
dfa_lun_inquiry() ;
}
//+-----------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result nand_check_wp() reentrant
{
uint8 cs ;
trace0(0, nand, 0, "nand_check_wp()") ;
if( _lun_data(media)&kbm_lun_media_removable)
{
// check to see if there's been a change
cs=_mcu_register_rd(x_media_sts)&kbm_media_sts_sm_wp;
_nand_media_status&= kbm_media_sts_sm_wp;
if(_nand_media_status^cs)
{
trace2(0, nand, 0, "media_sts sm_wp bit change detected. _nand_media_status:%02X x_media_sts:%02X", _nand_media_status, x_media_sts) ;
_lun_data(sensep) = &sense_media_change ;
_lun_data(media) |= kbm_lun_media_unknown;
_nand_media_status=cs;
// change
return k_true ;
}
}
// no change in wp status
return k_false ;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void nand_process_idle() reentrant
{
trace0(0, nand, 0, "nand_dfa_process_idle()") ;
#if 0
if( _media_data(options)&kbm_media_data_opt_write_cache)
{
trace0(0, nand, 0, "flushing write cache()") ;
map_write_cache_flush_all();
}
#endif
if( _media_data(options)&kbm_media_data_opt_erase_cache)
{
trace0(0, nand, 0, "flushing erase cache()") ;
map_erase_cache_flush_all();
}
_lun_data(media)&=~kbm_lun_media_process_idle;
}
//+-----------------------------------------------------------------------------
// Name:
// nand_dfa_test_unit_ready
//
// Declaration:
// void dfa_lun_test_unit_ready(void);
//
// Purpose:
//
// Arguments:
//
// Return:
//
// Notes:
// This allows us to check if the wp status has 'changed' since previous cmd.
// if so, then report a media change.
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
void nand_dfa_test_unit_ready(void)reentrant
{
trace0(0, nand, 0, "nand_dfa_test_unit_ready()");
// if happy, check wp status. this function will update sensep
if( _lun_data(sensep) == &sense_none)
nand_check_wp() ;
// call base-class
dfa_lun_test_unit_ready() ;
// report sense as normal.
_thread_return_dfa((_lun_data(sensep) == &sense_none) ? k_command_passed : k_command_failed);
}
//+-----------------------------------------------------------------------------
// Name:
// sm_dfa_verify()
//
// Declaration:
// void sm_dfa_verify(void);
//
// Purpose:
// Verify that the data on the drive matches the data sent down.
//
// Arguments:
// None.
// Uses _lun_data and g_bot_cbw to get its parameters.
//
// Return:
// No return value.
// However, on exit the DFA's argument pointer is written with a t_csw_status indicating:
// k_command_passed - command completed.
// k_command_failed - an error occurred.
//
// Notes:
// This is the start STATE of the dfa_ata_verify DFA.
// It overrides dfa_lun_verify.
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
void nand_dfa_verify() reentrant
{
trace0(0, nand, 0, "dfa_ata_verify");
// _fmc_set_callback(sm_read_begin_xfer, sm_read_end_xfer, sm_read_begin_split, sm_read_end_split, sm_read_begin_burst, fmc_dflt_callback, sm_read_end_burst);
dfa_lun_verify();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -