📄 ms.c
字号:
// pages per block?
_ms_page_per_block = _ms_byte_per_block.u16 / 512;
trace1(0, ms, 80, "_ms_page_per_block:%d", _ms_page_per_block);
_media_data(pages_per_block) = _ms_page_per_block;
// 1 segment (sector) per page
_media_data(segments_per_page) = 1 ;
// ASSEMBLER:
// SanDisk 01 (sampled 15 cards)
// Lexar 02, 03 (sampled 15 cards)
// Sony 01 (sampled 4 cards)
// Apacer 01 (sampled 1 card)
#if 0
{
uint8 assembler;
t_udw32 assembly;
xbuf_rd(440, 1, &(assembler));
trace1(0, ms, 80, "assembler code:%d", assembler);
xbuf_rd(441, 80, &(assembly.u8.lh));
xbuf_rd(442, 80, &(assembly.u8.hl));
xbuf_rd(443, 80, &(assembly.u8.lo));
trace3(0, ms, 80, "assembly model code:00%02X%02X%02X", assembly.u8.lh, assembly.u8.hl, assembly.u8.lo);
}
#endif
// this block is only enabled to facilitate debugging the SanDisk 64MB issue...
#if 1 // this is currently unused by the mapper
// found the disabled block data
g_ms_page = 1;
if (k_success != (rslt = ms_pio_read_page(k_max_pnr)))
{
trace0(0, err, 80, "error: cant read page one of this boot block");
continue;
//goto exit;
}
trace0(0, ms, 80, "PAGE 1 (DISABLED BLOCK DATA)");
{
t_uw16 x;
uint8 i;
for (i=0; i<255; i++)
{
#if 0
xbuf_rd(i*2, 1, &x.u8.lo); // big endian
xbuf_rd(i*2+1, 1, &x.u8.hi);
#else
xbuf_rd(i*2, 1, &x.u8.hi); // big endian
xbuf_rd(i*2+1, 1, &x.u8.lo);
#endif
// stop at the end of the list
_ms_bad_blk_tbl[i] = x.u16;
if (x.u16 == 0xFFFF)
break;
if (i)
{
trace1(0, ms, 80, "bad block:%d", x.u16);
}
else
{
trace1(0, ms, 80, "information block:%d", x.u16);
}
trace2(0, ms, 80, " (zone:%d phy:%d)", x.u16/k_phy_block_per_segment, x.u16%512);
if (x.u16/k_phy_block_per_segment > _media_data(num_zones))
{
trace0(0, ms, 80, " (off the end of the card - meaningless)");
continue;
}
g_ms_blk_addr_msb = 0;
g_ms_blk_addr_mid = 0;
g_ms_blk_addr_lsb = x.u16;
g_ms_page = 0;
if (k_success != ms_read_extra_data_reg())
{
trace0(0, err, 80, " error: can't read xtra data");
}
else
{
trace4(0, ms, 80, " xtra[0..3]:%02X%02X%02X%02X", g_ms_extra[0], g_ms_extra[1], g_ms_extra[2], g_ms_extra[3]);
// block status of 0 is bad
if (!(g_ms_extra[k_ovwr_flg_offset] & kbm_ms_ext_ovwr_bkst))
{
trace0(0, ms, 80, " bad block by bkst - mapper will detect");
}
else
{
// if this is seen for VALID bad blocks then ms_media_is_phyblock_ok
// needs to refer to the bad block table before rendering its decision
trace0(0, ms, 80, " good block by bkst - mapper needs assist to detect");
}
}
}
//fmc_dbg_dump_sector((uint8*)_ms_bad_blk_tbl);
}
g_ms_blk_addr_msb = 0;
g_ms_blk_addr_mid = 0;
g_ms_blk_addr_lsb = blk;
#endif
// found the cis/idi page
g_ms_page = 2;
if (k_success != (rslt = ms_pio_read_page(k_max_pnr)))
{
trace0(0, err, 80, "error: cant read page two of this boot block");
continue;
//goto exit;
}
trace0(0, ms, 80, "PAGE 2 (CIS/IDI)");
#if 0 // this is debug stuff
//dbg_dumpram(k_pkt_addrlo[pnr], k_pkt_addrhi[pnr], 512);
{
t_uw16 x, y;
trace0(0, ms, 0, "=====STUFF FROM THE IDI=====");
xbuf_rd(258, 1, &x.u8.lo);
xbuf_rd(259, 1, &x.u8.hi);
trace1(0, ms, 80, "cylinders per head:%d", x.u16);
xbuf_rd(262, 1, &x.u8.lo);
xbuf_rd(263, 1, &x.u8.hi);
trace1(0, ms, 80, "heads per disk:%d", x.u16);
xbuf_rd(264, 1, &x.u8.lo);
xbuf_rd(265, 1, &x.u8.hi);
trace1(0, ms, 80, "bytes per track:%d", x.u16);
xbuf_rd(266, 1, &x.u8.lo);
xbuf_rd(267, 1, &x.u8.hi);
trace1(0, ms, 80, "bytes per sector:%d", x.u16);
xbuf_rd(268, 1, &x.u8.lo);
xbuf_rd(269, 1, &x.u8.hi);
trace1(0, ms, 80, "sectors per track:%d", x.u16);
xbuf_rd(364, 1, &x.u8.lo);
xbuf_rd(365, 1, &x.u8.hi);
trace1(0, ms, 80, "current cylinders per head:%d", x.u16);
xbuf_rd(366, 1, &x.u8.lo);
xbuf_rd(367, 1, &x.u8.hi);
trace1(0, ms, 80, "current heads per disk:%d", x.u16);
xbuf_rd(368, 1, &x.u8.lo);
xbuf_rd(369, 1, &x.u8.hi);
trace1(0, ms, 80, "sectors per track:%d", x.u16);
xbuf_rd(264, 1, &x.u8.lo);
xbuf_rd(265, 1, &x.u8.hi);
xbuf_rd(264, 1, &y.u8.lo);
xbuf_rd(265, 1, &y.u8.hi);
trace2(0, ms, 80, "current capacity in sectors:0x%04X%04X", x.u16, y.u16);
}
#endif
#if 0
// firmware version
{
t_udw32 fwlo;
t_udw32 fwhi;
xbuf_rd(302, 1, &(fwhi.u8.hi));
xbuf_rd(303, 1, &(fwhi.u8.lh));
xbuf_rd(304, 1, &(fwhi.u8.hl));
xbuf_rd(305, 1, &(fwhi.u8.lo));
xbuf_rd(306, 1, &(fwlo.u8.hi));
xbuf_rd(307, 1, &(fwlo.u8.lh));
xbuf_rd(308, 1, &(fwlo.u8.hl));
xbuf_rd(309, 1, &(fwlo.u8.lo));
trace4(0, ms, 80, "fwver:%02X%02X%02X%02X", fwhi.u8.hi, fwhi.u8.lh, fwhi.u8.hl, fwhi.u8.lo);
trace4(0, ms, 80, " %02X%02X%02X%02X", fwlo.u8.hi, fwlo.u8.lh, fwlo.u8.hl, fwlo.u8.lo);
}
#endif
// total logical sectors?
xbuf_rd(270, 1, &(_lun_data(capacity).lba_max.u8.lh));
xbuf_rd(271, 1, &(_lun_data(capacity).lba_max.u8.hi));
xbuf_rd(272, 1, &(_lun_data(capacity).lba_max.u8.lo));
xbuf_rd(273, 1, &(_lun_data(capacity).lba_max.u8.hl));
_lun_data(capacity).lba_max.u32 -= 1;
trace2(0, ms, 80, "Total User-addressable Sectors: %04X%04X", _hw(_lun_data(capacity).lba_max.u32), _lw(_lun_data(capacity).lba_max.u32));
_lun_data(capacity).lba_sz.u32 = 512;
}
//get_out:
rslt = k_error;
if (boot_count)
{
g_addr_zone = 0;
rslt = k_success;
}
//exit:
trace1(0, ms, 80, "found %d boot blocks", boot_count);
trace1(0, ms, 80, "user area starts at block %d", g_ms_user_area_start_blk);
return rslt;
}
//------------------------------------------------------------------------------
t_result ms_find_map_block(void) reentrant;
t_result ms_find_map_block() reentrant
{
uint16 blk;
uint8 zone;
uint8 old_zone;
t_result rslt;
trace0(0, ms, 80, "ms_find_map_block()");
trace1(0, ms, 80, "current zone:%d", g_addr_zone);
rslt = k_error;
zone = _media_data(num_zones) - 1;
old_zone = g_addr_zone;
g_addr_zone = zone;
set_rd_phyblk();
g_ms_page = 0;
for (blk=0; blk<512; blk++)
{
trace2(0, ms, 80, "checking block %d of zone:%d", blk, zone);
// read page 0 of the block
if (k_success != (rslt = ms_pio_read_page(k_max_pnr)))
{
trace1(0, err, 80, "error: cant read page zero of block:%d", blk);
continue;
}
// 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)
{
continue;
}
// found the map block
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);
trace1(0, ms, 80, "MAP BLOCK:%d", blk);
fmc_dbg_dump_sector((uint8*)g_sector_buffer);
rslt = k_success;
}
g_addr_zone = old_zone;
trace1(0, ms, 80, "restored zone:%d", g_addr_zone);
return rslt;
}
//+-----------------------------------------------------------------------------
// Name:
// ms_reset_controller
//
// Declaration:
// void ms_reset_controller(void);
//
// Purpose:
// Reset the MSC block of the 210.
//
// Arguments:
// None.
//
// Return:
// None.
//
// Notes:
// This is a FUNCTION, not a DFA.
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
void ms_reset_controller() reentrant
{
uint8 loop;
trace0(0, ms, 0, "ms_reset_controller()");
//_stack_check();
ms_mode_ctl |= kbm_ms_mode_ctl_msc_rst;
loop = 0xff;
while (loop--);
ms_mode_ctl &= ~kbm_ms_mode_ctl_msc_rst;
_mcu_register_set_bits(x_fmc_clk_ctl, k_fmc_clk_ctl_ms_20mhz);
_ms_register_set_bits(ms_mode_ctl, kbm_ms_mode_ctl_sien);
}
//+-----------------------------------------------------------------------------
// Name:
// ms_initialize_controller
//
// Declaration:
// void ms_initialize_controller(void);
//
// Purpose:
// Initialize the MSC block of the 210.
//
// Arguments:
// None.
//
// Return:
// None.
//
// Notes:
// This is a FUNCTION, not a DFA.
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
void ms_initialize_controller() reentrant
{
trace0(0, ms, 1, "ms_initialize_controller()");
//_stack_check();
//strncpy(_lun_data(k_lun_ms, device_id), "MEMORY STICK", k_lun_max_devid_sz);
memcpy(_lun_data(device_id), "MS", k_lun_max_devid_sz);
_lun_data(device_type) = k_device_type_ms;
_lun_data(max_lb_per_burst) = 1;
_mcu_register_set_bits(x_fmc_clk_ctl, k_fmc_clk_ctl_ms_20mhz);
_ms_register_set_bits(ms_mode_ctl, kbm_ms_mode_ctl_sien);
media_set_active(k_ix_media_ms);
_media_data(log2phy_map) = (t_log2phy_map_ref)_ms_log2phy;
_media_data(assign_map) = (t_assign_map_ref)_ms_assign_map;
}
//+-----------------------------------------------------------------------------
// Name:
// dfa_ms_reset_media
//
// Declaration:
// void dfa_ms_reset_media(void);
//
// Purpose:
// Deliver a reset command to the MS card.
//
// Arguments:
// None.
//
// Return:
// None.
//
// Notes:
// This is a DFA, not a FUNCTION.
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
void dfa_ms_reset_media() reentrant
{
trace0(0, ms, 0, "dfa_ms_reset_media()");
//_stack_check();
// must wait at least 1 msec after por before issuing commands to ms
thread_set_timer(2);
while (!thread_got_sync(kbm_sync_timer));
// issue the reset
ms_set_cmd(k_ms_reset);
_thread_return_dfa(k_success);
}
//+-----------------------------------------------------------------------------
// Name:
// ms_initialize_media2
//
// Declaration:
// void ms_initialize_media2(void);
//
// Purpose:
// After the media has received a reset command, and then at least 1msec has
// expired, clear the media changed flag so that the device layer will not reast
// and initialize the card an more and will instead attempt to identify the media.
//
// Arguments:
// None
//
// 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 a state in a DFA, not a FUNCTION.
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
void ms_in
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -