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