X-Git-Url: http://www.aleph1.co.uk/gitweb/?a=blobdiff_plain;f=yaffs_fileem.c;h=b850581d9b1e3da6ddee81f6fb87bf522a240786;hb=cacf6da20462fa436de86a66dcb6e5aa11ba76b1;hp=a137fb47fd14f79c498add26f9b6693fd0c72002;hpb=cefeada5db633fd3c37cde66e2e62c73052c18bd;p=yaffs%2F.git diff --git a/yaffs_fileem.c b/yaffs_fileem.c index a137fb4..b850581 100644 --- a/yaffs_fileem.c +++ b/yaffs_fileem.c @@ -14,7 +14,7 @@ */ //yaffs_fileem.c -#include "yaffs_nandif.h" +#include "yaffs_fileem.h" #include "yaffs_guts.h" #include "yaffsinterface.h" @@ -26,7 +26,7 @@ #include #include -#define FILE_SIZE_IN_MEG 2 +#define FILE_SIZE_IN_MEG 32 #define BLOCK_SIZE (32 * 528) #define BLOCKS_PER_MEG ((1024*1024)/(32 * 512)) @@ -37,9 +37,91 @@ static int h; static __u8 ffChunk[528]; +static int eraseDisplayEnabled; +static int markedBadBlocks[] = { 1, 4, -1}; -static void CheckInit(void) +static int IsAMarkedBadBlock(int blk) +{ + int *m = markedBadBlocks; + + while(*m >= 0) + { + if(*m == blk) return 1; + m++; + } + return 0; +} + + +static __u8 yaffs_WriteFailCorruption(int chunkInNAND) +{ + + // Whole blocks that fail + switch(chunkInNAND/YAFFS_CHUNKS_PER_BLOCK) + { + case 50: + case 52: + return 7; + } + + // Single blocks that fail + switch(chunkInNAND) + { + case 2000: + case 2003: + case 3000: + case 3001: + return 3;// ding two bits + case 2001: + case 3003: + case 3004: + case 3005: + case 3006: + case 3007: return 1;// ding one bit + + + } + + return 0; +} + +static void yaffs_ModifyWriteData(int chunkInNAND,__u8 *data) +{ + if(data) + { + *data ^= yaffs_WriteFailCorruption(chunkInNAND); + } +} + +static __u8 yaffs_ReadFailCorruption(int chunkInNAND) +{ + switch(chunkInNAND) + { + case 500: + return 3;// ding two bits + case 700: + case 750: + return 1;// ding one bit + + default: return 0; + + } +} + +static void yaffs_ModifyReadData(int chunkInNAND,__u8 *data) +{ + if(data) + { + *data ^= yaffs_ReadFailCorruption(chunkInNAND); + } +} + + + + + +static void CheckInit(yaffs_Device *dev) { static int initialised = 0; @@ -67,25 +149,39 @@ static void CheckInit(void) printf("Creating emulation file...\n"); for(i = 0; i < FILE_SIZE_IN_BLOCKS; i++) { - yaffs_EraseBlockInNAND(i); + yaffs_FEEraseBlockInNAND(dev,i); + + if(IsAMarkedBadBlock(i)) + { + yaffs_Spare spare; + memset(&spare,0xff,sizeof(spare)); + spare.blockStatus = 1; + + yaffs_FEWriteChunkToNAND(dev, i * 32,NULL,&spare); + } } } + eraseDisplayEnabled = 1; } } -int yaffs_WriteChunkToNAND(int chunkInNAND,__u8 *data, yaffs_Spare *spare) +int yaffs_FEWriteChunkToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_Spare *spare) { + __u8 localData[512]; + int pos; pos = chunkInNAND * 528; - CheckInit(); + CheckInit(dev); if(data) { + memcpy(localData,data,512); + yaffs_ModifyWriteData(chunkInNAND,localData); lseek(h,pos,SEEK_SET); - write(h,data,512); + write(h,localData,512); } pos += 512; @@ -100,19 +196,20 @@ int yaffs_WriteChunkToNAND(int chunkInNAND,__u8 *data, yaffs_Spare *spare) } -int yaffs_ReadChunkFromNAND(int chunkInNAND, __u8 *data, yaffs_Spare *spare) +int yaffs_FEReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare) { int pos; pos = chunkInNAND * 528; - CheckInit(); + CheckInit(dev); if(data) { lseek(h,pos,SEEK_SET); read(h,data,512); + yaffs_ModifyReadData(chunkInNAND,data); } pos += 512; @@ -127,19 +224,33 @@ int yaffs_ReadChunkFromNAND(int chunkInNAND, __u8 *data, yaffs_Spare *spare) } -int yaffs_EraseBlockInNAND(int blockInNAND) +int yaffs_FEEraseBlockInNAND(yaffs_Device *dev,int blockInNAND) { int i; - CheckInit(); + CheckInit(dev); - printf("Erasing block %d\n",blockInNAND); + if(eraseDisplayEnabled) + { + printf("Erasing block %d\n",blockInNAND); + } lseek(h,blockInNAND * BLOCK_SIZE,SEEK_SET); for(i = 0; i < 32; i++) { write(h,ffChunk,528); } + + switch(blockInNAND) + { + case 10: + case 15: return YAFFS_FAIL; + + } return YAFFS_OK; } +int yaffs_FEInitialiseNAND(yaffs_Device *dev) +{ + return YAFFS_OK; +}