smc_log.c
上传用户:yj_qqy
上传日期:2017-01-28
资源大小:2911k
文件大小:37k
源码类别:

uCOS

开发平台:

C/C++

  1. /*
  2. **********************************************************************
  3. *                          Micrium, Inc.
  4. *                      949 Crestview Circle
  5. *                     Weston,  FL 33327-1848
  6. *
  7. *                            uC/FS
  8. *
  9. *             (c) Copyright 2001 - 2003, Micrium, Inc.
  10. *                      All rights reserved.
  11. *
  12. ***********************************************************************
  13. ----------------------------------------------------------------------
  14. File        : smc_log.c
  15. Purpose     : Generic logical sector read/write access module for SMC
  16. ----------------------------------------------------------------------
  17. Known problems or limitations with current version
  18. ----------------------------------------------------------------------
  19. None.
  20. ---------------------------END-OF-HEADER------------------------------
  21. */
  22. /*********************************************************************
  23. *
  24. *             #include Section
  25. *
  26. **********************************************************************
  27. */
  28. #include "fs_port.h"
  29. #include "fs_dev.h"
  30. #include "fs_conf.h"
  31. #if FS_USE_SMC_DRIVER
  32. #include "smc.h"
  33. /*********************************************************************
  34. *
  35. *             #define macros
  36. *
  37. **********************************************************************
  38. */
  39. #define Set_X_Bit(a,b)    (a[(unsigned char)((b)/8)]|= _FS_SMC_BitData[(b)%8])
  40. #define Clr_X_Bit(a,b)    (a[(unsigned char)((b)/8)]&=~_FS_SMC_BitData[(b)%8])
  41. #define Chk_X_Bit(a,b)    (a[(unsigned char)((b)/8)] & _FS_SMC_BitData[(b)%8])
  42. /*********************************************************************
  43. *
  44. *             Local Variables        
  45. *
  46. **********************************************************************
  47. */
  48. static const char     _FS_SMC_BitData[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 };
  49. static unsigned int   _FS_SMC_ErrCode[FS_SMC_MAXUNIT];
  50. static unsigned char  _FS_SMC_SectBuf[SECTSIZE];
  51. static unsigned char  _FS_SMC_WorkBuf[SECTSIZE];
  52. static unsigned char  _FS_SMC_Redundant[REDTSIZE];
  53. static unsigned char  _FS_SMC_WorkRedund[REDTSIZE];
  54. static unsigned short _FS_SMC_Log2Phy[FS_SMC_MAXUNIT][2][MAX_LOGBLOCK];
  55. static unsigned char  _FS_SMC_Assign[FS_SMC_MAXUNIT][2][MAX_BLOCKNUM/8];
  56. static unsigned short _FS_SMC_AssignStart[FS_SMC_MAXUNIT][2];
  57. static unsigned short _FS_SMC_AssignZone[FS_SMC_MAXUNIT];
  58. static unsigned short _FS_SMC_ReadBlock[FS_SMC_MAXUNIT];
  59. static unsigned short _FS_SMC_WriteBlock[FS_SMC_MAXUNIT];
  60. static unsigned int   _FS_SMC_MediaChange[FS_SMC_MAXUNIT];
  61. static unsigned int   _FS_SMC_SectCopyMode[FS_SMC_MAXUNIT];
  62. /*********************************************************************
  63. *
  64. *             Local functions
  65. *
  66. **********************************************************************
  67. */
  68. /*********************************************************************
  69. *
  70. *             _FS_SMC_Bit_Count
  71. */
  72. static char _FS_SMC_Bit_Count(unsigned char cdata)
  73. {
  74.     char bitcount=0;
  75.     while(cdata) {
  76.         bitcount+=(cdata &0x01);
  77.         cdata   /=2;
  78.     }
  79.     return(bitcount);
  80. }
  81. /*********************************************************************
  82. *
  83. *             _FS_SMC_Bit_CountWord
  84. */
  85. static char _FS_SMC_Bit_CountWord(unsigned short cdata)
  86. {
  87.     char bitcount=0;
  88.     while(cdata) {
  89.         bitcount+=(cdata &0x01);
  90.         cdata   /=2;
  91.     }
  92.     return(bitcount);
  93. }
  94. /*********************************************************************
  95. *
  96. *             _FS_SMC_Chk_DataBlank
  97. */
  98. static int _FS_SMC_Chk_DataBlank(unsigned char *redundant)
  99. {
  100.     char i;
  101.     for(i=0; i<REDTSIZE; i++)
  102.         if(*redundant++!=0xFF)      return(ERROR);
  103.     return(SUCCESS);
  104. }
  105. /*********************************************************************
  106. *
  107. *             _FS_SMC_Chk_FailBlock
  108. */
  109. static int _FS_SMC_Chk_FailBlock(unsigned char *redundant)
  110. {
  111.     redundant+=REDT_BLOCK;
  112.     if(*redundant==0xFF)            return(SUCCESS);
  113.     if(! *redundant)                return(ERROR);
  114.     if(_FS_SMC_Bit_Count(*redundant)<7)     return(ERROR);
  115.     return(SUCCESS);
  116. }
  117. /*********************************************************************
  118. *
  119. *             _FS_SMC_Chk_CisBlock
  120. */
  121. static int _FS_SMC_Chk_CisBlock(unsigned char *redundant)
  122. {
  123.     if(! (*(redundant+REDT_ADDR1H)|*(redundant+REDT_ADDR1L)))
  124.         return(SUCCESS);
  125.     if(! (*(redundant+REDT_ADDR2H)|*(redundant+REDT_ADDR2L)))
  126.         return(SUCCESS);
  127.     return(ERROR);
  128. }
  129. /*********************************************************************
  130. *
  131. *             _FS_SMC_Chk_DataStatus
  132. */
  133. static int _FS_SMC_Chk_DataStatus(unsigned char *redundant)
  134. {
  135.     redundant+=REDT_DATA;
  136.     if(*redundant==0xFF)            return(SUCCESS);
  137.     if(! *redundant)                return(ERROR);
  138.     if(_FS_SMC_Bit_Count(*redundant)<5)     return(ERROR);
  139.     return(SUCCESS);
  140. }
  141. /*********************************************************************
  142. *
  143. *             _FS_SMC_Load_LogBlockAddr
  144. */
  145. static int _FS_SMC_Load_LogBlockAddr(FS_u32 id,unsigned char *redundant)
  146. {
  147.     unsigned short addr1,addr2;
  148.     addr1=*(redundant+REDT_ADDR1H)*0x100+*(redundant+REDT_ADDR1L);
  149.     addr2=*(redundant+REDT_ADDR2H)*0x100+*(redundant+REDT_ADDR2L);
  150.     if(addr1==addr2)
  151.         if((addr1 &0xF000)==0x1000)
  152.             { FS__SMC_cardparam[id].LogBlock=(addr1 &0x0FFF)/2; return(SUCCESS); }
  153.     if(_FS_SMC_Bit_CountWord(addr1^addr2)>1)            return(ERROR);
  154.     if((addr1 &0xF000)==0x1000)
  155.         if(! (_FS_SMC_Bit_CountWord(addr1) &0x0001))
  156.             { FS__SMC_cardparam[id].LogBlock=(addr1 &0x0FFF)/2; return(SUCCESS); }
  157.     if((addr2 &0xF000)==0x1000)
  158.         if(! (_FS_SMC_Bit_CountWord(addr2) &0x0001))
  159.             { FS__SMC_cardparam[id].LogBlock=(addr2 &0x0FFF)/2; return(SUCCESS); }
  160.     return(ERROR);
  161. }
  162. /*********************************************************************
  163. *
  164. *             _FS_SMC_Clr_RedundantData
  165. */
  166. static void _FS_SMC_Clr_RedundantData(unsigned char *redundant)
  167. {
  168.     char i;
  169.     for(i=0; i<REDTSIZE; i++)   *(redundant+i)=0xFF;
  170. }
  171. /*********************************************************************
  172. *
  173. *             _FS_SMC_Set_LogBlockAddr
  174. */
  175. static void _FS_SMC_Set_LogBlockAddr(FS_u32 id,unsigned char *redundant)
  176. {
  177.     unsigned short addr;
  178.     *(redundant+REDT_BLOCK)=0xFF;
  179.     *(redundant+REDT_DATA) =0xFF;
  180.     addr=FS__SMC_cardparam[id].LogBlock*2+0x1000;
  181.     if((_FS_SMC_Bit_CountWord(addr)%2)) addr++;
  182.     *(redundant+REDT_ADDR1H)=*(redundant+REDT_ADDR2H)=addr/0x100;
  183.     *(redundant+REDT_ADDR1L)=*(redundant+REDT_ADDR2L)=(unsigned char)addr;
  184. }
  185. /*********************************************************************
  186. *
  187. *             _FS_SMC_Set_FailBlock
  188. */
  189. static void _FS_SMC_Set_FailBlock(unsigned char *redundant)
  190. {
  191.     char i;
  192.     for(i=0; i<REDTSIZE; i++)
  193.         *redundant++=((i==REDT_BLOCK)?0xF0:0xFF);
  194. }
  195. /*********************************************************************
  196. *
  197. *             _FS_SMC_Set_DataStatus
  198. */
  199. static void _FS_SMC_Set_DataStatus(unsigned char *redundant)
  200. {
  201.     redundant+=REDT_DATA;
  202.     *redundant=0x00;
  203. }
  204. /*********************************************************************
  205. *
  206. *             _FS_SMC_Init_Media
  207. */
  208. static void _FS_SMC_Init_Media(FS_u32 id)
  209. {
  210.     _FS_SMC_ErrCode[id]=NO_ERROR;
  211.     _FS_SMC_MediaChange[id]=(unsigned int) ERROR;
  212.     _FS_SMC_SectCopyMode[id]=COMPLETED;
  213.     FS__SMC_PHY_Cnt_Reset(id);
  214. }
  215. /*********************************************************************
  216. *
  217. *             _FS_SMC_Chk_MediaPower
  218. */
  219. static int _FS_SMC_Chk_MediaPower(FS_u32 id)
  220. {
  221.     if(FS__SMC_PHY_Chk_CardStsChg(id))      _FS_SMC_MediaChange[id]=(unsigned int) ERROR;
  222.     if((! FS__SMC_PHY_Chk_CntPower(id))&&(! _FS_SMC_MediaChange[id]))          return(SUCCESS);
  223.     if(FS__SMC_PHY_Chk_CardExist(id))
  224.         { _FS_SMC_MediaChange[id]=(unsigned int) ERROR; _FS_SMC_ErrCode[id]=ERR_NoSmartMedia; return(ERROR); }
  225.     if(FS__SMC_PHY_Cnt_PowerOn(id))
  226.         { _FS_SMC_MediaChange[id]=(unsigned int) ERROR; _FS_SMC_ErrCode[id]=ERR_NoSmartMedia; return(ERROR); }
  227.     FS__SMC_PHY_Reset(id);
  228.     return(SUCCESS);
  229. }
  230. /*********************************************************************
  231. *
  232. *             _FS_SMC_Chk_MediaWP
  233. */
  234. static int _FS_SMC_Chk_MediaWP(FS_u32 id)
  235. {
  236.     if(FS__SMC_cardattrib[id].Attribute &MWP)
  237.         { _FS_SMC_ErrCode[id]=ERR_WrtProtect;   return(ERROR); }
  238.     return(SUCCESS);
  239. }
  240. /*********************************************************************
  241. *
  242. *             _FS_SMC_MarkFail_PhyOneBlock
  243. */
  244. static int _FS_SMC_MarkFail_PhyOneBlock(FS_u32 id)
  245. {
  246.     unsigned char sect;
  247.     sect=FS__SMC_cardparam[id].Sector;
  248.     _FS_SMC_Set_FailBlock(_FS_SMC_WorkRedund);
  249.     FS__SMC_PHY_WriteRedtMode(id);
  250.     for(FS__SMC_cardparam[id].Sector=0; FS__SMC_cardparam[id].Sector<FS__SMC_cardattrib[id].MaxSectors; FS__SMC_cardparam[id].Sector++)
  251.         if(FS__SMC_PHY_WriteRedtData(id,_FS_SMC_WorkRedund)) {
  252.             FS__SMC_PHY_Reset(id);
  253.             FS__SMC_cardparam[id].Sector=sect;
  254.             _FS_SMC_ErrCode[id]=ERR_HwError;
  255.             return(ERROR);
  256.         }   /* NO Status Check */
  257.     FS__SMC_PHY_Reset(id);
  258.     FS__SMC_cardparam[id].Sector=sect;
  259.     return(SUCCESS);
  260. }
  261. /*********************************************************************
  262. *
  263. *             _FS_SMC_Set_PhyFmtValue
  264. */
  265. static int _FS_SMC_Set_PhyFmtValue(FS_u32 id)
  266. {
  267.     unsigned short idcode;
  268.     FS__SMC_PHY_ReadID(id,&idcode);
  269.     if(FS__SMC_PHY_Set_Model(id,(unsigned char)idcode))
  270.         return(ERROR);
  271.     if(FS__SMC_PHY_Chk_WP(id))
  272.         FS__SMC_cardattrib[id].Attribute|=WP;
  273.     return(SUCCESS);
  274. }
  275. /*********************************************************************
  276. *
  277. *             _FS_SMC_Search_CIS
  278. */
  279. static int _FS_SMC_Search_CIS(FS_u32 id,unsigned short *pcis)
  280. {
  281.     FS__SMC_cardparam[id].Zone=0;   FS__SMC_cardparam[id].Sector=0;
  282.     for(FS__SMC_cardparam[id].PhyBlock=0; FS__SMC_cardparam[id].PhyBlock<(FS__SMC_cardattrib[id].MaxBlocks-FS__SMC_cardattrib[id].MaxLogBlocks-1); FS__SMC_cardparam[id].PhyBlock++) {
  283.         if(FS__SMC_PHY_ReadRedtData(id,_FS_SMC_Redundant))
  284.             { FS__SMC_PHY_Reset(id);        return(ERROR); }
  285.         if(! _FS_SMC_Chk_FailBlock(_FS_SMC_Redundant)) {
  286.             if(_FS_SMC_Chk_CisBlock(_FS_SMC_Redundant))
  287.                 { FS__SMC_PHY_Reset(id);    return(ERROR); }
  288.             break;
  289.         }
  290.     }
  291.     while(FS__SMC_cardparam[id].Sector<FS__SMC_cardattrib[id].MaxSectors) {
  292.         if(FS__SMC_cardparam[id].Sector)
  293.             if(FS__SMC_PHY_ReadRedtData(id,_FS_SMC_Redundant))
  294.                 { FS__SMC_PHY_Reset(id);    return(ERROR); }
  295.         if(! _FS_SMC_Chk_DataStatus(_FS_SMC_Redundant)) {
  296.             if(FS__SMC_PHY_ReadSect(id,_FS_SMC_WorkBuf,_FS_SMC_Redundant))
  297.                 { FS__SMC_PHY_Reset(id);    return(ERROR); }
  298.             if(FS__SMC_ECC_Chk_CISdata(_FS_SMC_WorkBuf,_FS_SMC_Redundant))
  299.                 { FS__SMC_PHY_Reset(id);    return(ERROR); }
  300.             *pcis=FS__SMC_cardparam[id].PhyBlock;
  301.             FS__SMC_PHY_Reset(id);
  302.             return(SUCCESS);
  303.         }
  304.         FS__SMC_cardparam[id].Sector++;
  305.     }
  306.     FS__SMC_PHY_Reset(id);
  307.     return(ERROR);
  308. }
  309. /*********************************************************************
  310. *
  311. *             _FS_SMC_Make_LogTable
  312. */
  313. static int _FS_SMC_Make_LogTable(FS_u32 id,unsigned short start)
  314. {
  315.     unsigned short block;
  316.     FS__SMC_cardparam[id].Sector=0;
  317.         /*****/
  318.         for(FS__SMC_cardparam[id].LogBlock=0; FS__SMC_cardparam[id].LogBlock<FS__SMC_cardattrib[id].MaxLogBlocks; FS__SMC_cardparam[id].LogBlock++)
  319.             _FS_SMC_Log2Phy[id][FS__SMC_cardparam[id].Zone?1:0][FS__SMC_cardparam[id].LogBlock]=NO_ASSIGN;
  320.         for(FS__SMC_cardparam[id].PhyBlock=0; FS__SMC_cardparam[id].PhyBlock<(MAX_BLOCKNUM/8); FS__SMC_cardparam[id].PhyBlock++)
  321.             _FS_SMC_Assign[id][FS__SMC_cardparam[id].Zone?1:0][FS__SMC_cardparam[id].PhyBlock]=0x00;
  322.         /*******************************************************************/
  323.         for(FS__SMC_cardparam[id].PhyBlock=0; FS__SMC_cardparam[id].PhyBlock<FS__SMC_cardattrib[id].MaxBlocks; FS__SMC_cardparam[id].PhyBlock++) {
  324.             if((! FS__SMC_cardparam[id].Zone) && (FS__SMC_cardparam[id].PhyBlock<start)) {
  325.                 Set_X_Bit(_FS_SMC_Assign[id][FS__SMC_cardparam[id].Zone?1:0],FS__SMC_cardparam[id].PhyBlock);
  326.                 continue;
  327.             }
  328.             if(FS__SMC_PHY_ReadRedtData(id,_FS_SMC_Redundant))
  329.                 { FS__SMC_PHY_Reset(id); return(ERROR); }
  330.             if(! _FS_SMC_Chk_DataBlank(_FS_SMC_Redundant))
  331.                 continue;
  332.             Set_X_Bit(_FS_SMC_Assign[id][FS__SMC_cardparam[id].Zone?1:0],FS__SMC_cardparam[id].PhyBlock);
  333.             if(_FS_SMC_Chk_FailBlock(_FS_SMC_Redundant))
  334.                 continue;
  335.             if(_FS_SMC_Load_LogBlockAddr(id,_FS_SMC_Redundant))
  336.                 continue;
  337.             if(FS__SMC_cardparam[id].LogBlock>=FS__SMC_cardattrib[id].MaxLogBlocks)
  338.                 continue;
  339.             if(_FS_SMC_Log2Phy[id][FS__SMC_cardparam[id].Zone?1:0][FS__SMC_cardparam[id].LogBlock]==NO_ASSIGN) {
  340.                 _FS_SMC_Log2Phy[id][FS__SMC_cardparam[id].Zone?1:0][FS__SMC_cardparam[id].LogBlock]=FS__SMC_cardparam[id].PhyBlock;
  341.                 continue;
  342.             }
  343.             FS__SMC_cardparam[id].Sector=FS__SMC_cardattrib[id].MaxSectors-1;
  344.             if(FS__SMC_PHY_ReadRedtData(id,_FS_SMC_Redundant))
  345.                 { FS__SMC_PHY_Reset(id); return(ERROR); }
  346.             FS__SMC_cardparam[id].Sector=0;
  347.             block=FS__SMC_cardparam[id].LogBlock;
  348.             if(! _FS_SMC_Load_LogBlockAddr(id,_FS_SMC_Redundant))
  349.                 if(FS__SMC_cardparam[id].LogBlock==block) {
  350. #ifdef L2P_ERR_ERASE    /***************************************************/
  351.                     block=_FS_SMC_Log2Phy[id][FS__SMC_cardparam[id].Zone?1:0][FS__SMC_cardparam[id].LogBlock];
  352.                     _FS_SMC_Log2Phy[id][FS__SMC_cardparam[id].Zone?1:0][FS__SMC_cardparam[id].LogBlock]=FS__SMC_cardparam[id].PhyBlock;
  353.                     FS__SMC_cardparam[id].PhyBlock=block;
  354.                     if(!(FS__SMC_cardattrib[id].Attribute &MWP)) {
  355.                         FS__SMC_PHY_Reset(id);
  356.                         if(FS__SMC_PHY_EraseBlock(id))      return(ERROR);
  357.                         if(FS__SMC_PHY_CheckStatus(id))
  358.                             { if(_FS_SMC_MarkFail_PhyOneBlock(id))    return(ERROR); }
  359.                         else Clr_X_Bit(_FS_SMC_Assign[id][FS__SMC_cardparam[id].Zone?1:0],FS__SMC_cardparam[id].PhyBlock);
  360.                     }
  361.                     FS__SMC_cardparam[id].PhyBlock=_FS_SMC_Log2Phy[id][FS__SMC_cardparam[id].Zone?1:0][FS__SMC_cardparam[id].LogBlock];
  362. #else   /*******************************************************************/
  363.                     _FS_SMC_Log2Phy[id][FS__SMC_cardparam[id].Zone?1:0][FS__SMC_cardparam[id].LogBlock]=FS__SMC_cardparam[id].PhyBlock;
  364. #endif  /*******************************************************************/
  365.                     continue;
  366.                 }
  367. #ifdef L2P_ERR_ERASE    /***************************************************/
  368.             if(!(FS__SMC_cardattrib[id].Attribute &MWP)) {
  369.                 FS__SMC_PHY_Reset(id);
  370.                 if(FS__SMC_PHY_EraseBlock(id))      return(ERROR);
  371.                 if(FS__SMC_PHY_CheckStatus(id))
  372.                     { if(_FS_SMC_MarkFail_PhyOneBlock(id))    return(ERROR); }
  373.                 else Clr_X_Bit(_FS_SMC_Assign[id][FS__SMC_cardparam[id].Zone?1:0],FS__SMC_cardparam[id].PhyBlock);
  374.             }
  375. #endif  /*******************************************************************/
  376.         }
  377.         _FS_SMC_AssignStart[id][FS__SMC_cardparam[id].Zone?1:0]=0;
  378.         /*****/
  379.     FS__SMC_PHY_Reset(id);
  380.     return(SUCCESS);
  381. }
  382. /*********************************************************************
  383. *
  384. *             _FS_SMC_Check_MediaFmt
  385. */
  386. static int _FS_SMC_Check_MediaFmt(FS_u32 id)
  387. {
  388.     unsigned short cis;
  389.     if(! _FS_SMC_MediaChange[id])               return(SUCCESS);
  390.     _FS_SMC_MediaChange[id]=(unsigned int) ERROR;
  391.     _FS_SMC_SectCopyMode[id]=COMPLETED;
  392.     if(_FS_SMC_Set_PhyFmtValue(id))
  393.         { _FS_SMC_ErrCode[id]=ERR_UnknownMedia; return(ERROR); }
  394.     if(_FS_SMC_Search_CIS(id,&cis))
  395.         { _FS_SMC_ErrCode[id]=ERR_IllegalFmt;   return(ERROR); }
  396.     _FS_SMC_AssignZone[id]=0;
  397.     FS__SMC_cardparam[id].Zone=0;
  398.     if(_FS_SMC_Make_LogTable(id,cis+1))
  399.         { _FS_SMC_ErrCode[id]=ERR_IllegalFmt;   return(ERROR); }
  400.     _FS_SMC_MediaChange[id]=SUCCESS;
  401.     return(SUCCESS);
  402. }
  403. /*********************************************************************
  404. *
  405. *             _FS_SMC_Conv_MediaAddr
  406. */
  407. static int _FS_SMC_Conv_MediaAddr(FS_u32 id,unsigned long addr)
  408. {
  409.     unsigned long temp;
  410.     unsigned short block;
  411.     unsigned char sect;
  412.     temp          =addr/FS__SMC_cardattrib[id].MaxSectors;
  413.     FS__SMC_cardparam[id].Sector  =addr%FS__SMC_cardattrib[id].MaxSectors;
  414.     FS__SMC_cardparam[id].LogBlock=temp%FS__SMC_cardattrib[id].MaxLogBlocks;
  415.     FS__SMC_cardparam[id].Zone    =temp/FS__SMC_cardattrib[id].MaxLogBlocks;
  416.     if(FS__SMC_cardparam[id].Zone<FS__SMC_cardattrib[id].MaxZones) {
  417.         if(FS__SMC_cardparam[id].Zone!=0 && FS__SMC_cardparam[id].Zone!=_FS_SMC_AssignZone[id]) {
  418.             _FS_SMC_AssignZone[id]=0;
  419.             block=FS__SMC_cardparam[id].LogBlock;
  420.             sect=FS__SMC_cardparam[id].Sector;
  421.             if(_FS_SMC_Make_LogTable(id,0))
  422.                 { _FS_SMC_ErrCode[id]=ERR_IllegalFmt;   return(ERROR); }
  423.             _FS_SMC_AssignZone[id]=FS__SMC_cardparam[id].Zone;
  424.             FS__SMC_cardparam[id].LogBlock=block;
  425.             FS__SMC_cardparam[id].Sector=sect;
  426.         }
  427.         _FS_SMC_Clr_RedundantData(_FS_SMC_Redundant);
  428.         _FS_SMC_Set_LogBlockAddr(id,_FS_SMC_Redundant);
  429.         FS__SMC_cardparam[id].PhyBlock=_FS_SMC_Log2Phy[id][FS__SMC_cardparam[id].Zone?1:0][FS__SMC_cardparam[id].LogBlock];
  430.         return(SUCCESS);
  431.     }
  432.     _FS_SMC_ErrCode[id]=ERR_OutOfLBA;
  433.     return(ERROR);
  434. }
  435. /*********************************************************************
  436. *
  437. *             _FS_SMC_Inc_MediaAddr
  438. */
  439. static int _FS_SMC_Inc_MediaAddr(FS_u32 id)
  440. {
  441.     unsigned short block;
  442.     unsigned char sect;
  443.     if(++FS__SMC_cardparam[id].Sector<FS__SMC_cardattrib[id].MaxSectors)
  444.         return(SUCCESS);
  445.     FS__SMC_cardparam[id].Sector=0;
  446.     if(++FS__SMC_cardparam[id].LogBlock<FS__SMC_cardattrib[id].MaxLogBlocks) {
  447.         _FS_SMC_Clr_RedundantData(_FS_SMC_Redundant);
  448.         _FS_SMC_Set_LogBlockAddr(id,_FS_SMC_Redundant);
  449.         FS__SMC_cardparam[id].PhyBlock=_FS_SMC_Log2Phy[id][FS__SMC_cardparam[id].Zone?1:0][FS__SMC_cardparam[id].LogBlock];
  450.         return(SUCCESS);
  451.     }
  452.     FS__SMC_cardparam[id].LogBlock=0;
  453.     if(++FS__SMC_cardparam[id].Zone<FS__SMC_cardattrib[id].MaxZones) {
  454.         if(FS__SMC_cardparam[id].Zone!=_FS_SMC_AssignZone[id]) {
  455.             _FS_SMC_AssignZone[id]=0;
  456.             block=FS__SMC_cardparam[id].LogBlock;
  457.             sect=FS__SMC_cardparam[id].Sector;
  458.             if(_FS_SMC_Make_LogTable(id,0))
  459.                 { _FS_SMC_ErrCode[id]=ERR_IllegalFmt;   return(ERROR); }
  460.             _FS_SMC_AssignZone[id]=FS__SMC_cardparam[id].Zone;
  461.             FS__SMC_cardparam[id].LogBlock=block;
  462.             FS__SMC_cardparam[id].Sector=sect;
  463.         }
  464.         _FS_SMC_Clr_RedundantData(_FS_SMC_Redundant);
  465.         _FS_SMC_Set_LogBlockAddr(id,_FS_SMC_Redundant);
  466.         FS__SMC_cardparam[id].PhyBlock=_FS_SMC_Log2Phy[id][FS__SMC_cardparam[id].Zone?1:0][FS__SMC_cardparam[id].LogBlock];
  467.         return(SUCCESS);
  468.     }
  469.     FS__SMC_cardparam[id].Zone=0;
  470.     _FS_SMC_ErrCode[id]=ERR_OutOfLBA;
  471.     return(ERROR);
  472. }
  473. /*********************************************************************
  474. *
  475. *             _FS_SMC_Chk_FirstSect
  476. */
  477. static int _FS_SMC_Chk_FirstSect(FS_u32 id)
  478. {
  479.     if(! FS__SMC_cardparam[id].Sector)
  480.         return(SUCCESS);
  481.     return(ERROR);
  482. }
  483. /*********************************************************************
  484. *
  485. *             _FS_SMC_Chk_LastSect
  486. */
  487. static int _FS_SMC_Chk_LastSect(FS_u32 id)
  488. {
  489.     if(FS__SMC_cardparam[id].Sector<(FS__SMC_cardattrib[id].MaxSectors-1))
  490.         return(ERROR);
  491.     return(SUCCESS);
  492. }
  493. /*********************************************************************
  494. *
  495. *             _FS_SMC_Copy_PhyOneSect
  496. */
  497. static int _FS_SMC_Copy_PhyOneSect(FS_u32 id)
  498. {
  499.     int i;
  500.     unsigned int err, retry;
  501.     if(_FS_SMC_ReadBlock[id]!=NO_ASSIGN) {
  502.         FS__SMC_cardparam[id].PhyBlock=_FS_SMC_ReadBlock[id];
  503.         for(retry=0; retry<2; retry++) {
  504.             err=SUCCESS;
  505.             if(FS__SMC_PHY_ReadSect(id,_FS_SMC_WorkBuf,_FS_SMC_WorkRedund))
  506.                 { _FS_SMC_ErrCode[id]=ERR_HwError;  return(ERROR); }
  507.             if(_FS_SMC_Chk_DataStatus(_FS_SMC_WorkRedund))
  508.                 { err=(unsigned int) ERROR;    break; }
  509.             err=FS__SMC_ECC_Chk_ECCdata(_FS_SMC_WorkBuf,_FS_SMC_WorkRedund);
  510.             if(err==CORRECT)    break;
  511.             if(! err)           break;
  512.             _FS_SMC_SectCopyMode[id]=REQ_FAIL;
  513.         }
  514.     } else {
  515.         err=SUCCESS;
  516.         for(i=0; i<SECTSIZE; i++)
  517.             _FS_SMC_WorkBuf[i]=DUMMY_DATA;
  518.         _FS_SMC_Clr_RedundantData(_FS_SMC_WorkRedund);
  519.     }
  520.     _FS_SMC_Set_LogBlockAddr(id,_FS_SMC_WorkRedund);
  521.     if(err==CORRECT)
  522.         FS__SMC_ECC_Set_ECCdata(_FS_SMC_WorkBuf,_FS_SMC_WorkRedund);
  523.     if(err==(unsigned int)ERROR) {
  524.         FS__SMC_ECC_Set_ECCdata(_FS_SMC_WorkBuf,_FS_SMC_WorkRedund);
  525.         _FS_SMC_Set_DataStatus(_FS_SMC_WorkRedund);
  526.     }
  527.     FS__SMC_cardparam[id].PhyBlock=_FS_SMC_WriteBlock[id];
  528.     if(FS__SMC_PHY_WriteSect(id,_FS_SMC_WorkBuf,_FS_SMC_WorkRedund))
  529.         { _FS_SMC_ErrCode[id]=ERR_HwError;      return(ERROR); }
  530.     if(FS__SMC_PHY_CheckStatus(id))
  531.         { _FS_SMC_ErrCode[id]=ERR_WriteFault;   return(ERROR); }
  532.     FS__SMC_cardparam[id].PhyBlock=_FS_SMC_ReadBlock[id];
  533.     return(SUCCESS);
  534. }
  535. /*********************************************************************
  536. *
  537. *             _FS_SMC_Read_PhyOneSect
  538. */
  539. static int _FS_SMC_Read_PhyOneSect(FS_u32 id,unsigned char *buf)
  540. {
  541.     int i;
  542.     unsigned int err, retry;
  543.     if(FS__SMC_cardparam[id].PhyBlock==NO_ASSIGN) {
  544.         for(i=0; i<SECTSIZE; i++)
  545.             *buf++=DUMMY_DATA;
  546.         return(SUCCESS);
  547.     }
  548.     for(retry=0; retry<2; retry++) {
  549.         if(FS__SMC_PHY_ReadSect(id,buf,_FS_SMC_Redundant))
  550.             { _FS_SMC_ErrCode[id]=ERR_HwError;      return(ERROR); }
  551.         if(_FS_SMC_Chk_DataStatus(_FS_SMC_Redundant))
  552.             { _FS_SMC_ErrCode[id]=ERR_DataStatus;   return(ERROR); }
  553.         if(! (err=FS__SMC_ECC_Chk_ECCdata(buf,_FS_SMC_Redundant)))
  554.             return(SUCCESS);
  555.     }
  556.     if(err==CORRECT)
  557.          _FS_SMC_ErrCode[id]=ERR_CorReadErr;
  558.     else _FS_SMC_ErrCode[id]=ERR_EccReadErr;
  559.     return(ERROR);
  560. }
  561. /*********************************************************************
  562. *
  563. *             _FS_SMC_Write_PhyOneSect
  564. */
  565. static int _FS_SMC_Write_PhyOneSect(FS_u32 id,unsigned char *buf)
  566. {
  567.     FS__SMC_ECC_Set_ECCdata(buf,_FS_SMC_Redundant);
  568.     if(FS__SMC_PHY_WriteSect(id,buf,_FS_SMC_Redundant))
  569.         { _FS_SMC_ErrCode[id]=ERR_HwError;      return(ERROR); }
  570.     if(FS__SMC_PHY_CheckStatus(id))
  571.         { _FS_SMC_ErrCode[id]=ERR_WriteFault;   return(ERROR); }
  572.     return(SUCCESS);
  573. }
  574. /*********************************************************************
  575. *
  576. *             _FS_SMC_Erase_PhyOneBlock
  577. */
  578. static int _FS_SMC_Erase_PhyOneBlock(FS_u32 id)
  579. {
  580.     if(FS__SMC_PHY_EraseBlock(id))
  581.         { _FS_SMC_ErrCode[id]=ERR_HwError;      return(ERROR); }
  582.     if(FS__SMC_PHY_CheckStatus(id))
  583.         { _FS_SMC_ErrCode[id]=ERR_WriteFault;   return(ERROR); }
  584.     return(SUCCESS);
  585. }
  586. /*********************************************************************
  587. *
  588. *             _FS_SMC_Assign_WriteBlock
  589. */
  590. static int _FS_SMC_Assign_WriteBlock(FS_u32 id)
  591. {
  592.     _FS_SMC_ReadBlock[id]=FS__SMC_cardparam[id].PhyBlock;
  593.     for(_FS_SMC_WriteBlock[id]=_FS_SMC_AssignStart[id][FS__SMC_cardparam[id].Zone?1:0]; _FS_SMC_WriteBlock[id]<FS__SMC_cardattrib[id].MaxBlocks; _FS_SMC_WriteBlock[id]++)
  594.         if(! Chk_X_Bit(_FS_SMC_Assign[id][FS__SMC_cardparam[id].Zone?1:0],_FS_SMC_WriteBlock[id])) {
  595.             Set_X_Bit(_FS_SMC_Assign[id][FS__SMC_cardparam[id].Zone?1:0],_FS_SMC_WriteBlock[id]);
  596.             _FS_SMC_AssignStart[id][FS__SMC_cardparam[id].Zone?1:0]=_FS_SMC_WriteBlock[id]+1;
  597.             FS__SMC_cardparam[id].PhyBlock=_FS_SMC_WriteBlock[id];
  598.             _FS_SMC_SectCopyMode[id]=REQ_ERASE;
  599.             return(SUCCESS);
  600.         }
  601.     for(_FS_SMC_WriteBlock[id]=0; _FS_SMC_WriteBlock[id]<_FS_SMC_AssignStart[id][FS__SMC_cardparam[id].Zone?1:0]; _FS_SMC_WriteBlock[id]++)
  602.         if(! Chk_X_Bit(_FS_SMC_Assign[id][FS__SMC_cardparam[id].Zone?1:0],_FS_SMC_WriteBlock[id])) {
  603.             Set_X_Bit(_FS_SMC_Assign[id][FS__SMC_cardparam[id].Zone?1:0],_FS_SMC_WriteBlock[id]);
  604.             _FS_SMC_AssignStart[id][FS__SMC_cardparam[id].Zone?1:0]=_FS_SMC_WriteBlock[id]+1;
  605.             FS__SMC_cardparam[id].PhyBlock=_FS_SMC_WriteBlock[id];
  606.             _FS_SMC_SectCopyMode[id]=REQ_ERASE;
  607.             return(SUCCESS);
  608.         }
  609.     _FS_SMC_WriteBlock[id]=NO_ASSIGN;
  610.     _FS_SMC_ErrCode[id]=ERR_WriteFault;
  611.     return(ERROR);
  612. }
  613. /*********************************************************************
  614. *
  615. *             _FS_SMC_Release_ReadBlock
  616. */
  617. static int _FS_SMC_Release_ReadBlock(FS_u32 id)
  618. {
  619.     unsigned int mode;
  620.     mode=_FS_SMC_SectCopyMode[id];
  621.     _FS_SMC_SectCopyMode[id]=COMPLETED;
  622.     if(mode==COMPLETED)             return(SUCCESS);
  623.     _FS_SMC_Log2Phy[id][FS__SMC_cardparam[id].Zone?1:0][FS__SMC_cardparam[id].LogBlock]=_FS_SMC_WriteBlock[id];
  624.     FS__SMC_cardparam[id].PhyBlock=_FS_SMC_ReadBlock[id];
  625.     if(FS__SMC_cardparam[id].PhyBlock==NO_ASSIGN)
  626.       { FS__SMC_cardparam[id].PhyBlock=_FS_SMC_WriteBlock[id];  return(SUCCESS); }
  627.     if(mode==REQ_ERASE) {
  628.         if(_FS_SMC_Erase_PhyOneBlock(id)) {
  629.             if(_FS_SMC_ErrCode[id]==ERR_HwError)    return(ERROR);
  630.             if(_FS_SMC_MarkFail_PhyOneBlock(id))  return(ERROR);
  631.         } else Clr_X_Bit(_FS_SMC_Assign[id][FS__SMC_cardparam[id].Zone?1:0],FS__SMC_cardparam[id].PhyBlock);
  632.     } else if(_FS_SMC_MarkFail_PhyOneBlock(id))   return(ERROR);
  633.     FS__SMC_cardparam[id].PhyBlock=_FS_SMC_WriteBlock[id];
  634.     return(SUCCESS);
  635. }
  636. /*********************************************************************
  637. *
  638. *             _FS_SMC_Release_WriteBlock
  639. */
  640. static int _FS_SMC_Release_WriteBlock(FS_u32 id)
  641. {
  642.     _FS_SMC_SectCopyMode[id]=COMPLETED;
  643.     FS__SMC_cardparam[id].PhyBlock=_FS_SMC_WriteBlock[id];
  644.     if(_FS_SMC_MarkFail_PhyOneBlock(id))      return(ERROR);
  645.     FS__SMC_cardparam[id].PhyBlock=_FS_SMC_ReadBlock[id];
  646.     return(SUCCESS);
  647. }
  648. /*********************************************************************
  649. *
  650. *             _FS_SMC_Copy_BlockAll
  651. */
  652. static int _FS_SMC_Copy_BlockAll(FS_u32 id,unsigned int mode)
  653. {
  654.     unsigned char sect;
  655.     sect=FS__SMC_cardparam[id].Sector;
  656.     if(_FS_SMC_Assign_WriteBlock(id))         return(ERROR);
  657.     if(mode==REQ_FAIL)      _FS_SMC_SectCopyMode[id]=REQ_FAIL;
  658.     for(FS__SMC_cardparam[id].Sector=0; FS__SMC_cardparam[id].Sector<FS__SMC_cardattrib[id].MaxSectors; FS__SMC_cardparam[id].Sector++)
  659.         if(_FS_SMC_Copy_PhyOneSect(id)) {
  660.             if(_FS_SMC_ErrCode[id]==ERR_HwError)    return(ERROR);
  661.             if(_FS_SMC_Release_WriteBlock(id))    return(ERROR);
  662.             _FS_SMC_ErrCode[id]=ERR_WriteFault;
  663.             FS__SMC_cardparam[id].PhyBlock=_FS_SMC_ReadBlock[id];
  664.             FS__SMC_cardparam[id].Sector=sect;
  665.             return(ERROR);
  666.         }
  667.     if(_FS_SMC_Release_ReadBlock(id))         return(ERROR);
  668.     FS__SMC_cardparam[id].PhyBlock=_FS_SMC_WriteBlock[id];
  669.     FS__SMC_cardparam[id].Sector=sect;
  670.     return(SUCCESS);
  671. }
  672. /*********************************************************************
  673. *
  674. *             _FS_SMC_Copy_BlockHead
  675. */
  676. static int _FS_SMC_Copy_BlockHead(FS_u32 id)
  677. {
  678.     unsigned char sect;
  679.     sect=FS__SMC_cardparam[id].Sector;
  680.     if(_FS_SMC_Assign_WriteBlock(id))         return(ERROR);
  681.     for(FS__SMC_cardparam[id].Sector=0; FS__SMC_cardparam[id].Sector<sect; FS__SMC_cardparam[id].Sector++)
  682.         if(_FS_SMC_Copy_PhyOneSect(id)) {
  683.             if(_FS_SMC_ErrCode[id]==ERR_HwError)    return(ERROR);
  684.             if(_FS_SMC_Release_WriteBlock(id))    return(ERROR);
  685.             _FS_SMC_ErrCode[id]=ERR_WriteFault;
  686.             FS__SMC_cardparam[id].PhyBlock=_FS_SMC_ReadBlock[id];
  687.             FS__SMC_cardparam[id].Sector=sect;
  688.             return(ERROR);
  689.         }
  690.     FS__SMC_cardparam[id].PhyBlock=_FS_SMC_WriteBlock[id];
  691.     FS__SMC_cardparam[id].Sector=sect;
  692.     return(SUCCESS);
  693. }
  694. /*********************************************************************
  695. *
  696. *             _FS_SMC_Copy_BlockTail
  697. */
  698. static int _FS_SMC_Copy_BlockTail(FS_u32 id)
  699. {
  700.     unsigned char sect;
  701.     for(sect=FS__SMC_cardparam[id].Sector; FS__SMC_cardparam[id].Sector<FS__SMC_cardattrib[id].MaxSectors; FS__SMC_cardparam[id].Sector++)
  702.         if(_FS_SMC_Copy_PhyOneSect(id)) {
  703.             if(_FS_SMC_ErrCode[id]==ERR_HwError)    return(ERROR);
  704.             FS__SMC_cardparam[id].PhyBlock=_FS_SMC_WriteBlock[id];
  705.             FS__SMC_cardparam[id].Sector=sect;
  706.             return(ERROR);
  707.         }
  708.     if(_FS_SMC_Release_ReadBlock(id))         return(ERROR);
  709.     FS__SMC_cardparam[id].PhyBlock=_FS_SMC_WriteBlock[id];
  710.     FS__SMC_cardparam[id].Sector=sect;
  711.     return(SUCCESS);
  712. }
  713. /*********************************************************************
  714. *
  715. *             _FS_SMC_Reassign_BlockHead
  716. */
  717. static int _FS_SMC_Reassign_BlockHead(FS_u32 id)
  718. {
  719.     unsigned int mode;
  720.     unsigned short block;
  721.     unsigned char sect;
  722.     mode=_FS_SMC_SectCopyMode[id];
  723.     block=_FS_SMC_ReadBlock[id];
  724.     sect=FS__SMC_cardparam[id].Sector;
  725.     if(_FS_SMC_Assign_WriteBlock(id))         return(ERROR);
  726.     _FS_SMC_SectCopyMode[id]=REQ_FAIL;
  727.     for(FS__SMC_cardparam[id].Sector=0; FS__SMC_cardparam[id].Sector<sect; FS__SMC_cardparam[id].Sector++)
  728.         if(_FS_SMC_Copy_PhyOneSect(id)) {
  729.             if(_FS_SMC_ErrCode[id]==ERR_HwError)    return(ERROR);
  730.             if(_FS_SMC_Release_WriteBlock(id))    return(ERROR);
  731.             _FS_SMC_ErrCode[id]=ERR_WriteFault;
  732.             _FS_SMC_SectCopyMode[id]=mode;
  733.             _FS_SMC_WriteBlock[id]=_FS_SMC_ReadBlock[id];
  734.             _FS_SMC_ReadBlock[id]=block;
  735.             FS__SMC_cardparam[id].Sector=sect;
  736.             FS__SMC_cardparam[id].PhyBlock=_FS_SMC_WriteBlock[id];
  737.             return(ERROR);
  738.         }
  739.     if(_FS_SMC_Release_ReadBlock(id))         return(ERROR);
  740.     _FS_SMC_SectCopyMode[id]=mode;
  741.     _FS_SMC_ReadBlock[id]=block;
  742.     FS__SMC_cardparam[id].Sector=sect;
  743.     FS__SMC_cardparam[id].PhyBlock=_FS_SMC_WriteBlock[id];
  744.     return(SUCCESS);
  745. }
  746. /*********************************************************************
  747. *
  748. *             _FS_SMC_Media_ReadOneSect
  749. */
  750. static int _FS_SMC_Media_ReadOneSect(FS_u32 id,unsigned char *buf)
  751. {
  752.     unsigned int err, retry;
  753.     if(! _FS_SMC_Read_PhyOneSect(id,buf))      return(SUCCESS);
  754.     if(_FS_SMC_ErrCode[id]==ERR_HwError)        return(ERROR);
  755.     if(_FS_SMC_ErrCode[id]==ERR_DataStatus)     return(ERROR);
  756. #ifdef RDERR_REASSIGN   /***************************************************/
  757.     if(FS__SMC_cardattrib[id].Attribute &MWP) {
  758.         if(_FS_SMC_ErrCode[id]==ERR_CorReadErr) return(SUCCESS);
  759.         return(ERROR);
  760.     }
  761.     err=_FS_SMC_ErrCode[id];
  762.     for(retry=0; retry<2; retry++) {
  763.         if(_FS_SMC_Copy_BlockAll(id,(err==ERR_EccReadErr)?REQ_FAIL:REQ_ERASE)) {
  764.             if(_FS_SMC_ErrCode[id]==ERR_HwError) return(ERROR);
  765.             continue;
  766.         }
  767.         _FS_SMC_ErrCode[id]=err;
  768.         if(_FS_SMC_ErrCode[id]==ERR_CorReadErr) return(SUCCESS);
  769.         return(ERROR);
  770.     }
  771. #else   /*******************************************************************/
  772.     if(_FS_SMC_ErrCode[id]==ERR_CorReadErr)     return(SUCCESS);
  773. #endif  /*******************************************************************/
  774.     return(ERROR);
  775. }
  776. /*********************************************************************
  777. *
  778. *             _FS_SMC_Media_WriteOneSect
  779. */
  780. static int _FS_SMC_Media_WriteOneSect(FS_u32 id,unsigned char *buf)
  781. {
  782.     unsigned int retry;
  783.     if(! _FS_SMC_Write_PhyOneSect(id,buf))     return(SUCCESS);
  784.     if(_FS_SMC_ErrCode[id]==ERR_HwError)        return(ERROR);
  785.     for(retry=1; retry<2; retry++) {
  786.         if(_FS_SMC_Reassign_BlockHead(id)) {
  787.             if(_FS_SMC_ErrCode[id]==ERR_HwError) return(ERROR);
  788.             continue;
  789.         }
  790.         if(! _FS_SMC_Write_PhyOneSect(id,buf)) return(SUCCESS);
  791.         if(_FS_SMC_ErrCode[id]==ERR_HwError)    return(ERROR);
  792.     }
  793.     if(_FS_SMC_Release_WriteBlock(id))        return(ERROR);
  794.     _FS_SMC_ErrCode[id]=ERR_WriteFault;
  795.     return(ERROR);
  796. }
  797. /*********************************************************************
  798. *
  799. *             _FS_SMC_Media_CopyBlockHead
  800. */
  801. static int _FS_SMC_Media_CopyBlockHead(FS_u32 id)
  802. {
  803.     unsigned int retry;
  804.     for(retry=0; retry<2; retry++) {
  805.         if(! _FS_SMC_Copy_BlockHead(id))      return(SUCCESS);
  806.         if(_FS_SMC_ErrCode[id]==ERR_HwError)    return(ERROR);
  807.     }
  808.     return(ERROR);
  809. }
  810. /*********************************************************************
  811. *
  812. *             _FS_SMC_Media_CopyBlockTail
  813. */
  814. static int _FS_SMC_Media_CopyBlockTail(FS_u32 id)
  815. {
  816.     unsigned int retry;
  817.     if(! _FS_SMC_Copy_BlockTail(id))          return(SUCCESS);
  818.     if(_FS_SMC_ErrCode[id]==ERR_HwError)        return(ERROR);
  819.     for(retry=1; retry<2; retry++) {
  820.         if(_FS_SMC_Reassign_BlockHead(id)) {
  821.             if(_FS_SMC_ErrCode[id]==ERR_HwError) return(ERROR);
  822.             continue;
  823.         }
  824.         if(! _FS_SMC_Copy_BlockTail(id))      return(SUCCESS);
  825.         if(_FS_SMC_ErrCode[id]==ERR_HwError)    return(ERROR);
  826.     }
  827.     if(_FS_SMC_Release_WriteBlock(id))        return(ERROR);
  828.     _FS_SMC_ErrCode[id]=ERR_WriteFault;
  829.     return(ERROR);
  830. }
  831. /*********************************************************************
  832. *
  833. *             Global functions
  834. *
  835. **********************************************************************
  836. */
  837. /*********************************************************************
  838. *
  839. *             FS__SMC_ReadSector
  840. */
  841. int FS__SMC_ReadSector(FS_u32 id,unsigned long start,unsigned short count,unsigned char *buf)
  842. {
  843.     int i;
  844.     if(_FS_SMC_Chk_MediaPower(id))          return(_FS_SMC_ErrCode[id]);
  845.     if(_FS_SMC_Check_MediaFmt(id))          return(_FS_SMC_ErrCode[id]);
  846.     if(_FS_SMC_Conv_MediaAddr(id,start))    return(_FS_SMC_ErrCode[id]);
  847.     while(1) {
  848.         if(_FS_SMC_Media_ReadOneSect(id,_FS_SMC_SectBuf))
  849.           { _FS_SMC_ErrCode[id]=ERR_EccReadErr; return(_FS_SMC_ErrCode[id]); }
  850.         for(i=0;i<SECTSIZE;i++)
  851.             *buf++=_FS_SMC_SectBuf[i];
  852.         if(--count<=0)      break;
  853.         if(_FS_SMC_Inc_MediaAddr(id))         return(_FS_SMC_ErrCode[id]);
  854.     }
  855.     return(NO_ERROR);
  856. }
  857. /*********************************************************************
  858. *
  859. *             FS__SMC_WriteSector
  860. */
  861. int FS__SMC_WriteSector(FS_u32 id,unsigned long start,unsigned short count,unsigned char *buf)
  862. {
  863.     int i;
  864.     if(_FS_SMC_Chk_MediaPower(id))          return(_FS_SMC_ErrCode[id]);
  865.     if(_FS_SMC_Check_MediaFmt(id))          return(_FS_SMC_ErrCode[id]);
  866.     if(_FS_SMC_Chk_MediaWP(id))             return(_FS_SMC_ErrCode[id]);
  867.     if(_FS_SMC_Conv_MediaAddr(id,start))    return(_FS_SMC_ErrCode[id]);
  868.     if(_FS_SMC_Chk_FirstSect(id))
  869.         if(_FS_SMC_Media_CopyBlockHead(id))
  870.           { _FS_SMC_ErrCode[id]=ERR_WriteFault; return(_FS_SMC_ErrCode[id]); }
  871.     while(1) {
  872.         if(! _FS_SMC_Chk_FirstSect(id))
  873.             if(_FS_SMC_Assign_WriteBlock(id)) return(_FS_SMC_ErrCode[id]);
  874.         for(i=0;i<SECTSIZE;i++)
  875.             _FS_SMC_SectBuf[i]=*buf++;
  876.         if(_FS_SMC_Media_WriteOneSect(id,_FS_SMC_SectBuf))
  877.           { _FS_SMC_ErrCode[id]=ERR_WriteFault; return(_FS_SMC_ErrCode[id]); }
  878.         if(! _FS_SMC_Chk_LastSect(id)) {
  879.             if(_FS_SMC_Release_ReadBlock(id))
  880.                 if(_FS_SMC_ErrCode[id]==ERR_HwError) {
  881.                     _FS_SMC_ErrCode[id]=ERR_WriteFault;
  882.                     return(_FS_SMC_ErrCode[id]);
  883.                 }
  884.         }
  885.         if(--count<=0)      break;
  886.         if(_FS_SMC_Inc_MediaAddr(id))         return(_FS_SMC_ErrCode[id]);
  887.     }
  888.     if(! _FS_SMC_Chk_LastSect(id))          return(NO_ERROR);
  889.     if(_FS_SMC_Inc_MediaAddr(id))             return(_FS_SMC_ErrCode[id]);
  890.     if(_FS_SMC_Media_CopyBlockTail(id))
  891.         { _FS_SMC_ErrCode[id]=ERR_WriteFault;   return(_FS_SMC_ErrCode[id]); }
  892.     return(NO_ERROR);
  893. }
  894. /*********************************************************************
  895. *
  896. *             FS__SMC_Init
  897. */
  898. int FS__SMC_Init(FS_u32 id)
  899. {
  900.     _FS_SMC_Init_Media(id);
  901.     return(NO_ERROR);
  902. }
  903. #endif /* FS_USE_SMC_DRIVER */