uffs_nand_samsung.c

Go to the documentation of this file.
00001 
00007 #include "uffs/uffs_public.h"
00008 #include "uffs/uffs_ecc.h"
00009 #include <string.h>
00010 
00011 #define PFX "samsung NAND:"
00012 
00013 #define SAMSUNG_ECC_LEN             6
00014 #define SAMSUNG_SPARE_LENGTH        16
00015 #define SAMSUNG_BLOCK_STATUS_OFS    5
00016 
00021 struct uffs_SamsungSpareSt {
00022     u8 x[SAMSUNG_SPARE_LENGTH];
00023 };
00024 
00025 typedef struct uffs_SamsungSpareSt      uffs_SamsungSpare;      //NAND flash page spare
00026 
00027 
00028 
00036 URET Samsung_LoadPageSpare(uffs_Device *dev, int block, int page, uffs_Tags *tag)
00037 {
00038     uffs_SamsungSpare phi_spare;
00039     u8 * p = (u8 *)(tag);
00040     u8 * p_spare = (u8 *) &phi_spare;
00041     u32 ofs_end;
00042 
00043     dev->ops->ReadPage(dev, block, page, NULL, p_spare);
00044     
00046     memcpy(p, p_spare, SAMSUNG_BLOCK_STATUS_OFS);
00047     p += (SAMSUNG_BLOCK_STATUS_OFS);
00048     p_spare += SAMSUNG_BLOCK_STATUS_OFS;
00049     p_spare++;      //skip the status byte!
00050 
00051     ofs_end = (u32)(&(((uffs_Tags *)NULL)->blockStatus));
00052     memcpy(p, p_spare, ofs_end - (SAMSUNG_BLOCK_STATUS_OFS));
00053     tag->blockStatus = phi_spare.x[SAMSUNG_BLOCK_STATUS_OFS]; 
00054 
00055     return U_SUCC;
00056 }
00057 
00068 URET Samsung_WritePageSpare(uffs_Device *dev, int block, int page, uffs_Tags *tag)
00069 {
00070     uffs_SamsungSpare phi_spare;
00071     u8 * p = (u8 *)tag;
00072     u8 * p_spare = (u8 *) &phi_spare;
00073     u32 ofs_end;
00074     
00075     dev->ops->ReadPage(dev, block, page, NULL, (u8 *)(&phi_spare));
00076 
00077     if(page == 0 || page == 1) {
00078         if(phi_spare.x[SAMSUNG_BLOCK_STATUS_OFS] != 0xff) {
00079             uffs_Perror(UFFS_ERR_SERIOUS, PFX"try to write to a bad block(%d) ? \n", block);
00080             return U_FAIL;
00081         }
00082     }
00083 
00084     memcpy(p_spare, p, SAMSUNG_BLOCK_STATUS_OFS);   //copy bytes first
00085     p += (SAMSUNG_BLOCK_STATUS_OFS);
00086     p_spare += SAMSUNG_BLOCK_STATUS_OFS;            
00087     p_spare++;                                      //skip the status byte
00088     ofs_end = (u32)(&(((uffs_Tags *)NULL)->blockStatus));
00089     memcpy(p_spare, p, ofs_end - (SAMSUNG_BLOCK_STATUS_OFS));  //the rest bytes
00090 
00091     return dev->ops->WritePage(dev, block, page, NULL, (u8 *)(&phi_spare));
00092 }
00093 
00101 URET Samsung_MakePageValid(uffs_Device *dev, int block, int page, uffs_Tags *tag)
00102 {
00103     //tag->valid = TAG_VALID; //0: valid, 1: invalid
00104     return Samsung_WritePageSpare(dev, block, page, tag);
00105 }
00106 
00112 int Samsung_GetEccSize(uffs_Device *dev)
00113 {
00114     return SAMSUNG_ECC_LEN;
00115 }
00116 
00117 //using public ECC algorithm
00118 //URET Samsung_MakeEcc(uffs_Device *dev, void *data, int size, void *ecc)
00119 //{
00120 //  return U_SUCC;
00121 //}
00122 
00123 UBOOL Samsung_IsBlockBad(uffs_Device *dev, uffs_blockInfo *bc)
00124 {
00125     uffs_LoadBlockInfo(dev, bc, 0);
00126 #ifdef SAFE_CHECK_BAD_BLOCK_DOUBLE
00127     uffs_LoadBlockInfo(dev, bc, 1);
00128 #endif
00129     if(bc->spares[0].tag.blockStatus != 0xff
00130 #ifdef SAFE_CHECK_BAD_BLOCK_DOUBLE
00131          || bc->spares[1].tag.blockStatus != 0xff
00132 #endif
00133          ) {
00134         return U_TRUE;
00135     }
00136 
00137     return U_FALSE;
00138 }
00139 
00140 URET Samsung_MakeBadBlockMark(uffs_Device *dev, int block)
00141 {
00142     u8 mark = 0;
00143 
00144     dev->ops->ReadPageSpare(dev, block, 0, &mark, SAMSUNG_BLOCK_STATUS_OFS, 1);
00145     if(mark == 0xff){
00146         uffs_Perror(UFFS_ERR_NOISY, PFX"New bad block generated! %d\n", block);
00147         dev->ops->WritePageSpare(dev, block, 0, (u8 *)"1", SAMSUNG_BLOCK_STATUS_OFS, 1);
00148     }
00149     
00150     return U_SUCC;
00151 }
00152 
00153 
00154 static struct uffs_FlashOpsSt Samsung_Flash = {
00155     Samsung_LoadPageSpare,
00156     Samsung_WritePageSpare,
00157     Samsung_MakePageValid,
00158     uffs_GetEccSize512,
00159     uffs_MakeEcc512,
00160     uffs_EccCorrect512,
00161     Samsung_IsBlockBad,
00162     Samsung_MakeBadBlockMark
00163 };
00164  
00166 static int valid_id_list[] = {0xe3, 0xe5, 0xe6, 0x73, 0x75, 0x76, 0x79, 0x35, 0x36, -1};
00167 
00168 
00169 struct uffs_FlashClassSt Samsung_FlashClass = {
00170     "Samsung NAND",
00171     0xec,               /* Samsung Manufacture ID: 0xEC */
00172     valid_id_list,
00173     &Samsung_Flash,
00174 };
00175 
00176 

Generated on Sat Mar 17 15:45:45 2007 for uffs-doc by  doxygen 1.5.0