www.pudn.com > ucos_vc.zip > smc_log.c
/*
**********************************************************************
* Micrium, Inc.
* 949 Crestview Circle
* Weston, FL 33327-1848
*
* uC/FS
*
* (c) Copyright 2001 - 2003, Micrium, Inc.
* All rights reserved.
*
***********************************************************************
----------------------------------------------------------------------
File : smc_log.c
Purpose : Generic logical sector read/write access module for SMC
----------------------------------------------------------------------
Known problems or limitations with current version
----------------------------------------------------------------------
None.
---------------------------END-OF-HEADER------------------------------
*/
/*********************************************************************
*
* #include Section
*
**********************************************************************
*/
#include "fs_port.h"
#include "fs_dev.h"
#include "fs_conf.h"
#if FS_USE_SMC_DRIVER
#include "smc.h"
/*********************************************************************
*
* #define macros
*
**********************************************************************
*/
#define Set_X_Bit(a,b) (a[(unsigned char)((b)/8)]|= _FS_SMC_BitData[(b)%8])
#define Clr_X_Bit(a,b) (a[(unsigned char)((b)/8)]&=~_FS_SMC_BitData[(b)%8])
#define Chk_X_Bit(a,b) (a[(unsigned char)((b)/8)] & _FS_SMC_BitData[(b)%8])
/*********************************************************************
*
* Local Variables
*
**********************************************************************
*/
static const char _FS_SMC_BitData[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 };
static unsigned int _FS_SMC_ErrCode[FS_SMC_MAXUNIT];
static unsigned char _FS_SMC_SectBuf[SECTSIZE];
static unsigned char _FS_SMC_WorkBuf[SECTSIZE];
static unsigned char _FS_SMC_Redundant[REDTSIZE];
static unsigned char _FS_SMC_WorkRedund[REDTSIZE];
static unsigned short _FS_SMC_Log2Phy[FS_SMC_MAXUNIT][2][MAX_LOGBLOCK];
static unsigned char _FS_SMC_Assign[FS_SMC_MAXUNIT][2][MAX_BLOCKNUM/8];
static unsigned short _FS_SMC_AssignStart[FS_SMC_MAXUNIT][2];
static unsigned short _FS_SMC_AssignZone[FS_SMC_MAXUNIT];
static unsigned short _FS_SMC_ReadBlock[FS_SMC_MAXUNIT];
static unsigned short _FS_SMC_WriteBlock[FS_SMC_MAXUNIT];
static unsigned int _FS_SMC_MediaChange[FS_SMC_MAXUNIT];
static unsigned int _FS_SMC_SectCopyMode[FS_SMC_MAXUNIT];
/*********************************************************************
*
* Local functions
*
**********************************************************************
*/
/*********************************************************************
*
* _FS_SMC_Bit_Count
*/
static char _FS_SMC_Bit_Count(unsigned char cdata)
{
char bitcount=0;
while(cdata) {
bitcount+=(cdata &0x01);
cdata /=2;
}
return(bitcount);
}
/*********************************************************************
*
* _FS_SMC_Bit_CountWord
*/
static char _FS_SMC_Bit_CountWord(unsigned short cdata)
{
char bitcount=0;
while(cdata) {
bitcount+=(cdata &0x01);
cdata /=2;
}
return(bitcount);
}
/*********************************************************************
*
* _FS_SMC_Chk_DataBlank
*/
static int _FS_SMC_Chk_DataBlank(unsigned char *redundant)
{
char i;
for(i=0; i1) return(ERROR);
if((addr1 &0xF000)==0x1000)
if(! (_FS_SMC_Bit_CountWord(addr1) &0x0001))
{ FS__SMC_cardparam[id].LogBlock=(addr1 &0x0FFF)/2; return(SUCCESS); }
if((addr2 &0xF000)==0x1000)
if(! (_FS_SMC_Bit_CountWord(addr2) &0x0001))
{ FS__SMC_cardparam[id].LogBlock=(addr2 &0x0FFF)/2; return(SUCCESS); }
return(ERROR);
}
/*********************************************************************
*
* _FS_SMC_Clr_RedundantData
*/
static void _FS_SMC_Clr_RedundantData(unsigned char *redundant)
{
char i;
for(i=0; i=FS__SMC_cardattrib[id].MaxLogBlocks)
continue;
if(_FS_SMC_Log2Phy[id][FS__SMC_cardparam[id].Zone?1:0][FS__SMC_cardparam[id].LogBlock]==NO_ASSIGN) {
_FS_SMC_Log2Phy[id][FS__SMC_cardparam[id].Zone?1:0][FS__SMC_cardparam[id].LogBlock]=FS__SMC_cardparam[id].PhyBlock;
continue;
}
FS__SMC_cardparam[id].Sector=FS__SMC_cardattrib[id].MaxSectors-1;
if(FS__SMC_PHY_ReadRedtData(id,_FS_SMC_Redundant))
{ FS__SMC_PHY_Reset(id); return(ERROR); }
FS__SMC_cardparam[id].Sector=0;
block=FS__SMC_cardparam[id].LogBlock;
if(! _FS_SMC_Load_LogBlockAddr(id,_FS_SMC_Redundant))
if(FS__SMC_cardparam[id].LogBlock==block) {
#ifdef L2P_ERR_ERASE /***************************************************/
block=_FS_SMC_Log2Phy[id][FS__SMC_cardparam[id].Zone?1:0][FS__SMC_cardparam[id].LogBlock];
_FS_SMC_Log2Phy[id][FS__SMC_cardparam[id].Zone?1:0][FS__SMC_cardparam[id].LogBlock]=FS__SMC_cardparam[id].PhyBlock;
FS__SMC_cardparam[id].PhyBlock=block;
if(!(FS__SMC_cardattrib[id].Attribute &MWP)) {
FS__SMC_PHY_Reset(id);
if(FS__SMC_PHY_EraseBlock(id)) return(ERROR);
if(FS__SMC_PHY_CheckStatus(id))
{ if(_FS_SMC_MarkFail_PhyOneBlock(id)) return(ERROR); }
else Clr_X_Bit(_FS_SMC_Assign[id][FS__SMC_cardparam[id].Zone?1:0],FS__SMC_cardparam[id].PhyBlock);
}
FS__SMC_cardparam[id].PhyBlock=_FS_SMC_Log2Phy[id][FS__SMC_cardparam[id].Zone?1:0][FS__SMC_cardparam[id].LogBlock];
#else /*******************************************************************/
_FS_SMC_Log2Phy[id][FS__SMC_cardparam[id].Zone?1:0][FS__SMC_cardparam[id].LogBlock]=FS__SMC_cardparam[id].PhyBlock;
#endif /*******************************************************************/
continue;
}
#ifdef L2P_ERR_ERASE /***************************************************/
if(!(FS__SMC_cardattrib[id].Attribute &MWP)) {
FS__SMC_PHY_Reset(id);
if(FS__SMC_PHY_EraseBlock(id)) return(ERROR);
if(FS__SMC_PHY_CheckStatus(id))
{ if(_FS_SMC_MarkFail_PhyOneBlock(id)) return(ERROR); }
else Clr_X_Bit(_FS_SMC_Assign[id][FS__SMC_cardparam[id].Zone?1:0],FS__SMC_cardparam[id].PhyBlock);
}
#endif /*******************************************************************/
}
_FS_SMC_AssignStart[id][FS__SMC_cardparam[id].Zone?1:0]=0;
/*****/
FS__SMC_PHY_Reset(id);
return(SUCCESS);
}
/*********************************************************************
*
* _FS_SMC_Check_MediaFmt
*/
static int _FS_SMC_Check_MediaFmt(FS_u32 id)
{
unsigned short cis;
if(! _FS_SMC_MediaChange[id]) return(SUCCESS);
_FS_SMC_MediaChange[id]=(unsigned int) ERROR;
_FS_SMC_SectCopyMode[id]=COMPLETED;
if(_FS_SMC_Set_PhyFmtValue(id))
{ _FS_SMC_ErrCode[id]=ERR_UnknownMedia; return(ERROR); }
if(_FS_SMC_Search_CIS(id,&cis))
{ _FS_SMC_ErrCode[id]=ERR_IllegalFmt; return(ERROR); }
_FS_SMC_AssignZone[id]=0;
FS__SMC_cardparam[id].Zone=0;
if(_FS_SMC_Make_LogTable(id,cis+1))
{ _FS_SMC_ErrCode[id]=ERR_IllegalFmt; return(ERROR); }
_FS_SMC_MediaChange[id]=SUCCESS;
return(SUCCESS);
}
/*********************************************************************
*
* _FS_SMC_Conv_MediaAddr
*/
static int _FS_SMC_Conv_MediaAddr(FS_u32 id,unsigned long addr)
{
unsigned long temp;
unsigned short block;
unsigned char sect;
temp =addr/FS__SMC_cardattrib[id].MaxSectors;
FS__SMC_cardparam[id].Sector =addr%FS__SMC_cardattrib[id].MaxSectors;
FS__SMC_cardparam[id].LogBlock=temp%FS__SMC_cardattrib[id].MaxLogBlocks;
FS__SMC_cardparam[id].Zone =temp/FS__SMC_cardattrib[id].MaxLogBlocks;
if(FS__SMC_cardparam[id].Zone