📄 media.c
字号:
/*============================================================================
____________________________________________________________________________
______________________________________________
SSSS M M CCCC Standard Microsystems Corporation
S MM MM SSSS C Austin Design Center
SSS M M M S C 11000 N. Mopac Expressway
S M M SSS C Stonelake Bldg. 6, Suite 500
SSSS M M S CCCC Austin, Texas 78759
SSSS ______________________________________________
____________________________________________________________________________
Copyright(C) 1999, Standard Microsystems Corporation
All Rights Reserved.
This program code listing is proprietary to SMSC and may not be copied,
distributed, or used without a license to do so. Such license may have
Limited or Restricted Rights. Please refer to the license for further
clarification.
____________________________________________________________________________
Notice: The program contained in this listing is a proprietary trade
secret of SMSC, Hauppauge, New York, and is copyrighted
under the United States Copyright Act of 1976 as an unpublished work,
pursuant to Section 104 and Section 408 of Title XVII of the United
States code. Unauthorized copying, adaption, distribution, use, or
display is prohibited by this law.
____________________________________________________________________________
Use, duplication, or disclosure by the Government is subject to
restrictions as set forth in subparagraph(c)(1)(ii) of the Rights
in Technical Data and Computer Software clause at DFARS 52.227-7013.
Contractor/Manufacturer is Standard Microsystems Corporation,
80 Arkay Drive, Hauppauge, New York, 1178-8847.
____________________________________________________________________________
____________________________________________________________________________
media.c - common media sector-mapping, sector copying code, used as a base
class for sm_media & ms_media specific classes
____________________________________________________________________________
comments tbd
____________________________________________________________________________
Revision History
Date Who Comment
________ ___ _____________________________________________________________
03/01/02 cds initial version
04/19/02 cds added stub for media_resolve_conflict virtual method
06/21/02 cds removed place-holder media and nil_media vtbl definitions with
a single "placeholder" vtbl initialized to NULL so that
media derived from code shared between luns can be included
in the project independently of whether one, or both luns
are included. (i.e. Smart Media removable lun coexists with
NAND fix media lun, even though nand.c derives from sm.c
06/27/02 cds added default media_set_read_addr(), media_set_write_addr(),
and media_set_erase_addr() functions
07/09/02 cds - _media_data(sectors_per_block) and g_addr_sector 8->16 bit conversion
- renamed WorkBuf to g_sector_buffer
- moved definition of g_sector_buffer to lun.c
07/16/02 cds aded nand_2k_media to code vtable
07/29/02 cds removed g_media_err_code references (old smil leftover)
07/31/02 cds - defined set of global g_media_data variables which correspond
(in order) to the media_data_structure... it's is IMPORTANT
that the compile time directive 'ORDER' be used so that these
variables are linked in memory in the order they are defined,
starting with g_media_data_max_zones.
- implemented media_set_active() to swap active media objects
by storing current globals into the media_data table, and
loading the new media object data into the globals
- repeated paging experiment with the vtable as well... another
1 1/2K code shaved! faster too
09/04/02 cds address name & usage change-over
g_addr_sector => g_addr_page,
g_addr_page => g_addr_segment,
_media_data(sectors_per_block) => _media_data(pages_per_block)
_media_data(cis_phy_block) => _media_data(boot_block)
_media_data(cis_sector) => _media_data(boot_sector)
09/18/02 cds added _media_data(options) field
09/22/02 cds abstracted media_copy_block() to reduce repeat of code between
the copy_head and copy_tail functions... shouldn't, but may
affect other luns, since copy_head no longer allocates a block
for writing... it assumes one has been pre-allocated like all
other media functions.
09/22/02 cds - fixed glitch in copy-head count calculation.
09/22/02 cds - added erase cache variables to media instance data
09/23/02 cds moved mode sense dfa for fmt dev page from lun to media so that
luns w/o the mapper will be able to link
09/26/02 cds updated media_dfa_report_media_geometry to return sectors per page
rather than bytes per sector
10/01/02 cds fixed definition of copy_block() to use reentrant model as it
was declared
10/02/02 cds updated safe_erase to only tap into nand/sm private variables when
they are in the build. (fixes single-lun MS builds)
10/10/02 cds updated media erase to erase any password after erasing either the
whole media or the boot block. Should the cable be pulled before the flash is erased,
the password will still be intact
10/11/02 cds fixed erase media logic, so on zone==0, it erases only zone 0, not all zones.
10/13/02 cds - fixed bug in erase media to fail if media is reported to be write protected
- updated erase media clear-password feature loop control slightly.
- added code to re-seek teh boot block after doing a block erase (fixes corrupted eeprom bug)
10/17/02 cds - project-wide lun data & vtbl paging to reduce code space.
- removed g_active_media from _lun_data, _lun_() virtual functions
- added _lun_data_rd() and _lun_data_wr() macros to bypass lun paging
- added lun_set_active(log_lun) function to switch luns
10/23/02 cds - added feature to mark source block "bad" when a read (copy_src) error occurs, but pass the copy
- added feature to erase dest block when copy write (copy_dst) error occurs, and fail the copy
10/29/02 cds - added new virtual media_block_has_bad_data() function to check for data_status failures in smart media
- added defautl media_block_has_bad_data() function to return false for memory stick.
11/02/02 cds - updated media_resolve_conflict to call map_resolve_conflict by default
11/03/02 cds - added default media_is_phyblock_reserved() function
11/13/02 ds added nan_int_media to the vtable
============================================================================*/
#define __media_dot_c__
#include "project.h"
#include "dev.h"
// provide a NULL place holder for un-used media classes
code _vtbl_decl(media) = { (t_thd_entry) NULL } ;
//------------------------------------------------------------------------------
// tables indexed by physical lun number. they are fixed, and do not change orded with build
xdata uint8 g_media_data[k_max_media][sizeof(t_media_data)] ;
code t_thd_entry* g_media_tbl[k_max_media] =
{
#if (k_log_lun_sm < k_max_log_lun)
_vtbl(sm_media),
#else
_vtbl(media),
#endif
#if (k_log_lun_ms < k_max_log_lun)
_vtbl(ms_media),
#else
_vtbl(media),
#endif
#if (k_log_lun_nand < k_max_log_lun)
_vtbl(nand_media),
_vtbl(nand_2k_media),
_vtbl(nand_int_media)
#else
_vtbl(media),
_vtbl(media)
#endif
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
xdata uint8 g_active_media;
// it is necessary for the ORDER directive to be used
// when compiling media.c so that these variables are
// linked into sequential memory
xdata uint8 g_media_data_num_zones;
xdata uint16 g_media_data_physical_blocks_per_zone;
xdata uint16 g_media_data_logical_blocks_per_zone;
xdata uint16 g_media_data_logical_blocks_per_boot_zone;
xdata uint8 g_media_data_pages_per_block;
xdata uint8 g_media_data_segments_per_page;
xdata t_log2phy_map_ref g_media_data_log2phy_map;
xdata t_assign_map_ref g_media_data_assign_map;
xdata t_erase_cache_ref g_media_data_erase_cache;
xdata uint16 g_media_data_assign_start[2];
xdata uint16 g_media_data_erase_start[2];
xdata uint16 g_media_data_assign_zone;
xdata uint16 g_media_data_boot_block;
xdata uint16 g_media_data_boot_page;
xdata uint8 g_media_data_options;
xdata t_xdata_ref g_media_data_sector_buffer;
// media address of current operation
xdata uint8 g_addr_zone; // zone/segment component of address
xdata uint16 g_addr_page; // 0-based sector/page (512 bytes) within block
xdata uint16 g_addr_rd_phy_blk; // 0-based physical block # within zone/segment
xdata uint16 g_addr_wr_phy_blk; // 0-based physical block # within zone/segment
xdata uint16 g_addr_log_blk; // 0-based logical block # within zone/segment
xdata uint8 g_addr_segment ; // 0-based page that may contain 1 or more sectors (2048 byte page nand flash)
// or contained partial sector data (256 byte pages for sm)
// vtable cached into xdata indirect function pointers
xdata t_media_entry v_media_erase_block;
xdata t_media_entry v_media_read_sector;
xdata t_media_entry v_media_write_sector;
xdata t_media_entry v_media_copy_sector;
xdata t_media_entry v_media_read_cis;
xdata t_media_entry v_media_phy2log;
xdata t_media_entry v_media_bind_log2phy;
xdata t_media_entry v_media_set_phyblock_failed;
xdata t_media_entry v_media_is_phyblock_reserved;
xdata t_media_entry v_media_is_phyblock_ok;
xdata t_media_entry v_media_is_phyblock_blank;
xdata t_media_entry v_media_read_extra_data;
xdata t_media_entry v_media_write_extra_data;
xdata t_media_entry v_media_clear_extra_data;
xdata t_media_entry v_media_resolve_conflict;
xdata t_media_entry v_media_set_read_addr;
xdata t_media_entry v_media_set_write_addr;
xdata t_media_entry v_media_set_erase_addr;
xdata t_media_entry v_media_block_has_bad_data;
//+-----------------------------------------------------------------------------
// Name:
// media_set_active()
//
// Declaration:
// void media_set_active(uint8 media) reentrant
//
// Purpose:
//
// Arguments:
//
// Return:
//
// Notes:
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
void media_set_active(uint8 media) reentrant
{
mcu_begin_critical_section() ;
if(g_active_media != media)
{
if (g_active_media < k_max_media)
{
TRACE1(308, media, 0, "storing media data %d", g_active_media) ;
// media_dbg_dump_active() ;
memcpy(g_media_data[g_active_media], (uint8 *) &g_media_data_num_zones, sizeof(t_media_data)) ;
}
TRACE1(309, media, 0, "loading media data %d", media) ;
memcpy((uint8 *) &g_media_data_num_zones, g_media_data[media], sizeof(t_media_data)) ;
TRACE1(310, media, 0, "loading media vtable %d", media) ;
memcpy((uint8 *) &v_media_erase_block, g_media_tbl[media], sizeof(t_media_entry)*k_media_vtbl_sz) ;
g_active_media=media ;
// media_dbg_dump_active() ;
}
TRACE1(311, media, 0, "media %d already active", g_active_media) ;
mcu_end_critical_section() ;
}
#if 0
//+-----------------------------------------------------------------------------
// Name:
// media_dump_addr()
//
// Declaration:
// void media_dump_addr() reentrant
//
// Purpose:
//
// Arguments:
//
// Return:
//
// Notes:
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
void media_dump_addr() reentrant;
void media_dump_addr() reentrant
{
mcu_begin_critical_section() ;
TRACE3(312, media, 0, "g_addr: zone:%d log:%d page:%d segment:%d", g_addr_zone, g_addr_log_blk, g_addr_page, g_addr_segment) ;
TRACE2(313, media, 0, "g_addr: rd_phy:%d wr_phy:%d", g_addr_rd_phy_blk, g_addr_wr_phy_blk) ;
mcu_end_critical_section() ;
}
//+-----------------------------------------------------------------------------
// Name:
// media_dbg_dump_active()
//
// Declaration:
// void media_dbg_dump_active(void) reentrant
//
// Purpose:
// TBD
//
// Arguments:
// TBD
//
// Return:
// TBD
//
// Notes:
// TBD
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
void media_dbg_dump_active() reentrant
{
TRACE1(314, media, 0, "------- Active Media: %d -------",g_active_media) ;
TRACE1(315, media, 0, "g_media_data_num_zones :%d", g_media_data_num_zones) ;
TRACE1(316, media, 0, "g_media_data_physical_blocks_per_zone :%d", g_media_data_physical_blocks_per_zone);
TRACE1(317, media, 0, "g_media_data_logical_blocks_per_zone :%d", g_media_data_logical_blocks_per_zone);
TRACE1(318, media, 0, "g_media_data_logical_blocks_per_boot_zone :%d", g_media_data_logical_blocks_per_boot_zone);
TRACE1(319, media, 0, "g_media_data_pages_per_block :%d", g_media_data_pages_per_block);
TRACE1(320, media, 0, "g_media_data_segments_per_page :%d", g_media_data_segments_per_page);
TRACE1(321, media, 0, "g_media_data_log2phy_map :%04X", ((uint16) g_media_data_log2phy_map)) ;
TRACE1(322, media, 0, "g_media_data_assign_map :%04X", ((uint16) g_media_data_assign_map)) ;
TRACE2(323, media, 0, "g_media_data_assign_start [0],[1] :%d,%d", g_media_data_assign_start[0],g_media_data_assign_start[1]) ;
TRACE1(324, media, 0, "g_media_data_assign_zone :%d", g_media_data_assign_zone) ;
TRACE1(325, media, 0, "g_media_data_cis_phy_block :%d", g_media_data_cis_phy_block) ;
TRACE1(326, media, 0, "g_media_data_cis_sector :%d", g_media_data_cis_sector) ;
TRACE1(327, media, 0, "g_media_data_sector_buffer: :%04X", ((uint16) g_media_data_sector_buffer)) ;
}
#endif
//+-----------------------------------------------------------------------------
// Name:
// media_erase_block()
//
// Declaration:
// t_result media_erase_block(void) reentrant
//
// Purpose:
// TBD
//
// Arguments:
// TBD
//
// Return:
// TBD
//
// Notes:
// TBD
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
t_result media_erase_block(void) reentrant
{
TRACE0(328, media, 0, "+media_erase_block()") ;
return k_error ;
}
//+-----------------------------------------------------------------------------
// Name:
// media_read_sector()
//
// Declaration:
// t_result media_read_sector(void) reentrant
//
// Purpose:
// TBD
//
// Arguments:
// TBD
//
// Return:
// TBD
//
// Notes:
// TBD
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
t_result media_read_sector(void) reentrant
{
TRACE0(329, media, 0, "+media_read_sector()") ;
return k_error ;
}
//+-----------------------------------------------------------------------------
// Name:
// media_write_sector()
//
// Declaration:
// t_result media_write_sector(void) reentrant
//
// Purpose:
// TBD
//
// Arguments:
// TBD
//
// Return:
// TBD
//
// Notes:
// TBD
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
t_result media_write_sector(void) reentrant
{
TRACE0(330, media, 0, "+media_write_sector()") ;
return k_error ;
}
//+-----------------------------------------------------------------------------
// Name:
// media_read_cis()
//
// Declaration:
// t_result media_read_cis(void) reentrant
//
// Purpose:
// TBD
//
// Arguments:
// TBD
//
// Return:
// TBD
//
// Notes:
// TBD
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
t_result media_read_cis(void) reentrant
{
TRACE0(331, media, 0, "+media_read_cis()") ;
return k_error ;
}
//+-----------------------------------------------------------------------------
// Name:
// media_phy2log()
//
// Declaration:
// t_result media_phy2log(void) reentrant
//
// Purpose:
// TBD
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -